From 41e60bf5518ac088a48e5450ed001cdb5514f443 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Fri, 30 Mar 2012 01:38:03 +0200 Subject: [PATCH] --- yaml --- r: 305407 b: refs/heads/master c: 35372a7d45291140a97518a8d1c8cb0e31ee2bb7 h: refs/heads/master i: 305405: c6b14cb48d0f454e67ee99d086ca2ebb37eb123c 305403: 833d2060237c5f868c23f1a92e8ae940a411526b 305399: 74ff1bbe67c2344535cef87cdabf2514a06b2cae 305391: 562839f30d50a4ad8a425296c925bb2b591ece1e 305375: db283aa4b3dfbbfdd09e27689589d8d190b300aa 305343: 9ae7c620880643258e6ca2e38d723e16c068f8fd 305279: 5277092bcb2cc8d6bd166c44c2300a8c3e6a155a 305151: 19a987b541cab7be76d8bdb054989b08c0713595 v: v3 --- [refs] | 2 +- .../ABI/stable/sysfs-driver-usb-usbtmc | 16 +- .../ABI/testing/sysfs-block-rssd | 18 - .../sysfs-bus-event_source-devices-format | 14 - trunk/Documentation/ABI/testing/sysfs-bus-hsi | 19 - .../ABI/testing/sysfs-cfq-target-latency | 8 - .../ABI/testing/sysfs-firmware-acpi | 20 - trunk/Documentation/CodingStyle | 29 - trunk/Documentation/DMA-attributes.txt | 18 - .../Documentation/DocBook/device-drivers.tmpl | 17 - .../DocBook/media/v4l/pixfmt-nv12m.xml | 2 +- .../DocBook/media/v4l/pixfmt-yuv420m.xml | 2 +- trunk/Documentation/acpi/apei/einj.txt | 8 - trunk/Documentation/aoe/aoe.txt | 2 +- trunk/Documentation/aoe/autoload.sh | 4 +- trunk/Documentation/blockdev/floppy.txt | 2 +- trunk/Documentation/cgroups/cpusets.txt | 2 +- trunk/Documentation/cgroups/memory.txt | 5 +- trunk/Documentation/cpu-hotplug.txt | 22 +- trunk/Documentation/cpuidle/sysfs.txt | 5 - .../{ahci-platform.txt => calxeda-sata.txt} | 5 +- .../devicetree/bindings/mtd/atmel-nand.txt | 10 +- .../devicetree/bindings/mtd/fsmc-nand.txt | 33 - .../devicetree/bindings/mtd/spear_smi.txt | 31 - .../power_supply/max17042_battery.txt | 18 - .../bindings/regulator/anatop-regulator.txt | 29 - .../devicetree/bindings/sound/sgtl5000.txt | 2 - trunk/Documentation/dontdiff | 1 + trunk/Documentation/fb/intel810.txt | 2 +- trunk/Documentation/fb/intelfb.txt | 2 +- .../feature-removal-schedule.txt | 26 +- trunk/Documentation/filesystems/vfs.txt | 2 +- trunk/Documentation/hwmon/k10temp | 2 +- trunk/Documentation/i2c/busses/scx200_acb | 2 +- trunk/Documentation/ide/ide.txt | 2 +- trunk/Documentation/input/input.txt | 4 +- trunk/Documentation/ioctl/ioctl-number.txt | 1 - trunk/Documentation/isdn/README.gigaset | 16 +- trunk/Documentation/kbuild/kconfig.txt | 8 +- trunk/Documentation/laptops/sonypi.txt | 2 +- trunk/Documentation/mono.txt | 8 +- trunk/Documentation/networking/baycom.txt | 2 +- trunk/Documentation/networking/bonding.txt | 46 +- trunk/Documentation/networking/dl2k.txt | 11 +- trunk/Documentation/networking/driver.txt | 31 +- trunk/Documentation/networking/e100.txt | 6 +- trunk/Documentation/networking/ip-sysctl.txt | 15 +- trunk/Documentation/networking/ipv6.txt | 6 +- trunk/Documentation/networking/ixgb.txt | 6 +- trunk/Documentation/networking/ltpc.txt | 2 +- trunk/Documentation/networking/netdevices.txt | 25 +- trunk/Documentation/networking/vortex.txt | 6 +- trunk/Documentation/parport.txt | 13 +- .../Documentation/power/freezing-of-tasks.txt | 37 +- trunk/Documentation/s390/3270.txt | 21 +- trunk/Documentation/scsi/00-INDEX | 2 - trunk/Documentation/scsi/aic79xx.txt | 2 +- trunk/Documentation/scsi/aic7xxx.txt | 2 +- trunk/Documentation/scsi/osst.txt | 2 +- trunk/Documentation/scsi/st.txt | 4 - trunk/Documentation/scsi/ufs.txt | 133 - trunk/Documentation/security/keys.txt | 14 +- trunk/Documentation/serial/computone.txt | 8 +- trunk/Documentation/serial/rocket.txt | 2 +- trunk/Documentation/serial/stallion.txt | 4 +- .../sound/alsa/ALSA-Configuration.txt | 10 +- .../sound/alsa/Audiophile-Usb.txt | 4 +- .../sound/alsa/HD-Audio-Models.txt | 4 +- trunk/Documentation/sound/alsa/MIXART.txt | 6 +- .../sound/alsa/OSS-Emulation.txt | 2 +- trunk/Documentation/sound/oss/AudioExcelDSP16 | 10 +- trunk/Documentation/sound/oss/CMI8330 | 5 +- trunk/Documentation/sound/oss/Introduction | 10 +- trunk/Documentation/sound/oss/Opti | 8 +- trunk/Documentation/sound/oss/PAS16 | 4 +- trunk/Documentation/sound/oss/README.modules | 10 +- trunk/Documentation/sysrq.txt | 5 +- trunk/Documentation/usb/URB.txt | 22 - trunk/Documentation/usb/power-management.txt | 3 +- trunk/Documentation/usb/usbmon.txt | 6 +- trunk/Documentation/video4linux/CQcam.txt | 14 +- trunk/Documentation/video4linux/Zoran | 2 +- .../video4linux/bttv/Modules.conf | 2 +- trunk/Documentation/video4linux/meye.txt | 2 +- trunk/MAINTAINERS | 104 +- trunk/Makefile | 6 +- trunk/arch/alpha/Kconfig | 2 +- trunk/arch/alpha/include/asm/atomic.h | 68 +- trunk/arch/alpha/include/asm/cmpxchg.h | 71 - trunk/arch/alpha/include/asm/dma-mapping.h | 18 +- trunk/arch/alpha/include/asm/rtc.h | 8 +- trunk/arch/alpha/include/asm/xchg.h | 4 +- trunk/arch/alpha/kernel/core_tsunami.c | 1 - trunk/arch/alpha/kernel/pci-noop.c | 10 +- trunk/arch/alpha/kernel/pci_iommu.c | 10 +- trunk/arch/alpha/kernel/signal.c | 31 +- trunk/arch/alpha/kernel/smp.c | 2 +- trunk/arch/alpha/kernel/sys_marvel.c | 2 +- trunk/arch/arm/Kconfig | 10 - trunk/arch/arm/boot/Makefile | 23 +- trunk/arch/arm/boot/compressed/atags_to_fdt.c | 2 - trunk/arch/arm/boot/compressed/head.S | 2 +- trunk/arch/arm/boot/dts/at91sam9g20.dtsi | 3 +- trunk/arch/arm/boot/dts/at91sam9g25ek.dts | 4 +- trunk/arch/arm/boot/dts/at91sam9g45.dtsi | 3 +- trunk/arch/arm/boot/dts/at91sam9m10g45ek.dts | 6 +- trunk/arch/arm/boot/dts/at91sam9x5.dtsi | 7 +- trunk/arch/arm/boot/dts/at91sam9x5cm.dtsi | 2 +- trunk/arch/arm/boot/dts/db8500.dtsi | 1 + trunk/arch/arm/boot/dts/highbank.dts | 1 + trunk/arch/arm/boot/dts/msm8660-surf.dts | 4 +- trunk/arch/arm/boot/dts/usb_a9g20.dts | 2 +- trunk/arch/arm/boot/dts/versatile-ab.dts | 2 +- trunk/arch/arm/boot/dts/versatile-pb.dts | 2 +- trunk/arch/arm/common/vic.c | 9 +- trunk/arch/arm/configs/imx_v4_v5_defconfig | 1 - trunk/arch/arm/configs/mini2440_defconfig | 2 - trunk/arch/arm/configs/u8500_defconfig | 9 +- trunk/arch/arm/include/asm/barrier.h | 2 +- trunk/arch/arm/include/asm/cpuidle.h | 29 - trunk/arch/arm/include/asm/io.h | 2 +- trunk/arch/arm/include/asm/jump_label.h | 2 +- trunk/arch/arm/include/asm/thread_info.h | 7 - trunk/arch/arm/include/asm/tls.h | 4 - trunk/arch/arm/kernel/Makefile | 2 +- trunk/arch/arm/kernel/bios32.c | 1 + trunk/arch/arm/kernel/cpuidle.c | 21 - trunk/arch/arm/kernel/insn.c | 1 - trunk/arch/arm/kernel/irq.c | 6 +- trunk/arch/arm/kernel/kprobes.c | 2 +- trunk/arch/arm/kernel/ptrace.c | 4 +- trunk/arch/arm/kernel/setup.c | 16 +- trunk/arch/arm/kernel/signal.c | 55 +- trunk/arch/arm/kernel/smp.c | 29 +- trunk/arch/arm/mach-at91/at91rm9200_devices.c | 1 + trunk/arch/arm/mach-at91/at91rm9200_time.c | 2 - .../arch/arm/mach-at91/at91sam9260_devices.c | 3 - .../arch/arm/mach-at91/at91sam9261_devices.c | 3 - .../arch/arm/mach-at91/at91sam9263_devices.c | 6 +- .../arch/arm/mach-at91/at91sam9g45_devices.c | 11 +- trunk/arch/arm/mach-at91/at91sam9rl_devices.c | 3 - trunk/arch/arm/mach-at91/at91sam9x5.c | 2 - trunk/arch/arm/mach-at91/at91x40.c | 1 - trunk/arch/arm/mach-at91/board-rm9200ek.c | 2 +- trunk/arch/arm/mach-at91/board-sam9261ek.c | 5 +- trunk/arch/arm/mach-at91/board-sam9263ek.c | 1 - trunk/arch/arm/mach-at91/board-sam9m10g45ek.c | 1 - trunk/arch/arm/mach-at91/clock.c | 1 - trunk/arch/arm/mach-at91/cpuidle.c | 59 +- .../arm/mach-at91/include/mach/at91_pmc.h | 2 +- trunk/arch/arm/mach-at91/include/mach/board.h | 13 +- trunk/arch/arm/mach-at91/include/mach/io.h | 27 - trunk/arch/arm/mach-at91/setup.c | 3 - trunk/arch/arm/mach-bcmring/core.c | 4 +- trunk/arch/arm/mach-clps711x/edb7211-mm.c | 1 - trunk/arch/arm/mach-davinci/cpuidle.c | 83 +- trunk/arch/arm/mach-exynos/Kconfig | 2 - trunk/arch/arm/mach-exynos/clock-exynos4.c | 24 +- trunk/arch/arm/mach-exynos/clock-exynos5.c | 24 +- trunk/arch/arm/mach-exynos/common.c | 17 +- trunk/arch/arm/mach-exynos/dev-dwmci.c | 13 +- trunk/arch/arm/mach-exynos/dma.c | 2 + .../mach-exynos/include/mach/debug-macro.S | 7 +- .../arch/arm/mach-exynos/include/mach/irqs.h | 2 - trunk/arch/arm/mach-exynos/include/mach/map.h | 4 - .../arm/mach-exynos/include/mach/regs-clock.h | 6 - .../arm/mach-exynos/include/mach/uncompress.h | 17 +- trunk/arch/arm/mach-exynos/mach-exynos5-dt.c | 2 +- trunk/arch/arm/mach-exynos/mach-nuri.c | 47 +- .../arm/mach-exynos/mach-universal_c210.c | 3 - trunk/arch/arm/mach-h720x/common.c | 1 - trunk/arch/arm/mach-imx/clock-imx27.c | 1 - trunk/arch/arm/mach-imx/clock-imx35.c | 2 +- trunk/arch/arm/mach-imx/imx27-dt.c | 6 +- trunk/arch/arm/mach-imx/mach-armadillo5x0.c | 9 - trunk/arch/arm/mach-imx/mach-kzm_arm11_01.c | 9 - trunk/arch/arm/mach-imx/mach-mx31lilly.c | 9 - trunk/arch/arm/mach-imx/mach-mx31lite.c | 9 - trunk/arch/arm/mach-imx/mach-mx35_3ds.c | 2 +- trunk/arch/arm/mach-imx/mach-mx53_ard.c | 8 - trunk/arch/arm/mach-imx/mm-imx3.c | 1 - trunk/arch/arm/mach-imx/mm-imx5.c | 3 +- trunk/arch/arm/mach-ixp23xx/core.c | 1 - trunk/arch/arm/mach-ixp4xx/common.c | 1 - trunk/arch/arm/mach-kirkwood/cpuidle.c | 72 +- trunk/arch/arm/mach-msm/board-halibut.c | 3 + trunk/arch/arm/mach-msm/board-msm8x60.c | 25 +- trunk/arch/arm/mach-msm/board-trout-panel.c | 1 - trunk/arch/arm/mach-msm/board-trout.c | 1 - .../arm/mach-msm/include/mach/uncompress.h | 1 - trunk/arch/arm/mach-msm/proc_comm.c | 2 +- trunk/arch/arm/mach-msm/smd_debug.c | 8 +- .../arm/mach-mxs/include/mach/dma.h} | 0 trunk/arch/arm/mach-omap1/flash.c | 20 +- trunk/arch/arm/mach-omap1/include/mach/io.h | 45 - trunk/arch/arm/mach-omap1/mux.c | 1 - trunk/arch/arm/mach-omap1/timer.c | 4 +- trunk/arch/arm/mach-omap2/board-4430sdp.c | 12 +- trunk/arch/arm/mach-omap2/board-cm-t35.c | 16 - trunk/arch/arm/mach-omap2/board-generic.c | 2 +- trunk/arch/arm/mach-omap2/board-igep0020.c | 6 - trunk/arch/arm/mach-omap2/board-ldp.c | 7 - trunk/arch/arm/mach-omap2/board-omap3evm.c | 15 +- trunk/arch/arm/mach-omap2/board-omap3logic.c | 7 - .../arch/arm/mach-omap2/board-omap3stalker.c | 16 +- trunk/arch/arm/mach-omap2/board-omap4panda.c | 13 +- trunk/arch/arm/mach-omap2/board-overo.c | 8 - .../arm/mach-omap2/board-zoom-debugboard.c | 9 - .../arm/mach-omap2/clkt2xxx_virt_prcm_set.c | 80 + trunk/arch/arm/mach-omap2/clock.c | 5 + trunk/arch/arm/mach-omap2/clock.h | 8 + trunk/arch/arm/mach-omap2/clock3xxx_data.c | 18 +- trunk/arch/arm/mach-omap2/clock44xx_data.c | 5 +- .../arm/mach-omap2/clockdomains44xx_data.c | 2 +- trunk/arch/arm/mach-omap2/cpuidle34xx.c | 42 +- trunk/arch/arm/mach-omap2/cpuidle44xx.c | 21 +- trunk/arch/arm/mach-omap2/gpmc-smsc911x.c | 65 +- trunk/arch/arm/mach-omap2/hsmmc.c | 7 - .../arm/mach-omap2/include/mach/barriers.h | 2 - trunk/arch/arm/mach-omap2/omap_hwmod.c | 85 +- .../arm/mach-omap2/omap_hwmod_2420_data.c | 1 + .../arm/mach-omap2/omap_hwmod_2430_data.c | 1 + .../arm/mach-omap2/omap_hwmod_3xxx_data.c | 1 + .../arm/mach-omap2/omap_hwmod_44xx_data.c | 37 - trunk/arch/arm/mach-omap2/opp.c | 4 +- trunk/arch/arm/mach-omap2/pm34xx.c | 38 +- trunk/arch/arm/mach-omap2/pm44xx.c | 10 +- trunk/arch/arm/mach-omap2/powerdomain.c | 8 +- trunk/arch/arm/mach-omap2/prm44xx.c | 21 +- trunk/arch/arm/mach-omap2/prm_common.c | 2 +- trunk/arch/arm/mach-omap2/serial.c | 124 +- trunk/arch/arm/mach-omap2/twl-common.c | 37 +- trunk/arch/arm/mach-omap2/twl-common.h | 10 +- trunk/arch/arm/mach-omap2/usb-host.c | 10 +- trunk/arch/arm/mach-pxa/Kconfig | 1 - trunk/arch/arm/mach-pxa/include/mach/io.h | 17 - .../arm/mach-pxa/include/mach/mfp-pxa2xx.h | 7 - trunk/arch/arm/mach-pxa/mfp-pxa2xx.c | 21 +- trunk/arch/arm/mach-pxa/pxa27x.c | 6 +- trunk/arch/arm/mach-pxa/raumfeld.c | 2 - trunk/arch/arm/mach-s3c24xx/Kconfig | 8 +- trunk/arch/arm/mach-s3c24xx/common.h | 18 - trunk/arch/arm/mach-s3c24xx/simtec-nor.c | 3 + trunk/arch/arm/mach-s5pv210/dma.c | 2 + trunk/arch/arm/mach-s5pv210/mach-aquila.c | 4 +- trunk/arch/arm/mach-s5pv210/mach-goni.c | 6 +- trunk/arch/arm/mach-sa1100/collie.c | 4 - trunk/arch/arm/mach-sa1100/generic.c | 2 +- .../arm/mach-sa1100/include/mach/collie.h | 3 +- trunk/arch/arm/mach-shark/core.c | 1 - trunk/arch/arm/mach-shmobile/board-mackerel.c | 71 - trunk/arch/arm/mach-shmobile/clock-sh7372.c | 4 +- trunk/arch/arm/mach-shmobile/cpuidle.c | 31 +- trunk/arch/arm/mach-u300/core.c | 8 +- trunk/arch/arm/mach-u300/i2c.c | 9 +- trunk/arch/arm/mach-u300/include/mach/irqs.h | 150 +- .../arm/mach-u300/include/mach/u300-regs.h | 5 - trunk/arch/arm/mach-ux500/Kconfig | 1 - trunk/arch/arm/mach-ux500/mbox-db5500.c | 2 +- trunk/arch/arm/mach-ux500/platsmp.c | 2 +- trunk/arch/arm/mach-versatile/pci.c | 10 +- trunk/arch/arm/mach-w90x900/dev.c | 1 - trunk/arch/arm/mm/Kconfig | 2 +- trunk/arch/arm/mm/abort-ev6.S | 17 +- trunk/arch/arm/mm/cache-l2x0.c | 25 +- trunk/arch/arm/mm/fault.c | 2 +- trunk/arch/arm/mm/init.c | 4 +- trunk/arch/arm/mm/mmu.c | 4 +- trunk/arch/arm/mm/nommu.c | 2 - trunk/arch/arm/mm/proc-v7.S | 12 - trunk/arch/arm/plat-mxc/3ds_debugboard.c | 2 +- trunk/arch/arm/plat-omap/Kconfig | 1 - trunk/arch/arm/plat-omap/clock.c | 31 +- trunk/arch/arm/plat-omap/dma.c | 14 - trunk/arch/arm/plat-omap/include/plat/clock.h | 10 + .../arm/plat-omap/include/plat/omap_hwmod.h | 16 +- trunk/arch/arm/plat-omap/sram.c | 12 +- trunk/arch/arm/plat-s3c24xx/cpu.c | 1 - trunk/arch/arm/plat-samsung/Kconfig | 1 - .../arm/plat-samsung/include/plat/sdhci.h | 28 - trunk/arch/arm/vfp/vfpmodule.c | 99 - trunk/arch/avr32/boot/images/Makefile | 9 +- trunk/arch/avr32/include/asm/barrier.h | 2 - trunk/arch/avr32/include/asm/special_insns.h | 13 + .../avr32/mach-at32ap/include/mach/board.h | 2 +- trunk/arch/blackfin/Kconfig | 2 +- trunk/arch/blackfin/boot/Makefile | 19 +- .../blackfin/configs/BF527-EZKIT_defconfig | 1 - trunk/arch/blackfin/include/asm/cmpxchg.h | 3 +- trunk/arch/blackfin/include/asm/gpio.h | 14 +- trunk/arch/blackfin/kernel/setup.c | 7 +- trunk/arch/blackfin/mach-bf538/boards/ezkit.c | 53 +- trunk/arch/c6x/include/asm/irq.h | 4 + trunk/arch/c6x/kernel/irq.c | 13 + trunk/arch/c6x/kernel/signal.c | 16 +- trunk/arch/frv/mb93090-mb00/pci-dma.c | 1 - trunk/arch/hexagon/include/asm/dma-mapping.h | 18 +- trunk/arch/hexagon/kernel/dma.c | 10 +- trunk/arch/hexagon/kernel/process.c | 6 +- trunk/arch/hexagon/kernel/ptrace.c | 1 - trunk/arch/hexagon/kernel/smp.c | 16 +- trunk/arch/hexagon/kernel/time.c | 1 - trunk/arch/hexagon/kernel/vdso.c | 1 - trunk/arch/ia64/hp/common/sba_iommu.c | 11 +- trunk/arch/ia64/include/asm/cmpxchg.h | 148 +- trunk/arch/ia64/include/asm/dma-mapping.h | 18 +- trunk/arch/ia64/include/asm/futex.h | 9 +- trunk/arch/ia64/include/asm/intrinsics.h | 114 +- trunk/arch/ia64/kernel/acpi.c | 2 +- trunk/arch/ia64/kernel/pci-swiotlb.c | 14 +- trunk/arch/ia64/kernel/perfmon.c | 18 +- trunk/arch/ia64/sn/pci/pci_dma.c | 9 +- trunk/arch/m68k/configs/m5275evb_defconfig | 1 + trunk/arch/m68k/include/asm/atomic.h | 1 - trunk/arch/m68k/mac/config.c | 3 - trunk/arch/m68k/platform/527x/config.c | 2 + trunk/arch/m68k/platform/68EZ328/Makefile | 6 + .../platform/{68VZ328 => 68EZ328}/bootlogo.h | 2 +- trunk/arch/m68k/platform/68VZ328/Makefile | 9 +- trunk/arch/m68k/platform/coldfire/device.c | 2 +- trunk/arch/m68k/q40/config.c | 3 - trunk/arch/microblaze/boot/Makefile | 10 +- trunk/arch/microblaze/include/asm/cmpxchg.h | 2 - .../arch/microblaze/include/asm/dma-mapping.h | 18 +- trunk/arch/microblaze/include/asm/futex.h | 2 +- trunk/arch/microblaze/include/asm/processor.h | 4 +- trunk/arch/microblaze/kernel/dma.c | 10 +- trunk/arch/microblaze/kernel/early_printk.c | 2 - trunk/arch/microblaze/kernel/setup.c | 2 - trunk/arch/microblaze/kernel/unwind.c | 1 - trunk/arch/microblaze/lib/uaccess_old.S | 98 +- trunk/arch/mips/ath79/dev-wmac.c | 2 +- trunk/arch/mips/cavium-octeon/dma-octeon.c | 12 +- trunk/arch/mips/cavium-octeon/flash_setup.c | 2 +- trunk/arch/mips/cavium-octeon/smp.c | 4 +- trunk/arch/mips/include/asm/dma-mapping.h | 18 +- trunk/arch/mips/include/asm/mach-jz4740/irq.h | 2 +- trunk/arch/mips/include/asm/mmu_context.h | 6 + trunk/arch/mips/kernel/mips-mt-fpaff.c | 2 +- trunk/arch/mips/kernel/proc.c | 2 +- trunk/arch/mips/kernel/signal.c | 27 +- trunk/arch/mips/kernel/signal32.c | 20 +- trunk/arch/mips/kernel/signal_n32.c | 10 +- trunk/arch/mips/kernel/smp-bmips.c | 2 +- trunk/arch/mips/kernel/smp.c | 27 +- trunk/arch/mips/kernel/smtc.c | 2 +- trunk/arch/mips/mm/c-octeon.c | 6 +- trunk/arch/mips/mm/dma-default.c | 8 +- trunk/arch/mips/netlogic/common/smp.c | 6 +- trunk/arch/mips/pmc-sierra/yosemite/smp.c | 8 +- trunk/arch/mips/sgi-ip27/ip27-smp.c | 2 +- trunk/arch/mips/sibyte/bcm1480/smp.c | 7 +- trunk/arch/mips/sibyte/sb1250/smp.c | 7 +- trunk/arch/parisc/include/asm/atomic.h | 107 +- trunk/arch/parisc/include/asm/cmpxchg.h | 116 - trunk/arch/parisc/include/asm/futex.h | 31 +- trunk/arch/parisc/kernel/pdc_cons.c | 2 +- trunk/arch/parisc/kernel/smp.c | 3 +- .../boot/dts/fsl/pq3-mpic-message-B.dtsi | 43 - trunk/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi | 10 - trunk/arch/powerpc/boot/dts/p1020mbg-pc.dtsi | 151 - .../arch/powerpc/boot/dts/p1020mbg-pc_32b.dts | 89 - .../arch/powerpc/boot/dts/p1020mbg-pc_36b.dts | 89 - trunk/arch/powerpc/boot/dts/p1020utm-pc.dtsi | 140 - .../arch/powerpc/boot/dts/p1020utm-pc_32b.dts | 89 - .../arch/powerpc/boot/dts/p1020utm-pc_36b.dts | 89 - trunk/arch/powerpc/boot/dts/p2041rdb.dts | 3 + trunk/arch/powerpc/boot/dts/p3041ds.dts | 4 + trunk/arch/powerpc/boot/dts/p3060qds.dts | 2 + trunk/arch/powerpc/boot/dts/p4080ds.dts | 3 + trunk/arch/powerpc/boot/dts/p5020ds.dts | 4 + .../powerpc/configs/corenet32_smp_defconfig | 1 - .../powerpc/configs/corenet64_smp_defconfig | 2 - trunk/arch/powerpc/configs/mpc85xx_defconfig | 1 - .../powerpc/configs/mpc85xx_smp_defconfig | 1 - trunk/arch/powerpc/include/asm/dma-mapping.h | 24 +- trunk/arch/powerpc/include/asm/epapr_hcalls.h | 7 +- trunk/arch/powerpc/include/asm/fsl_guts.h | 26 +- trunk/arch/powerpc/include/asm/irq.h | 6 + trunk/arch/powerpc/include/asm/mpic.h | 18 + trunk/arch/powerpc/include/asm/mpic_msgr.h | 1 - trunk/arch/powerpc/include/asm/reg_booke.h | 5 + trunk/arch/powerpc/kernel/dma-iommu.c | 10 +- trunk/arch/powerpc/kernel/dma-swiotlb.c | 4 +- trunk/arch/powerpc/kernel/dma.c | 10 +- trunk/arch/powerpc/kernel/entry_32.S | 39 +- trunk/arch/powerpc/kernel/fadump.c | 2 - trunk/arch/powerpc/kernel/ibmebus.c | 10 +- trunk/arch/powerpc/kernel/irq.c | 12 +- trunk/arch/powerpc/kernel/kgdb.c | 1 - trunk/arch/powerpc/kernel/machine_kexec.c | 7 +- trunk/arch/powerpc/kernel/process.c | 4 +- trunk/arch/powerpc/kernel/setup_32.c | 3 - trunk/arch/powerpc/kernel/vio.c | 14 +- trunk/arch/powerpc/kvm/book3s_emulate.c | 1 - trunk/arch/powerpc/kvm/book3s_hv_builtin.c | 9 +- trunk/arch/powerpc/kvm/book3s_hv_interrupts.S | 8 +- trunk/arch/powerpc/kvm/book3s_interrupts.S | 7 - .../arch/powerpc/kvm/book3s_paired_singles.c | 1 - trunk/arch/powerpc/kvm/book3s_pr.c | 10 +- trunk/arch/powerpc/kvm/booke_interrupts.S | 7 +- trunk/arch/powerpc/net/bpf_jit.h | 8 +- trunk/arch/powerpc/net/bpf_jit_64.S | 108 +- trunk/arch/powerpc/net/bpf_jit_comp.c | 26 +- .../arch/powerpc/platforms/52xx/mpc52xx_pci.c | 2 +- trunk/arch/powerpc/platforms/85xx/common.c | 6 - .../arch/powerpc/platforms/85xx/mpc85xx_mds.c | 13 +- .../arch/powerpc/platforms/85xx/mpc85xx_rdb.c | 2 +- trunk/arch/powerpc/platforms/85xx/p1022_ds.c | 17 +- .../powerpc/platforms/86xx/mpc8610_hpcd.c | 2 +- trunk/arch/powerpc/platforms/cell/axon_msi.c | 8 +- .../powerpc/platforms/cell/beat_interrupt.c | 4 +- trunk/arch/powerpc/platforms/cell/iommu.c | 16 +- .../arch/powerpc/platforms/cell/qpace_setup.c | 2 +- trunk/arch/powerpc/platforms/cell/setup.c | 2 +- .../arch/powerpc/platforms/powermac/low_i2c.c | 9 - trunk/arch/powerpc/platforms/powermac/pic.c | 6 +- trunk/arch/powerpc/platforms/powermac/smp.c | 2 +- trunk/arch/powerpc/platforms/ps3/interrupt.c | 3 +- trunk/arch/powerpc/platforms/ps3/system-bus.c | 13 +- trunk/arch/powerpc/platforms/pseries/Kconfig | 4 +- trunk/arch/powerpc/platforms/pseries/eeh.c | 2 +- .../powerpc/platforms/pseries/eeh_event.c | 4 +- trunk/arch/powerpc/sysdev/cpm2_pic.c | 3 +- trunk/arch/powerpc/sysdev/mpc8xx_pic.c | 61 +- trunk/arch/powerpc/sysdev/mpic.c | 54 +- trunk/arch/powerpc/sysdev/mpic_msgr.c | 12 +- trunk/arch/powerpc/sysdev/qe_lib/qe.c | 22 +- trunk/arch/powerpc/sysdev/scom.c | 1 - trunk/arch/powerpc/sysdev/xics/xics-common.c | 7 +- trunk/arch/s390/Kconfig | 1 + trunk/arch/s390/defconfig | 37 +- trunk/arch/s390/include/asm/cpu_mf.h | 2 - trunk/arch/s390/include/asm/facility.h | 3 +- trunk/arch/s390/include/asm/mmu.h | 2 - trunk/arch/s390/include/asm/pgalloc.h | 3 + trunk/arch/s390/include/asm/swab.h | 2 +- trunk/arch/s390/include/asm/tlb.h | 22 +- trunk/arch/s390/kernel/head.S | 2 +- trunk/arch/s390/kernel/irq.c | 9 +- trunk/arch/s390/kernel/lgr.c | 1 - trunk/arch/s390/kernel/perf_cpum_cf.c | 6 +- trunk/arch/s390/kernel/perf_event.c | 1 + trunk/arch/s390/kernel/setup.c | 1 - trunk/arch/s390/kernel/smp.c | 2 - trunk/arch/s390/mm/maccess.c | 27 +- trunk/arch/s390/mm/pgtable.c | 63 +- trunk/arch/sh/Kconfig.debug | 1 - trunk/arch/sh/boards/board-sh7785lcr.c | 1 - trunk/arch/sh/boards/mach-hp6xx/pm.c | 1 - trunk/arch/sh/boot/Makefile | 8 +- trunk/arch/sh/drivers/dma/dma-sysfs.c | 2 +- trunk/arch/sh/include/asm/atomic.h | 2 +- trunk/arch/sh/include/asm/dma-mapping.h | 28 +- trunk/arch/sh/kernel/cpu/fpu.c | 1 - trunk/arch/sh/kernel/cpu/sh2a/fpu.c | 1 - trunk/arch/sh/kernel/cpu/sh4/fpu.c | 1 - trunk/arch/sh/kernel/cpu/sh4a/clock-sh7757.c | 2 +- trunk/arch/sh/kernel/cpu/shmobile/cpuidle.c | 10 +- trunk/arch/sh/kernel/cpu/shmobile/pm.c | 1 - trunk/arch/sh/kernel/dma-nommu.c | 4 +- trunk/arch/sh/kernel/idle.c | 2 +- trunk/arch/sh/kernel/kgdb.c | 1 - trunk/arch/sh/kernel/process_32.c | 1 - trunk/arch/sh/kernel/smp.c | 1 - .../sh/kernel/vsyscall/vsyscall-sigreturn.S | 35 - .../arch/sh/kernel/vsyscall/vsyscall-trapa.S | 23 +- trunk/arch/sh/mm/cache-sh4.c | 1 - trunk/arch/sh/mm/consistent.c | 6 +- trunk/arch/sh/mm/fault_32.c | 2 +- trunk/arch/sh/mm/flush-sh4.c | 1 - trunk/arch/sh/mm/sram.c | 1 - trunk/arch/sparc/boot/Makefile | 9 +- trunk/arch/sparc/include/asm/dma-mapping.h | 18 +- trunk/arch/sparc/include/asm/pgtable_64.h | 4 +- trunk/arch/sparc/include/asm/ptrace.h | 2 - trunk/arch/sparc/kernel/ds.c | 2 +- trunk/arch/sparc/kernel/iommu.c | 10 +- trunk/arch/sparc/kernel/ioport.c | 18 +- trunk/arch/sparc/kernel/jump_label.c | 2 - trunk/arch/sparc/kernel/kgdb_64.c | 1 - trunk/arch/sparc/kernel/leon_kernel.c | 6 +- trunk/arch/sparc/kernel/leon_pci.c | 13 + trunk/arch/sparc/kernel/leon_smp.c | 3 - trunk/arch/sparc/kernel/pci_sun4v.c | 9 +- trunk/arch/sparc/kernel/rtrap_64.S | 7 + trunk/arch/sparc/kernel/sun4d_smp.c | 1 - trunk/arch/sparc/kernel/sun4m_smp.c | 1 - trunk/arch/sparc/kernel/sys_sparc_64.c | 7 +- trunk/arch/sparc/mm/fault_32.c | 37 +- trunk/arch/sparc/mm/fault_64.c | 37 +- trunk/arch/tile/Kconfig | 8 +- trunk/arch/tile/Makefile | 5 +- trunk/arch/tile/include/arch/spr_def.h | 4 +- trunk/arch/tile/include/asm/atomic.h | 50 +- trunk/arch/tile/include/asm/atomic_32.h | 2 +- trunk/arch/tile/include/asm/bitops_64.h | 8 +- trunk/arch/tile/include/asm/cmpxchg.h | 73 - trunk/arch/tile/include/asm/irq.h | 2 +- trunk/arch/tile/include/asm/pci.h | 4 +- trunk/arch/tile/include/asm/spinlock_64.h | 2 +- trunk/arch/tile/include/asm/stack.h | 1 + trunk/arch/tile/include/asm/traps.h | 6 +- trunk/arch/tile/kernel/entry.S | 2 - trunk/arch/tile/kernel/intvec_32.S | 24 +- trunk/arch/tile/kernel/intvec_64.S | 52 +- trunk/arch/tile/kernel/module.c | 2 - trunk/arch/tile/kernel/pci.c | 4 +- trunk/arch/tile/kernel/proc.c | 4 +- trunk/arch/tile/kernel/process.c | 3 +- trunk/arch/tile/kernel/setup.c | 36 +- trunk/arch/tile/kernel/single_step.c | 35 +- trunk/arch/tile/kernel/smp.c | 8 +- trunk/arch/tile/kernel/smpboot.c | 2 - trunk/arch/tile/kernel/stack.c | 232 +- trunk/arch/tile/kernel/traps.c | 15 +- trunk/arch/tile/lib/Makefile | 1 - trunk/arch/tile/lib/cacheflush.c | 30 +- trunk/arch/tile/lib/memcpy_user_64.c | 8 +- trunk/arch/tile/lib/spinlock_common.h | 2 +- trunk/arch/tile/mm/fault.c | 22 +- trunk/arch/tile/mm/homecache.c | 1 - trunk/arch/tile/mm/init.c | 26 +- trunk/arch/tile/mm/pgtable.c | 38 +- trunk/arch/um/drivers/cow.h | 35 + trunk/arch/um/drivers/cow_user.c | 43 +- trunk/arch/um/drivers/mconsole_kern.c | 1 - trunk/arch/um/include/asm/Kbuild | 3 +- trunk/arch/um/kernel/Makefile | 7 +- trunk/arch/um/kernel/process.c | 6 +- trunk/arch/um/kernel/skas/mmu.c | 1 + trunk/arch/um/kernel/skas/process.c | 2 +- trunk/arch/um/kernel/smp.c | 9 +- trunk/arch/unicore32/boot/Makefile | 12 +- .../arch/unicore32/include/asm/dma-mapping.h | 18 +- trunk/arch/unicore32/mm/dma-swiotlb.c | 18 +- trunk/arch/x86/Kconfig | 2 +- trunk/arch/x86/Makefile | 1 - trunk/arch/x86/Makefile.um | 3 - trunk/arch/x86/boot/compressed/head_32.S | 14 +- trunk/arch/x86/boot/compressed/head_64.S | 22 +- trunk/arch/x86/boot/compressed/relocs.c | 2 + trunk/arch/x86/boot/tools/build.c | 15 +- trunk/arch/x86/ia32/ia32_aout.c | 35 +- trunk/arch/x86/ia32/sys_ia32.c | 23 + trunk/arch/x86/include/asm/cmpxchg.h | 4 +- trunk/arch/x86/include/asm/dma-mapping.h | 26 +- trunk/arch/x86/include/asm/posix_types.h | 6 +- trunk/arch/x86/include/asm/processor.h | 10 + trunk/arch/x86/include/asm/sigcontext.h | 2 +- trunk/arch/x86/include/asm/siginfo.h | 8 +- trunk/arch/x86/include/asm/spinlock.h | 2 - trunk/arch/x86/include/asm/uaccess.h | 2 - trunk/arch/x86/include/asm/uaccess_32.h | 5 + trunk/arch/x86/include/asm/uaccess_64.h | 4 + trunk/arch/x86/include/asm/unistd.h | 6 +- trunk/arch/x86/include/asm/word-at-a-time.h | 79 - trunk/arch/x86/include/asm/x86_init.h | 1 + trunk/arch/x86/kernel/acpi/boot.c | 3 +- trunk/arch/x86/kernel/acpi/sleep.c | 4 - trunk/arch/x86/kernel/acpi/sleep.h | 4 - trunk/arch/x86/kernel/acpi/wakeup_32.S | 4 +- trunk/arch/x86/kernel/acpi/wakeup_64.S | 4 +- trunk/arch/x86/kernel/amd_gart_64.c | 11 +- trunk/arch/x86/kernel/apic/apic.c | 34 +- trunk/arch/x86/kernel/apic/apic_numachip.c | 7 +- trunk/arch/x86/kernel/apic/x2apic_phys.c | 6 - trunk/arch/x86/kernel/cpu/amd.c | 29 +- trunk/arch/x86/kernel/cpu/common.c | 9 + trunk/arch/x86/kernel/cpu/intel_cacheinfo.c | 8 +- trunk/arch/x86/kernel/cpu/perf_event.c | 17 +- trunk/arch/x86/kernel/cpu/perf_event.h | 1 - trunk/arch/x86/kernel/cpu/perf_event_amd.c | 18 - trunk/arch/x86/kernel/cpu/perf_event_intel.c | 36 - trunk/arch/x86/kernel/cpu/perf_event_p4.c | 13 - trunk/arch/x86/kernel/cpu/perf_event_p6.c | 19 - trunk/arch/x86/kernel/i387.c | 1 - trunk/arch/x86/kernel/irq.c | 7 +- trunk/arch/x86/kernel/kdebugfs.c | 9 +- trunk/arch/x86/kernel/kgdb.c | 60 - trunk/arch/x86/kernel/kvm.c | 4 - trunk/arch/x86/kernel/microcode_amd.c | 12 +- trunk/arch/x86/kernel/microcode_core.c | 10 +- trunk/arch/x86/kernel/pci-calgary_64.c | 9 +- trunk/arch/x86/kernel/pci-dma.c | 3 +- trunk/arch/x86/kernel/pci-nommu.c | 6 +- trunk/arch/x86/kernel/pci-swiotlb.c | 17 +- trunk/arch/x86/kernel/process.c | 24 + trunk/arch/x86/kernel/process_64.c | 1 - trunk/arch/x86/kernel/smpboot.c | 4 +- trunk/arch/x86/kernel/tboot.c | 9 +- trunk/arch/x86/kernel/vsyscall_64.c | 6 +- trunk/arch/x86/kernel/x86_init.c | 1 + trunk/arch/x86/kvm/pmu.c | 20 +- trunk/arch/x86/kvm/vmx.c | 7 +- trunk/arch/x86/kvm/x86.c | 8 +- trunk/arch/x86/lib/insn.c | 53 +- trunk/arch/x86/lib/usercopy.c | 103 - trunk/arch/x86/lib/usercopy_32.c | 87 + trunk/arch/x86/lib/usercopy_64.c | 49 + trunk/arch/x86/net/bpf_jit.S | 122 +- trunk/arch/x86/net/bpf_jit_comp.c | 43 +- trunk/arch/x86/platform/geode/net5501.c | 2 +- trunk/arch/x86/platform/mrst/mrst.c | 4 +- trunk/arch/x86/power/cpu.c | 2 +- trunk/arch/x86/um/asm/barrier.h | 75 - trunk/arch/x86/um/asm/system.h | 135 + trunk/arch/x86/xen/enlighten.c | 6 +- trunk/arch/x86/xen/mmu.c | 4 +- trunk/arch/x86/xen/pci-swiotlb-xen.c | 4 +- trunk/arch/x86/xen/smp.c | 17 +- trunk/arch/x86/xen/xen-asm.S | 2 +- trunk/arch/xtensa/include/asm/hardirq.h | 3 + trunk/arch/xtensa/include/asm/io.h | 1 - trunk/arch/xtensa/kernel/signal.c | 1 - trunk/block/blk-core.c | 5 +- trunk/block/blk-throttle.c | 2 +- trunk/block/cfq-iosched.c | 10 +- trunk/crypto/Kconfig | 6 +- trunk/crypto/ablkcipher.c | 4 +- trunk/crypto/aead.c | 4 +- trunk/crypto/crypto_user.c | 80 +- trunk/crypto/pcrypt.c | 8 +- trunk/crypto/sha512_generic.c | 2 +- trunk/drivers/Kconfig | 2 - trunk/drivers/Makefile | 1 - trunk/drivers/acpi/Kconfig | 9 - trunk/drivers/acpi/Makefile | 1 - trunk/drivers/acpi/acpica/Makefile | 4 +- trunk/drivers/acpi/acpica/accommon.h | 1 + .../acpi => drivers/acpi/acpica}/acconfig.h | 19 +- trunk/drivers/acpi/acpica/acdebug.h | 8 +- trunk/drivers/acpi/acpica/acevents.h | 21 +- trunk/drivers/acpi/acpica/acglobal.h | 11 +- trunk/drivers/acpi/acpica/achware.h | 32 +- trunk/drivers/acpi/acpica/aclocal.h | 1 - trunk/drivers/acpi/acpica/acmacros.h | 6 - trunk/drivers/acpi/acpica/acnamesp.h | 5 +- trunk/drivers/acpi/acpica/actables.h | 5 - trunk/drivers/acpi/acpica/evevent.c | 4 +- trunk/drivers/acpi/acpica/evglock.c | 4 +- trunk/drivers/acpi/acpica/evgpe.c | 4 +- trunk/drivers/acpi/acpica/evgpeblk.c | 4 +- trunk/drivers/acpi/acpica/evgpeinit.c | 4 +- trunk/drivers/acpi/acpica/evgpeutil.c | 3 - trunk/drivers/acpi/acpica/evmisc.c | 26 +- trunk/drivers/acpi/acpica/evsci.c | 4 +- trunk/drivers/acpi/acpica/evxface.c | 436 ++- trunk/drivers/acpi/acpica/evxfevnt.c | 2 - trunk/drivers/acpi/acpica/evxfgpe.c | 2 - trunk/drivers/acpi/acpica/hwacpi.c | 3 - trunk/drivers/acpi/acpica/hwesleep.c | 247 -- trunk/drivers/acpi/acpica/hwgpe.c | 4 +- trunk/drivers/acpi/acpica/hwregs.c | 16 +- trunk/drivers/acpi/acpica/hwsleep.c | 401 ++- trunk/drivers/acpi/acpica/hwtimer.c | 2 - trunk/drivers/acpi/acpica/hwxface.c | 47 +- trunk/drivers/acpi/acpica/hwxfsleep.c | 431 --- trunk/drivers/acpi/acpica/nsdump.c | 15 +- trunk/drivers/acpi/acpica/nsdumpdv.c | 2 +- trunk/drivers/acpi/acpica/nspredef.c | 4 +- trunk/drivers/acpi/acpica/nsrepair.c | 159 +- trunk/drivers/acpi/acpica/nsutils.c | 2 +- trunk/drivers/acpi/acpica/tbfadt.c | 8 +- trunk/drivers/acpi/acpica/tbinstal.c | 117 +- trunk/drivers/acpi/acpica/tbutils.c | 95 +- trunk/drivers/acpi/acpica/utdecode.c | 34 +- trunk/drivers/acpi/acpica/utglobal.c | 9 +- trunk/drivers/acpi/acpica/utinit.c | 37 +- trunk/drivers/acpi/acpica/utxface.c | 6 +- trunk/drivers/acpi/apei/apei-base.c | 61 +- trunk/drivers/acpi/apei/cper.c | 2 - trunk/drivers/acpi/apei/einj.c | 17 +- trunk/drivers/acpi/apei/erst.c | 2 +- trunk/drivers/acpi/bgrt.c | 175 -- trunk/drivers/acpi/bus.c | 1 - trunk/drivers/acpi/ec.c | 8 +- trunk/drivers/acpi/ec_sys.c | 8 +- trunk/drivers/acpi/nvs.c | 4 +- trunk/drivers/acpi/osl.c | 121 +- trunk/drivers/acpi/power.c | 168 +- trunk/drivers/acpi/processor_driver.c | 62 +- trunk/drivers/acpi/processor_idle.c | 34 +- trunk/drivers/acpi/processor_thermal.c | 45 +- trunk/drivers/acpi/processor_throttling.c | 5 +- trunk/drivers/acpi/scan.c | 15 +- trunk/drivers/acpi/sleep.c | 80 +- trunk/drivers/acpi/thermal.c | 8 +- trunk/drivers/acpi/video.c | 50 +- trunk/drivers/amba/bus.c | 42 +- trunk/drivers/ata/ahci.c | 2 - trunk/drivers/ata/ahci_platform.c | 1 - trunk/drivers/ata/ata_piix.c | 2 - trunk/drivers/ata/libata-core.c | 4 +- trunk/drivers/ata/libata-eh.c | 3 +- trunk/drivers/ata/libata-scsi.c | 38 +- trunk/drivers/ata/libata-transport.c | 1 - trunk/drivers/ata/libata.h | 2 +- trunk/drivers/ata/pata_arasan_cf.c | 4 +- trunk/drivers/ata/sata_mv.c | 3 +- trunk/drivers/base/firmware_class.c | 208 +- trunk/drivers/base/power/runtime.c | 3 +- trunk/drivers/base/regmap/regcache-rbtree.c | 10 +- trunk/drivers/base/regmap/regcache.c | 1 - trunk/drivers/base/regmap/regmap-debugfs.c | 12 +- trunk/drivers/base/soc.c | 4 +- trunk/drivers/bcma/Kconfig | 2 +- trunk/drivers/bcma/driver_pci_host.c | 1 - trunk/drivers/bcma/sprom.c | 7 +- trunk/drivers/block/cciss_scsi.c | 3 +- trunk/drivers/block/floppy.c | 36 + trunk/drivers/block/mtip32xx/Kconfig | 2 +- trunk/drivers/block/mtip32xx/mtip32xx.c | 860 ++--- trunk/drivers/block/mtip32xx/mtip32xx.h | 58 +- trunk/drivers/block/virtio_blk.c | 42 +- trunk/drivers/block/xen-blkback/blkback.c | 50 +- trunk/drivers/block/xen-blkback/common.h | 6 + trunk/drivers/block/xen-blkback/xenbus.c | 89 +- trunk/drivers/block/xen-blkfront.c | 43 +- trunk/drivers/bluetooth/ath3k.c | 8 - trunk/drivers/bluetooth/btmrvl_debugfs.c | 26 +- trunk/drivers/bluetooth/btusb.c | 11 +- trunk/drivers/bluetooth/hci_ldisc.c | 2 +- trunk/drivers/char/agp/intel-agp.h | 1 - trunk/drivers/char/agp/intel-gtt.c | 3 +- trunk/drivers/char/apm-emulation.c | 2 +- trunk/drivers/char/hpet.c | 4 +- trunk/drivers/char/random.c | 11 +- trunk/drivers/char/tile-srom.c | 12 +- trunk/drivers/char/virtio_console.c | 8 +- trunk/drivers/clocksource/acpi_pm.c | 24 +- trunk/drivers/cpufreq/Kconfig.arm | 11 +- trunk/drivers/cpufreq/db8500-cpufreq.c | 2 +- trunk/drivers/cpuidle/cpuidle.c | 100 +- trunk/drivers/cpuidle/driver.c | 2 +- trunk/drivers/cpuidle/governors/menu.c | 7 +- trunk/drivers/cpuidle/sysfs.c | 40 - trunk/drivers/crypto/ixp4xx_crypto.c | 1 - trunk/drivers/crypto/talitos.c | 20 +- trunk/drivers/dma/Kconfig | 5 +- trunk/drivers/dma/amba-pl08x.c | 1 - trunk/drivers/dma/at_hdmac.c | 4 + trunk/drivers/dma/coh901318.c | 9 +- trunk/drivers/dma/dmaengine.c | 14 - trunk/drivers/dma/imx-dma.c | 9 +- trunk/drivers/dma/ioat/dma.c | 16 +- trunk/drivers/dma/ioat/dma.h | 6 +- trunk/drivers/dma/ioat/dma_v2.c | 12 +- trunk/drivers/dma/ioat/dma_v2.h | 4 +- trunk/drivers/dma/ioat/dma_v3.c | 49 +- trunk/drivers/dma/iop-adma.c | 4 +- trunk/drivers/dma/mxs-dma.c | 44 +- trunk/drivers/dma/pl330.c | 25 +- trunk/drivers/dma/sa11x0-dma.c | 2 +- trunk/drivers/dma/ste_dma40.c | 323 +- trunk/drivers/dma/ste_dma40_ll.h | 2 + trunk/drivers/edac/mce_amd.c | 6 +- trunk/drivers/edac/tile_edac.c | 4 - trunk/drivers/firmware/efivars.c | 196 -- trunk/drivers/gpio/Kconfig | 2 +- trunk/drivers/gpio/gpio-adp5588.c | 2 +- trunk/drivers/gpio/gpio-pxa.c | 21 +- trunk/drivers/gpio/gpio-samsung.c | 16 +- trunk/drivers/gpio/gpio-sodaville.c | 23 +- trunk/drivers/gpio/gpio-tegra.c | 59 +- trunk/drivers/gpu/drm/Kconfig | 1 - trunk/drivers/gpu/drm/Makefile | 2 +- trunk/drivers/gpu/drm/drm_bufs.c | 12 +- trunk/drivers/gpu/drm/drm_crtc.c | 10 +- trunk/drivers/gpu/drm/drm_drv.c | 4 - trunk/drivers/gpu/drm/drm_fb_helper.c | 8 +- trunk/drivers/gpu/drm/drm_fops.c | 13 +- trunk/drivers/gpu/drm/drm_gem.c | 9 - trunk/drivers/gpu/drm/drm_prime.c | 304 -- trunk/drivers/gpu/drm/drm_usb.c | 6 +- trunk/drivers/gpu/drm/exynos/exynos_drm_buf.c | 47 +- .../drivers/gpu/drm/exynos/exynos_drm_core.c | 14 +- trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h | 10 +- .../drivers/gpu/drm/exynos/exynos_drm_fimd.c | 20 +- trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c | 79 +- trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h | 2 - .../drivers/gpu/drm/exynos/exynos_drm_hdmi.c | 107 +- .../drivers/gpu/drm/exynos/exynos_drm_hdmi.h | 23 +- .../drivers/gpu/drm/exynos/exynos_drm_plane.c | 4 - .../drivers/gpu/drm/exynos/exynos_drm_vidi.c | 20 +- trunk/drivers/gpu/drm/exynos/exynos_hdmi.c | 42 +- trunk/drivers/gpu/drm/exynos/exynos_mixer.c | 40 +- .../drivers/gpu/drm/gma500/mdfld_dsi_output.h | 1 + trunk/drivers/gpu/drm/i810/i810_dma.c | 6 +- trunk/drivers/gpu/drm/i915/i915_debugfs.c | 17 +- trunk/drivers/gpu/drm/i915/i915_dma.c | 36 +- trunk/drivers/gpu/drm/i915/i915_drv.c | 15 +- trunk/drivers/gpu/drm/i915/i915_drv.h | 23 +- trunk/drivers/gpu/drm/i915/i915_gem.c | 43 +- .../gpu/drm/i915/i915_gem_execbuffer.c | 10 +- trunk/drivers/gpu/drm/i915/i915_gem_gtt.c | 9 + trunk/drivers/gpu/drm/i915/i915_reg.h | 5 - trunk/drivers/gpu/drm/i915/intel_bios.c | 23 +- trunk/drivers/gpu/drm/i915/intel_crt.c | 29 +- trunk/drivers/gpu/drm/i915/intel_display.c | 130 +- trunk/drivers/gpu/drm/i915/intel_dp.c | 49 +- trunk/drivers/gpu/drm/i915/intel_drv.h | 4 - trunk/drivers/gpu/drm/i915/intel_fb.c | 4 - trunk/drivers/gpu/drm/i915/intel_hdmi.c | 2 +- trunk/drivers/gpu/drm/i915/intel_i2c.c | 2 +- trunk/drivers/gpu/drm/i915/intel_lvds.c | 18 +- trunk/drivers/gpu/drm/i915/intel_panel.c | 2 + trunk/drivers/gpu/drm/i915/intel_ringbuffer.c | 12 +- trunk/drivers/gpu/drm/i915/intel_sdvo.c | 34 +- trunk/drivers/gpu/drm/i915/intel_sprite.c | 4 +- trunk/drivers/gpu/drm/nouveau/Kconfig | 1 - trunk/drivers/gpu/drm/nouveau/nouveau_acpi.c | 2 +- trunk/drivers/gpu/drm/nouveau/nouveau_bios.c | 15 +- .../drivers/gpu/drm/nouveau/nouveau_channel.c | 10 +- trunk/drivers/gpu/drm/nouveau/nouveau_dma.h | 4 +- trunk/drivers/gpu/drm/nouveau/nouveau_hdmi.c | 4 +- trunk/drivers/gpu/drm/nouveau/nouveau_pm.c | 1 - trunk/drivers/gpu/drm/nouveau/nouveau_state.c | 2 +- trunk/drivers/gpu/drm/nouveau/nv10_gpio.c | 2 +- trunk/drivers/gpu/drm/nouveau/nv50_sor.c | 2 +- trunk/drivers/gpu/drm/nouveau/nvc0_fb.c | 5 - trunk/drivers/gpu/drm/radeon/atom.c | 15 +- trunk/drivers/gpu/drm/radeon/atom.h | 1 - trunk/drivers/gpu/drm/radeon/atombios_crtc.c | 7 +- .../gpu/drm/radeon/atombios_encoders.c | 4 - trunk/drivers/gpu/drm/radeon/r100.c | 2 +- trunk/drivers/gpu/drm/radeon/r600.c | 6 +- trunk/drivers/gpu/drm/radeon/r600_cp.c | 6 +- trunk/drivers/gpu/drm/radeon/radeon_clocks.c | 24 +- trunk/drivers/gpu/drm/radeon/radeon_combios.c | 8 +- .../gpu/drm/radeon/radeon_connectors.c | 4 +- trunk/drivers/gpu/drm/radeon/radeon_device.c | 4 +- trunk/drivers/gpu/drm/radeon/radeon_display.c | 3 +- trunk/drivers/gpu/drm/radeon/radeon_i2c.c | 4 - trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c | 6 - .../gpu/drm/radeon/radeon_legacy_encoders.c | 12 +- trunk/drivers/gpu/drm/radeon/radeon_object.c | 3 +- trunk/drivers/gpu/drm/radeon/rv770.c | 4 +- trunk/drivers/gpu/drm/radeon/si.c | 5 +- trunk/drivers/gpu/drm/savage/savage_state.c | 6 +- trunk/drivers/gpu/drm/udl/udl_drv.c | 2 +- trunk/drivers/gpu/drm/udl/udl_drv.h | 1 - trunk/drivers/gpu/drm/udl/udl_gem.c | 14 - trunk/drivers/hid/Kconfig | 2 +- trunk/drivers/hid/hid-picolcd.c | 16 +- trunk/drivers/hid/hid-tivo.c | 2 +- trunk/drivers/hid/hid-wiimote-debug.c | 8 +- trunk/drivers/hsi/Kconfig | 19 - trunk/drivers/hsi/Makefile | 6 - trunk/drivers/hsi/clients/Kconfig | 13 - trunk/drivers/hsi/clients/Makefile | 5 - trunk/drivers/hsi/clients/hsi_char.c | 802 ----- trunk/drivers/hsi/hsi.c | 507 --- trunk/drivers/hsi/hsi_boardinfo.c | 62 - trunk/drivers/hsi/hsi_core.h | 35 - trunk/drivers/hwmon/Kconfig | 7 +- trunk/drivers/hwmon/acpi_power_meter.c | 3 - trunk/drivers/hwmon/ad7314.c | 13 +- trunk/drivers/hwmon/adm1031.c | 20 +- trunk/drivers/hwmon/ads1015.c | 33 +- trunk/drivers/hwmon/coretemp.c | 6 +- trunk/drivers/hwmon/f75375s.c | 2 - trunk/drivers/hwmon/fam15h_power.c | 42 - trunk/drivers/hwmon/k10temp.c | 4 - trunk/drivers/hwmon/max6639.c | 15 +- trunk/drivers/hwmon/pmbus/pmbus_core.c | 17 +- trunk/drivers/hwmon/smsc47b397.c | 14 +- trunk/drivers/hwmon/smsc47m1.c | 19 +- trunk/drivers/hwmon/w83627ehf.c | 18 +- .../i2c/busses/i2c-designware-pcidrv.c | 1 + trunk/drivers/i2c/busses/i2c-eg20t.c | 4 +- trunk/drivers/i2c/busses/i2c-mxs.c | 8 +- trunk/drivers/i2c/busses/i2c-pnx.c | 3 +- trunk/drivers/i2c/busses/i2c-tegra.c | 8 - trunk/drivers/idle/i7300_idle.c | 8 +- trunk/drivers/infiniband/core/mad.c | 8 +- trunk/drivers/infiniband/core/sysfs.c | 9 +- trunk/drivers/infiniband/hw/mlx4/main.c | 7 +- trunk/drivers/infiniband/ulp/srpt/ib_srpt.c | 1 - trunk/drivers/input/misc/Kconfig | 3 +- trunk/drivers/input/misc/da9052_onkey.c | 3 +- trunk/drivers/input/misc/twl6040-vibra.c | 4 +- trunk/drivers/input/mouse/elantech.c | 10 +- trunk/drivers/input/mouse/gpio_mouse.c | 2 +- trunk/drivers/input/mouse/sentelic.c | 8 - trunk/drivers/input/mouse/synaptics.c | 3 +- trunk/drivers/input/mouse/trackpoint.c | 14 +- trunk/drivers/input/touchscreen/tps6507x-ts.c | 4 +- trunk/drivers/iommu/amd_iommu.c | 10 +- trunk/drivers/iommu/intel-iommu.c | 9 +- trunk/drivers/iommu/omap-iommu-debug.c | 10 +- trunk/drivers/isdn/gigaset/interface.c | 2 +- trunk/drivers/isdn/hardware/mISDN/avmfritz.c | 2 +- trunk/drivers/isdn/hardware/mISDN/hfcpci.c | 2 +- trunk/drivers/isdn/hardware/mISDN/hfcsusb.c | 2 +- trunk/drivers/isdn/hardware/mISDN/mISDNipac.c | 2 +- trunk/drivers/isdn/hardware/mISDN/mISDNisar.c | 2 +- trunk/drivers/isdn/hardware/mISDN/netjet.c | 2 +- trunk/drivers/isdn/hardware/mISDN/w6692.c | 2 +- trunk/drivers/leds/leds-atmel-pwm.c | 2 +- trunk/drivers/md/bitmap.c | 8 +- trunk/drivers/md/bitmap.h | 3 + trunk/drivers/md/dm-raid.c | 4 +- trunk/drivers/md/linear.c | 9 +- trunk/drivers/md/md.c | 7 +- trunk/drivers/md/raid0.c | 27 +- trunk/drivers/md/raid1.c | 16 +- trunk/drivers/md/raid10.c | 6 +- trunk/drivers/md/raid5.c | 59 +- trunk/drivers/media/common/tuners/xc5000.c | 39 +- trunk/drivers/media/common/tuners/xc5000.h | 1 - .../drivers/media/dvb/dvb-core/dvb_frontend.c | 37 +- trunk/drivers/media/dvb/dvb-usb/it913x.c | 54 +- trunk/drivers/media/dvb/frontends/drxk_hard.c | 6 +- trunk/drivers/media/rc/winbond-cir.c | 1 - trunk/drivers/media/video/Kconfig | 2 +- trunk/drivers/media/video/ivtv/ivtv-ioctl.c | 4 +- trunk/drivers/media/video/mt9m032.c | 5 +- trunk/drivers/media/video/uvc/uvc_video.c | 50 +- trunk/drivers/mfd/Kconfig | 11 +- trunk/drivers/mfd/aat2870-core.c | 9 +- trunk/drivers/mfd/ab3100-core.c | 8 +- trunk/drivers/mfd/asic3.c | 4 +- trunk/drivers/mfd/db8500-prcmu.c | 1 - trunk/drivers/mfd/omap-usb-host.c | 45 +- trunk/drivers/mfd/rc5t583.c | 39 +- trunk/drivers/mfd/twl6040-core.c | 114 +- trunk/drivers/misc/ibmasm/ibmasmfs.c | 8 +- trunk/drivers/misc/kgdbts.c | 160 +- trunk/drivers/mmc/card/block.c | 83 +- trunk/drivers/mmc/card/queue.c | 2 +- trunk/drivers/mmc/core/bus.c | 41 +- trunk/drivers/mmc/core/cd-gpio.c | 1 - trunk/drivers/mmc/core/core.c | 74 +- trunk/drivers/mmc/core/mmc.c | 30 +- trunk/drivers/mmc/core/sdio_bus.c | 12 +- trunk/drivers/mmc/host/atmel-mci-regs.h | 1 - trunk/drivers/mmc/host/atmel-mci.c | 55 +- trunk/drivers/mmc/host/dw_mmc.c | 7 +- trunk/drivers/mmc/host/mxs-mmc.c | 15 +- trunk/drivers/mmc/host/omap_hsmmc.c | 187 +- trunk/drivers/mmc/host/sdhci-dove.c | 1 - trunk/drivers/mmc/host/sdhci-esdhc-imx.c | 3 +- trunk/drivers/mmc/host/sdhci-pci.c | 6 + trunk/drivers/mmc/host/sdhci-s3c.c | 159 +- trunk/drivers/mmc/host/sdhci.c | 7 +- trunk/drivers/mmc/host/sh_mmcif.c | 13 +- trunk/drivers/mtd/Kconfig | 3 + trunk/drivers/mtd/chips/cfi_cmdset_0001.c | 83 +- trunk/drivers/mtd/chips/cfi_cmdset_0002.c | 283 +- trunk/drivers/mtd/chips/cfi_cmdset_0020.c | 33 +- trunk/drivers/mtd/chips/cfi_util.c | 6 + trunk/drivers/mtd/chips/fwh_lock.h | 4 +- trunk/drivers/mtd/chips/map_absent.c | 10 +- trunk/drivers/mtd/chips/map_ram.c | 14 +- trunk/drivers/mtd/chips/map_rom.c | 13 +- trunk/drivers/mtd/devices/Kconfig | 7 - trunk/drivers/mtd/devices/Makefile | 1 - trunk/drivers/mtd/devices/block2mtd.c | 28 +- trunk/drivers/mtd/devices/doc2000.c | 25 +- trunk/drivers/mtd/devices/doc2001.c | 22 +- trunk/drivers/mtd/devices/doc2001plus.c | 22 +- trunk/drivers/mtd/devices/docg3.c | 201 +- trunk/drivers/mtd/devices/docg3.h | 20 +- trunk/drivers/mtd/devices/lart.c | 17 +- trunk/drivers/mtd/devices/m25p80.c | 56 +- trunk/drivers/mtd/devices/ms02-nv.c | 12 +- trunk/drivers/mtd/devices/mtd_dataflash.c | 50 +- trunk/drivers/mtd/devices/mtdram.c | 35 +- trunk/drivers/mtd/devices/phram.c | 76 +- trunk/drivers/mtd/devices/pmc551.c | 99 +- trunk/drivers/mtd/devices/slram.c | 41 +- trunk/drivers/mtd/devices/spear_smi.c | 1147 ------- trunk/drivers/mtd/devices/sst25l.c | 46 +- trunk/drivers/mtd/inftlcore.c | 2 +- trunk/drivers/mtd/lpddr/lpddr_cmds.c | 37 +- trunk/drivers/mtd/maps/bfin-async-flash.c | 4 +- trunk/drivers/mtd/maps/dc21285.c | 2 +- trunk/drivers/mtd/maps/gpio-addr-flash.c | 4 +- trunk/drivers/mtd/maps/h720x-flash.c | 4 +- trunk/drivers/mtd/maps/impa7.c | 2 +- trunk/drivers/mtd/maps/intel_vr_nor.c | 2 +- trunk/drivers/mtd/maps/ixp2000.c | 2 +- trunk/drivers/mtd/maps/ixp4xx.c | 5 +- trunk/drivers/mtd/maps/l440gx.c | 14 +- trunk/drivers/mtd/maps/lantiq-flash.c | 6 +- trunk/drivers/mtd/maps/latch-addr-flash.c | 5 +- trunk/drivers/mtd/maps/pcmciamtd.c | 13 +- trunk/drivers/mtd/maps/physmap.c | 24 +- trunk/drivers/mtd/maps/plat-ram.c | 5 +- trunk/drivers/mtd/maps/pxa2xx-flash.c | 3 +- trunk/drivers/mtd/maps/rbtx4939-flash.c | 4 +- trunk/drivers/mtd/maps/sa1100-flash.c | 18 +- trunk/drivers/mtd/maps/solutionengine.c | 4 +- trunk/drivers/mtd/maps/uclinux.c | 2 +- trunk/drivers/mtd/maps/vmu-flash.c | 14 +- trunk/drivers/mtd/maps/wr_sbc82xx_flash.c | 2 +- trunk/drivers/mtd/mtd_blkdevs.c | 1 - trunk/drivers/mtd/mtdblock.c | 8 +- trunk/drivers/mtd/mtdchar.c | 77 +- trunk/drivers/mtd/mtdconcat.c | 106 +- trunk/drivers/mtd/mtdcore.c | 271 +- trunk/drivers/mtd/mtdoops.c | 9 +- trunk/drivers/mtd/mtdpart.c | 200 +- trunk/drivers/mtd/nand/Kconfig | 21 +- trunk/drivers/mtd/nand/Makefile | 1 - trunk/drivers/mtd/nand/alauda.c | 9 +- trunk/drivers/mtd/nand/atmel_nand.c | 1 - trunk/drivers/mtd/nand/bcm_umi_nand.c | 10 +- trunk/drivers/mtd/nand/bf5xx_nand.c | 2 - trunk/drivers/mtd/nand/cafe_nand.c | 3 +- trunk/drivers/mtd/nand/cmx270_nand.c | 2 +- trunk/drivers/mtd/nand/cs553x_nand.c | 4 +- trunk/drivers/mtd/nand/davinci_nand.c | 5 +- trunk/drivers/mtd/nand/denali.c | 3 - trunk/drivers/mtd/nand/diskonchip.c | 1 - trunk/drivers/mtd/nand/docg4.c | 1377 -------- trunk/drivers/mtd/nand/fsl_elbc_nand.c | 6 - trunk/drivers/mtd/nand/fsmc_nand.c | 924 ++---- trunk/drivers/mtd/nand/gpmi-nand/gpmi-lib.c | 26 +- trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 15 +- trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.h | 2 +- trunk/drivers/mtd/nand/h1910.c | 4 +- trunk/drivers/mtd/nand/jz4740_nand.c | 11 +- trunk/drivers/mtd/nand/mxc_nand.c | 11 +- trunk/drivers/mtd/nand/nand_base.c | 194 +- trunk/drivers/mtd/nand/ndfc.c | 1 - trunk/drivers/mtd/nand/omap2.c | 5 +- trunk/drivers/mtd/nand/orion_nand.c | 4 +- trunk/drivers/mtd/nand/plat_nand.c | 5 +- trunk/drivers/mtd/nand/ppchameleonevb.c | 18 +- trunk/drivers/mtd/nand/pxa3xx_nand.c | 6 +- trunk/drivers/mtd/nand/r852.c | 1 - trunk/drivers/mtd/nand/rtc_from4.c | 1 - trunk/drivers/mtd/nand/s3c2410.c | 5 +- trunk/drivers/mtd/nand/sh_flctl.c | 106 +- trunk/drivers/mtd/nand/sharpsl.c | 5 +- trunk/drivers/mtd/nand/tmio_nand.c | 7 +- trunk/drivers/mtd/nand/txx9ndfmc.c | 3 +- trunk/drivers/mtd/nftlcore.c | 7 + trunk/drivers/mtd/onenand/generic.c | 6 +- trunk/drivers/mtd/onenand/omap2.c | 6 +- trunk/drivers/mtd/onenand/onenand_base.c | 68 +- trunk/drivers/mtd/onenand/samsung.c | 6 +- trunk/drivers/mtd/redboot.c | 6 +- trunk/drivers/mtd/sm_ftl.c | 2 +- trunk/drivers/mtd/ubi/debug.c | 10 +- trunk/drivers/mtd/ubi/gluebi.c | 29 +- trunk/drivers/net/arcnet/arc-rimi.c | 8 +- trunk/drivers/net/bonding/bond_main.c | 68 +- trunk/drivers/net/caif/caif_hsi.c | 9 +- trunk/drivers/net/caif/caif_spi.c | 10 +- .../net/can/usb/peak_usb/pcan_usb_pro.c | 2 - trunk/drivers/net/dummy.c | 6 +- trunk/drivers/net/eql.c | 7 +- .../drivers/net/ethernet/atheros/atlx/atl1.c | 12 +- .../drivers/net/ethernet/atheros/atlx/atl1.h | 3 +- .../drivers/net/ethernet/atheros/atlx/atlx.c | 2 +- .../net/ethernet/broadcom/bnx2x/bnx2x.h | 7 - .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 41 +- .../net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 3 - .../ethernet/broadcom/bnx2x/bnx2x_fw_defs.h | 110 +- .../net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 3 - .../net/ethernet/broadcom/bnx2x/bnx2x_link.c | 160 +- .../net/ethernet/broadcom/bnx2x/bnx2x_link.h | 2 - .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 464 +-- .../net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 12 - .../net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 2 +- trunk/drivers/net/ethernet/broadcom/tg3.c | 22 +- .../net/ethernet/chelsio/cxgb3/cxgb3_main.c | 92 +- .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 9 +- trunk/drivers/net/ethernet/dlink/dl2k.c | 52 +- trunk/drivers/net/ethernet/dlink/dl2k.h | 7 + .../net/ethernet/freescale/fsl_pq_mdio.c | 12 +- .../drivers/net/ethernet/freescale/ucc_geth.c | 12 +- .../drivers/net/ethernet/freescale/ucc_geth.h | 2 +- .../drivers/net/ethernet/ibm/ehea/ehea_main.c | 60 +- .../drivers/net/ethernet/ibm/ehea/ehea_phyp.h | 2 +- .../net/ethernet/intel/e1000/e1000_main.c | 40 +- .../drivers/net/ethernet/intel/e1000e/e1000.h | 6 - .../net/ethernet/intel/e1000e/ich8lan.c | 15 +- .../net/ethernet/intel/e1000e/netdev.c | 35 +- .../drivers/net/ethernet/intel/e1000e/param.c | 99 +- .../drivers/net/ethernet/intel/igb/igb_main.c | 7 +- .../drivers/net/ethernet/intel/igbvf/netdev.c | 11 +- .../net/ethernet/intel/ixgb/ixgb_main.c | 6 +- .../drivers/net/ethernet/intel/ixgbe/ixgbe.h | 2 +- .../net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c | 164 +- .../net/ethernet/intel/ixgbe/ixgbe_fcoe.c | 1 - .../net/ethernet/intel/ixgbe/ixgbe_lib.c | 10 - .../net/ethernet/intel/ixgbe/ixgbe_main.c | 42 +- .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 7 +- trunk/drivers/net/ethernet/marvell/sky2.c | 49 +- trunk/drivers/net/ethernet/marvell/sky2.h | 1 + .../net/ethernet/mellanox/mlx4/mlx4_en.h | 5 +- trunk/drivers/net/ethernet/micrel/ks8851.c | 21 +- .../drivers/net/ethernet/micrel/ks8851_mll.c | 2 +- trunk/drivers/net/ethernet/micrel/ksz884x.c | 2 +- trunk/drivers/net/ethernet/nxp/lpc_eth.c | 2 +- trunk/drivers/net/ethernet/realtek/8139cp.c | 10 +- trunk/drivers/net/ethernet/realtek/r8169.c | 3 - trunk/drivers/net/ethernet/renesas/Kconfig | 5 +- trunk/drivers/net/ethernet/renesas/sh_eth.c | 22 +- trunk/drivers/net/ethernet/renesas/sh_eth.h | 15 +- trunk/drivers/net/ethernet/sfc/mtd.c | 10 +- trunk/drivers/net/ethernet/smsc/smsc911x.c | 17 +- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +- trunk/drivers/net/ethernet/sun/sungem.c | 2 +- trunk/drivers/net/ethernet/ti/davinci_emac.c | 2 +- trunk/drivers/net/ethernet/ti/davinci_mdio.c | 5 - trunk/drivers/net/ethernet/ti/tlan.c | 2 +- trunk/drivers/net/ethernet/tile/tilepro.c | 77 +- trunk/drivers/net/ethernet/via/via-rhine.c | 12 +- .../net/ethernet/xilinx/xilinx_axienet.h | 4 +- .../net/ethernet/xilinx/xilinx_axienet_main.c | 6 +- .../net/ethernet/xilinx/xilinx_axienet_mdio.c | 6 +- trunk/drivers/net/hyperv/netvsc_drv.c | 38 +- trunk/drivers/net/irda/sa1100_ir.c | 2 +- trunk/drivers/net/phy/icplus.c | 15 +- trunk/drivers/net/ppp/ppp_generic.c | 3 +- trunk/drivers/net/rionet.c | 11 +- trunk/drivers/net/usb/asix.c | 4 +- trunk/drivers/net/usb/cdc-phonet.c | 4 +- trunk/drivers/net/usb/cdc_eem.c | 1 - trunk/drivers/net/usb/qmi_wwan.c | 30 - trunk/drivers/net/usb/rtl8150.c | 26 + trunk/drivers/net/usb/smsc75xx.c | 36 +- trunk/drivers/net/usb/smsc95xx.c | 3 +- trunk/drivers/net/usb/usbnet.c | 5 +- trunk/drivers/net/usb/zaurus.c | 5 - trunk/drivers/net/virtio_net.c | 10 +- trunk/drivers/net/wan/Kconfig | 4 +- trunk/drivers/net/wan/farsync.c | 1 - trunk/drivers/net/wimax/i2400m/debugfs.c | 15 +- trunk/drivers/net/wimax/i2400m/netdev.c | 3 +- trunk/drivers/net/wimax/i2400m/usb.c | 18 - trunk/drivers/net/wireless/ath/ath5k/ahb.c | 8 +- trunk/drivers/net/wireless/ath/ath5k/debug.c | 23 +- trunk/drivers/net/wireless/ath/ath6kl/debug.c | 42 +- .../net/wireless/ath/ath9k/ar5008_phy.c | 2 +- .../net/wireless/ath/ath9k/ar9003_paprd.c | 2 +- .../net/wireless/ath/ath9k/ar9003_phy.c | 2 +- trunk/drivers/net/wireless/ath/ath9k/calib.c | 5 +- trunk/drivers/net/wireless/ath/ath9k/debug.c | 37 +- .../net/wireless/ath/ath9k/dfs_debug.c | 9 +- .../net/wireless/ath/ath9k/eeprom_9287.c | 2 - .../net/wireless/ath/ath9k/htc_drv_debug.c | 26 +- trunk/drivers/net/wireless/ath/ath9k/hw.c | 9 +- trunk/drivers/net/wireless/ath/ath9k/hw.h | 3 +- trunk/drivers/net/wireless/ath/ath9k/init.c | 2 +- trunk/drivers/net/wireless/ath/ath9k/main.c | 21 +- trunk/drivers/net/wireless/ath/ath9k/rc.c | 8 +- trunk/drivers/net/wireless/ath/ath9k/recv.c | 4 +- trunk/drivers/net/wireless/ath/ath9k/xmit.c | 10 +- .../drivers/net/wireless/ath/carl9170/debug.c | 7 +- trunk/drivers/net/wireless/b43/debugfs.c | 8 +- trunk/drivers/net/wireless/b43/main.c | 10 +- .../drivers/net/wireless/b43legacy/debugfs.c | 8 +- .../brcm80211/brcmfmac/bcmsdh_sdmmc.c | 8 +- .../wireless/brcm80211/brcmfmac/dhd_sdio.c | 63 +- .../net/wireless/brcm80211/brcmsmac/main.c | 11 +- trunk/drivers/net/wireless/ipw2x00/ipw2200.c | 17 +- .../drivers/net/wireless/iwlegacy/3945-mac.c | 2 + trunk/drivers/net/wireless/iwlegacy/3945-rs.c | 8 +- .../drivers/net/wireless/iwlegacy/4965-mac.c | 2 + trunk/drivers/net/wireless/iwlegacy/4965-rs.c | 12 +- trunk/drivers/net/wireless/iwlegacy/common.c | 31 +- trunk/drivers/net/wireless/iwlegacy/debug.c | 12 +- trunk/drivers/net/wireless/iwlwifi/iwl-1000.c | 8 +- trunk/drivers/net/wireless/iwlwifi/iwl-2000.c | 16 +- trunk/drivers/net/wireless/iwlwifi/iwl-5000.c | 11 +- trunk/drivers/net/wireless/iwlwifi/iwl-6000.c | 10 +- .../drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 11 +- trunk/drivers/net/wireless/iwlwifi/iwl-agn.c | 3 + .../net/wireless/iwlwifi/iwl-debugfs.c | 12 +- trunk/drivers/net/wireless/iwlwifi/iwl-fh.h | 24 +- .../net/wireless/iwlwifi/iwl-mac80211.c | 10 +- trunk/drivers/net/wireless/iwlwifi/iwl-prph.h | 27 +- .../net/wireless/iwlwifi/iwl-trans-pcie.c | 12 +- .../net/wireless/iwmc3200wifi/debugfs.c | 14 +- .../drivers/net/wireless/iwmc3200wifi/sdio.c | 9 +- trunk/drivers/net/wireless/libertas/cfg.c | 9 +- trunk/drivers/net/wireless/libertas/debugfs.c | 10 +- trunk/drivers/net/wireless/mwifiex/debugfs.c | 18 +- trunk/drivers/net/wireless/mwifiex/pcie.h | 18 +- trunk/drivers/net/wireless/orinoco/main.c | 8 - trunk/drivers/net/wireless/rt2x00/rt2800usb.c | 10 +- trunk/drivers/net/wireless/rt2x00/rt2x00dev.c | 6 +- trunk/drivers/net/wireless/rtlwifi/base.c | 5 +- trunk/drivers/net/wireless/rtlwifi/pci.c | 8 +- .../wireless/rtlwifi/rtl8192c/phy_common.c | 2 +- .../net/wireless/rtlwifi/rtl8192de/phy.c | 2 +- .../net/wireless/rtlwifi/rtl8192de/sw.c | 6 + trunk/drivers/net/wireless/rtlwifi/usb.c | 34 +- trunk/drivers/net/wireless/rtlwifi/wifi.h | 6 +- trunk/drivers/net/wireless/wl1251/debugfs.c | 14 +- trunk/drivers/net/wireless/wl1251/main.c | 1 - trunk/drivers/net/wireless/wl1251/sdio.c | 2 +- trunk/drivers/net/wireless/wl12xx/debugfs.c | 38 +- trunk/drivers/net/xen-netfront.c | 2 +- trunk/drivers/of/gpio.c | 2 +- trunk/drivers/oprofile/oprofilefs.c | 14 +- trunk/drivers/pci/Makefile | 1 - trunk/drivers/pci/pci-acpi.c | 44 +- trunk/drivers/pci/pci.c | 71 +- trunk/drivers/pci/pcie/aspm.c | 13 +- trunk/drivers/pci/xen-pcifront.c | 1 - trunk/drivers/pinctrl/core.c | 25 +- trunk/drivers/platform/x86/acerhdf.c | 67 +- trunk/drivers/platform/x86/dell-laptop.c | 1 - trunk/drivers/platform/x86/intel_ips.c | 15 +- .../drivers/platform/x86/intel_mid_powerbtn.c | 2 +- trunk/drivers/pnp/pnpacpi/core.c | 7 +- trunk/drivers/power/Kconfig | 21 +- trunk/drivers/power/Makefile | 2 - trunk/drivers/power/ab8500_btemp.c | 1124 ------- trunk/drivers/power/ab8500_charger.c | 2789 ----------------- trunk/drivers/power/ab8500_fg.c | 2637 ---------------- trunk/drivers/power/abx500_chargalg.c | 1921 ------------ trunk/drivers/power/charger-manager.c | 67 +- trunk/drivers/power/da9052-battery.c | 15 +- trunk/drivers/power/ds2782_battery.c | 13 +- trunk/drivers/power/isp1704_charger.c | 1 - trunk/drivers/power/lp8727_charger.c | 131 +- trunk/drivers/power/max17040_battery.c | 13 +- trunk/drivers/power/max17042_battery.c | 508 +-- trunk/drivers/power/sbs-battery.c | 13 +- trunk/drivers/power/smb347-charger.c | 1294 -------- trunk/drivers/power/z2_battery.c | 14 +- trunk/drivers/regulator/anatop-regulator.c | 11 +- trunk/drivers/regulator/core.c | 4 +- trunk/drivers/regulator/fixed-helper.c | 3 +- trunk/drivers/regulator/mc13892-regulator.c | 10 +- trunk/drivers/regulator/s5m8767.c | 14 +- trunk/drivers/regulator/tps6586x-regulator.c | 5 - trunk/drivers/regulator/wm831x-dcdc.c | 9 +- trunk/drivers/regulator/wm831x-isink.c | 2 +- trunk/drivers/regulator/wm831x-ldo.c | 7 +- trunk/drivers/regulator/wm8350-regulator.c | 34 +- trunk/drivers/remoteproc/remoteproc_debugfs.c | 13 +- trunk/drivers/rtc/rtc-88pm860x.c | 4 +- trunk/drivers/rtc/rtc-ds1307.c | 1 - trunk/drivers/rtc/rtc-efi.c | 1 + trunk/drivers/rtc/rtc-mpc5121.c | 3 +- trunk/drivers/rtc/rtc-pl031.c | 3 +- trunk/drivers/rtc/rtc-r9701.c | 22 - trunk/drivers/rtc/rtc-s3c.c | 31 +- trunk/drivers/rtc/rtc-twl.c | 43 +- trunk/drivers/s390/block/dasd_eckd.c | 24 +- trunk/drivers/s390/char/vmur.c | 2 +- trunk/drivers/s390/net/qeth_core_main.c | 6 +- trunk/drivers/scsi/Kconfig | 1 - trunk/drivers/scsi/Makefile | 1 - trunk/drivers/scsi/aic7xxx/aic79xx_osm.c | 8 +- trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c | 8 +- trunk/drivers/scsi/atp870u.c | 4 +- trunk/drivers/scsi/bfa/bfa.h | 9 +- trunk/drivers/scsi/bfa/bfa_core.c | 693 ++-- trunk/drivers/scsi/bfa/bfa_defs_svc.h | 2 +- trunk/drivers/scsi/bfa/bfa_fcs_lport.c | 2 - trunk/drivers/scsi/bfa/bfa_fcs_rport.c | 5 +- trunk/drivers/scsi/bfa/bfa_ioc.c | 188 +- trunk/drivers/scsi/bfa/bfa_ioc.h | 17 +- trunk/drivers/scsi/bfa/bfa_ioc_ct.c | 151 +- trunk/drivers/scsi/bfa/bfa_svc.c | 69 +- trunk/drivers/scsi/bfa/bfa_svc.h | 4 + trunk/drivers/scsi/bfa/bfad_attr.c | 47 +- trunk/drivers/scsi/bfa/bfad_bsg.c | 62 +- trunk/drivers/scsi/bfa/bfad_bsg.h | 2 + trunk/drivers/scsi/bfa/bfad_drv.h | 2 +- trunk/drivers/scsi/bfa/bfi_ms.h | 17 +- trunk/drivers/scsi/bfa/bfi_reg.h | 6 - trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 4 +- trunk/drivers/scsi/fcoe/fcoe.c | 83 +- trunk/drivers/scsi/fcoe/fcoe_ctlr.c | 38 +- trunk/drivers/scsi/ipr.c | 79 +- trunk/drivers/scsi/ipr.h | 16 +- trunk/drivers/scsi/libfc/fc_exch.c | 14 +- trunk/drivers/scsi/libfc/fc_lport.c | 14 +- trunk/drivers/scsi/libsas/sas_ata.c | 33 +- trunk/drivers/scsi/libsas/sas_discover.c | 61 +- trunk/drivers/scsi/libsas/sas_event.c | 24 +- trunk/drivers/scsi/libsas/sas_expander.c | 56 +- trunk/drivers/scsi/libsas/sas_init.c | 11 +- trunk/drivers/scsi/libsas/sas_internal.h | 6 +- trunk/drivers/scsi/libsas/sas_phy.c | 21 +- trunk/drivers/scsi/libsas/sas_port.c | 17 +- trunk/drivers/scsi/lpfc/Makefile | 4 +- trunk/drivers/scsi/lpfc/lpfc.h | 8 +- trunk/drivers/scsi/lpfc/lpfc_attr.c | 4 +- trunk/drivers/scsi/lpfc/lpfc_debugfs.c | 89 +- trunk/drivers/scsi/lpfc/lpfc_els.c | 17 +- trunk/drivers/scsi/lpfc/lpfc_hbadisc.c | 24 +- trunk/drivers/scsi/lpfc/lpfc_hw4.h | 8 +- trunk/drivers/scsi/lpfc/lpfc_init.c | 41 +- trunk/drivers/scsi/lpfc/lpfc_nportdisc.c | 10 +- trunk/drivers/scsi/lpfc/lpfc_scsi.c | 488 ++- trunk/drivers/scsi/lpfc/lpfc_scsi.h | 13 +- trunk/drivers/scsi/lpfc/lpfc_sli.c | 62 +- trunk/drivers/scsi/lpfc/lpfc_version.h | 4 +- trunk/drivers/scsi/mpt2sas/mpt2sas_base.c | 6 +- trunk/drivers/scsi/mpt2sas/mpt2sas_ctl.c | 4 +- trunk/drivers/scsi/pm8001/pm8001_hwi.c | 18 +- trunk/drivers/scsi/qla4xxx/ql4_isr.c | 4 +- trunk/drivers/scsi/qla4xxx/ql4_os.c | 10 +- trunk/drivers/scsi/qla4xxx/ql4_version.h | 2 +- trunk/drivers/scsi/scsi_debug.c | 27 +- trunk/drivers/scsi/scsi_error.c | 2 +- trunk/drivers/scsi/scsi_lib.c | 2 +- trunk/drivers/scsi/scsi_transport_iscsi.c | 8 +- trunk/drivers/scsi/sd.c | 15 +- trunk/drivers/scsi/st.c | 21 +- trunk/drivers/scsi/st.h | 1 - trunk/drivers/scsi/ufs/Kconfig | 49 - trunk/drivers/scsi/ufs/Makefile | 2 - trunk/drivers/scsi/ufs/ufs.h | 207 -- trunk/drivers/scsi/ufs/ufshcd.c | 1978 ------------ trunk/drivers/scsi/ufs/ufshci.h | 376 --- trunk/drivers/scsi/vmw_pvscsi.c | 65 +- trunk/drivers/scsi/vmw_pvscsi.h | 109 +- trunk/drivers/spi/Kconfig | 2 +- trunk/drivers/spi/Makefile | 2 +- trunk/drivers/spi/spi-bcm63xx.c | 163 +- trunk/drivers/spi/spi-bfin-sport.c | 21 +- trunk/drivers/spi/spi-bfin5xx.c | 14 +- trunk/drivers/spi/spi-davinci.c | 6 +- trunk/drivers/spi/spi-dw.c | 8 +- trunk/drivers/spi/spi-ep93xx.c | 24 +- trunk/drivers/spi/spi-fsl-spi.c | 4 +- trunk/drivers/spi/spi-imx.c | 12 +- trunk/drivers/spi/spi-pl022.c | 60 +- trunk/drivers/staging/android/Kconfig | 3 +- .../drivers/staging/android/lowmemorykiller.c | 48 +- .../drivers/staging/android/persistent_ram.c | 11 +- trunk/drivers/staging/android/timed_gpio.c | 27 +- trunk/drivers/staging/asus_oled/README | 2 +- trunk/drivers/staging/iio/inkern.c | 1 - .../drivers/staging/iio/magnetometer/ak8975.c | 8 +- .../staging/iio/magnetometer/hmc5843.c | 4 +- trunk/drivers/staging/media/as102/as102_fw.c | 2 +- trunk/drivers/staging/octeon/ethernet-rx.c | 1 - trunk/drivers/staging/octeon/ethernet-tx.c | 1 - trunk/drivers/staging/octeon/ethernet.c | 1 - trunk/drivers/staging/omapdrm/omap_drv.c | 7 +- trunk/drivers/staging/ozwpan/TODO | 4 +- trunk/drivers/staging/ozwpan/ozpd.c | 2 + trunk/drivers/staging/ramster/Kconfig | 6 +- trunk/drivers/staging/rts_pstor/ms.c | 3 +- trunk/drivers/staging/rts_pstor/rtsx.c | 5 - .../staging/rts_pstor/rtsx_transport.c | 11 +- trunk/drivers/staging/sep/sep_main.c | 6 +- .../staging/tidspbridge/core/tiomap3430.c | 20 +- trunk/drivers/staging/tidspbridge/core/wdt.c | 8 +- .../staging/vme/devices/vme_pio2_core.c | 4 +- trunk/drivers/staging/vt6655/key.c | 3 - trunk/drivers/staging/vt6656/ioctl.c | 3 +- trunk/drivers/staging/vt6656/key.c | 3 - trunk/drivers/staging/xgifb/vb_init.c | 2 +- trunk/drivers/staging/xgifb/vb_setmode.c | 7 - trunk/drivers/staging/xgifb/vb_table.h | 11 +- trunk/drivers/staging/zcache/Kconfig | 2 +- .../drivers/staging/zsmalloc/zsmalloc-main.c | 30 +- trunk/drivers/target/tcm_fc/tcm_fc.h | 1 - trunk/drivers/target/tcm_fc/tfc_cmd.c | 10 +- trunk/drivers/target/tcm_fc/tfc_conf.c | 13 +- trunk/drivers/target/tcm_fc/tfc_io.c | 2 - trunk/drivers/thermal/Kconfig | 8 - trunk/drivers/thermal/Makefile | 1 - trunk/drivers/thermal/spear_thermal.c | 206 -- trunk/drivers/thermal/thermal_sys.c | 94 +- trunk/drivers/tty/amiserial.c | 4 +- trunk/drivers/tty/isicom.c | 2 +- trunk/drivers/tty/serial/8250/8250.c | 12 +- trunk/drivers/tty/serial/8250/8250_pci.c | 16 +- trunk/drivers/tty/serial/Kconfig | 2 +- trunk/drivers/tty/serial/altera_uart.c | 4 +- trunk/drivers/tty/serial/amba-pl011.c | 8 +- trunk/drivers/tty/serial/atmel_serial.c | 4 - trunk/drivers/tty/serial/clps711x.c | 14 +- trunk/drivers/tty/serial/mfd.c | 9 +- trunk/drivers/tty/serial/omap-serial.c | 43 +- trunk/drivers/tty/serial/pch_uart.c | 20 +- trunk/drivers/tty/serial/pmac_zilog.c | 6 +- trunk/drivers/tty/serial/samsung.c | 1 - trunk/drivers/tty/serial/sh-sci.c | 167 +- trunk/drivers/tty/serial/sh-sci.h | 8 +- trunk/drivers/tty/serial/sunzilog.c | 4 +- trunk/drivers/tty/sysrq.c | 2 +- trunk/drivers/tty/vt/keyboard.c | 26 +- trunk/drivers/tty/vt/vt.c | 3 +- trunk/drivers/usb/Kconfig | 16 +- trunk/drivers/usb/class/cdc-wdm.c | 7 +- trunk/drivers/usb/core/driver.c | 9 +- trunk/drivers/usb/core/hcd-pci.c | 9 - trunk/drivers/usb/core/hcd.c | 12 - trunk/drivers/usb/core/hub.c | 19 +- trunk/drivers/usb/core/inode.c | 10 +- trunk/drivers/usb/core/message.c | 17 +- trunk/drivers/usb/core/urb.c | 12 - trunk/drivers/usb/dwc3/core.c | 6 +- trunk/drivers/usb/dwc3/ep0.c | 12 +- trunk/drivers/usb/gadget/at91_udc.c | 8 +- trunk/drivers/usb/gadget/dummy_hcd.c | 1 + trunk/drivers/usb/gadget/f_fs.c | 3 +- trunk/drivers/usb/gadget/f_mass_storage.c | 2 +- trunk/drivers/usb/gadget/f_phonet.c | 2 +- trunk/drivers/usb/gadget/f_rndis.c | 1 - trunk/drivers/usb/gadget/file_storage.c | 2 +- trunk/drivers/usb/gadget/fsl_udc_core.c | 25 +- trunk/drivers/usb/gadget/g_ffs.c | 4 +- trunk/drivers/usb/gadget/inode.c | 1 + trunk/drivers/usb/gadget/s3c-hsotg.c | 17 +- trunk/drivers/usb/gadget/udc-core.c | 6 +- trunk/drivers/usb/gadget/uvc.h | 2 +- trunk/drivers/usb/gadget/uvc_queue.c | 4 +- trunk/drivers/usb/gadget/uvc_v4l2.c | 2 +- trunk/drivers/usb/host/ehci-atmel.c | 1 - trunk/drivers/usb/host/ehci-dbg.c | 9 +- trunk/drivers/usb/host/ehci-fsl.c | 7 +- trunk/drivers/usb/host/ehci-hcd.c | 12 +- trunk/drivers/usb/host/ehci-hub.c | 31 +- trunk/drivers/usb/host/ehci-omap.c | 39 +- trunk/drivers/usb/host/ehci-pci.c | 8 - trunk/drivers/usb/host/ehci-tegra.c | 379 ++- trunk/drivers/usb/host/ehci.h | 2 - trunk/drivers/usb/host/ohci-at91.c | 175 +- trunk/drivers/usb/host/pci-quirks.c | 10 +- trunk/drivers/usb/host/uhci-hub.c | 5 +- trunk/drivers/usb/host/xhci-dbg.c | 2 +- trunk/drivers/usb/host/xhci-ext-caps.h | 5 +- trunk/drivers/usb/host/xhci-mem.c | 9 +- trunk/drivers/usb/host/xhci-pci.c | 4 +- trunk/drivers/usb/host/xhci-ring.c | 6 +- trunk/drivers/usb/host/xhci.c | 12 +- trunk/drivers/usb/host/xhci.h | 4 - trunk/drivers/usb/misc/usbtest.c | 9 +- trunk/drivers/usb/misc/yurex.c | 10 +- trunk/drivers/usb/musb/davinci.c | 3 +- trunk/drivers/usb/musb/musb_core.c | 40 +- trunk/drivers/usb/musb/musb_core.h | 2 +- trunk/drivers/usb/musb/musb_host.c | 2 +- trunk/drivers/usb/musb/omap2430.c | 31 +- trunk/drivers/usb/otg/gpio_vbus.c | 15 +- trunk/drivers/usb/serial/bus.c | 5 + trunk/drivers/usb/serial/cp210x.c | 9 +- trunk/drivers/usb/serial/ftdi_sio.c | 39 +- trunk/drivers/usb/serial/metro-usb.c | 6 +- trunk/drivers/usb/serial/option.c | 1 - trunk/drivers/usb/serial/pl2303.c | 2 +- trunk/drivers/usb/serial/sierra.c | 5 +- trunk/drivers/usb/serial/usb-serial.c | 31 +- trunk/drivers/usb/storage/Kconfig | 2 +- trunk/drivers/usb/storage/usb.c | 30 - trunk/drivers/uwb/hwa-rc.c | 3 +- trunk/drivers/uwb/neh.c | 12 +- trunk/drivers/uwb/uwb-debug.c | 9 +- trunk/drivers/vhost/net.c | 2 +- trunk/drivers/vhost/test.c | 2 +- trunk/drivers/vhost/vhost.c | 5 +- trunk/drivers/vhost/vhost.h | 2 +- trunk/drivers/video/au1100fb.c | 5 +- trunk/drivers/video/au1200fb.c | 2 +- trunk/drivers/video/backlight/Kconfig | 6 - trunk/drivers/video/backlight/Makefile | 1 - trunk/drivers/video/backlight/da9052_bl.c | 187 -- trunk/drivers/video/backlight/locomolcd.c | 9 +- trunk/drivers/video/bfin-lq035q1-fb.c | 1 - trunk/drivers/video/kyro/STG4000Reg.h | 376 +-- trunk/drivers/video/msm/mddi.c | 8 +- trunk/drivers/video/uvesafb.c | 11 +- trunk/drivers/virtio/virtio_balloon.c | 72 +- trunk/drivers/virtio/virtio_pci.c | 74 +- trunk/drivers/watchdog/hpwdt.c | 6 +- trunk/drivers/xen/events.c | 2 +- trunk/drivers/xen/gntdev.c | 2 +- trunk/drivers/xen/grant-table.c | 13 +- trunk/drivers/xen/manage.c | 1 - trunk/drivers/xen/swiotlb-xen.c | 5 +- trunk/drivers/xen/xen-acpi-processor.c | 5 +- trunk/drivers/xen/xen-pciback/pciback_ops.c | 2 +- .../xen/xenbus/xenbus_probe_frontend.c | 69 +- trunk/fs/aio.c | 48 +- trunk/fs/autofs4/autofs_i.h | 12 +- trunk/fs/autofs4/dev-ioctl.c | 3 +- trunk/fs/autofs4/inode.c | 4 +- trunk/fs/autofs4/waitq.c | 22 +- trunk/fs/binfmt_aout.c | 32 +- trunk/fs/binfmt_elf.c | 23 +- trunk/fs/binfmt_elf_fdpic.c | 18 +- trunk/fs/binfmt_flat.c | 12 +- trunk/fs/binfmt_som.c | 12 +- trunk/fs/btrfs/async-thread.c | 15 +- trunk/fs/btrfs/async-thread.h | 4 +- trunk/fs/btrfs/backref.c | 149 +- trunk/fs/btrfs/backref.h | 5 +- trunk/fs/btrfs/compression.c | 40 +- trunk/fs/btrfs/compression.h | 2 +- trunk/fs/btrfs/ctree.c | 412 ++- trunk/fs/btrfs/ctree.h | 173 +- trunk/fs/btrfs/delayed-inode.c | 33 +- trunk/fs/btrfs/delayed-ref.c | 33 +- trunk/fs/btrfs/dir-item.c | 10 +- trunk/fs/btrfs/disk-io.c | 673 ++-- trunk/fs/btrfs/disk-io.h | 13 +- trunk/fs/btrfs/export.c | 2 +- trunk/fs/btrfs/extent-tree.c | 751 ++--- trunk/fs/btrfs/extent_io.c | 1087 ++----- trunk/fs/btrfs/extent_io.h | 64 +- trunk/fs/btrfs/file-item.c | 57 +- trunk/fs/btrfs/file.c | 61 +- trunk/fs/btrfs/free-space-cache.c | 24 +- trunk/fs/btrfs/inode-item.c | 6 +- trunk/fs/btrfs/inode-map.c | 25 +- trunk/fs/btrfs/inode.c | 511 ++- trunk/fs/btrfs/ioctl.c | 199 +- trunk/fs/btrfs/ioctl.h | 4 +- trunk/fs/btrfs/locking.c | 6 +- trunk/fs/btrfs/locking.h | 4 +- trunk/fs/btrfs/ordered-data.c | 60 +- trunk/fs/btrfs/ordered-data.h | 24 +- trunk/fs/btrfs/orphan.c | 2 +- trunk/fs/btrfs/reada.c | 58 +- trunk/fs/btrfs/relocation.c | 134 +- trunk/fs/btrfs/root-tree.c | 25 +- trunk/fs/btrfs/scrub.c | 1409 +++------ trunk/fs/btrfs/struct-funcs.c | 53 +- trunk/fs/btrfs/super.c | 199 +- trunk/fs/btrfs/transaction.c | 224 +- trunk/fs/btrfs/transaction.h | 3 - trunk/fs/btrfs/tree-log.c | 98 +- trunk/fs/btrfs/tree-log.h | 2 +- trunk/fs/btrfs/volumes.c | 273 +- trunk/fs/btrfs/volumes.h | 4 +- trunk/fs/buffer.c | 1 + trunk/fs/cifs/cifs_debug.c | 68 +- trunk/fs/cifs/cifs_debug.h | 4 +- trunk/fs/cifs/cifsfs.c | 27 +- trunk/fs/cifs/cifsfs.h | 2 +- trunk/fs/cifs/cifsglob.h | 39 +- trunk/fs/cifs/cifsproto.h | 20 +- trunk/fs/cifs/cifssmb.c | 156 +- trunk/fs/cifs/connect.c | 1442 ++++----- trunk/fs/cifs/dir.c | 17 +- trunk/fs/cifs/file.c | 282 +- trunk/fs/cifs/misc.c | 100 +- trunk/fs/cifs/netmisc.c | 6 +- trunk/fs/cifs/transport.c | 227 +- trunk/fs/dcache.c | 26 +- trunk/fs/debugfs/file.c | 14 +- trunk/fs/dlm/debug_fs.c | 9 +- trunk/fs/dlm/lock.c | 12 - trunk/fs/eventpoll.c | 4 +- trunk/fs/exec.c | 7 +- trunk/fs/ext2/ext2.h | 631 ---- trunk/fs/ext2/xattr_security.c | 5 +- trunk/fs/ext2/xattr_trusted.c | 5 +- trunk/fs/ext2/xip.c | 2 + trunk/fs/ext3/acl.c | 8 +- trunk/fs/ext3/balloc.c | 10 +- trunk/fs/ext3/bitmap.c | 4 +- trunk/fs/ext3/dir.c | 7 +- trunk/fs/ext3/ext3_jbd.c | 2 +- trunk/fs/ext3/file.c | 6 +- trunk/fs/ext3/fsync.c | 8 +- trunk/fs/ext3/hash.c | 4 +- trunk/fs/ext3/ialloc.c | 13 +- trunk/fs/ext3/inode.c | 12 +- trunk/fs/ext3/ioctl.c | 7 +- trunk/fs/ext3/namei.c | 14 +- trunk/fs/ext3/resize.c | 5 +- trunk/fs/ext3/super.c | 18 +- trunk/fs/ext3/symlink.c | 4 +- trunk/fs/ext3/xattr.c | 7 +- trunk/fs/ext3/xattr_security.c | 6 +- trunk/fs/ext3/xattr_trusted.c | 6 +- trunk/fs/ext3/xattr_user.c | 5 +- trunk/fs/ext4/ext4.h | 3 + trunk/fs/ext4/extents.c | 6 +- trunk/fs/ext4/super.c | 50 +- trunk/fs/fuse/dir.c | 25 +- trunk/fs/fuse/file.c | 129 +- trunk/fs/fuse/inode.c | 1 - trunk/fs/gfs2/Kconfig | 7 +- trunk/fs/gfs2/aops.c | 4 +- trunk/fs/gfs2/bmap.c | 6 +- trunk/fs/gfs2/dir.c | 4 - trunk/fs/gfs2/file.c | 1 + trunk/fs/gfs2/inode.c | 13 +- trunk/fs/gfs2/lock_dlm.c | 10 +- trunk/fs/gfs2/rgrp.c | 8 +- trunk/fs/gfs2/xattr.c | 12 - trunk/fs/hfsplus/catalog.c | 4 - trunk/fs/hfsplus/dir.c | 11 - trunk/fs/hugetlbfs/inode.c | 2 +- trunk/fs/jbd2/commit.c | 4 +- trunk/fs/jffs2/acl.c | 2 - trunk/fs/jffs2/background.c | 29 +- trunk/fs/jffs2/build.c | 6 +- trunk/fs/jffs2/compr.c | 32 +- trunk/fs/jffs2/compr_lzo.c | 1 + trunk/fs/jffs2/compr_rubin.c | 2 - trunk/fs/jffs2/compr_zlib.c | 45 +- trunk/fs/jffs2/debug.c | 22 +- trunk/fs/jffs2/debug.h | 50 +- trunk/fs/jffs2/dir.c | 41 +- trunk/fs/jffs2/erase.c | 72 +- trunk/fs/jffs2/file.c | 33 +- trunk/fs/jffs2/fs.c | 67 +- trunk/fs/jffs2/gc.c | 322 +- trunk/fs/jffs2/malloc.c | 2 - trunk/fs/jffs2/nodelist.c | 30 +- trunk/fs/jffs2/nodemgmt.c | 214 +- trunk/fs/jffs2/os-linux.h | 4 +- trunk/fs/jffs2/read.c | 70 +- trunk/fs/jffs2/readinode.c | 2 - trunk/fs/jffs2/scan.c | 229 +- trunk/fs/jffs2/security.c | 4 +- trunk/fs/jffs2/summary.c | 16 +- trunk/fs/jffs2/super.c | 30 +- trunk/fs/jffs2/symlink.c | 7 +- trunk/fs/jffs2/wbuf.c | 148 +- trunk/fs/jffs2/write.c | 113 +- trunk/fs/jffs2/xattr.c | 2 - trunk/fs/libfs.c | 9 - trunk/fs/lockd/clnt4xdr.c | 2 +- trunk/fs/lockd/clntxdr.c | 2 +- trunk/fs/locks.c | 3 +- trunk/fs/namei.c | 234 +- trunk/fs/nfs/blocklayout/blocklayout.c | 4 +- trunk/fs/nfs/client.c | 5 +- trunk/fs/nfs/dir.c | 4 +- trunk/fs/nfs/idmap.c | 4 - trunk/fs/nfs/internal.h | 8 +- trunk/fs/nfs/namespace.c | 93 +- trunk/fs/nfs/nfs4_fs.h | 11 +- trunk/fs/nfs/nfs4filelayoutdev.c | 2 +- trunk/fs/nfs/nfs4namespace.c | 86 +- trunk/fs/nfs/nfs4proc.c | 186 +- trunk/fs/nfs/nfs4state.c | 31 +- trunk/fs/nfs/nfs4xdr.c | 53 +- trunk/fs/nfs/objlayout/objlayout.c | 2 + trunk/fs/nfs/pnfs.c | 2 +- trunk/fs/nfs/read.c | 2 +- trunk/fs/nfs/super.c | 12 +- trunk/fs/nfs/write.c | 5 +- trunk/fs/nfsd/nfs3xdr.c | 22 +- trunk/fs/nfsd/nfs4proc.c | 15 +- trunk/fs/nfsd/nfs4recover.c | 2 +- trunk/fs/nfsd/nfs4state.c | 23 +- trunk/fs/nfsd/nfs4xdr.c | 4 +- trunk/fs/nfsd/vfs.c | 2 +- trunk/fs/ocfs2/alloc.c | 2 +- trunk/fs/ocfs2/ioctl.c | 2 + trunk/fs/ocfs2/refcounttree.c | 12 +- trunk/fs/ocfs2/suballoc.c | 4 +- trunk/fs/pipe.c | 31 +- trunk/fs/proc/root.c | 9 +- trunk/fs/proc/stat.c | 34 +- trunk/fs/proc/task_mmu.c | 3 + trunk/fs/pstore/inode.c | 34 +- trunk/fs/romfs/storage.c | 2 +- trunk/fs/splice.c | 5 +- trunk/fs/sysfs/dir.c | 5 +- trunk/fs/sysfs/group.c | 6 +- trunk/fs/xattr.c | 40 +- trunk/include/acpi/acexcep.h | 7 +- trunk/include/acpi/acnames.h | 12 +- trunk/include/acpi/acpi_bus.h | 7 - trunk/include/acpi/acpiosxf.h | 13 +- trunk/include/acpi/acpixf.h | 229 +- trunk/include/acpi/actbl.h | 7 - trunk/include/acpi/actypes.h | 29 +- trunk/include/asm-generic/cmpxchg.h | 1 - trunk/include/asm-generic/siginfo.h | 14 +- trunk/include/asm-generic/statfs.h | 2 +- trunk/include/crypto/internal/aead.h | 2 - trunk/include/crypto/internal/skcipher.h | 2 - trunk/include/drm/drm.h | 14 +- trunk/include/drm/drmP.h | 62 - trunk/include/drm/exynos_drm.h | 5 +- trunk/include/drm/intel-gtt.h | 4 - trunk/include/linux/Kbuild | 2 +- trunk/include/linux/acpi.h | 10 - trunk/include/linux/amba/bus.h | 7 + trunk/include/linux/amba/pl022.h | 2 - trunk/include/linux/blkdev.h | 18 +- trunk/include/linux/cpuidle.h | 22 +- trunk/include/linux/cpumask.h | 6 + trunk/include/linux/cryptouser.h | 3 - trunk/include/linux/dma-attrs.h | 2 - trunk/include/linux/dma-mapping.h | 13 +- trunk/include/linux/dmaengine.h | 1 - trunk/include/linux/efi.h | 13 +- trunk/include/linux/ethtool.h | 3 +- trunk/include/linux/ext2_fs.h | 569 +++- trunk/include/linux/ext2_fs_sb.h | 126 + .../ext3/ext3.h => include/linux/ext3_fs.h} | 488 +-- trunk/include/linux/ext3_fs_i.h | 151 + trunk/include/linux/ext3_fs_sb.h | 91 + trunk/include/linux/ext3_jbd.h | 229 ++ trunk/include/linux/firewire.h | 3 +- trunk/include/linux/fs.h | 6 - trunk/include/linux/ftrace_event.h | 2 - trunk/include/linux/fuse.h | 2 +- trunk/include/linux/gpio-pxa.h | 4 - trunk/include/linux/hsi/Kbuild | 1 - trunk/include/linux/hsi/hsi.h | 413 --- trunk/include/linux/hsi/hsi_char.h | 63 - trunk/include/linux/i2c/twl.h | 12 + trunk/include/linux/if_eql.h | 2 +- trunk/include/linux/irq.h | 12 - trunk/include/linux/irqdomain.h | 12 +- trunk/include/linux/kconfig.h | 22 +- trunk/include/linux/kernel.h | 15 +- trunk/include/linux/kgdb.h | 7 +- trunk/include/linux/kmod.h | 27 +- trunk/include/linux/kvm_host.h | 6 - trunk/include/linux/libata.h | 3 +- trunk/include/linux/lp8727.h | 18 +- trunk/include/linux/lsm_audit.h | 96 +- trunk/include/linux/mfd/abx500.h | 273 -- trunk/include/linux/mfd/abx500/ab8500-bm.h | 474 --- .../include/linux/mfd/abx500/ux500_chargalg.h | 38 - trunk/include/linux/mfd/db5500-prcmu.h | 88 +- trunk/include/linux/mfd/rc5t583.h | 47 +- trunk/include/linux/mfd/twl6040.h | 27 - trunk/include/linux/mm.h | 27 +- trunk/include/linux/mmc/card.h | 2 +- trunk/include/linux/mtd/bbm.h | 5 - trunk/include/linux/mtd/blktrans.h | 1 - trunk/include/linux/mtd/fsmc.h | 169 +- trunk/include/linux/mtd/mtd.h | 304 +- trunk/include/linux/mtd/nand.h | 7 +- trunk/include/linux/mtd/pmc551.h | 78 + trunk/include/linux/mtd/sh_flctl.h | 40 - trunk/include/linux/mtd/spear_smi.h | 65 - trunk/include/linux/mtio.h | 1 - trunk/include/linux/netdevice.h | 2 + trunk/include/linux/netfilter/xt_set.h | 4 +- trunk/include/linux/netfilter_bridge.h | 9 - .../include/linux/netfilter_ipv6/ip6_tables.h | 12 +- trunk/include/linux/nfs_xdr.h | 7 +- trunk/include/linux/nfsd/Kbuild | 1 - trunk/include/linux/perf_event.h | 90 +- trunk/include/linux/pinctrl/machine.h | 4 +- trunk/include/linux/pipe_fs_i.h | 1 - trunk/include/linux/platform_data/atmel.h | 6 +- .../linux/platform_data/spear_thermal.h | 26 - trunk/include/linux/pm_qos.h | 4 - trunk/include/linux/power/max17042_battery.h | 93 +- trunk/include/linux/power/smb347-charger.h | 117 - trunk/include/linux/regulator/machine.h | 8 +- trunk/include/linux/ring_buffer.h | 3 - trunk/include/linux/seqlock.h | 23 +- trunk/include/linux/serial_core.h | 2 +- trunk/include/linux/skbuff.h | 24 +- trunk/include/linux/socket.h | 2 +- trunk/include/linux/spi/spi.h | 2 +- trunk/include/linux/stddef.h | 8 +- trunk/include/linux/swap.h | 14 +- trunk/include/linux/tboot.h | 1 + trunk/include/linux/types.h | 6 - trunk/include/linux/usb/hcd.h | 2 - trunk/include/linux/usb/otg.h | 1 - trunk/include/linux/usb/serial.h | 8 + trunk/include/linux/vgaarb.h | 2 - trunk/include/linux/virtio.h | 1 + trunk/include/linux/vm_event_item.h | 5 +- trunk/include/net/bluetooth/hci.h | 3 +- trunk/include/net/bluetooth/hci_core.h | 15 +- trunk/include/net/bluetooth/mgmt.h | 2 +- trunk/include/net/cfg80211.h | 6 +- trunk/include/net/dst.h | 7 +- trunk/include/net/ip6_fib.h | 48 - trunk/include/net/ip_vs.h | 4 +- trunk/include/net/mac80211.h | 2 +- trunk/include/net/netfilter/xt_log.h | 2 +- trunk/include/net/red.h | 6 +- trunk/include/net/sock.h | 5 +- trunk/include/scsi/iscsi_if.h | 19 +- trunk/include/scsi/libfcoe.h | 4 +- trunk/include/scsi/libsas.h | 40 +- trunk/include/scsi/sas_ata.h | 4 +- trunk/include/scsi/scsi_cmnd.h | 3 - trunk/include/sound/core.h | 10 - trunk/include/trace/events/btrfs.h | 44 - trunk/include/trace/events/sched.h | 2 +- trunk/include/xen/swiotlb-xen.h | 6 +- trunk/init/Kconfig | 4 +- trunk/init/do_mounts.c | 2 +- trunk/init/do_mounts_initrd.c | 1 + trunk/init/do_mounts_rd.c | 9 +- trunk/init/main.c | 25 +- trunk/kernel/cpuset.c | 10 +- trunk/kernel/cred.c | 2 - trunk/kernel/debug/debug_core.c | 53 +- trunk/kernel/debug/kdb/kdb_io.c | 2 +- trunk/kernel/events/core.c | 13 +- trunk/kernel/futex.c | 38 +- trunk/kernel/futex_compat.c | 38 +- trunk/kernel/irq/Kconfig | 2 +- trunk/kernel/irq/debug.h | 38 +- trunk/kernel/irq/handle.c | 16 +- trunk/kernel/irq/irqdomain.c | 47 +- trunk/kernel/irq/manage.c | 19 +- trunk/kernel/irq/migration.c | 10 +- trunk/kernel/irq_work.c | 2 - trunk/kernel/itimer.c | 8 +- trunk/kernel/kmod.c | 117 +- trunk/kernel/padata.c | 13 +- trunk/kernel/panic.c | 2 +- trunk/kernel/power/hibernate.c | 18 +- trunk/kernel/power/process.c | 8 - trunk/kernel/power/qos.c | 50 - trunk/kernel/power/suspend.c | 7 + trunk/kernel/power/swap.c | 28 +- trunk/kernel/power/user.c | 10 +- trunk/kernel/rcutree.c | 1 + trunk/kernel/sched/core.c | 35 +- trunk/kernel/sched/fair.c | 18 +- trunk/kernel/sched/features.h | 1 - trunk/kernel/sched/sched.h | 3 - trunk/kernel/sysctl.c | 8 +- trunk/kernel/time/Kconfig | 4 - trunk/kernel/time/tick-broadcast.c | 11 +- trunk/kernel/time/tick-sched.c | 4 +- trunk/kernel/trace/Kconfig | 2 +- trunk/kernel/trace/blktrace.c | 18 +- trunk/kernel/trace/ftrace.c | 3 +- trunk/kernel/trace/ring_buffer.c | 157 +- trunk/kernel/trace/trace.c | 115 - trunk/kernel/trace/trace.h | 7 +- trunk/kernel/trace/trace_entries.h | 16 +- trunk/kernel/trace/trace_export.c | 2 +- trunk/kernel/trace/trace_output.c | 5 - trunk/lib/kobject.c | 14 +- trunk/lib/mpi/mpi-bit.c | 5 +- trunk/mm/hugetlb.c | 4 +- trunk/mm/memblock.c | 7 +- trunk/mm/memcontrol.c | 22 +- trunk/mm/mempolicy.c | 11 +- trunk/mm/migrate.c | 16 +- trunk/mm/mmap.c | 59 +- trunk/mm/nobootmem.c | 10 +- trunk/mm/nommu.c | 41 +- trunk/mm/swap_state.c | 2 +- trunk/mm/vmscan.c | 18 +- trunk/mm/vmstat.c | 4 +- trunk/net/802/garp.c | 22 +- trunk/net/ax25/af_ax25.c | 9 +- trunk/net/bluetooth/hci_core.c | 34 +- trunk/net/bluetooth/hci_event.c | 3 - trunk/net/bluetooth/l2cap_core.c | 3 - trunk/net/bluetooth/l2cap_sock.c | 5 +- trunk/net/bluetooth/mgmt.c | 15 +- trunk/net/bridge/br_forward.c | 1 - trunk/net/bridge/br_multicast.c | 81 + trunk/net/bridge/br_netfilter.c | 8 +- trunk/net/bridge/br_private.h | 4 + trunk/net/caif/chnl_net.c | 9 +- trunk/net/core/dev.c | 79 +- trunk/net/core/dev_addr_lists.c | 3 +- trunk/net/core/drop_monitor.c | 89 +- trunk/net/core/filter.c | 9 +- trunk/net/core/net_namespace.c | 33 +- trunk/net/core/skbuff.c | 8 +- trunk/net/ieee802154/6lowpan.c | 40 +- trunk/net/ipv4/inet_diag.c | 2 +- .../netfilter/nf_conntrack_l3proto_ipv4.c | 12 +- trunk/net/ipv4/route.c | 2 +- trunk/net/ipv4/tcp.c | 26 +- trunk/net/ipv4/tcp_input.c | 23 +- trunk/net/ipv4/tcp_ipv4.c | 2 +- trunk/net/ipv4/tcp_output.c | 3 +- trunk/net/ipv4/udp_diag.c | 9 - trunk/net/ipv6/addrconf.c | 9 +- trunk/net/ipv6/ip6_fib.c | 9 +- trunk/net/ipv6/mcast.c | 2 +- trunk/net/ipv6/ndisc.c | 3 +- trunk/net/ipv6/netfilter/ip6_tables.c | 14 + trunk/net/ipv6/route.c | 105 +- trunk/net/ipv6/tcp_ipv6.c | 6 +- trunk/net/key/af_key.c | 2 +- trunk/net/l2tp/l2tp_ip.c | 8 +- trunk/net/mac80211/agg-rx.c | 3 +- trunk/net/mac80211/debugfs.c | 12 +- trunk/net/mac80211/debugfs.h | 1 + trunk/net/mac80211/debugfs_key.c | 4 +- trunk/net/mac80211/debugfs_netdev.c | 2 +- trunk/net/mac80211/debugfs_sta.c | 4 +- trunk/net/mac80211/ibss.c | 4 +- trunk/net/mac80211/ieee80211_i.h | 2 +- trunk/net/mac80211/iface.c | 4 +- trunk/net/mac80211/main.c | 3 + trunk/net/mac80211/mlme.c | 5 +- trunk/net/mac80211/rate.c | 2 +- trunk/net/mac80211/rx.c | 10 +- trunk/net/mac80211/scan.c | 2 +- trunk/net/mac80211/tx.c | 3 +- trunk/net/netfilter/ipvs/ip_vs_core.c | 11 - trunk/net/netfilter/ipvs/ip_vs_ctl.c | 56 +- trunk/net/netfilter/ipvs/ip_vs_ftp.c | 2 - trunk/net/netfilter/ipvs/ip_vs_lblc.c | 3 - trunk/net/netfilter/ipvs/ip_vs_lblcr.c | 3 - trunk/net/netfilter/ipvs/ip_vs_proto.c | 38 +- trunk/net/netfilter/ipvs/ip_vs_proto_sctp.c | 5 +- trunk/net/netfilter/ipvs/ip_vs_proto_tcp.c | 5 +- trunk/net/netfilter/ipvs/ip_vs_proto_udp.c | 5 +- trunk/net/netfilter/nf_conntrack_core.c | 3 +- trunk/net/netfilter/nf_conntrack_proto_tcp.c | 4 +- trunk/net/netfilter/nfnetlink_acct.c | 2 +- trunk/net/netfilter/xt_CT.c | 30 +- trunk/net/netlink/af_netlink.c | 24 +- trunk/net/nfc/llcp/commands.c | 4 +- trunk/net/phonet/pep.c | 3 - trunk/net/phonet/pn_dev.c | 21 +- trunk/net/rose/rose_dev.c | 4 +- trunk/net/sched/sch_gred.c | 7 +- trunk/net/sched/sch_netem.c | 6 +- trunk/net/sctp/socket.c | 5 +- trunk/net/socket.c | 6 +- trunk/net/sunrpc/clnt.c | 50 +- trunk/net/sunrpc/rpc_pipe.c | 3 +- trunk/net/sunrpc/sunrpc_syms.c | 17 +- trunk/net/wireless/debugfs.c | 10 +- trunk/net/wireless/nl80211.c | 60 +- trunk/net/wireless/util.c | 2 +- trunk/net/wireless/wext-core.c | 6 +- trunk/scripts/Kbuild.include | 2 +- trunk/scripts/Makefile.build | 2 - trunk/scripts/Makefile.lib | 24 - trunk/scripts/checkpatch.pl | 6 + trunk/scripts/coccinelle/api/ptr_ret.cocci | 70 - .../scripts/coccinelle/api/simple_open.cocci | 70 - trunk/scripts/coccinelle/free/clk_put.cocci | 67 - trunk/scripts/coccinelle/free/iounmap.cocci | 67 - trunk/scripts/coccinelle/misc/boolinit.cocci | 178 -- trunk/scripts/coccinelle/misc/cstptr.cocci | 41 - trunk/scripts/coccinelle/null/badzero.cocci | 237 -- trunk/scripts/dtc/dtc.c | 5 +- trunk/scripts/dtc/flattree.c | 2 + trunk/scripts/headers_check.pl | 38 +- trunk/scripts/kconfig/confdata.c | 64 +- trunk/scripts/kconfig/merge_config.sh | 15 +- trunk/scripts/kconfig/symbol.c | 9 +- trunk/scripts/mod/file2alias.c | 4 - trunk/scripts/mod/modpost.c | 9 +- trunk/scripts/mod/modpost.h | 1 - trunk/scripts/package/builddeb | 20 +- trunk/scripts/patch-kernel | 4 - trunk/scripts/setlocalversion | 3 +- trunk/scripts/tags.sh | 13 +- trunk/scripts/xz_wrap.sh | 4 +- trunk/security/apparmor/audit.c | 42 +- trunk/security/apparmor/capability.c | 6 +- trunk/security/apparmor/file.c | 54 +- trunk/security/apparmor/include/audit.h | 28 +- trunk/security/apparmor/ipc.c | 10 +- trunk/security/apparmor/lib.c | 4 +- trunk/security/apparmor/lsm.c | 8 +- trunk/security/apparmor/policy.c | 10 +- trunk/security/apparmor/policy_unpack.c | 20 +- trunk/security/apparmor/resource.c | 12 +- trunk/security/commoncap.c | 6 - trunk/security/lsm_audit.c | 80 +- trunk/security/selinux/avc.c | 101 +- trunk/security/selinux/hooks.c | 185 +- trunk/security/selinux/include/avc.h | 25 - trunk/security/selinux/selinuxfs.c | 110 +- trunk/security/smack/smack.h | 23 +- trunk/security/smack/smack_access.c | 14 +- trunk/security/smack/smack_lsm.c | 86 +- trunk/security/smack/smackfs.c | 14 + trunk/sound/core/seq/seq_dummy.c | 2 +- trunk/sound/core/vmaster.c | 1 - trunk/sound/drivers/Kconfig | 3 +- trunk/sound/isa/opti9xx/opti92x-ad1848.c | 2 +- trunk/sound/isa/sscape.c | 6 +- trunk/sound/last.c | 2 +- trunk/sound/oss/msnd_pinnacle.c | 10 +- trunk/sound/pci/Kconfig | 4 +- trunk/sound/pci/asihpi/hpi_internal.h | 2 +- trunk/sound/pci/asihpi/hpios.c | 8 +- trunk/sound/pci/hda/hda_codec.h | 3 - trunk/sound/pci/hda/hda_eld.c | 6 +- trunk/sound/pci/hda/hda_proc.c | 13 +- trunk/sound/pci/hda/patch_conexant.c | 143 +- trunk/sound/pci/hda/patch_hdmi.c | 9 +- trunk/sound/pci/hda/patch_realtek.c | 97 +- trunk/sound/pci/hda/patch_sigmatel.c | 5 +- trunk/sound/soc/blackfin/bf5xx-ssm2602.c | 2 - trunk/sound/soc/codecs/Kconfig | 3 +- trunk/sound/soc/codecs/ak4642.c | 2 +- trunk/sound/soc/codecs/cs42l73.c | 2 - trunk/sound/soc/codecs/sgtl5000.c | 25 +- trunk/sound/soc/codecs/tlv320aic23.c | 4 +- trunk/sound/soc/codecs/twl6040.c | 3 +- trunk/sound/soc/codecs/wm8350.c | 11 +- trunk/sound/soc/codecs/wm8994.c | 278 +- trunk/sound/soc/codecs/wm_hubs.c | 15 +- trunk/sound/soc/fsl/mpc8610_hpcd.c | 8 +- trunk/sound/soc/fsl/p1022_ds.c | 10 +- trunk/sound/soc/imx/imx-audmux.c | 13 +- trunk/sound/soc/mxs/mxs-pcm.c | 2 +- trunk/sound/soc/mxs/mxs-saif.c | 2 +- trunk/sound/soc/omap/Kconfig | 2 +- trunk/sound/soc/omap/omap-pcm.c | 4 - trunk/sound/soc/pxa/pxa2xx-i2s.c | 1 - trunk/sound/soc/samsung/s3c2412-i2s.c | 2 +- trunk/sound/soc/sh/fsi.c | 7 +- trunk/sound/soc/soc-core.c | 17 +- trunk/sound/soc/soc-dapm.c | 18 +- trunk/sound/soc/soc-dmaengine-pcm.c | 2 +- trunk/sound/soc/tegra/tegra_i2s.c | 6 +- trunk/sound/soc/tegra/tegra_spdif.c | 4 - trunk/tools/perf/.gitignore | 2 - .../tools/perf/Documentation/perf-report.txt | 5 - trunk/tools/perf/Makefile | 63 +- trunk/tools/perf/builtin-diff.c | 60 +- trunk/tools/perf/builtin-report.c | 57 +- trunk/tools/perf/builtin-sched.c | 1 - trunk/tools/perf/builtin-stat.c | 2 +- trunk/tools/perf/builtin-test.c | 204 +- trunk/tools/perf/builtin-top.c | 36 +- trunk/tools/perf/config/feature-tests.mak | 15 - trunk/tools/perf/perf-archive.sh | 3 +- trunk/tools/perf/util/annotate.c | 22 +- trunk/tools/perf/util/cache.h | 12 - trunk/tools/perf/util/evlist.c | 6 +- trunk/tools/perf/util/evsel.c | 10 +- trunk/tools/perf/util/evsel.h | 5 +- trunk/tools/perf/util/gtk/browser.c | 189 -- trunk/tools/perf/util/gtk/gtk.h | 8 - trunk/tools/perf/util/header.c | 2 +- trunk/tools/perf/util/hist.c | 212 +- trunk/tools/perf/util/hist.h | 19 - .../util/include/linux/{export.h => module.h} | 0 trunk/tools/perf/util/map.c | 1 - trunk/tools/perf/util/map.h | 1 - trunk/tools/perf/util/parse-events.c | 603 ++-- trunk/tools/perf/util/parse-events.h | 49 - trunk/tools/perf/util/parse-events.l | 127 - trunk/tools/perf/util/parse-events.y | 229 -- trunk/tools/perf/util/pmu.c | 469 --- trunk/tools/perf/util/pmu.h | 41 - trunk/tools/perf/util/pmu.l | 43 - trunk/tools/perf/util/pmu.y | 93 - trunk/tools/perf/util/probe-finder.c | 4 +- trunk/tools/perf/util/session.c | 17 +- trunk/tools/perf/util/symbol.c | 16 +- trunk/tools/perf/util/trace-event-parse.c | 10 +- trunk/tools/perf/util/ui/browser.h | 2 - trunk/tools/perf/util/ui/browsers/hists.c | 17 +- trunk/tools/perf/util/ui/keysyms.h | 2 - trunk/tools/perf/util/ui/util.c | 82 - trunk/tools/power/x86/turbostat/turbostat.8 | 99 +- trunk/tools/power/x86/turbostat/turbostat.c | 245 +- trunk/tools/testing/ktest/ktest.pl | 12 +- trunk/virt/kvm/iommu.c | 30 +- trunk/virt/kvm/kvm_main.c | 5 +- 2060 files changed, 21113 insertions(+), 54082 deletions(-) delete mode 100644 trunk/Documentation/ABI/testing/sysfs-block-rssd delete mode 100644 trunk/Documentation/ABI/testing/sysfs-bus-event_source-devices-format delete mode 100644 trunk/Documentation/ABI/testing/sysfs-bus-hsi delete mode 100644 trunk/Documentation/ABI/testing/sysfs-cfq-target-latency rename trunk/Documentation/devicetree/bindings/ata/{ahci-platform.txt => calxeda-sata.txt} (90%) delete mode 100644 trunk/Documentation/devicetree/bindings/mtd/fsmc-nand.txt delete mode 100644 trunk/Documentation/devicetree/bindings/mtd/spear_smi.txt delete mode 100644 trunk/Documentation/devicetree/bindings/power_supply/max17042_battery.txt delete mode 100644 trunk/Documentation/devicetree/bindings/regulator/anatop-regulator.txt delete mode 100644 trunk/Documentation/scsi/ufs.txt delete mode 100644 trunk/arch/alpha/include/asm/cmpxchg.h delete mode 100644 trunk/arch/arm/include/asm/cpuidle.h delete mode 100644 trunk/arch/arm/kernel/cpuidle.c delete mode 100644 trunk/arch/arm/mach-at91/include/mach/io.h rename trunk/{include/linux/fsl/mxs-dma.h => arch/arm/mach-mxs/include/mach/dma.h} (100%) delete mode 100644 trunk/arch/arm/mach-omap1/include/mach/io.h delete mode 100644 trunk/arch/arm/mach-pxa/include/mach/io.h delete mode 100644 trunk/arch/arm/mach-s3c24xx/common.h create mode 100644 trunk/arch/avr32/include/asm/special_insns.h rename trunk/arch/m68k/platform/{68VZ328 => 68EZ328}/bootlogo.h (99%) delete mode 100644 trunk/arch/parisc/include/asm/cmpxchg.h delete mode 100644 trunk/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi delete mode 100644 trunk/arch/powerpc/boot/dts/p1020mbg-pc.dtsi delete mode 100644 trunk/arch/powerpc/boot/dts/p1020mbg-pc_32b.dts delete mode 100644 trunk/arch/powerpc/boot/dts/p1020mbg-pc_36b.dts delete mode 100644 trunk/arch/powerpc/boot/dts/p1020utm-pc.dtsi delete mode 100644 trunk/arch/powerpc/boot/dts/p1020utm-pc_32b.dts delete mode 100644 trunk/arch/powerpc/boot/dts/p1020utm-pc_36b.dts delete mode 100644 trunk/arch/tile/include/asm/cmpxchg.h delete mode 100644 trunk/arch/x86/include/asm/word-at-a-time.h delete mode 100644 trunk/arch/x86/um/asm/barrier.h create mode 100644 trunk/arch/x86/um/asm/system.h rename trunk/{include/acpi => drivers/acpi/acpica}/acconfig.h (92%) delete mode 100644 trunk/drivers/acpi/acpica/hwesleep.c delete mode 100644 trunk/drivers/acpi/acpica/hwxfsleep.c delete mode 100644 trunk/drivers/acpi/bgrt.c delete mode 100644 trunk/drivers/gpu/drm/drm_prime.c delete mode 100644 trunk/drivers/hsi/Kconfig delete mode 100644 trunk/drivers/hsi/Makefile delete mode 100644 trunk/drivers/hsi/clients/Kconfig delete mode 100644 trunk/drivers/hsi/clients/Makefile delete mode 100644 trunk/drivers/hsi/clients/hsi_char.c delete mode 100644 trunk/drivers/hsi/hsi.c delete mode 100644 trunk/drivers/hsi/hsi_boardinfo.c delete mode 100644 trunk/drivers/hsi/hsi_core.h delete mode 100644 trunk/drivers/mtd/devices/spear_smi.c delete mode 100644 trunk/drivers/mtd/nand/docg4.c delete mode 100644 trunk/drivers/power/ab8500_btemp.c delete mode 100644 trunk/drivers/power/ab8500_charger.c delete mode 100644 trunk/drivers/power/ab8500_fg.c delete mode 100644 trunk/drivers/power/abx500_chargalg.c delete mode 100644 trunk/drivers/power/smb347-charger.c delete mode 100644 trunk/drivers/scsi/ufs/Kconfig delete mode 100644 trunk/drivers/scsi/ufs/Makefile delete mode 100644 trunk/drivers/scsi/ufs/ufs.h delete mode 100644 trunk/drivers/scsi/ufs/ufshcd.c delete mode 100644 trunk/drivers/scsi/ufs/ufshci.h delete mode 100644 trunk/drivers/thermal/spear_thermal.c delete mode 100644 trunk/drivers/video/backlight/da9052_bl.c create mode 100644 trunk/include/linux/ext2_fs_sb.h rename trunk/{fs/ext3/ext3.h => include/linux/ext3_fs.h} (67%) create mode 100644 trunk/include/linux/ext3_fs_i.h create mode 100644 trunk/include/linux/ext3_fs_sb.h create mode 100644 trunk/include/linux/ext3_jbd.h delete mode 100644 trunk/include/linux/hsi/Kbuild delete mode 100644 trunk/include/linux/hsi/hsi.h delete mode 100644 trunk/include/linux/hsi/hsi_char.h delete mode 100644 trunk/include/linux/mfd/abx500/ab8500-bm.h delete mode 100644 trunk/include/linux/mfd/abx500/ux500_chargalg.h create mode 100644 trunk/include/linux/mtd/pmc551.h delete mode 100644 trunk/include/linux/mtd/spear_smi.h delete mode 100644 trunk/include/linux/platform_data/spear_thermal.h delete mode 100644 trunk/include/linux/power/smb347-charger.h delete mode 100644 trunk/scripts/coccinelle/api/ptr_ret.cocci delete mode 100644 trunk/scripts/coccinelle/api/simple_open.cocci delete mode 100644 trunk/scripts/coccinelle/free/clk_put.cocci delete mode 100644 trunk/scripts/coccinelle/free/iounmap.cocci delete mode 100644 trunk/scripts/coccinelle/misc/boolinit.cocci delete mode 100644 trunk/scripts/coccinelle/misc/cstptr.cocci delete mode 100644 trunk/scripts/coccinelle/null/badzero.cocci mode change 100755 => 100644 trunk/scripts/kconfig/merge_config.sh delete mode 100644 trunk/tools/perf/util/gtk/browser.c delete mode 100644 trunk/tools/perf/util/gtk/gtk.h rename trunk/tools/perf/util/include/linux/{export.h => module.h} (100%) delete mode 100644 trunk/tools/perf/util/parse-events.l delete mode 100644 trunk/tools/perf/util/parse-events.y delete mode 100644 trunk/tools/perf/util/pmu.c delete mode 100644 trunk/tools/perf/util/pmu.h delete mode 100644 trunk/tools/perf/util/pmu.l delete mode 100644 trunk/tools/perf/util/pmu.y diff --git a/[refs] b/[refs] index 3d23e2dd02c5..463a80bd201c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: fba60c620a6a9ec11140c179e5d0fe0bc3c3ea29 +refs/heads/master: 35372a7d45291140a97518a8d1c8cb0e31ee2bb7 diff --git a/trunk/Documentation/ABI/stable/sysfs-driver-usb-usbtmc b/trunk/Documentation/ABI/stable/sysfs-driver-usb-usbtmc index e960cd027e1e..23a43b8207e6 100644 --- a/trunk/Documentation/ABI/stable/sysfs-driver-usb-usbtmc +++ b/trunk/Documentation/ABI/stable/sysfs-driver-usb-usbtmc @@ -1,5 +1,5 @@ -What: /sys/bus/usb/drivers/usbtmc/*/interface_capabilities -What: /sys/bus/usb/drivers/usbtmc/*/device_capabilities +What: /sys/bus/usb/drivers/usbtmc/devices/*/interface_capabilities +What: /sys/bus/usb/drivers/usbtmc/devices/*/device_capabilities Date: August 2008 Contact: Greg Kroah-Hartman Description: @@ -12,8 +12,8 @@ Description: The files are read only. -What: /sys/bus/usb/drivers/usbtmc/*/usb488_interface_capabilities -What: /sys/bus/usb/drivers/usbtmc/*/usb488_device_capabilities +What: /sys/bus/usb/drivers/usbtmc/devices/*/usb488_interface_capabilities +What: /sys/bus/usb/drivers/usbtmc/devices/*/usb488_device_capabilities Date: August 2008 Contact: Greg Kroah-Hartman Description: @@ -27,7 +27,7 @@ Description: The files are read only. -What: /sys/bus/usb/drivers/usbtmc/*/TermChar +What: /sys/bus/usb/drivers/usbtmc/devices/*/TermChar Date: August 2008 Contact: Greg Kroah-Hartman Description: @@ -40,7 +40,7 @@ Description: sent to the device or not. -What: /sys/bus/usb/drivers/usbtmc/*/TermCharEnabled +What: /sys/bus/usb/drivers/usbtmc/devices/*/TermCharEnabled Date: August 2008 Contact: Greg Kroah-Hartman Description: @@ -51,11 +51,11 @@ Description: published by the USB-IF. -What: /sys/bus/usb/drivers/usbtmc/*/auto_abort +What: /sys/bus/usb/drivers/usbtmc/devices/*/auto_abort Date: August 2008 Contact: Greg Kroah-Hartman Description: - This file determines if the transaction of the USB TMC + This file determines if the the transaction of the USB TMC device is to be automatically aborted if there is any error. For more details about this, please see the document, "Universal Serial Bus Test and Measurement Class Specification diff --git a/trunk/Documentation/ABI/testing/sysfs-block-rssd b/trunk/Documentation/ABI/testing/sysfs-block-rssd deleted file mode 100644 index d535757799fe..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-block-rssd +++ /dev/null @@ -1,18 +0,0 @@ -What: /sys/block/rssd*/registers -Date: March 2012 -KernelVersion: 3.3 -Contact: Asai Thambi S P -Description: This is a read-only file. Dumps below driver information and - hardware registers. - - S ACTive - - Command Issue - - Allocated - - Completed - - PORT IRQ STAT - - HOST IRQ STAT - -What: /sys/block/rssd*/status -Date: April 2012 -KernelVersion: 3.4 -Contact: Asai Thambi S P -Description: This is a read-only file. Indicates the status of the device. diff --git a/trunk/Documentation/ABI/testing/sysfs-bus-event_source-devices-format b/trunk/Documentation/ABI/testing/sysfs-bus-event_source-devices-format deleted file mode 100644 index 079afc71363d..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-bus-event_source-devices-format +++ /dev/null @@ -1,14 +0,0 @@ -Where: /sys/bus/event_source/devices//format -Date: January 2012 -Kernel Version: 3.3 -Contact: Jiri Olsa -Description: - Attribute group to describe the magic bits that go into - perf_event_attr::config[012] for a particular pmu. - Each attribute of this group defines the 'hardware' bitmask - we want to export, so that userspace can deal with sane - name/value pairs. - - Example: 'config1:1,6-10,44' - Defines contents of attribute that occupies bits 1,6-10,44 of - perf_event_attr::config1. diff --git a/trunk/Documentation/ABI/testing/sysfs-bus-hsi b/trunk/Documentation/ABI/testing/sysfs-bus-hsi deleted file mode 100644 index 1b1b282a99e1..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-bus-hsi +++ /dev/null @@ -1,19 +0,0 @@ -What: /sys/bus/hsi -Date: April 2012 -KernelVersion: 3.4 -Contact: Carlos Chinea -Description: - High Speed Synchronous Serial Interface (HSI) is a - serial interface mainly used for connecting application - engines (APE) with cellular modem engines (CMT) in cellular - handsets. - The bus will be populated with devices (hsi_clients) representing - the protocols available in the system. Bus drivers implement - those protocols. - -What: /sys/bus/hsi/devices/.../modalias -Date: April 2012 -KernelVersion: 3.4 -Contact: Carlos Chinea -Description: Stores the same MODALIAS value emitted by uevent - Format: hsi: diff --git a/trunk/Documentation/ABI/testing/sysfs-cfq-target-latency b/trunk/Documentation/ABI/testing/sysfs-cfq-target-latency deleted file mode 100644 index df0f7828c5e3..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-cfq-target-latency +++ /dev/null @@ -1,8 +0,0 @@ -What: /sys/block//iosched/target_latency -Date: March 2012 -contact: Tao Ma -Description: - The /sys/block//iosched/target_latency only exists - when the user sets cfq to /sys/block//scheduler. - It contains an estimated latency time for the cfq. cfq will - use it to calculate the time slice used for every task. diff --git a/trunk/Documentation/ABI/testing/sysfs-firmware-acpi b/trunk/Documentation/ABI/testing/sysfs-firmware-acpi index dd930c8db41f..4f9ba3c2fca7 100644 --- a/trunk/Documentation/ABI/testing/sysfs-firmware-acpi +++ b/trunk/Documentation/ABI/testing/sysfs-firmware-acpi @@ -1,23 +1,3 @@ -What: /sys/firmware/acpi/bgrt/ -Date: January 2012 -Contact: Matthew Garrett -Description: - The BGRT is an ACPI 5.0 feature that allows the OS - to obtain a copy of the firmware boot splash and - some associated metadata. This is intended to be used - by boot splash applications in order to interact with - the firmware boot splash in order to avoid jarring - transitions. - - image: The image bitmap. Currently a 32-bit BMP. - status: 1 if the image is valid, 0 if firmware invalidated it. - type: 0 indicates image is in BMP format. - version: The version of the BGRT. Currently 1. - xoffset: The number of pixels between the left of the screen - and the left edge of the image. - yoffset: The number of pixels between the top of the screen - and the top edge of the image. - What: /sys/firmware/acpi/interrupts/ Date: February 2008 Contact: Len Brown diff --git a/trunk/Documentation/CodingStyle b/trunk/Documentation/CodingStyle index c58b236bbe04..2b90d328b3ba 100644 --- a/trunk/Documentation/CodingStyle +++ b/trunk/Documentation/CodingStyle @@ -793,35 +793,6 @@ own custom mode, or may have some other magic method for making indentation work correctly. - Chapter 19: Inline assembly - -In architecture-specific code, you may need to use inline assembly to interface -with CPU or platform functionality. Don't hesitate to do so when necessary. -However, don't use inline assembly gratuitously when C can do the job. You can -and should poke hardware from C when possible. - -Consider writing simple helper functions that wrap common bits of inline -assembly, rather than repeatedly writing them with slight variations. Remember -that inline assembly can use C parameters. - -Large, non-trivial assembly functions should go in .S files, with corresponding -C prototypes defined in C header files. The C prototypes for assembly -functions should use "asmlinkage". - -You may need to mark your asm statement as volatile, to prevent GCC from -removing it if GCC doesn't notice any side effects. You don't always need to -do so, though, and doing so unnecessarily can limit optimization. - -When writing a single inline assembly statement containing multiple -instructions, put each instruction on a separate line in a separate quoted -string, and end each string except the last with \n\t to properly indent the -next instruction in the assembly output: - - asm ("magic %reg1, #42\n\t" - "more_magic %reg2, %reg3" - : /* outputs */ : /* inputs */ : /* clobbers */); - - Appendix I: References diff --git a/trunk/Documentation/DMA-attributes.txt b/trunk/Documentation/DMA-attributes.txt index 5c72eed89563..b768cc0e402b 100644 --- a/trunk/Documentation/DMA-attributes.txt +++ b/trunk/Documentation/DMA-attributes.txt @@ -31,21 +31,3 @@ may be weakly ordered, that is that reads and writes may pass each other. Since it is optional for platforms to implement DMA_ATTR_WEAK_ORDERING, those that do not will simply ignore the attribute and exhibit default behavior. - -DMA_ATTR_WRITE_COMBINE ----------------------- - -DMA_ATTR_WRITE_COMBINE specifies that writes to the mapping may be -buffered to improve performance. - -Since it is optional for platforms to implement DMA_ATTR_WRITE_COMBINE, -those that do not will simply ignore the attribute and exhibit default -behavior. - -DMA_ATTR_NON_CONSISTENT ------------------------ - -DMA_ATTR_NON_CONSISTENT lets the platform to choose to return either -consistent or non-consistent memory as it sees fit. By using this API, -you are guaranteeing to the platform that you have all the correct and -necessary sync points for this memory in the driver. diff --git a/trunk/Documentation/DocBook/device-drivers.tmpl b/trunk/Documentation/DocBook/device-drivers.tmpl index 7514dbf0a679..9c27e5125dd2 100644 --- a/trunk/Documentation/DocBook/device-drivers.tmpl +++ b/trunk/Documentation/DocBook/device-drivers.tmpl @@ -446,21 +446,4 @@ X!Idrivers/video/console/fonts.c !Edrivers/i2c/i2c-core.c - - High Speed Synchronous Serial Interface (HSI) - - - High Speed Synchronous Serial Interface (HSI) is a - serial interface mainly used for connecting application - engines (APE) with cellular modem engines (CMT) in cellular - handsets. - - HSI provides multiplexing for up to 16 logical channels, - low-latency and full duplex communication. - - -!Iinclude/linux/hsi/hsi.h -!Edrivers/hsi/hsi.c - - diff --git a/trunk/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml b/trunk/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml index 5274c24d11e0..3fd3ce5df270 100644 --- a/trunk/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml +++ b/trunk/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml @@ -1,6 +1,6 @@ - V4L2_PIX_FMT_NV12M ('NM12') + V4L2_PIX_FMT_NV12M ('NV12M') &manvol; diff --git a/trunk/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml b/trunk/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml index 60308f1eefdf..9957863daf18 100644 --- a/trunk/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml +++ b/trunk/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml @@ -1,6 +1,6 @@ - V4L2_PIX_FMT_YUV420M ('YM12') + V4L2_PIX_FMT_YUV420M ('YU12M') &manvol; diff --git a/trunk/Documentation/acpi/apei/einj.txt b/trunk/Documentation/acpi/apei/einj.txt index e20b6daaced4..e7cc36397217 100644 --- a/trunk/Documentation/acpi/apei/einj.txt +++ b/trunk/Documentation/acpi/apei/einj.txt @@ -53,14 +53,6 @@ directory apei/einj. The following files are provided. This file is used to set the second error parameter value. Effect of parameter depends on error_type specified. -- notrigger - The EINJ mechanism is a two step process. First inject the error, then - perform some actions to trigger it. Setting "notrigger" to 1 skips the - trigger phase, which *may* allow the user to cause the error in some other - context by a simple access to the cpu, memory location, or device that is - the target of the error injection. Whether this actually works depends - on what operations the BIOS actually includes in the trigger phase. - BIOS versions based in the ACPI 4.0 specification have limited options to control where the errors are injected. Your BIOS may support an extension (enabled with the param_extension=1 module parameter, or diff --git a/trunk/Documentation/aoe/aoe.txt b/trunk/Documentation/aoe/aoe.txt index 5f5aa16047ff..b5aada9f20cc 100644 --- a/trunk/Documentation/aoe/aoe.txt +++ b/trunk/Documentation/aoe/aoe.txt @@ -35,7 +35,7 @@ CREATING DEVICE NODES sh Documentation/aoe/mkshelf.sh /dev/etherd 0 There is also an autoload script that shows how to edit - /etc/modprobe.d/aoe.conf to ensure that the aoe module is loaded when + /etc/modprobe.conf to ensure that the aoe module is loaded when necessary. USING DEVICE NODES diff --git a/trunk/Documentation/aoe/autoload.sh b/trunk/Documentation/aoe/autoload.sh index 815dff4691c9..78dad1334c6f 100644 --- a/trunk/Documentation/aoe/autoload.sh +++ b/trunk/Documentation/aoe/autoload.sh @@ -1,8 +1,8 @@ #!/bin/sh # set aoe to autoload by installing the -# aliases in /etc/modprobe.d/ +# aliases in /etc/modprobe.conf -f=/etc/modprobe.d/aoe.conf +f=/etc/modprobe.conf if test ! -r $f || test ! -w $f; then echo "cannot configure $f for module autoloading" 1>&2 diff --git a/trunk/Documentation/blockdev/floppy.txt b/trunk/Documentation/blockdev/floppy.txt index 470fe4b5e379..6ccab88705cb 100644 --- a/trunk/Documentation/blockdev/floppy.txt +++ b/trunk/Documentation/blockdev/floppy.txt @@ -49,7 +49,7 @@ you can put: options floppy omnibook messages -in a configuration file in /etc/modprobe.d/. +in /etc/modprobe.conf. The floppy driver related options are: diff --git a/trunk/Documentation/cgroups/cpusets.txt b/trunk/Documentation/cgroups/cpusets.txt index cefd3d8bbd11..5c51ed406d1d 100644 --- a/trunk/Documentation/cgroups/cpusets.txt +++ b/trunk/Documentation/cgroups/cpusets.txt @@ -217,7 +217,7 @@ and name space for cpusets, with a minimum of additional kernel code. The cpus and mems files in the root (top_cpuset) cpuset are read-only. The cpus file automatically tracks the value of -cpu_online_mask using a CPU hotplug notifier, and the mems file +cpu_online_map using a CPU hotplug notifier, and the mems file automatically tracks the value of node_states[N_HIGH_MEMORY]--i.e., nodes with memory--using the cpuset_track_online_nodes() hook. diff --git a/trunk/Documentation/cgroups/memory.txt b/trunk/Documentation/cgroups/memory.txt index 9b1067afb224..4c95c0034a4b 100644 --- a/trunk/Documentation/cgroups/memory.txt +++ b/trunk/Documentation/cgroups/memory.txt @@ -34,7 +34,8 @@ Current Status: linux-2.6.34-mmotm(development version of 2010/April) Features: - accounting anonymous pages, file caches, swap caches usage and limiting them. - - pages are linked to per-memcg LRU exclusively, and there is no global LRU. + - private LRU and reclaim routine. (system's global LRU and private LRU + work independently from each other) - optionally, memory+swap usage can be accounted and limited. - hierarchical accounting - soft limit @@ -153,7 +154,7 @@ updated. page_cgroup has its own LRU on cgroup. 2.2.1 Accounting details All mapped anon pages (RSS) and cache pages (Page Cache) are accounted. -Some pages which are never reclaimable and will not be on the LRU +Some pages which are never reclaimable and will not be on the global LRU are not accounted. We just account pages under usual VM management. RSS pages are accounted at page_fault unless they've already been accounted diff --git a/trunk/Documentation/cpu-hotplug.txt b/trunk/Documentation/cpu-hotplug.txt index 66ef8f35613d..a20bfd415e41 100644 --- a/trunk/Documentation/cpu-hotplug.txt +++ b/trunk/Documentation/cpu-hotplug.txt @@ -47,7 +47,7 @@ maxcpus=n Restrict boot time cpus to n. Say if you have 4 cpus, using other cpus later online, read FAQ's for more info. additional_cpus=n (*) Use this to limit hotpluggable cpus. This option sets - cpu_possible_mask = cpu_present_mask + additional_cpus + cpu_possible_map = cpu_present_map + additional_cpus cede_offline={"off","on"} Use this option to disable/enable putting offlined processors to an extended H_CEDE state on @@ -64,11 +64,11 @@ should only rely on this to count the # of cpus, but *MUST* not rely on the apicid values in those tables for disabled apics. In the event BIOS doesn't mark such hot-pluggable cpus as disabled entries, one could use this parameter "additional_cpus=x" to represent those cpus in the -cpu_possible_mask. +cpu_possible_map. possible_cpus=n [s390,x86_64] use this to set hotpluggable cpus. This option sets possible_cpus bits in - cpu_possible_mask. Thus keeping the numbers of bits set + cpu_possible_map. Thus keeping the numbers of bits set constant even if the machine gets rebooted. CPU maps and such @@ -76,7 +76,7 @@ CPU maps and such [More on cpumaps and primitive to manipulate, please check include/linux/cpumask.h that has more descriptive text.] -cpu_possible_mask: Bitmap of possible CPUs that can ever be available in the +cpu_possible_map: Bitmap of possible CPUs that can ever be available in the system. This is used to allocate some boot time memory for per_cpu variables that aren't designed to grow/shrink as CPUs are made available or removed. Once set during boot time discovery phase, the map is static, i.e no bits @@ -84,13 +84,13 @@ are added or removed anytime. Trimming it accurately for your system needs upfront can save some boot time memory. See below for how we use heuristics in x86_64 case to keep this under check. -cpu_online_mask: Bitmap of all CPUs currently online. Its set in __cpu_up() +cpu_online_map: Bitmap of all CPUs currently online. Its set in __cpu_up() after a cpu is available for kernel scheduling and ready to receive interrupts from devices. Its cleared when a cpu is brought down using __cpu_disable(), before which all OS services including interrupts are migrated to another target CPU. -cpu_present_mask: Bitmap of CPUs currently present in the system. Not all +cpu_present_map: Bitmap of CPUs currently present in the system. Not all of them may be online. When physical hotplug is processed by the relevant subsystem (e.g ACPI) can change and new bit either be added or removed from the map depending on the event is hot-add/hot-remove. There are currently @@ -99,22 +99,22 @@ at which time hotplug is disabled. You really dont need to manipulate any of the system cpu maps. They should be read-only for most use. When setting up per-cpu resources almost always use -cpu_possible_mask/for_each_possible_cpu() to iterate. +cpu_possible_map/for_each_possible_cpu() to iterate. Never use anything other than cpumask_t to represent bitmap of CPUs. #include - for_each_possible_cpu - Iterate over cpu_possible_mask - for_each_online_cpu - Iterate over cpu_online_mask - for_each_present_cpu - Iterate over cpu_present_mask + for_each_possible_cpu - Iterate over cpu_possible_map + for_each_online_cpu - Iterate over cpu_online_map + for_each_present_cpu - Iterate over cpu_present_map for_each_cpu_mask(x,mask) - Iterate over some random collection of cpu mask. #include get_online_cpus() and put_online_cpus(): The above calls are used to inhibit cpu hotplug operations. While the -cpu_hotplug.refcount is non zero, the cpu_online_mask will not change. +cpu_hotplug.refcount is non zero, the cpu_online_map will not change. If you merely need to avoid cpus going away, you could also use preempt_disable() and preempt_enable() for those sections. Just remember the critical section cannot call any diff --git a/trunk/Documentation/cpuidle/sysfs.txt b/trunk/Documentation/cpuidle/sysfs.txt index 9d28a3406e74..50d7b1642759 100644 --- a/trunk/Documentation/cpuidle/sysfs.txt +++ b/trunk/Documentation/cpuidle/sysfs.txt @@ -36,7 +36,6 @@ drwxr-xr-x 2 root root 0 Feb 8 10:42 state3 /sys/devices/system/cpu/cpu0/cpuidle/state0: total 0 -r--r--r-- 1 root root 4096 Feb 8 10:42 desc --rw-r--r-- 1 root root 4096 Feb 8 10:42 disable -r--r--r-- 1 root root 4096 Feb 8 10:42 latency -r--r--r-- 1 root root 4096 Feb 8 10:42 name -r--r--r-- 1 root root 4096 Feb 8 10:42 power @@ -46,7 +45,6 @@ total 0 /sys/devices/system/cpu/cpu0/cpuidle/state1: total 0 -r--r--r-- 1 root root 4096 Feb 8 10:42 desc --rw-r--r-- 1 root root 4096 Feb 8 10:42 disable -r--r--r-- 1 root root 4096 Feb 8 10:42 latency -r--r--r-- 1 root root 4096 Feb 8 10:42 name -r--r--r-- 1 root root 4096 Feb 8 10:42 power @@ -56,7 +54,6 @@ total 0 /sys/devices/system/cpu/cpu0/cpuidle/state2: total 0 -r--r--r-- 1 root root 4096 Feb 8 10:42 desc --rw-r--r-- 1 root root 4096 Feb 8 10:42 disable -r--r--r-- 1 root root 4096 Feb 8 10:42 latency -r--r--r-- 1 root root 4096 Feb 8 10:42 name -r--r--r-- 1 root root 4096 Feb 8 10:42 power @@ -66,7 +63,6 @@ total 0 /sys/devices/system/cpu/cpu0/cpuidle/state3: total 0 -r--r--r-- 1 root root 4096 Feb 8 10:42 desc --rw-r--r-- 1 root root 4096 Feb 8 10:42 disable -r--r--r-- 1 root root 4096 Feb 8 10:42 latency -r--r--r-- 1 root root 4096 Feb 8 10:42 name -r--r--r-- 1 root root 4096 Feb 8 10:42 power @@ -76,7 +72,6 @@ total 0 * desc : Small description about the idle state (string) -* disable : Option to disable this idle state (bool) * latency : Latency to exit out of this idle state (in microseconds) * name : Name of the idle state (string) * power : Power consumed while in this idle state (in milliwatts) diff --git a/trunk/Documentation/devicetree/bindings/ata/ahci-platform.txt b/trunk/Documentation/devicetree/bindings/ata/calxeda-sata.txt similarity index 90% rename from trunk/Documentation/devicetree/bindings/ata/ahci-platform.txt rename to trunk/Documentation/devicetree/bindings/ata/calxeda-sata.txt index 8bb8a76d42e8..79caa5651f53 100644 --- a/trunk/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ b/trunk/Documentation/devicetree/bindings/ata/calxeda-sata.txt @@ -1,10 +1,10 @@ -* AHCI SATA Controller +* Calxeda SATA Controller SATA nodes are defined to describe on-chip Serial ATA controllers. Each SATA controller should have its own node. Required properties: -- compatible : compatible list, contains "calxeda,hb-ahci" or "snps,spear-ahci" +- compatible : compatible list, contains "calxeda,hb-ahci" - interrupts : - reg : @@ -14,3 +14,4 @@ Example: reg = <0xffe08000 0x1000>; interrupts = <115>; }; + diff --git a/trunk/Documentation/devicetree/bindings/mtd/atmel-nand.txt b/trunk/Documentation/devicetree/bindings/mtd/atmel-nand.txt index a20069502f5a..5903ecf6e895 100644 --- a/trunk/Documentation/devicetree/bindings/mtd/atmel-nand.txt +++ b/trunk/Documentation/devicetree/bindings/mtd/atmel-nand.txt @@ -27,13 +27,13 @@ nand0: nand@40000000,0 { reg = <0x40000000 0x10000000 0xffffe800 0x200 >; - atmel,nand-addr-offset = <21>; /* ale */ - atmel,nand-cmd-offset = <22>; /* cle */ + atmel,nand-addr-offset = <21>; + atmel,nand-cmd-offset = <22>; nand-on-flash-bbt; nand-ecc-mode = "soft"; - gpios = <&pioC 13 0 /* rdy */ - &pioC 14 0 /* nce */ - 0 /* cd */ + gpios = <&pioC 13 0 + &pioC 14 0 + 0 >; partition@0 { ... diff --git a/trunk/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/trunk/Documentation/devicetree/bindings/mtd/fsmc-nand.txt deleted file mode 100644 index e2c663b354d2..000000000000 --- a/trunk/Documentation/devicetree/bindings/mtd/fsmc-nand.txt +++ /dev/null @@ -1,33 +0,0 @@ -* FSMC NAND - -Required properties: -- compatible : "st,spear600-fsmc-nand" -- reg : Address range of the mtd chip -- reg-names: Should contain the reg names "fsmc_regs" and "nand_data" -- st,ale-off : Chip specific offset to ALE -- st,cle-off : Chip specific offset to CLE - -Optional properties: -- bank-width : Width (in bytes) of the device. If not present, the width - defaults to 1 byte -- nand-skip-bbtscan: Indicates the the BBT scanning should be skipped - -Example: - - fsmc: flash@d1800000 { - compatible = "st,spear600-fsmc-nand"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0xd1800000 0x1000 /* FSMC Register */ - 0xd2000000 0x4000>; /* NAND Base */ - reg-names = "fsmc_regs", "nand_data"; - st,ale-off = <0x20000>; - st,cle-off = <0x10000>; - - bank-width = <1>; - nand-skip-bbtscan; - - partition@0 { - ... - }; - }; diff --git a/trunk/Documentation/devicetree/bindings/mtd/spear_smi.txt b/trunk/Documentation/devicetree/bindings/mtd/spear_smi.txt deleted file mode 100644 index 7248aadd89e4..000000000000 --- a/trunk/Documentation/devicetree/bindings/mtd/spear_smi.txt +++ /dev/null @@ -1,31 +0,0 @@ -* SPEAr SMI - -Required properties: -- compatible : "st,spear600-smi" -- reg : Address range of the mtd chip -- #address-cells, #size-cells : Must be present if the device has sub-nodes - representing partitions. -- interrupt-parent: Should be the phandle for the interrupt controller - that services interrupts for this device -- interrupts: Should contain the STMMAC interrupts -- clock-rate : Functional clock rate of SMI in Hz - -Optional properties: -- st,smi-fast-mode : Flash supports read in fast mode - -Example: - - smi: flash@fc000000 { - compatible = "st,spear600-smi"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0xfc000000 0x1000>; - interrupt-parent = <&vic1>; - interrupts = <12>; - clock-rate = <50000000>; /* 50MHz */ - - flash@f8000000 { - st,smi-fast-mode; - ... - }; - }; diff --git a/trunk/Documentation/devicetree/bindings/power_supply/max17042_battery.txt b/trunk/Documentation/devicetree/bindings/power_supply/max17042_battery.txt deleted file mode 100644 index 5bc9b685cf8a..000000000000 --- a/trunk/Documentation/devicetree/bindings/power_supply/max17042_battery.txt +++ /dev/null @@ -1,18 +0,0 @@ -max17042_battery -~~~~~~~~~~~~~~~~ - -Required properties : - - compatible : "maxim,max17042" - -Optional properties : - - maxim,rsns-microohm : Resistance of rsns resistor in micro Ohms - (datasheet-recommended value is 10000). - Defining this property enables current-sense functionality. - -Example: - - battery-charger@36 { - compatible = "maxim,max17042"; - reg = <0x36>; - maxim,rsns-microohm = <10000>; - }; diff --git a/trunk/Documentation/devicetree/bindings/regulator/anatop-regulator.txt b/trunk/Documentation/devicetree/bindings/regulator/anatop-regulator.txt deleted file mode 100644 index 357758cb6e92..000000000000 --- a/trunk/Documentation/devicetree/bindings/regulator/anatop-regulator.txt +++ /dev/null @@ -1,29 +0,0 @@ -Anatop Voltage regulators - -Required properties: -- compatible: Must be "fsl,anatop-regulator" -- anatop-reg-offset: Anatop MFD register offset -- anatop-vol-bit-shift: Bit shift for the register -- anatop-vol-bit-width: Number of bits used in the register -- anatop-min-bit-val: Minimum value of this register -- anatop-min-voltage: Minimum voltage of this regulator -- anatop-max-voltage: Maximum voltage of this regulator - -Any property defined as part of the core regulator -binding, defined in regulator.txt, can also be used. - -Example: - - regulator-vddpu { - compatible = "fsl,anatop-regulator"; - regulator-name = "vddpu"; - regulator-min-microvolt = <725000>; - regulator-max-microvolt = <1300000>; - regulator-always-on; - anatop-reg-offset = <0x140>; - anatop-vol-bit-shift = <9>; - anatop-vol-bit-width = <5>; - anatop-min-bit-val = <1>; - anatop-min-voltage = <725000>; - anatop-max-voltage = <1300000>; - }; diff --git a/trunk/Documentation/devicetree/bindings/sound/sgtl5000.txt b/trunk/Documentation/devicetree/bindings/sound/sgtl5000.txt index 9cc44449508d..2c3cd413f042 100644 --- a/trunk/Documentation/devicetree/bindings/sound/sgtl5000.txt +++ b/trunk/Documentation/devicetree/bindings/sound/sgtl5000.txt @@ -3,8 +3,6 @@ Required properties: - compatible : "fsl,sgtl5000". -- reg : the I2C address of the device - Example: codec: sgtl5000@0a { diff --git a/trunk/Documentation/dontdiff b/trunk/Documentation/dontdiff index b4a898f43c37..0c083c5c2faa 100644 --- a/trunk/Documentation/dontdiff +++ b/trunk/Documentation/dontdiff @@ -158,6 +158,7 @@ logo_*.c logo_*_clut224.c logo_*_mono.c lxdialog +mach mach-types mach-types.h machtypes.h diff --git a/trunk/Documentation/fb/intel810.txt b/trunk/Documentation/fb/intel810.txt index a8e9f5bca6f3..be3e7836abef 100644 --- a/trunk/Documentation/fb/intel810.txt +++ b/trunk/Documentation/fb/intel810.txt @@ -211,7 +211,7 @@ Using the same setup as described above, load the module like this: modprobe i810fb vram=2 xres=1024 bpp=8 hsync1=30 hsync2=55 vsync1=50 \ vsync2=85 accel=1 mtrr=1 -Or just add the following to a configuration file in /etc/modprobe.d/ +Or just add the following to /etc/modprobe.conf options i810fb vram=2 xres=1024 bpp=16 hsync1=30 hsync2=55 vsync1=50 \ vsync2=85 accel=1 mtrr=1 diff --git a/trunk/Documentation/fb/intelfb.txt b/trunk/Documentation/fb/intelfb.txt index feac4e4d6968..dd9e944ea628 100644 --- a/trunk/Documentation/fb/intelfb.txt +++ b/trunk/Documentation/fb/intelfb.txt @@ -120,7 +120,7 @@ Using the same setup as described above, load the module like this: modprobe intelfb mode=800x600-32@75 vram=8 accel=1 hwcursor=1 -Or just add the following to a configuration file in /etc/modprobe.d/ +Or just add the following to /etc/modprobe.conf options intelfb mode=800x600-32@75 vram=8 accel=1 hwcursor=1 diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 03ca210406ed..0cad4803ffac 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -6,6 +6,14 @@ be removed from this file. --------------------------- +What: x86 floppy disable_hlt +When: 2012 +Why: ancient workaround of dubious utility clutters the + code used by everybody else. +Who: Len Brown + +--------------------------- + What: CONFIG_APM_CPU_IDLE, and its ability to call APM BIOS in idle When: 2012 Why: This optional sub-feature of APM is of dubious reliability, @@ -521,21 +529,3 @@ When: 3.5 Why: The old kmap_atomic() with two arguments is deprecated, we only keep it for backward compatibility for few cycles and then drop it. Who: Cong Wang - ----------------------------- - -What: get_robust_list syscall -When: 2013 -Why: There appear to be no production users of the get_robust_list syscall, - and it runs the risk of leaking address locations, allowing the bypass - of ASLR. It was only ever intended for debugging, so it should be - removed. -Who: Kees Cook - ----------------------------- - -What: setitimer accepts user NULL pointer (value) -When: 3.6 -Why: setitimer is not returning -EFAULT if user pointer is NULL. This - violates the spec. -Who: Sasikantha Babu diff --git a/trunk/Documentation/filesystems/vfs.txt b/trunk/Documentation/filesystems/vfs.txt index 0d0492028082..e916e3d36488 100644 --- a/trunk/Documentation/filesystems/vfs.txt +++ b/trunk/Documentation/filesystems/vfs.txt @@ -114,7 +114,7 @@ members are defined: struct file_system_type { const char *name; int fs_flags; - struct dentry *(*mount) (struct file_system_type *, int, + struct dentry (*mount) (struct file_system_type *, int, const char *, void *); void (*kill_sb) (struct super_block *); struct module *owner; diff --git a/trunk/Documentation/hwmon/k10temp b/trunk/Documentation/hwmon/k10temp index 90956b618025..a10f73624ad3 100644 --- a/trunk/Documentation/hwmon/k10temp +++ b/trunk/Documentation/hwmon/k10temp @@ -11,7 +11,7 @@ Supported chips: Socket S1G2: Athlon (X2), Sempron (X2), Turion X2 (Ultra) * AMD Family 12h processors: "Llano" (E2/A4/A6/A8-Series) * AMD Family 14h processors: "Brazos" (C/E/G/Z-Series) -* AMD Family 15h processors: "Bulldozer" (FX-Series), "Trinity" +* AMD Family 15h processors: "Bulldozer" Prefix: 'k10temp' Addresses scanned: PCI space diff --git a/trunk/Documentation/i2c/busses/scx200_acb b/trunk/Documentation/i2c/busses/scx200_acb index ce83c871fe95..7c07883d4dfc 100644 --- a/trunk/Documentation/i2c/busses/scx200_acb +++ b/trunk/Documentation/i2c/busses/scx200_acb @@ -28,5 +28,5 @@ If the scx200_acb driver is built into the kernel, add the following parameter to your boot command line: scx200_acb.base=0x810,0x820 If the scx200_acb driver is built as a module, add the following line to -a configuration file in /etc/modprobe.d/ instead: +the file /etc/modprobe.conf instead: options scx200_acb base=0x810,0x820 diff --git a/trunk/Documentation/ide/ide.txt b/trunk/Documentation/ide/ide.txt index 7aca987c23d9..e77bebfa7b0d 100644 --- a/trunk/Documentation/ide/ide.txt +++ b/trunk/Documentation/ide/ide.txt @@ -169,7 +169,7 @@ When using ide.c as a module in combination with kmod, add: alias block-major-3 ide-probe -to a configuration file in /etc/modprobe.d/. +to /etc/modprobe.conf. When ide.c is used as a module, you can pass command line parameters to the driver using the "options=" keyword to insmod, while replacing any ',' with diff --git a/trunk/Documentation/input/input.txt b/trunk/Documentation/input/input.txt index 666c06c5ab0c..b3d6787b4fb1 100644 --- a/trunk/Documentation/input/input.txt +++ b/trunk/Documentation/input/input.txt @@ -250,8 +250,8 @@ And so on up to event31. a USB keyboard works and is correctly connected to the kernel keyboard driver. - Doing a "cat /dev/input/mouse0" (c, 13, 32) will verify that a mouse -is also emulated; characters should appear if you move it. + Doing a cat /dev/input/mouse0 (c, 13, 32) will verify that a mouse +is also emulated, characters should appear if you move it. You can test the joystick emulation with the 'jstest' utility, available in the joystick package (see Documentation/input/joystick.txt). diff --git a/trunk/Documentation/ioctl/ioctl-number.txt b/trunk/Documentation/ioctl/ioctl-number.txt index e34b531dc316..3b7488fc3373 100644 --- a/trunk/Documentation/ioctl/ioctl-number.txt +++ b/trunk/Documentation/ioctl/ioctl-number.txt @@ -225,7 +225,6 @@ Code Seq#(hex) Include File Comments 'j' 00-3F linux/joystick.h 'k' 00-0F linux/spi/spidev.h conflict! 'k' 00-05 video/kyro.h conflict! -'k' 10-17 linux/hsi/hsi_char.h HSI character device 'l' 00-3F linux/tcfs_fs.h transparent cryptographic file system 'l' 40-7F linux/udf_fs_i.h in development: diff --git a/trunk/Documentation/isdn/README.gigaset b/trunk/Documentation/isdn/README.gigaset index 7534c6039adc..ef3343eaa002 100644 --- a/trunk/Documentation/isdn/README.gigaset +++ b/trunk/Documentation/isdn/README.gigaset @@ -97,7 +97,8 @@ GigaSet 307x Device Driver 2.5.): 1=on (default), 0=off Depending on your distribution you may want to create a separate module - configuration file like /etc/modprobe.d/gigaset.conf for these. + configuration file /etc/modprobe.d/gigaset for these, or add them to a + custom file like /etc/modprobe.conf.local. 2.2. Device nodes for user space programs ------------------------------------ @@ -211,8 +212,8 @@ GigaSet 307x Device Driver options ppp_async flag_time=0 - to an appropriate module configuration file, like - /etc/modprobe.d/gigaset.conf. + to an appropriate module configuration file, like /etc/modprobe.d/gigaset + or /etc/modprobe.conf.local. Unimodem mode is needed for making some devices [e.g. SX100] work which do not support the regular Gigaset command set. If debug output (see @@ -236,8 +237,8 @@ GigaSet 307x Device Driver modprobe usb_gigaset startmode=0 or by adding a line like options usb_gigaset startmode=0 - to an appropriate module configuration file, like - /etc/modprobe.d/gigaset.conf + to an appropriate module configuration file, like /etc/modprobe.d/gigaset + or /etc/modprobe.conf.local. 2.6. Call-ID (CID) mode ------------------ @@ -309,7 +310,7 @@ GigaSet 307x Device Driver options isdn dialtimeout=15 - to /etc/modprobe.d/gigaset.conf or a similar file. + to /etc/modprobe.d/gigaset, /etc/modprobe.conf.local or a similar file. Problem: The isdnlog program emits error messages or just doesn't work. @@ -349,7 +350,8 @@ GigaSet 307x Device Driver The initial value can be set using the debug parameter when loading the module "gigaset", e.g. by adding a line options gigaset debug=0 - to your module configuration file, eg. /etc/modprobe.d/gigaset.conf + to your module configuration file, eg. /etc/modprobe.d/gigaset or + /etc/modprobe.conf.local. Generated debugging information can be found - as output of the command diff --git a/trunk/Documentation/kbuild/kconfig.txt b/trunk/Documentation/kbuild/kconfig.txt index 9d5f2a90dca9..c313d71324b4 100644 --- a/trunk/Documentation/kbuild/kconfig.txt +++ b/trunk/Documentation/kbuild/kconfig.txt @@ -28,10 +28,12 @@ new (default) values, so you can use: grep "(NEW)" conf.new -to see the new config symbols or you can use diffconfig to see the -differences between the previous and new .config files: +to see the new config symbols or you can 'diff' the previous and +new .config files to see the differences: - scripts/diffconfig .config.old .config | less + diff .config.old .config | less + +(Yes, we need something better here.) ______________________________________________________________________ Environment variables for '*config' diff --git a/trunk/Documentation/laptops/sonypi.txt b/trunk/Documentation/laptops/sonypi.txt index 606bdb9ce036..4857acfc50f1 100644 --- a/trunk/Documentation/laptops/sonypi.txt +++ b/trunk/Documentation/laptops/sonypi.txt @@ -110,7 +110,7 @@ Module use: ----------- In order to automatically load the sonypi module on use, you can put those -lines a configuration file in /etc/modprobe.d/: +lines in your /etc/modprobe.conf file: alias char-major-10-250 sonypi options sonypi minor=250 diff --git a/trunk/Documentation/mono.txt b/trunk/Documentation/mono.txt index d01ac6052194..e8e1758e87da 100644 --- a/trunk/Documentation/mono.txt +++ b/trunk/Documentation/mono.txt @@ -38,11 +38,11 @@ if [ ! -e /proc/sys/fs/binfmt_misc/register ]; then /sbin/modprobe binfmt_misc # Some distributions, like Fedora Core, perform # the following command automatically when the - # binfmt_misc module is loaded into the kernel - # or during normal boot up (systemd-based systems). + # binfmt_misc module is loaded into the kernel. # Thus, it is possible that the following line - # is not needed at all. - mount -t binfmt_misc none /proc/sys/fs/binfmt_misc + # is not needed at all. Look at /etc/modprobe.conf + # to check whether this is applicable or not. + mount -t binfmt_misc none /proc/sys/fs/binfmt_misc fi # Register support for .NET CLR binaries diff --git a/trunk/Documentation/networking/baycom.txt b/trunk/Documentation/networking/baycom.txt index 688f18fd4467..4e68849d5639 100644 --- a/trunk/Documentation/networking/baycom.txt +++ b/trunk/Documentation/networking/baycom.txt @@ -93,7 +93,7 @@ Every time a driver is inserted into the kernel, it has to know which modems it should access at which ports. This can be done with the setbaycom utility. If you are only using one modem, you can also configure the driver from the insmod command line (or by means of an option line in -/etc/modprobe.d/*.conf). +/etc/modprobe.conf). Examples: modprobe baycom_ser_fdx mode="ser12*" iobase=0x3f8 irq=4 diff --git a/trunk/Documentation/networking/bonding.txt b/trunk/Documentation/networking/bonding.txt index bfea8a338901..080ad26690ae 100644 --- a/trunk/Documentation/networking/bonding.txt +++ b/trunk/Documentation/networking/bonding.txt @@ -173,8 +173,9 @@ bonding module at load time, or are specified via sysfs. Module options may be given as command line arguments to the insmod or modprobe command, but are usually specified in either the -/etc/modrobe.d/*.conf configuration files, or in a distro-specific -configuration file (some of which are detailed in the next section). +/etc/modules.conf or /etc/modprobe.conf configuration file, or in a +distro-specific configuration file (some of which are detailed in the next +section). Details on bonding support for sysfs is provided in the "Configuring Bonding Manually via Sysfs" section, below. @@ -1020,7 +1021,7 @@ ifcfg-bondX files. Because the sysconfig scripts supply the bonding module options in the ifcfg-bondX file, it is not necessary to add them to -the system /etc/modules.d/*.conf configuration files. +the system /etc/modules.conf or /etc/modprobe.conf configuration file. 3.2 Configuration with Initscripts Support ------------------------------------------ @@ -1097,13 +1098,15 @@ queried targets, e.g., arp_ip_target=+192.168.1.1 arp_ip_target=+192.168.1.2 is the proper syntax to specify multiple targets. When specifying -options via BONDING_OPTS, it is not necessary to edit /etc/modprobe.d/*.conf. +options via BONDING_OPTS, it is not necessary to edit /etc/modules.conf or +/etc/modprobe.conf. For even older versions of initscripts that do not support -BONDING_OPTS, it is necessary to edit /etc/modprobe.d/*.conf, depending upon -your distro) to load the bonding module with your desired options when the -bond0 interface is brought up. The following lines in /etc/modprobe.d/*.conf -will load the bonding module, and select its options: +BONDING_OPTS, it is necessary to edit /etc/modules.conf (or +/etc/modprobe.conf, depending upon your distro) to load the bonding module +with your desired options when the bond0 interface is brought up. The +following lines in /etc/modules.conf (or modprobe.conf) will load the +bonding module, and select its options: alias bond0 bonding options bond0 mode=balance-alb miimon=100 @@ -1149,7 +1152,7 @@ knowledge of bonding. One such distro is SuSE Linux Enterprise Server version 8. The general method for these systems is to place the bonding -module parameters into a config file in /etc/modprobe.d/ (as +module parameters into /etc/modules.conf or /etc/modprobe.conf (as appropriate for the installed distro), then add modprobe and/or ifenslave commands to the system's global init script. The name of the global init script differs; for sysconfig, it is @@ -1225,7 +1228,7 @@ network initialization scripts. specify a different name for each instance (the module loading system requires that every loaded module, even multiple instances of the same module, have a unique name). This is accomplished by supplying multiple -sets of bonding options in /etc/modprobe.d/*.conf, for example: +sets of bonding options in /etc/modprobe.conf, for example: alias bond0 bonding options bond0 -o bond0 mode=balance-rr miimon=100 @@ -1790,8 +1793,8 @@ route additions may cause trouble. On systems with network configuration scripts that do not associate physical devices directly with network interface names (so that the same physical device always has the same "ethX" name), it may -be necessary to add some special logic to config files in -/etc/modprobe.d/. +be necessary to add some special logic to either /etc/modules.conf or +/etc/modprobe.conf (depending upon which is installed on the system). For example, given a modules.conf containing the following: @@ -1818,15 +1821,20 @@ add above bonding e1000 tg3 bonding is loaded. This command is fully documented in the modules.conf manual page. - On systems utilizing modprobe an equivalent problem can occur. -In this case, the following can be added to config files in -/etc/modprobe.d/ as: + On systems utilizing modprobe.conf (or modprobe.conf.local), +an equivalent problem can occur. In this case, the following can be +added to modprobe.conf (or modprobe.conf.local, as appropriate), as +follows (all on one line; it has been split here for clarity): -softdep bonding pre: tg3 e1000 +install bonding /sbin/modprobe tg3; /sbin/modprobe e1000; + /sbin/modprobe --ignore-install bonding - This will load tg3 and e1000 modules before loading the bonding one. -Full documentation on this can be found in the modprobe.d and modprobe -manual pages. + This will, when loading the bonding module, rather than +performing the normal action, instead execute the provided command. +This command loads the device drivers in the order needed, then calls +modprobe with --ignore-install to cause the normal action to then take +place. Full documentation on this can be found in the modprobe.conf +and modprobe manual pages. 8.3. Painfully Slow Or No Failed Link Detection By Miimon --------------------------------------------------------- diff --git a/trunk/Documentation/networking/dl2k.txt b/trunk/Documentation/networking/dl2k.txt index cba74f7a3abc..10e8490fa406 100644 --- a/trunk/Documentation/networking/dl2k.txt +++ b/trunk/Documentation/networking/dl2k.txt @@ -45,13 +45,12 @@ Now eth0 should active, you can test it by "ping" or get more information by "ifconfig". If tested ok, continue the next step. 4. cp dl2k.ko /lib/modules/`uname -r`/kernel/drivers/net -5. Add the following line to /etc/modprobe.d/dl2k.conf: +5. Add the following line to /etc/modprobe.conf: alias eth0 dl2k -6. Run depmod to updated module indexes. -7. Run "netconfig" or "netconf" to create configuration script ifcfg-eth0 +6. Run "netconfig" or "netconf" to create configuration script ifcfg-eth0 located at /etc/sysconfig/network-scripts or create it manually. [see - Configuration Script Sample] -8. Driver will automatically load and configure at next boot time. +7. Driver will automatically load and configure at next boot time. Compiling the Driver ==================== @@ -155,8 +154,8 @@ Installing the Driver ----------------- 1. Copy dl2k.o to the network modules directory, typically /lib/modules/2.x.x-xx/net or /lib/modules/2.x.x/kernel/drivers/net. - 2. Locate the boot module configuration file, most commonly in the - /etc/modprobe.d/ directory. Add the following lines: + 2. Locate the boot module configuration file, most commonly modprobe.conf + or modules.conf (for 2.4) in the /etc directory. Add the following lines: alias ethx dl2k options dl2k diff --git a/trunk/Documentation/networking/driver.txt b/trunk/Documentation/networking/driver.txt index da59e2884130..03283daa64fe 100644 --- a/trunk/Documentation/networking/driver.txt +++ b/trunk/Documentation/networking/driver.txt @@ -2,16 +2,16 @@ Document about softnet driver issues Transmit path guidelines: -1) The ndo_start_xmit method must not return NETDEV_TX_BUSY under - any normal circumstances. It is considered a hard error unless +1) The hard_start_xmit method must never return '1' under any + normal circumstances. It is considered a hard error unless there is no way your device can tell ahead of time when it's transmit function will become busy. Instead it must maintain the queue properly. For example, for a driver implementing scatter-gather this means: - static netdev_tx_t drv_hard_start_xmit(struct sk_buff *skb, - struct net_device *dev) + static int drv_hard_start_xmit(struct sk_buff *skb, + struct net_device *dev) { struct drv *dp = netdev_priv(dev); @@ -23,7 +23,7 @@ Transmit path guidelines: unlock_tx(dp); printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", dev->name); - return NETDEV_TX_BUSY; + return 1; } ... queue packet to card ... @@ -35,7 +35,6 @@ Transmit path guidelines: ... unlock_tx(dp); ... - return NETDEV_TX_OK; } And then at the end of your TX reclamation event handling: @@ -59,12 +58,15 @@ Transmit path guidelines: TX_BUFFS_AVAIL(dp) > 0) netif_wake_queue(dp->dev); -2) An ndo_start_xmit method must not modify the shared parts of a +2) Do not forget to update netdev->trans_start to jiffies after + each new tx packet is given to the hardware. + +3) A hard_start_xmit method must not modify the shared parts of a cloned SKB. -3) Do not forget that once you return NETDEV_TX_OK from your - ndo_start_xmit method, it is your driver's responsibility to free - up the SKB and in some finite amount of time. +4) Do not forget that once you return 0 from your hard_start_xmit + method, it is your driver's responsibility to free up the SKB + and in some finite amount of time. For example, this means that it is not allowed for your TX mitigation scheme to let TX packets "hang out" in the TX @@ -72,9 +74,8 @@ Transmit path guidelines: This error can deadlock sockets waiting for send buffer room to be freed up. - If you return NETDEV_TX_BUSY from the ndo_start_xmit method, you - must not keep any reference to that SKB and you must not attempt - to free it up. + If you return 1 from the hard_start_xmit method, you must not keep + any reference to that SKB and you must not attempt to free it up. Probing guidelines: @@ -84,10 +85,10 @@ Probing guidelines: Close/stop guidelines: -1) After the ndo_stop routine has been called, the hardware must +1) After the dev->stop routine has been called, the hardware must not receive or transmit any data. All in flight packets must be aborted. If necessary, poll or wait for completion of any reset commands. -2) The ndo_stop routine will be called by unregister_netdevice +2) The dev->stop routine will be called by unregister_netdevice if device is still UP. diff --git a/trunk/Documentation/networking/e100.txt b/trunk/Documentation/networking/e100.txt index fcb6c71cdb69..162f323a7a1f 100644 --- a/trunk/Documentation/networking/e100.txt +++ b/trunk/Documentation/networking/e100.txt @@ -94,8 +94,8 @@ Additional Configurations Configuring a network driver to load properly when the system is started is distribution dependent. Typically, the configuration process involves adding - an alias line to /etc/modprobe.d/*.conf as well as editing other system - startup scripts and/or configuration files. Many popular Linux + an alias line to /etc/modules.conf or /etc/modprobe.conf as well as editing + other system startup scripts and/or configuration files. Many popular Linux distributions ship with tools to make these changes for you. To learn the proper way to configure a network device for your system, refer to your distribution documentation. If during this process you are asked for the @@ -103,7 +103,7 @@ Additional Configurations PRO/100 Family of Adapters is e100. As an example, if you install the e100 driver for two PRO/100 adapters - (eth0 and eth1), add the following to a configuraton file in /etc/modprobe.d/ + (eth0 and eth1), add the following to modules.conf or modprobe.conf: alias eth0 e100 alias eth1 e100 diff --git a/trunk/Documentation/networking/ip-sysctl.txt b/trunk/Documentation/networking/ip-sysctl.txt index 1619a8c80873..ad3e80e17b4f 100644 --- a/trunk/Documentation/networking/ip-sysctl.txt +++ b/trunk/Documentation/networking/ip-sysctl.txt @@ -147,7 +147,7 @@ tcp_adv_win_scale - INTEGER (if tcp_adv_win_scale > 0) or bytes-bytes/2^(-tcp_adv_win_scale), if it is <= 0. Possible values are [-31, 31], inclusive. - Default: 1 + Default: 2 tcp_allowed_congestion_control - STRING Show/set the congestion control choices available to non-privileged @@ -410,7 +410,7 @@ tcp_rmem - vector of 3 INTEGERs: min, default, max net.core.rmem_max. Calling setsockopt() with SO_RCVBUF disables automatic tuning of that socket's receive buffer size, in which case this value is ignored. - Default: between 87380B and 6MB, depending on RAM size. + Default: between 87380B and 4MB, depending on RAM size. tcp_sack - BOOLEAN Enable select acknowledgments (SACKS). @@ -604,8 +604,15 @@ IP Variables: ip_local_port_range - 2 INTEGERS Defines the local port range that is used by TCP and UDP to choose the local port. The first number is the first, the - second the last local port number. The default values are - 32768 and 61000 respectively. + second the last local port number. Default value depends on + amount of memory available on the system: + > 128Mb 32768-61000 + < 128Mb 1024-4999 or even less. + This number defines number of active connections, which this + system can issue simultaneously to systems not supporting + TCP extensions (timestamps). With tcp_tw_recycle enabled + (i.e. by default) range 1024-4999 is enough to issue up to + 2000 connections per second to systems supporting timestamps. ip_local_reserved_ports - list of comma separated ranges Specify the ports which are reserved for known third-party diff --git a/trunk/Documentation/networking/ipv6.txt b/trunk/Documentation/networking/ipv6.txt index 6cd74fa55358..9fd7e21296c8 100644 --- a/trunk/Documentation/networking/ipv6.txt +++ b/trunk/Documentation/networking/ipv6.txt @@ -2,9 +2,9 @@ Options for the ipv6 module are supplied as parameters at load time. Module options may be given as command line arguments to the insmod -or modprobe command, but are usually specified in either -/etc/modules.d/*.conf configuration files, or in a distro-specific -configuration file. +or modprobe command, but are usually specified in either the +/etc/modules.conf or /etc/modprobe.conf configuration file, or in a +distro-specific configuration file. The available ipv6 module parameters are listed below. If a parameter is not specified the default value is used. diff --git a/trunk/Documentation/networking/ixgb.txt b/trunk/Documentation/networking/ixgb.txt index d75a1f9565bb..e196f16df313 100644 --- a/trunk/Documentation/networking/ixgb.txt +++ b/trunk/Documentation/networking/ixgb.txt @@ -274,9 +274,9 @@ Additional Configurations ------------------------------------------------- Configuring a network driver to load properly when the system is started is distribution dependent. Typically, the configuration process involves adding - an alias line to files in /etc/modprobe.d/ as well as editing other system - startup scripts and/or configuration files. Many popular Linux distributions - ship with tools to make these changes for you. To learn the proper way to + an alias line to /etc/modprobe.conf as well as editing other system startup + scripts and/or configuration files. Many popular Linux distributions ship + with tools to make these changes for you. To learn the proper way to configure a network device for your system, refer to your distribution documentation. If during this process you are asked for the driver or module name, the name for the Linux Base Driver for the Intel 10GbE Family of diff --git a/trunk/Documentation/networking/ltpc.txt b/trunk/Documentation/networking/ltpc.txt index 0bf3220c715b..fe2a9129d959 100644 --- a/trunk/Documentation/networking/ltpc.txt +++ b/trunk/Documentation/networking/ltpc.txt @@ -25,7 +25,7 @@ the driver will try to determine them itself. If you load the driver as a module, you can pass the parameters "io=", "irq=", and "dma=" on the command line with insmod or modprobe, or add -them as options in a configuration file in /etc/modprobe.d/ directory: +them as options in /etc/modprobe.conf: alias lt0 ltpc # autoload the module when the interface is configured options ltpc io=0x240 irq=9 dma=1 diff --git a/trunk/Documentation/networking/netdevices.txt b/trunk/Documentation/networking/netdevices.txt index c7ecc7080494..89358341682a 100644 --- a/trunk/Documentation/networking/netdevices.txt +++ b/trunk/Documentation/networking/netdevices.txt @@ -47,25 +47,26 @@ packets is preferred. struct net_device synchronization rules ======================================= -ndo_open: +dev->open: Synchronization: rtnl_lock() semaphore. Context: process -ndo_stop: +dev->stop: Synchronization: rtnl_lock() semaphore. Context: process - Note: netif_running() is guaranteed false + Note1: netif_running() is guaranteed false + Note2: dev->poll() is guaranteed to be stopped -ndo_do_ioctl: +dev->do_ioctl: Synchronization: rtnl_lock() semaphore. Context: process -ndo_get_stats: +dev->get_stats: Synchronization: dev_base_lock rwlock. Context: nominally process, but don't sleep inside an rwlock -ndo_start_xmit: - Synchronization: __netif_tx_lock spinlock. +dev->hard_start_xmit: + Synchronization: netif_tx_lock spinlock. When the driver sets NETIF_F_LLTX in dev->features this will be called without holding netif_tx_lock. In this case the driver @@ -86,20 +87,20 @@ ndo_start_xmit: o NETDEV_TX_LOCKED Locking failed, please retry quickly. Only valid when NETIF_F_LLTX is set. -ndo_tx_timeout: - Synchronization: netif_tx_lock spinlock; all TX queues frozen. +dev->tx_timeout: + Synchronization: netif_tx_lock spinlock. Context: BHs disabled Notes: netif_queue_stopped() is guaranteed true -ndo_set_rx_mode: - Synchronization: netif_addr_lock spinlock. +dev->set_rx_mode: + Synchronization: netif_tx_lock spinlock. Context: BHs disabled struct napi_struct synchronization rules ======================================== napi->poll: Synchronization: NAPI_STATE_SCHED bit in napi->state. Device - driver's ndo_stop method will invoke napi_disable() on + driver's dev->close method will invoke napi_disable() on all NAPI instances which will do a sleeping poll on the NAPI_STATE_SCHED napi->state bit, waiting for all pending NAPI activity to cease. diff --git a/trunk/Documentation/networking/vortex.txt b/trunk/Documentation/networking/vortex.txt index b4038ffb3bc5..bd70976b8160 100644 --- a/trunk/Documentation/networking/vortex.txt +++ b/trunk/Documentation/networking/vortex.txt @@ -67,8 +67,8 @@ Module parameters ================= There are several parameters which may be provided to the driver when -its module is loaded. These are usually placed in /etc/modprobe.d/*.conf -configuretion files. Example: +its module is loaded. These are usually placed in /etc/modprobe.conf +(/etc/modules.conf in 2.4). Example: options 3c59x debug=3 rx_copybreak=300 @@ -425,7 +425,7 @@ steps you should take: 1) Increase the debug level. Usually this is done via: a) modprobe driver debug=7 - b) In /etc/modprobe.d/driver.conf: + b) In /etc/modprobe.conf (or /etc/modules.conf for 2.4): options driver debug=7 2) Recreate the problem with the higher debug level, diff --git a/trunk/Documentation/parport.txt b/trunk/Documentation/parport.txt index c208e4366c03..93a7ceef398d 100644 --- a/trunk/Documentation/parport.txt +++ b/trunk/Documentation/parport.txt @@ -36,17 +36,18 @@ addresses should not be specified for supported PCI cards since they are automatically detected. -modprobe --------- +KMod +---- -If you use modprobe , you will find it useful to add lines as below to a -configuration file in /etc/modprobe.d/ directory:. +If you use kmod, you will find it useful to edit /etc/modprobe.conf. +Here is an example of the lines that need to be added: alias parport_lowlevel parport_pc options parport_pc io=0x378,0x278 irq=7,auto -modprobe will load parport_pc (with the options "io=0x378,0x278 irq=7,auto") -whenever a parallel port device driver (such as lp) is loaded. +KMod will then automatically load parport_pc (with the options +"io=0x378,0x278 irq=7,auto") whenever a parallel port device driver +(such as lp) is loaded. Note that these are example lines only! You shouldn't in general need to specify any options to parport_pc in order to be able to use a diff --git a/trunk/Documentation/power/freezing-of-tasks.txt b/trunk/Documentation/power/freezing-of-tasks.txt index 6ec291ea1c78..ec715cd78fbb 100644 --- a/trunk/Documentation/power/freezing-of-tasks.txt +++ b/trunk/Documentation/power/freezing-of-tasks.txt @@ -9,7 +9,7 @@ architectures). II. How does it work? -There are three per-task flags used for that, PF_NOFREEZE, PF_FROZEN +There are four per-task flags used for that, PF_NOFREEZE, PF_FROZEN, TIF_FREEZE and PF_FREEZER_SKIP (the last one is auxiliary). The tasks that have PF_NOFREEZE unset (all user space processes and some kernel threads) are regarded as 'freezable' and treated in a special way before the system enters a @@ -17,31 +17,30 @@ suspend state as well as before a hibernation image is created (in what follows we only consider hibernation, but the description also applies to suspend). Namely, as the first step of the hibernation procedure the function -freeze_processes() (defined in kernel/power/process.c) is called. A system-wide -variable system_freezing_cnt (as opposed to a per-task flag) is used to indicate -whether the system is to undergo a freezing operation. And freeze_processes() -sets this variable. After this, it executes try_to_freeze_tasks() that sends a -fake signal to all user space processes, and wakes up all the kernel threads. -All freezable tasks must react to that by calling try_to_freeze(), which -results in a call to __refrigerator() (defined in kernel/freezer.c), which sets -the task's PF_FROZEN flag, changes its state to TASK_UNINTERRUPTIBLE and makes -it loop until PF_FROZEN is cleared for it. Then, we say that the task is -'frozen' and therefore the set of functions handling this mechanism is referred -to as 'the freezer' (these functions are defined in kernel/power/process.c, -kernel/freezer.c & include/linux/freezer.h). User space processes are generally -frozen before kernel threads. +freeze_processes() (defined in kernel/power/process.c) is called. It executes +try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and +either wakes them up, if they are kernel threads, or sends fake signals to them, +if they are user space processes. A task that has TIF_FREEZE set, should react +to it by calling the function called __refrigerator() (defined in +kernel/freezer.c), which sets the task's PF_FROZEN flag, changes its state +to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it. +Then, we say that the task is 'frozen' and therefore the set of functions +handling this mechanism is referred to as 'the freezer' (these functions are +defined in kernel/power/process.c, kernel/freezer.c & include/linux/freezer.h). +User space processes are generally frozen before kernel threads. __refrigerator() must not be called directly. Instead, use the try_to_freeze() function (defined in include/linux/freezer.h), that checks -if the task is to be frozen and makes the task enter __refrigerator(). +the task's TIF_FREEZE flag and makes the task enter __refrigerator() if the +flag is set. For user space processes try_to_freeze() is called automatically from the signal-handling code, but the freezable kernel threads need to call it explicitly in suitable places or use the wait_event_freezable() or wait_event_freezable_timeout() macros (defined in include/linux/freezer.h) -that combine interruptible sleep with checking if the task is to be frozen and -calling try_to_freeze(). The main loop of a freezable kernel thread may look -like the following one: +that combine interruptible sleep with checking if TIF_FREEZE is set and calling +try_to_freeze(). The main loop of a freezable kernel thread may look like the +following one: set_freezable(); do { @@ -54,7 +53,7 @@ like the following one: (from drivers/usb/core/hub.c::hub_thread()). If a freezable kernel thread fails to call try_to_freeze() after the freezer has -initiated a freezing operation, the freezing of tasks will fail and the entire +set TIF_FREEZE for it, the freezing of tasks will fail and the entire hibernation operation will be cancelled. For this reason, freezable kernel threads must call try_to_freeze() somewhere or use one of the wait_event_freezable() and wait_event_freezable_timeout() macros. diff --git a/trunk/Documentation/s390/3270.txt b/trunk/Documentation/s390/3270.txt index 7c715de99774..7a5c73a7ed7f 100644 --- a/trunk/Documentation/s390/3270.txt +++ b/trunk/Documentation/s390/3270.txt @@ -47,9 +47,9 @@ including the console 3270, changes subchannel identifier relative to one another. ReIPL as soon as possible after running the configuration script and the resulting /tmp/mkdev3270. -If you have chosen to make tub3270 a module, you add a line to a -configuration file under /etc/modprobe.d/. If you are working on a VM -virtual machine, you can use DEF GRAF to define virtual 3270 devices. +If you have chosen to make tub3270 a module, you add a line to +/etc/modprobe.conf. If you are working on a VM virtual machine, you +can use DEF GRAF to define virtual 3270 devices. You may generate both 3270 and 3215 console support, or one or the other, or neither. If you generate both, the console type under VM is @@ -60,7 +60,7 @@ at boot time to a 3270 if it is a 3215. In brief, these are the steps: 1. Install the tub3270 patch - 2. (If a module) add a line to a file in /etc/modprobe.d/*.conf + 2. (If a module) add a line to /etc/modprobe.conf 3. (If VM) define devices with DEF GRAF 4. Reboot 5. Configure @@ -84,12 +84,13 @@ Here are the installation steps in detail: make modules_install 2. (Perform this step only if you have configured tub3270 as a - module.) Add a line to a file /etc/modprobe.d/*.conf to automatically - load the driver when it's needed. With this line added, you will see - login prompts appear on your 3270s as soon as boot is complete (or - with emulated 3270s, as soon as you dial into your vm guest using the - command "DIAL "). Since the line-mode major number is - 227, the line to add should be: + module.) Add a line to /etc/modprobe.conf to automatically + load the driver when it's needed. With this line added, + you will see login prompts appear on your 3270s as soon as + boot is complete (or with emulated 3270s, as soon as you dial + into your vm guest using the command "DIAL "). + Since the line-mode major number is 227, the line to add to + /etc/modprobe.conf should be: alias char-major-227 tub3270 3. Define graphic devices to your vm guest machine, if you diff --git a/trunk/Documentation/scsi/00-INDEX b/trunk/Documentation/scsi/00-INDEX index b7dd6502bec5..b48ded55b555 100644 --- a/trunk/Documentation/scsi/00-INDEX +++ b/trunk/Documentation/scsi/00-INDEX @@ -94,5 +94,3 @@ sym53c8xx_2.txt - info on second generation driver for sym53c8xx based adapters tmscsim.txt - info on driver for AM53c974 based adapters -ufs.txt - - info on Universal Flash Storage(UFS) and UFS host controller driver. diff --git a/trunk/Documentation/scsi/aic79xx.txt b/trunk/Documentation/scsi/aic79xx.txt index e2d3273000d4..64ac7093c872 100644 --- a/trunk/Documentation/scsi/aic79xx.txt +++ b/trunk/Documentation/scsi/aic79xx.txt @@ -215,7 +215,7 @@ The following information is available in this file: INCORRECTLY CAN RENDER YOUR SYSTEM INOPERABLE. USE THEM WITH CAUTION. - Put a .conf file in the /etc/modprobe.d/ directory and add/edit a + Edit the file "modprobe.conf" in the directory /etc and add/edit a line containing 'options aic79xx aic79xx=[command[,command...]]' where 'command' is one or more of the following: ----------------------------------------------------------------- diff --git a/trunk/Documentation/scsi/aic7xxx.txt b/trunk/Documentation/scsi/aic7xxx.txt index 7c5d0223d444..18f8d1905e6a 100644 --- a/trunk/Documentation/scsi/aic7xxx.txt +++ b/trunk/Documentation/scsi/aic7xxx.txt @@ -190,7 +190,7 @@ The following information is available in this file: INCORRECTLY CAN RENDER YOUR SYSTEM INOPERABLE. USE THEM WITH CAUTION. - Put a .conf file in the /etc/modprobe.d directory and add/edit a + Edit the file "modprobe.conf" in the directory /etc and add/edit a line containing 'options aic7xxx aic7xxx=[command[,command...]]' where 'command' is one or more of the following: ----------------------------------------------------------------- diff --git a/trunk/Documentation/scsi/osst.txt b/trunk/Documentation/scsi/osst.txt index 00c8ebb2fd18..ad86c6d1e898 100644 --- a/trunk/Documentation/scsi/osst.txt +++ b/trunk/Documentation/scsi/osst.txt @@ -66,7 +66,7 @@ recognized. If you want to have the module autoloaded on access to /dev/osst, you may add something like alias char-major-206 osst -to a file under /etc/modprobe.d/ directory. +to your /etc/modprobe.conf (before 2.6: modules.conf). You may find it convenient to create a symbolic link ln -s nosst0 /dev/tape diff --git a/trunk/Documentation/scsi/st.txt b/trunk/Documentation/scsi/st.txt index 685bf3582abe..691ca292c24d 100644 --- a/trunk/Documentation/scsi/st.txt +++ b/trunk/Documentation/scsi/st.txt @@ -390,10 +390,6 @@ MTSETDRVBUFFER MT_ST_SYSV sets the SYSV semantics (mode) MT_ST_NOWAIT enables immediate mode (i.e., don't wait for the command to finish) for some commands (e.g., rewind) - MT_ST_NOWAIT_EOF enables immediate filemark mode (i.e. when - writing a filemark, don't wait for it to complete). Please - see the BASICS note about MTWEOFI with respect to the - possible dangers of writing immediate filemarks. MT_ST_SILI enables setting the SILI bit in SCSI commands when reading in variable block mode to enhance performance when reading blocks shorter than the byte count; set this only diff --git a/trunk/Documentation/scsi/ufs.txt b/trunk/Documentation/scsi/ufs.txt deleted file mode 100644 index 41a6164592aa..000000000000 --- a/trunk/Documentation/scsi/ufs.txt +++ /dev/null @@ -1,133 +0,0 @@ - Universal Flash Storage - ======================= - - -Contents --------- - -1. Overview -2. UFS Architecture Overview - 2.1 Application Layer - 2.2 UFS Transport Protocol(UTP) layer - 2.3 UFS Interconnect(UIC) Layer -3. UFSHCD Overview - 3.1 UFS controller initialization - 3.2 UTP Transfer requests - 3.3 UFS error handling - 3.4 SCSI Error handling - - -1. Overview ------------ - -Universal Flash Storage(UFS) is a storage specification for flash devices. -It is aimed to provide a universal storage interface for both -embedded and removable flash memory based storage in mobile -devices such as smart phones and tablet computers. The specification -is defined by JEDEC Solid State Technology Association. UFS is based -on MIPI M-PHY physical layer standard. UFS uses MIPI M-PHY as the -physical layer and MIPI Unipro as the link layer. - -The main goals of UFS is to provide, - * Optimized performance: - For UFS version 1.0 and 1.1 the target performance is as follows, - Support for Gear1 is mandatory (rate A: 1248Mbps, rate B: 1457.6Mbps) - Support for Gear2 is optional (rate A: 2496Mbps, rate B: 2915.2Mbps) - Future version of the standard, - Gear3 (rate A: 4992Mbps, rate B: 5830.4Mbps) - * Low power consumption - * High random IOPs and low latency - - -2. UFS Architecture Overview ----------------------------- - -UFS has a layered communication architecture which is based on SCSI -SAM-5 architectural model. - -UFS communication architecture consists of following layers, - -2.1 Application Layer - - The Application layer is composed of UFS command set layer(UCS), - Task Manager and Device manager. The UFS interface is designed to be - protocol agnostic, however SCSI has been selected as a baseline - protocol for versions 1.0 and 1.1 of UFS protocol layer. - UFS supports subset of SCSI commands defined by SPC-4 and SBC-3. - * UCS: It handles SCSI commands supported by UFS specification. - * Task manager: It handles task management functions defined by the - UFS which are meant for command queue control. - * Device manager: It handles device level operations and device - configuration operations. Device level operations mainly involve - device power management operations and commands to Interconnect - layers. Device level configurations involve handling of query - requests which are used to modify and retrieve configuration - information of the device. - -2.2 UFS Transport Protocol(UTP) layer - - UTP layer provides services for - the higher layers through Service Access Points. UTP defines 3 - service access points for higher layers. - * UDM_SAP: Device manager service access point is exposed to device - manager for device level operations. These device level operations - are done through query requests. - * UTP_CMD_SAP: Command service access point is exposed to UFS command - set layer(UCS) to transport commands. - * UTP_TM_SAP: Task management service access point is exposed to task - manager to transport task management functions. - UTP transports messages through UFS protocol information unit(UPIU). - -2.3 UFS Interconnect(UIC) Layer - - UIC is the lowest layer of UFS layered architecture. It handles - connection between UFS host and UFS device. UIC consists of - MIPI UniPro and MIPI M-PHY. UIC provides 2 service access points - to upper layer, - * UIC_SAP: To transport UPIU between UFS host and UFS device. - * UIO_SAP: To issue commands to Unipro layers. - - -3. UFSHCD Overview ------------------- - -The UFS host controller driver is based on Linux SCSI Framework. -UFSHCD is a low level device driver which acts as an interface between -SCSI Midlayer and PCIe based UFS host controllers. - -The current UFSHCD implementation supports following functionality, - -3.1 UFS controller initialization - - The initialization module brings UFS host controller to active state - and prepares the controller to transfer commands/response between - UFSHCD and UFS device. - -3.2 UTP Transfer requests - - Transfer request handling module of UFSHCD receives SCSI commands - from SCSI Midlayer, forms UPIUs and issues the UPIUs to UFS Host - controller. Also, the module decodes, responses received from UFS - host controller in the form of UPIUs and intimates the SCSI Midlayer - of the status of the command. - -3.3 UFS error handling - - Error handling module handles Host controller fatal errors, - Device fatal errors and UIC interconnect layer related errors. - -3.4 SCSI Error handling - - This is done through UFSHCD SCSI error handling routines registered - with SCSI Midlayer. Examples of some of the error handling commands - issues by SCSI Midlayer are Abort task, Lun reset and host reset. - UFSHCD Routines to perform these tasks are registered with - SCSI Midlayer through .eh_abort_handler, .eh_device_reset_handler and - .eh_host_reset_handler. - -In this version of UFSHCD Query requests and power management -functionality are not implemented. - -UFS Specifications can be found at, -UFS - http://www.jedec.org/sites/default/files/docs/JESD220.pdf -UFSHCI - http://www.jedec.org/sites/default/files/docs/JESD223.pdf diff --git a/trunk/Documentation/security/keys.txt b/trunk/Documentation/security/keys.txt index d389acd31e19..787717091421 100644 --- a/trunk/Documentation/security/keys.txt +++ b/trunk/Documentation/security/keys.txt @@ -123,7 +123,7 @@ KEY SERVICE OVERVIEW The key service provides a number of features besides keys: - (*) The key service defines three special key types: + (*) The key service defines two special key types: (+) "keyring" @@ -137,18 +137,6 @@ The key service provides a number of features besides keys: blobs of data. These can be created, updated and read by userspace, and aren't intended for use by kernel services. - (+) "logon" - - Like a "user" key, a "logon" key has a payload that is an arbitrary - blob of data. It is intended as a place to store secrets which are - accessible to the kernel but not to userspace programs. - - The description can be arbitrary, but must be prefixed with a non-zero - length string that describes the key "subclass". The subclass is - separated from the rest of the description by a ':'. "logon" keys can - be created and updated from userspace, but the payload is only - readable from kernel space. - (*) Each process subscribes to three keyrings: a thread-specific keyring, a process-specific keyring, and a session-specific keyring. diff --git a/trunk/Documentation/serial/computone.txt b/trunk/Documentation/serial/computone.txt index a6a1158ea2ba..39ddcdbeeb85 100644 --- a/trunk/Documentation/serial/computone.txt +++ b/trunk/Documentation/serial/computone.txt @@ -49,7 +49,7 @@ Hardware - If you have an ISA card, find a free interrupt and io port. Note the hardware address from the Computone ISA cards installed into the system. These are required for editing ip2.c or editing - /etc/modprobe.d/*.conf, or for specification on the modprobe + /etc/modprobe.conf, or for specification on the modprobe command line. Note that the /etc/modules.conf should be used for older (pre-2.6) @@ -66,7 +66,7 @@ b) Run "make config" or "make menuconfig" or "make xconfig" c) Set address on ISA cards then: edit /usr/src/linux/drivers/char/ip2.c if needed or - edit config file in /etc/modprobe.d/ if needed (module). + edit /etc/modprobe.conf if needed (module). or both to match this setting. d) Run "make modules" e) Run "make modules_install" @@ -153,11 +153,11 @@ the irqs are not specified the driver uses the default in ip2.c (which selects polled mode). If no base addresses are specified the defaults in ip2.c are used. If you are autoloading the driver module with kerneld or kmod the base addresses and interrupt number must also be set in ip2.c -and recompile or just insert and options line in /etc/modprobe.d/*.conf or both. +and recompile or just insert and options line in /etc/modprobe.conf or both. The options line is equivalent to the command line and takes precedence over what is in ip2.c. -config sample to put /etc/modprobe.d/*.conf: +/etc/modprobe.conf sample: options ip2 io=1,0x328 irq=1,10 alias char-major-71 ip2 alias char-major-72 ip2 diff --git a/trunk/Documentation/serial/rocket.txt b/trunk/Documentation/serial/rocket.txt index 60b039891057..1d8582990435 100644 --- a/trunk/Documentation/serial/rocket.txt +++ b/trunk/Documentation/serial/rocket.txt @@ -62,7 +62,7 @@ in the system log at /var/log/messages. If installed as a module, the module must be loaded. This can be done manually by entering "modprobe rocket". To have the module loaded automatically -upon system boot, edit a /etc/modprobe.d/*.conf file and add the line +upon system boot, edit the /etc/modprobe.conf file and add the line "alias char-major-46 rocket". In order to use the ports, their device names (nodes) must be created with mknod. diff --git a/trunk/Documentation/serial/stallion.txt b/trunk/Documentation/serial/stallion.txt index 55090914a9c5..5c4902d9a5be 100644 --- a/trunk/Documentation/serial/stallion.txt +++ b/trunk/Documentation/serial/stallion.txt @@ -139,8 +139,8 @@ secondary address 0x280 and IRQ 10. You will probably want to enter this module load and configuration information into your system startup scripts so that the drivers are loaded and configured -on each system boot. Typically configuration files are put in the -/etc/modprobe.d/ directory. +on each system boot. Typically the start up script would be something like +/etc/modprobe.conf. 2.2 STATIC DRIVER CONFIGURATION: diff --git a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt index 8c16d50f6cb6..6f75ba3b8a39 100644 --- a/trunk/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/trunk/Documentation/sound/alsa/ALSA-Configuration.txt @@ -2044,7 +2044,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Install the necessary firmware files in alsa-firmware package. When no hotplug fw loader is available, you need to load the firmware via vxloader utility in alsa-tools package. To invoke - vxloader automatically, add the following to /etc/modprobe.d/alsa.conf + vxloader automatically, add the following to /etc/modprobe.conf install snd-vx222 /sbin/modprobe --first-time -i snd-vx222 && /usr/bin/vxloader @@ -2168,10 +2168,10 @@ corresponds to the card index of ALSA. Usually, define this as the same card module. An example configuration for a single emu10k1 card is like below: ------ /etc/modprobe.d/alsa.conf +----- /etc/modprobe.conf alias snd-card-0 snd-emu10k1 alias sound-slot-0 snd-emu10k1 ------ /etc/modprobe.d/alsa.conf +----- /etc/modprobe.conf The available number of auto-loaded sound cards depends on the module option "cards_limit" of snd module. As default it's set to 1. @@ -2184,7 +2184,7 @@ cards is kept consistent. An example configuration for two sound cards is like below: ------ /etc/modprobe.d/alsa.conf +----- /etc/modprobe.conf # ALSA portion options snd cards_limit=2 alias snd-card-0 snd-interwave @@ -2194,7 +2194,7 @@ options snd-ens1371 index=1 # OSS/Free portion alias sound-slot-0 snd-interwave alias sound-slot-1 snd-ens1371 ------ /etc/modprobe.d/alsa.conf +----- /etc/modprobe.conf In this example, the interwave card is always loaded as the first card (index 0) and ens1371 as the second (index 1). diff --git a/trunk/Documentation/sound/alsa/Audiophile-Usb.txt b/trunk/Documentation/sound/alsa/Audiophile-Usb.txt index 654dd3b694a8..a4c53d8961e1 100644 --- a/trunk/Documentation/sound/alsa/Audiophile-Usb.txt +++ b/trunk/Documentation/sound/alsa/Audiophile-Usb.txt @@ -232,7 +232,7 @@ The parameter can be given: # modprobe snd-usb-audio index=1 device_setup=0x09 * Or while configuring the modules options in your modules configuration file - (tipically a .conf file in /etc/modprobe.d/ directory: + - For Fedora distributions, edit the /etc/modprobe.conf file: alias snd-card-1 snd-usb-audio options snd-usb-audio index=1 device_setup=0x09 @@ -253,7 +253,7 @@ CAUTION when initializing the device - first turn off the device - de-register the snd-usb-audio module (modprobe -r) - change the device_setup parameter by changing the device_setup - option in /etc/modprobe.d/*.conf + option in /etc/modprobe.conf - turn on the device * A workaround for this last issue has been applied to kernel 2.6.23, but it may not be enough to ensure the 'stability' of the device initialization. diff --git a/trunk/Documentation/sound/alsa/HD-Audio-Models.txt b/trunk/Documentation/sound/alsa/HD-Audio-Models.txt index 03f7897c6414..d97d992ced14 100644 --- a/trunk/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/trunk/Documentation/sound/alsa/HD-Audio-Models.txt @@ -43,9 +43,7 @@ ALC680 ALC882/883/885/888/889 ====================== - acer-aspire-4930g Acer Aspire 4930G/5930G/6530G/6930G/7730G - acer-aspire-8930g Acer Aspire 8330G/6935G - acer-aspire Acer Aspire others + N/A ALC861/660 ========== diff --git a/trunk/Documentation/sound/alsa/MIXART.txt b/trunk/Documentation/sound/alsa/MIXART.txt index 4ee35b4fbe4a..ef42c44fa1f2 100644 --- a/trunk/Documentation/sound/alsa/MIXART.txt +++ b/trunk/Documentation/sound/alsa/MIXART.txt @@ -76,9 +76,9 @@ FIRMWARE when CONFIG_FW_LOADER is set. The mixartloader is necessary only for older versions or when you build the driver into kernel.] -For loading the firmware automatically after the module is loaded, use a -install command. For example, add the following entry to -/etc/modprobe.d/mixart.conf for miXart driver: +For loading the firmware automatically after the module is loaded, use +the post-install command. For example, add the following entry to +/etc/modprobe.conf for miXart driver: install snd-mixart /sbin/modprobe --first-time -i snd-mixart && \ /usr/bin/mixartloader diff --git a/trunk/Documentation/sound/alsa/OSS-Emulation.txt b/trunk/Documentation/sound/alsa/OSS-Emulation.txt index 152ca2a3f1bd..022aaeb0e9dd 100644 --- a/trunk/Documentation/sound/alsa/OSS-Emulation.txt +++ b/trunk/Documentation/sound/alsa/OSS-Emulation.txt @@ -19,7 +19,7 @@ the card number and the minor unit number. Usually you don't have to define these aliases by yourself. Only necessary step for auto-loading of OSS modules is to define the -card alias in /etc/modprobe.d/alsa.conf, such as +card alias in /etc/modprobe.conf, such as alias sound-slot-0 snd-emu10k1 diff --git a/trunk/Documentation/sound/oss/AudioExcelDSP16 b/trunk/Documentation/sound/oss/AudioExcelDSP16 index ea8549faede9..e0dc0641b480 100644 --- a/trunk/Documentation/sound/oss/AudioExcelDSP16 +++ b/trunk/Documentation/sound/oss/AudioExcelDSP16 @@ -41,7 +41,7 @@ mpu_base I/O base address for activate MPU-401 mode (0x300, 0x310, 0x320 or 0x330) mpu_irq MPU-401 irq line (5, 7, 9, 10 or 0) -A configuration file in /etc/modprobe.d/ directory will have lines like this: +The /etc/modprobe.conf will have lines like this: options opl3 io=0x388 options ad1848 io=0x530 irq=11 dma=3 @@ -51,11 +51,11 @@ Where the aedsp16 options are the options for this driver while opl3 and ad1848 are the corresponding options for the MSS and OPL3 modules. Loading MSS and OPL3 needs to pre load the aedsp16 module to set up correctly -the sound card. Installation dependencies must be written in configuration -files under /etc/modprobe.d/ directory: +the sound card. Installation dependencies must be written in the modprobe.conf +file: -softdep ad1848 pre: aedsp16 -softdep opl3 pre: aedsp16 +install ad1848 /sbin/modprobe aedsp16 && /sbin/modprobe -i ad1848 +install opl3 /sbin/modprobe aedsp16 && /sbin/modprobe -i opl3 Then you must load the sound modules stack in this order: sound -> aedsp16 -> [ ad1848, opl3 ] diff --git a/trunk/Documentation/sound/oss/CMI8330 b/trunk/Documentation/sound/oss/CMI8330 index 8a5fd1611c6f..9c439f1a6dba 100644 --- a/trunk/Documentation/sound/oss/CMI8330 +++ b/trunk/Documentation/sound/oss/CMI8330 @@ -143,10 +143,11 @@ CONFIG_SOUND_MSS=m -Alma Chao suggests the following in -a /etc/modprobe.d/*conf file: +Alma Chao suggests the following /etc/modprobe.conf: alias sound ad1848 alias synth0 opl3 options ad1848 io=0x530 irq=7 dma=0 soundpro=1 options opl3 io=0x388 + + diff --git a/trunk/Documentation/sound/oss/Introduction b/trunk/Documentation/sound/oss/Introduction index 42da2d8fa372..75d967ff9266 100644 --- a/trunk/Documentation/sound/oss/Introduction +++ b/trunk/Documentation/sound/oss/Introduction @@ -167,8 +167,8 @@ in a file such as /root/soundon.sh. MODPROBE: ========= -If loading via modprobe, these common files are automatically loaded when -requested by modprobe. For example, my /etc/modprobe.d/oss.conf contains: +If loading via modprobe, these common files are automatically loaded +when requested by modprobe. For example, my /etc/modprobe.conf contains: alias sound sb options sb io=0x240 irq=9 dma=3 dma16=5 mpu_io=0x300 @@ -228,7 +228,7 @@ http://www.opensound.com. Before loading the commercial sound driver, you should do the following: 1. remove sound modules (detailed above) -2. remove the sound modules from /etc/modprobe.d/*.conf +2. remove the sound modules from /etc/modprobe.conf 3. move the sound modules from /lib/modules//misc (for example, I make a /lib/modules//misc/tmp directory and copy the sound module files to that @@ -265,7 +265,7 @@ twice, you need to do the following: sb.o could be copied (or symlinked) to sb1.o for the second SoundBlaster. -2. Make a second entry in /etc/modprobe.d/*conf, for example, +2. Make a second entry in /etc/modprobe.conf, for example, sound1 or sb1. This second entry should refer to the new module names for example sb1, and should include the I/O, etc. for the second sound card. @@ -369,7 +369,7 @@ There are several ways of configuring your sound: 2) On the command line when using insmod or in a bash script using command line calls to load sound. -3) In /etc/modprobe.d/*conf when using modprobe. +3) In /etc/modprobe.conf when using modprobe. 4) Via Red Hat's GPL'd /usr/sbin/sndconfig program (text based). diff --git a/trunk/Documentation/sound/oss/Opti b/trunk/Documentation/sound/oss/Opti index 4cd5d9ab3580..c15af3c07d46 100644 --- a/trunk/Documentation/sound/oss/Opti +++ b/trunk/Documentation/sound/oss/Opti @@ -18,7 +18,7 @@ force the card into a mode in which it can be programmed. If you have another OS installed on your computer it is recommended that Linux and the other OS use the same resources. -Also, it is recommended that resources specified in /etc/modprobe.d/*.conf +Also, it is recommended that resources specified in /etc/modprobe.conf and resources specified in /etc/isapnp.conf agree. Compiling the sound driver @@ -67,7 +67,11 @@ address is hard-coded into the driver. Using kmod and autoloading the sound driver ------------------------------------------- -Config files in '/etc/modprobe.d/' are used as below: +Comment: as of linux-2.1.90 kmod is replacing kerneld. +The config file '/etc/modprobe.conf' is used as before. + +This is the sound part of my /etc/modprobe.conf file. +Following that I will explain each line. alias mixer0 mad16 alias audio0 mad16 diff --git a/trunk/Documentation/sound/oss/PAS16 b/trunk/Documentation/sound/oss/PAS16 index 5c27229eec8c..3dca4b75988e 100644 --- a/trunk/Documentation/sound/oss/PAS16 +++ b/trunk/Documentation/sound/oss/PAS16 @@ -128,7 +128,7 @@ CONFIG_SOUND_YM3812 You can then get OPL3 functionality by issuing the command: insmod opl3 In addition, you must either add the following line to - /etc/modprobe.d/*.conf: + /etc/modprobe.conf: options opl3 io=0x388 or else add the following line to /etc/lilo.conf: opl3=0x388 @@ -158,5 +158,5 @@ following line would be appropriate: append="pas2=0x388,10,3,-1,0,-1,-1,-1 opl3=0x388" If sound is built totally modular, the above options may be -specified in /etc/modprobe.d/*.conf for pas2, sb and opl3 +specified in /etc/modprobe.conf for pas2, sb and opl3 respectively. diff --git a/trunk/Documentation/sound/oss/README.modules b/trunk/Documentation/sound/oss/README.modules index cdc039421a46..e691d74e1e5e 100644 --- a/trunk/Documentation/sound/oss/README.modules +++ b/trunk/Documentation/sound/oss/README.modules @@ -26,7 +26,7 @@ Note that it is no longer necessary or possible to configure sound in the drivers/sound dir. Now one simply configures and makes one's kernel and modules in the usual way. - Then, add to your /etc/modprobe.d/oss.conf something like: + Then, add to your /etc/modprobe.conf something like: alias char-major-14-* sb install sb /sbin/modprobe -i sb && /sbin/modprobe adlib_card @@ -36,7 +36,7 @@ options adlib_card io=0x388 # FM synthesizer Alternatively, if you have compiled in kernel level ISAPnP support: alias char-major-14 sb -softdep sb post: adlib_card +post-install sb /sbin/modprobe "-k" "adlib_card" options adlib_card io=0x388 The effect of this is that the sound driver and all necessary bits and @@ -66,12 +66,12 @@ args are expected. Note that at present there is no way to configure the io, irq and other parameters for the modular drivers as one does for the wired drivers.. One needs to pass the modules the necessary parameters as arguments, either -with /etc/modprobe.d/*.conf or with command-line args to modprobe, e.g. +with /etc/modprobe.conf or with command-line args to modprobe, e.g. modprobe sb io=0x220 irq=7 dma=1 dma16=5 mpu_io=0x330 modprobe adlib_card io=0x388 - recommend using /etc/modprobe.d/*.conf. + recommend using /etc/modprobe.conf. Persistent DMA Buffers: @@ -89,7 +89,7 @@ wasteful of RAM, but it guarantees that sound always works. To make the sound driver use persistent DMA buffers we need to pass the sound.o module a "dmabuf=1" command-line argument. This is normally done -in /etc/modprobe.d/*.conf files like so: +in /etc/modprobe.conf like so: options sound dmabuf=1 diff --git a/trunk/Documentation/sysrq.txt b/trunk/Documentation/sysrq.txt index 642f84495b29..312e3754e8c5 100644 --- a/trunk/Documentation/sysrq.txt +++ b/trunk/Documentation/sysrq.txt @@ -241,8 +241,9 @@ command you are interested in. * I have more questions, who can I ask? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Just ask them on the linux-kernel mailing list: - linux-kernel@vger.kernel.org +And I'll answer any questions about the registration system you got, also +responding as soon as possible. + -Crutcher * Credits ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/trunk/Documentation/usb/URB.txt b/trunk/Documentation/usb/URB.txt index 00d2c644068e..8ffce746d496 100644 --- a/trunk/Documentation/usb/URB.txt +++ b/trunk/Documentation/usb/URB.txt @@ -168,28 +168,6 @@ that if the completion handler or anyone else tries to resubmit it they will get a -EPERM error. Thus you can be sure that when usb_kill_urb() returns, the URB is totally idle. -There is a lifetime issue to consider. An URB may complete at any -time, and the completion handler may free the URB. If this happens -while usb_unlink_urb or usb_kill_urb is running, it will cause a -memory-access violation. The driver is responsible for avoiding this, -which often means some sort of lock will be needed to prevent the URB -from being deallocated while it is still in use. - -On the other hand, since usb_unlink_urb may end up calling the -completion handler, the handler must not take any lock that is held -when usb_unlink_urb is invoked. The general solution to this problem -is to increment the URB's reference count while holding the lock, then -drop the lock and call usb_unlink_urb or usb_kill_urb, and then -decrement the URB's reference count. You increment the reference -count by calling - - struct urb *usb_get_urb(struct urb *urb) - -(ignore the return value; it is the same as the argument) and -decrement the reference count by calling usb_free_urb. Of course, -none of this is necessary if there's no danger of the URB being freed -by the completion handler. - 1.7. What about the completion handler? diff --git a/trunk/Documentation/usb/power-management.txt b/trunk/Documentation/usb/power-management.txt index 4204eb01fd38..817df299ea07 100644 --- a/trunk/Documentation/usb/power-management.txt +++ b/trunk/Documentation/usb/power-management.txt @@ -179,8 +179,7 @@ do: modprobe usbcore autosuspend=5 -Equivalently, you could add to a configuration file in /etc/modprobe.d -a line saying: +Equivalently, you could add to /etc/modprobe.conf a line saying: options usbcore autosuspend=5 diff --git a/trunk/Documentation/usb/usbmon.txt b/trunk/Documentation/usb/usbmon.txt index c42bb9cd3b43..5335fa8b06eb 100644 --- a/trunk/Documentation/usb/usbmon.txt +++ b/trunk/Documentation/usb/usbmon.txt @@ -183,10 +183,10 @@ An input control transfer to get a port status. d5ea89a0 3575914555 S Ci:1:001:0 s a3 00 0000 0003 0004 4 < d5ea89a0 3575914560 C Ci:1:001:0 0 4 = 01050000 -An output bulk transfer to send a SCSI command 0x28 (READ_10) in a 31-byte -Bulk wrapper to a storage device at address 5: +An output bulk transfer to send a SCSI command 0x5E in a 31-byte Bulk wrapper +to a storage device at address 5: -dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 ad000000 00800000 80010a28 20000000 20000040 00000000 000000 +dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 5e000000 00000000 00000600 00000000 00000000 00000000 000000 dd65f0e8 4128379808 C Bo:1:005:2 0 31 > * Raw binary format and API diff --git a/trunk/Documentation/video4linux/CQcam.txt b/trunk/Documentation/video4linux/CQcam.txt index 6e680fec1e9c..8977e7ce4dab 100644 --- a/trunk/Documentation/video4linux/CQcam.txt +++ b/trunk/Documentation/video4linux/CQcam.txt @@ -61,19 +61,29 @@ But that is my personal preference. 2.2 Configuration The configuration requires module configuration and device -configuration. The following sections detail these procedures. +configuration. I like kmod or kerneld process with the +/etc/modprobe.conf file so the modules can automatically load/unload as +they are used. The video devices could already exist, be generated +using MAKEDEV, or need to be created. The following sections detail +these procedures. 2.1 Module Configuration Using modules requires a bit of work to install and pass the -parameters. Understand that entries in /etc/modprobe.d/*.conf of: +parameters. Understand that entries in /etc/modprobe.conf of: alias parport_lowlevel parport_pc options parport_pc io=0x378 irq=none alias char-major-81 videodev alias char-major-81-0 c-qcam +will cause the kmod/modprobe to do certain things. If you are +using kmod, then a request for a 'char-major-81-0' will cause +the 'c-qcam' module to load. If you have other video sources with +modules, you might want to assign the different minor numbers to +different modules. + 2.2 Device Configuration At this point, we need to ensure that the device files exist. diff --git a/trunk/Documentation/video4linux/Zoran b/trunk/Documentation/video4linux/Zoran index b5a911fd0602..9ed629d4874b 100644 --- a/trunk/Documentation/video4linux/Zoran +++ b/trunk/Documentation/video4linux/Zoran @@ -255,7 +255,7 @@ Load zr36067.o. If it can't autodetect your card, use the card=X insmod option with X being the card number as given in the previous section. To have more than one card, use card=X1[,X2[,X3,[X4[..]]]] -To automate this, add the following to your /etc/modprobe.d/zoran.conf: +To automate this, add the following to your /etc/modprobe.conf: options zr36067 card=X1[,X2[,X3[,X4[..]]]] alias char-major-81-0 zr36067 diff --git a/trunk/Documentation/video4linux/bttv/Modules.conf b/trunk/Documentation/video4linux/bttv/Modules.conf index 8f258faf18f1..753f15956eb8 100644 --- a/trunk/Documentation/video4linux/bttv/Modules.conf +++ b/trunk/Documentation/video4linux/bttv/Modules.conf @@ -1,4 +1,4 @@ -# For modern kernels (2.6 or above), this belongs in /etc/modprobe.d/*.conf +# For modern kernels (2.6 or above), this belongs in /etc/modprobe.conf # For for 2.4 kernels or earlier, this belongs in /etc/modules.conf. # i2c diff --git a/trunk/Documentation/video4linux/meye.txt b/trunk/Documentation/video4linux/meye.txt index a051152ea99c..34e2842c70ae 100644 --- a/trunk/Documentation/video4linux/meye.txt +++ b/trunk/Documentation/video4linux/meye.txt @@ -55,7 +55,7 @@ Module use: ----------- In order to automatically load the meye module on use, you can put those lines -in your /etc/modprobe.d/meye.conf file: +in your /etc/modprobe.conf file: alias char-major-81 videodev alias char-major-81-0 meye diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 707163365a93..eecf3441ac21 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -228,7 +228,7 @@ M: Len Brown L: linux-acpi@vger.kernel.org W: http://www.lesswatts.org/projects/acpi/ Q: http://patchwork.kernel.org/project/linux-acpi/list/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux +T: git git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git S: Supported F: drivers/acpi/ F: drivers/pnp/pnpacpi/ @@ -1251,6 +1251,7 @@ ATHEROS ATH5K WIRELESS DRIVER M: Jiri Slaby M: Nick Kossifidis M: "Luis R. Rodriguez" +M: Bob Copeland L: linux-wireless@vger.kernel.org L: ath5k-devel@lists.ath5k.org W: http://wireless.kernel.org/en/users/Drivers/ath5k @@ -1521,8 +1522,8 @@ M: Gustavo Padovan M: Johan Hedberg L: linux-bluetooth@vger.kernel.org W: http://www.bluez.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git -T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jh/bluetooth.git S: Maintained F: drivers/bluetooth/ @@ -1532,8 +1533,8 @@ M: Gustavo Padovan M: Johan Hedberg L: linux-bluetooth@vger.kernel.org W: http://www.bluez.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git -T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/jh/bluetooth.git S: Maintained F: net/bluetooth/ F: include/net/bluetooth/ @@ -1968,7 +1969,10 @@ S: Maintained F: drivers/net/ethernet/ti/cpmac.c CPU FREQUENCY DRIVERS +M: Dave Jones L: cpufreq@vger.kernel.org +W: http://www.codemonkey.org.uk/projects/cpufreq/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq.git S: Maintained F: drivers/cpufreq/ F: include/linux/cpufreq.h @@ -2318,9 +2322,9 @@ S: Supported F: drivers/acpi/dock.c DOCUMENTATION -M: Rob Landley +M: Randy Dunlap L: linux-doc@vger.kernel.org -T: TBD +T: quilt http://xenotime.net/kernel-doc-patches/current/ S: Maintained F: Documentation/ @@ -2447,17 +2451,17 @@ F: fs/ecryptfs/ EDAC-CORE M: Doug Thompson -L: linux-edac@vger.kernel.org +L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) W: bluesmoke.sourceforge.net S: Supported F: Documentation/edac.txt -F: drivers/edac/ +F: drivers/edac/edac_* F: include/linux/edac.h EDAC-AMD64 M: Doug Thompson M: Borislav Petkov -L: linux-edac@vger.kernel.org +L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) W: bluesmoke.sourceforge.net S: Supported F: drivers/edac/amd64_edac* @@ -2465,35 +2469,35 @@ F: drivers/edac/amd64_edac* EDAC-E752X M: Mark Gross M: Doug Thompson -L: linux-edac@vger.kernel.org +L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) W: bluesmoke.sourceforge.net S: Maintained F: drivers/edac/e752x_edac.c EDAC-E7XXX M: Doug Thompson -L: linux-edac@vger.kernel.org +L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) W: bluesmoke.sourceforge.net S: Maintained F: drivers/edac/e7xxx_edac.c EDAC-I82443BXGX M: Tim Small -L: linux-edac@vger.kernel.org +L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) W: bluesmoke.sourceforge.net S: Maintained F: drivers/edac/i82443bxgx_edac.c EDAC-I3000 M: Jason Uhlenkott -L: linux-edac@vger.kernel.org +L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) W: bluesmoke.sourceforge.net S: Maintained F: drivers/edac/i3000_edac.c EDAC-I5000 M: Doug Thompson -L: linux-edac@vger.kernel.org +L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) W: bluesmoke.sourceforge.net S: Maintained F: drivers/edac/i5000_edac.c @@ -2522,21 +2526,21 @@ F: drivers/edac/i7core_edac.c EDAC-I82975X M: Ranganathan Desikan M: "Arvind R." -L: linux-edac@vger.kernel.org +L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) W: bluesmoke.sourceforge.net S: Maintained F: drivers/edac/i82975x_edac.c EDAC-PASEMI M: Egor Martovetsky -L: linux-edac@vger.kernel.org +L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) W: bluesmoke.sourceforge.net S: Maintained F: drivers/edac/pasemi_edac.c EDAC-R82600 M: Tim Small -L: linux-edac@vger.kernel.org +L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) W: bluesmoke.sourceforge.net S: Maintained F: drivers/edac/r82600_edac.c @@ -3553,13 +3557,17 @@ L: linux-pm@vger.kernel.org S: Supported F: arch/x86/platform/mrst/pmu.* -INTEL PRO/WIRELESS 2100, 2200BG, 2915ABG NETWORK CONNECTION SUPPORT -M: Stanislav Yakovlev +INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT L: linux-wireless@vger.kernel.org -S: Maintained +S: Orphan F: Documentation/networking/README.ipw2100 +F: drivers/net/wireless/ipw2x00/ipw2100.* + +INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT +L: linux-wireless@vger.kernel.org +S: Orphan F: Documentation/networking/README.ipw2200 -F: drivers/net/wireless/ipw2x00/ +F: drivers/net/wireless/ipw2x00/ipw2200.* INTEL(R) TRUSTED EXECUTION TECHNOLOGY (TXT) M: Joseph Cihula @@ -3589,7 +3597,6 @@ S: Supported F: drivers/net/wireless/iwlegacy/ INTEL WIRELESS WIFI LINK (iwlwifi) -M: Johannes Berg M: Wey-Yi Guy M: Intel Linux Wireless L: linux-wireless@vger.kernel.org @@ -4307,13 +4314,6 @@ W: http://www.kernel.org/doc/man-pages L: linux-man@vger.kernel.org S: Maintained -MARVELL GIGABIT ETHERNET DRIVERS (skge/sky2) -M: Mirko Lindner -M: Stephen Hemminger -L: netdev@vger.kernel.org -S: Maintained -F: drivers/net/ethernet/marvell/sk* - MARVELL LIBERTAS WIRELESS DRIVER M: Dan Williams L: libertas-dev@lists.infradead.org @@ -4344,6 +4344,12 @@ M: Nicolas Pitre S: Odd Fixes F: drivers/mmc/host/mvsdio.* +MARVELL YUKON / SYSKONNECT DRIVER +M: Mirko Lindner +M: Ralph Roesler +W: http://www.syskonnect.com +S: Supported + MATROX FRAMEBUFFER DRIVER L: linux-fbdev@vger.kernel.org S: Orphan @@ -4531,7 +4537,8 @@ S: Supported F: drivers/net/ethernet/myricom/myri10ge/ NATSEMI ETHERNET DRIVER (DP8381x) -S: Orphan +M: Tim Hockin +S: Maintained F: drivers/net/ethernet/natsemi/natsemi.c NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER @@ -4800,7 +4807,6 @@ F: arch/arm/mach-omap2/clockdomain2xxx_3xxx.c F: arch/arm/mach-omap2/clockdomain44xx.c OMAP AUDIO SUPPORT -M: Peter Ujfalusi M: Jarkko Nikula L: alsa-devel@alsa-project.org (subscribers-only) L: linux-omap@vger.kernel.org @@ -5115,11 +5121,6 @@ F: drivers/i2c/busses/i2c-pca-* F: include/linux/i2c-algo-pca.h F: include/linux/i2c-pca-platform.h -PCDP - PRIMARY CONSOLE AND DEBUG PORT -M: Khalid Aziz -S: Maintained -F: drivers/firmware/pcdp.* - PCI ERROR RECOVERY M: Linas Vepstas L: linux-pci@vger.kernel.org @@ -5641,7 +5642,7 @@ M: Ohad Ben-Cohen S: Maintained F: drivers/remoteproc/ F: Documentation/remoteproc.txt -F: include/linux/remoteproc.h +F: include/linux/remoteproc.txt RFKILL M: Johannes Berg @@ -5889,11 +5890,11 @@ F: Documentation/scsi/st.txt F: drivers/scsi/st* SCTP PROTOCOL -M: Vlad Yasevich +M: Vlad Yasevich M: Sridhar Samudrala L: linux-sctp@vger.kernel.org W: http://lksctp.sourceforge.net -S: Maintained +S: Supported F: Documentation/networking/sctp.txt F: include/linux/sctp.h F: include/net/sctp/ @@ -6120,6 +6121,12 @@ W: http://www.winischhofer.at/linuxsisusbvga.shtml S: Maintained F: drivers/usb/misc/sisusbvga/ +SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS +M: Stephen Hemminger +L: netdev@vger.kernel.org +S: Maintained +F: drivers/net/ethernet/marvell/sk* + SLAB ALLOCATOR M: Christoph Lameter M: Pekka Enberg @@ -6285,15 +6292,6 @@ F: drivers/tty/serial/sunsu.c F: drivers/tty/serial/sunzilog.c F: drivers/tty/serial/sunzilog.h -SPARSE CHECKER -M: "Christopher Li" -L: linux-sparse@vger.kernel.org -W: https://sparse.wiki.kernel.org/ -T: git git://git.kernel.org/pub/scm/devel/sparse/sparse.git -T: git git://git.kernel.org/pub/scm/devel/sparse/chrisl/sparse.git -S: Maintained -F: include/linux/compiler.h - SPEAR PLATFORM SUPPORT M: Viresh Kumar L: spear-devel@list.st.com @@ -6469,7 +6467,6 @@ S: Odd Fixes F: drivers/staging/olpc_dcon/ STAGING - OZMO DEVICES USB OVER WIFI DRIVER -M: Rupesh Gujare M: Chris Kelly S: Maintained F: drivers/staging/ozwpan/ @@ -7465,7 +7462,8 @@ F: include/linux/wm97xx.h WOLFSON MICROELECTRONICS DRIVERS M: Mark Brown -L: patches@opensource.wolfsonmicro.com +M: Ian Lartey +M: Dimitris Papastamos T: git git://opensource.wolfsonmicro.com/linux-2.6-asoc T: git git://opensource.wolfsonmicro.com/linux-2.6-audioplus W: http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices @@ -7576,8 +7574,8 @@ F: Documentation/filesystems/xfs.txt F: fs/xfs/ XILINX AXI ETHERNET DRIVER -M: Anirudha Sarangi -M: John Linn +M: Ariane Keller +M: Daniel Borkmann S: Maintained F: drivers/net/ethernet/xilinx/xilinx_axienet* diff --git a/trunk/Makefile b/trunk/Makefile index 9e384ae6c403..1932984478c1 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 -PATCHLEVEL = 4 +PATCHLEVEL = 3 SUBLEVEL = 0 -EXTRAVERSION = -rc6 +EXTRAVERSION = NAME = Saber-toothed Squirrel # *DOCUMENTATION* @@ -1170,7 +1170,7 @@ MRPROPER_FILES += .config .config.old .version .old_version \ # clean: rm-dirs := $(CLEAN_DIRS) clean: rm-files := $(CLEAN_FILES) -clean-dirs := $(addprefix _clean_, . $(vmlinux-alldirs) Documentation samples) +clean-dirs := $(addprefix _clean_, . $(vmlinux-alldirs) Documentation) PHONY += $(clean-dirs) clean archclean $(clean-dirs): diff --git a/trunk/arch/alpha/Kconfig b/trunk/arch/alpha/Kconfig index 22e58a99f38b..56a4df952fb0 100644 --- a/trunk/arch/alpha/Kconfig +++ b/trunk/arch/alpha/Kconfig @@ -477,7 +477,7 @@ config ALPHA_BROKEN_IRQ_MASK config VGA_HOSE bool - depends on VGA_CONSOLE && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL || ALPHA_TSUNAMI) + depends on ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL || ALPHA_TSUNAMI default y help Support VGA on an arbitrary hose; needed for several platforms diff --git a/trunk/arch/alpha/include/asm/atomic.h b/trunk/arch/alpha/include/asm/atomic.h index 3bb7ffeae3bc..f62251e82ffa 100644 --- a/trunk/arch/alpha/include/asm/atomic.h +++ b/trunk/arch/alpha/include/asm/atomic.h @@ -3,7 +3,6 @@ #include #include -#include /* * Atomic operations that C can't guarantee us. Useful for @@ -169,6 +168,73 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) return result; } +/* + * Atomic exchange routines. + */ + +#define __ASM__MB +#define ____xchg(type, args...) __xchg ## type ## _local(args) +#define ____cmpxchg(type, args...) __cmpxchg ## type ## _local(args) +#include + +#define xchg_local(ptr,x) \ + ({ \ + __typeof__(*(ptr)) _x_ = (x); \ + (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \ + sizeof(*(ptr))); \ + }) + +#define cmpxchg_local(ptr, o, n) \ + ({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, \ + sizeof(*(ptr))); \ + }) + +#define cmpxchg64_local(ptr, o, n) \ + ({ \ + BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ + cmpxchg_local((ptr), (o), (n)); \ + }) + +#ifdef CONFIG_SMP +#undef __ASM__MB +#define __ASM__MB "\tmb\n" +#endif +#undef ____xchg +#undef ____cmpxchg +#define ____xchg(type, args...) __xchg ##type(args) +#define ____cmpxchg(type, args...) __cmpxchg ##type(args) +#include + +#define xchg(ptr,x) \ + ({ \ + __typeof__(*(ptr)) _x_ = (x); \ + (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \ + sizeof(*(ptr))); \ + }) + +#define cmpxchg(ptr, o, n) \ + ({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, sizeof(*(ptr)));\ + }) + +#define cmpxchg64(ptr, o, n) \ + ({ \ + BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ + cmpxchg((ptr), (o), (n)); \ + }) + +#undef __ASM__MB +#undef ____cmpxchg + +#define __HAVE_ARCH_CMPXCHG 1 + #define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new)) #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) diff --git a/trunk/arch/alpha/include/asm/cmpxchg.h b/trunk/arch/alpha/include/asm/cmpxchg.h deleted file mode 100644 index 429e8cd0d78e..000000000000 --- a/trunk/arch/alpha/include/asm/cmpxchg.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef _ALPHA_CMPXCHG_H -#define _ALPHA_CMPXCHG_H - -/* - * Atomic exchange routines. - */ - -#define __ASM__MB -#define ____xchg(type, args...) __xchg ## type ## _local(args) -#define ____cmpxchg(type, args...) __cmpxchg ## type ## _local(args) -#include - -#define xchg_local(ptr, x) \ -({ \ - __typeof__(*(ptr)) _x_ = (x); \ - (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \ - sizeof(*(ptr))); \ -}) - -#define cmpxchg_local(ptr, o, n) \ -({ \ - __typeof__(*(ptr)) _o_ = (o); \ - __typeof__(*(ptr)) _n_ = (n); \ - (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \ - (unsigned long)_n_, \ - sizeof(*(ptr))); \ -}) - -#define cmpxchg64_local(ptr, o, n) \ -({ \ - BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ - cmpxchg_local((ptr), (o), (n)); \ -}) - -#ifdef CONFIG_SMP -#undef __ASM__MB -#define __ASM__MB "\tmb\n" -#endif -#undef ____xchg -#undef ____cmpxchg -#define ____xchg(type, args...) __xchg ##type(args) -#define ____cmpxchg(type, args...) __cmpxchg ##type(args) -#include - -#define xchg(ptr, x) \ -({ \ - __typeof__(*(ptr)) _x_ = (x); \ - (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \ - sizeof(*(ptr))); \ -}) - -#define cmpxchg(ptr, o, n) \ -({ \ - __typeof__(*(ptr)) _o_ = (o); \ - __typeof__(*(ptr)) _n_ = (n); \ - (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ - (unsigned long)_n_, sizeof(*(ptr)));\ -}) - -#define cmpxchg64(ptr, o, n) \ -({ \ - BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ - cmpxchg((ptr), (o), (n)); \ -}) - -#undef __ASM__MB -#undef ____cmpxchg - -#define __HAVE_ARCH_CMPXCHG 1 - -#endif /* _ALPHA_CMPXCHG_H */ diff --git a/trunk/arch/alpha/include/asm/dma-mapping.h b/trunk/arch/alpha/include/asm/dma-mapping.h index dfa32f061320..4567aca6fdd6 100644 --- a/trunk/arch/alpha/include/asm/dma-mapping.h +++ b/trunk/arch/alpha/include/asm/dma-mapping.h @@ -12,22 +12,16 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev) #include -#define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) - -static inline void *dma_alloc_attrs(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp, - struct dma_attrs *attrs) +static inline void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp) { - return get_dma_ops(dev)->alloc(dev, size, dma_handle, gfp, attrs); + return get_dma_ops(dev)->alloc_coherent(dev, size, dma_handle, gfp); } -#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) - -static inline void dma_free_attrs(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, - struct dma_attrs *attrs) +static inline void dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) { - get_dma_ops(dev)->free(dev, size, vaddr, dma_handle, attrs); + get_dma_ops(dev)->free_coherent(dev, size, vaddr, dma_handle); } static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) diff --git a/trunk/arch/alpha/include/asm/rtc.h b/trunk/arch/alpha/include/asm/rtc.h index d70408d36677..1f7fba671ae6 100644 --- a/trunk/arch/alpha/include/asm/rtc.h +++ b/trunk/arch/alpha/include/asm/rtc.h @@ -1,10 +1,14 @@ #ifndef _ALPHA_RTC_H #define _ALPHA_RTC_H -#if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP) \ - || defined(CONFIG_ALPHA_GENERIC) +#if defined(CONFIG_ALPHA_GENERIC) # define get_rtc_time alpha_mv.rtc_get_time # define set_rtc_time alpha_mv.rtc_set_time +#else +# if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP) +# define get_rtc_time marvel_get_rtc_time +# define set_rtc_time marvel_set_rtc_time +# endif #endif #include diff --git a/trunk/arch/alpha/include/asm/xchg.h b/trunk/arch/alpha/include/asm/xchg.h index 0ca9724597c1..1d1b436fbff2 100644 --- a/trunk/arch/alpha/include/asm/xchg.h +++ b/trunk/arch/alpha/include/asm/xchg.h @@ -1,10 +1,10 @@ -#ifndef _ALPHA_CMPXCHG_H +#ifndef _ALPHA_ATOMIC_H #error Do not include xchg.h directly! #else /* * xchg/xchg_local and cmpxchg/cmpxchg_local share the same code * except that local version do not have the expensive memory barrier. - * So this file is included twice from asm/cmpxchg.h. + * So this file is included twice from asm/system.h. */ /* diff --git a/trunk/arch/alpha/kernel/core_tsunami.c b/trunk/arch/alpha/kernel/core_tsunami.c index 61893d7bdda5..5e7c28f92f19 100644 --- a/trunk/arch/alpha/kernel/core_tsunami.c +++ b/trunk/arch/alpha/kernel/core_tsunami.c @@ -11,7 +11,6 @@ #include #undef __EXTERN_INLINE -#include #include #include #include diff --git a/trunk/arch/alpha/kernel/pci-noop.c b/trunk/arch/alpha/kernel/pci-noop.c index df24b76f9246..04eea4894ef3 100644 --- a/trunk/arch/alpha/kernel/pci-noop.c +++ b/trunk/arch/alpha/kernel/pci-noop.c @@ -108,8 +108,7 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn, } static void *alpha_noop_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp, - struct dma_attrs *attrs) + dma_addr_t *dma_handle, gfp_t gfp) { void *ret; @@ -124,8 +123,7 @@ static void *alpha_noop_alloc_coherent(struct device *dev, size_t size, } static void alpha_noop_free_coherent(struct device *dev, size_t size, - void *cpu_addr, dma_addr_t dma_addr, - struct dma_attrs *attrs) + void *cpu_addr, dma_addr_t dma_addr) { free_pages((unsigned long)cpu_addr, get_order(size)); } @@ -176,8 +174,8 @@ static int alpha_noop_set_mask(struct device *dev, u64 mask) } struct dma_map_ops alpha_noop_ops = { - .alloc = alpha_noop_alloc_coherent, - .free = alpha_noop_free_coherent, + .alloc_coherent = alpha_noop_alloc_coherent, + .free_coherent = alpha_noop_free_coherent, .map_page = alpha_noop_map_page, .map_sg = alpha_noop_map_sg, .mapping_error = alpha_noop_mapping_error, diff --git a/trunk/arch/alpha/kernel/pci_iommu.c b/trunk/arch/alpha/kernel/pci_iommu.c index cd634795aa9c..43610804987d 100644 --- a/trunk/arch/alpha/kernel/pci_iommu.c +++ b/trunk/arch/alpha/kernel/pci_iommu.c @@ -434,8 +434,7 @@ static void alpha_pci_unmap_page(struct device *dev, dma_addr_t dma_addr, else DMA_ADDRP is undefined. */ static void *alpha_pci_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_addrp, gfp_t gfp, - struct dma_attrs *attrs) + dma_addr_t *dma_addrp, gfp_t gfp) { struct pci_dev *pdev = alpha_gendev_to_pci(dev); void *cpu_addr; @@ -479,8 +478,7 @@ static void *alpha_pci_alloc_coherent(struct device *dev, size_t size, DMA_ADDR past this call are illegal. */ static void alpha_pci_free_coherent(struct device *dev, size_t size, - void *cpu_addr, dma_addr_t dma_addr, - struct dma_attrs *attrs) + void *cpu_addr, dma_addr_t dma_addr) { struct pci_dev *pdev = alpha_gendev_to_pci(dev); pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL); @@ -954,8 +952,8 @@ static int alpha_pci_set_mask(struct device *dev, u64 mask) } struct dma_map_ops alpha_pci_ops = { - .alloc = alpha_pci_alloc_coherent, - .free = alpha_pci_free_coherent, + .alloc_coherent = alpha_pci_alloc_coherent, + .free_coherent = alpha_pci_free_coherent, .map_page = alpha_pci_map_page, .unmap_page = alpha_pci_unmap_page, .map_sg = alpha_pci_map_sg, diff --git a/trunk/arch/alpha/kernel/signal.c b/trunk/arch/alpha/kernel/signal.c index 35f2ef44de12..6f7feb5db271 100644 --- a/trunk/arch/alpha/kernel/signal.c +++ b/trunk/arch/alpha/kernel/signal.c @@ -120,13 +120,12 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act, */ SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask) { - sigset_t blocked; - - current->saved_sigmask = current->blocked; - mask &= _BLOCKABLE; - siginitset(&blocked, mask); - set_current_blocked(&blocked); + spin_lock_irq(¤t->sighand->siglock); + current->saved_sigmask = current->blocked; + siginitset(¤t->blocked, mask); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); current->state = TASK_INTERRUPTIBLE; schedule(); @@ -239,7 +238,10 @@ do_sigreturn(struct sigcontext __user *sc, struct pt_regs *regs, goto give_sigsegv; sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(sc, regs, sw)) goto give_sigsegv; @@ -274,7 +276,10 @@ do_rt_sigreturn(struct rt_sigframe __user *frame, struct pt_regs *regs, goto give_sigsegv; sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(&frame->uc.uc_mcontext, regs, sw)) goto give_sigsegv; @@ -496,8 +501,14 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, else ret = setup_frame(sig, ka, oldset, regs, sw); - if (ret == 0) - block_sigmask(ka, sig); + if (ret == 0) { + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + if (!(ka->sa.sa_flags & SA_NODEFER)) + sigaddset(¤t->blocked,sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + } return ret; } diff --git a/trunk/arch/alpha/kernel/smp.c b/trunk/arch/alpha/kernel/smp.c index 50d438db1f6b..4087a569b43b 100644 --- a/trunk/arch/alpha/kernel/smp.c +++ b/trunk/arch/alpha/kernel/smp.c @@ -450,7 +450,7 @@ setup_smp(void) smp_num_probed = 1; } - printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", + printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_map = %lx\n", smp_num_probed, cpumask_bits(cpu_present_mask)[0]); } diff --git a/trunk/arch/alpha/kernel/sys_marvel.c b/trunk/arch/alpha/kernel/sys_marvel.c index 407accc80877..14a4b6a7cf59 100644 --- a/trunk/arch/alpha/kernel/sys_marvel.c +++ b/trunk/arch/alpha/kernel/sys_marvel.c @@ -317,7 +317,7 @@ marvel_init_irq(void) } static int -marvel_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +marvel_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct pci_controller *hose = dev->sysdata; struct io7_port *io7_port = hose->sysdata; diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 36586dba6fa6..93180845ae16 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -338,7 +338,6 @@ config ARCH_AT91 select HAVE_CLK select CLKDEV_LOOKUP select IRQ_DOMAIN - select NEED_MACH_IO_H if PCCARD help This enables support for systems based on the Atmel AT91RM9200, AT91SAM9 processors. @@ -1186,15 +1185,6 @@ if !MMU source "arch/arm/Kconfig-nommu" endif -config ARM_ERRATA_326103 - bool "ARM errata: FSR write bit incorrect on a SWP to read-only memory" - depends on CPU_V6 - help - Executing a SWP instruction to read-only memory does not set bit 11 - of the FSR on the ARM 1136 prior to r1p0. This causes the kernel to - treat the access as a read, preventing a COW from occurring and - causing the faulting task to livelock. - config ARM_ERRATA_411920 bool "ARM errata: Invalidation of the Instruction Cache operation can fail" depends on CPU_V6 || CPU_V6K diff --git a/trunk/arch/arm/boot/Makefile b/trunk/arch/arm/boot/Makefile index c877087d2000..fc871e719aae 100644 --- a/trunk/arch/arm/boot/Makefile +++ b/trunk/arch/arm/boot/Makefile @@ -11,6 +11,8 @@ # Copyright (C) 1995-2002 Russell King # +MKIMAGE := $(srctree)/scripts/mkuboot.sh + ifneq ($(MACHINE),) include $(srctree)/$(MACHINE)/Makefile.boot endif @@ -67,19 +69,22 @@ $(obj)/dtbs: $(addprefix $(obj)/, $(dtb-y)) clean-files := *.dtb -ifneq ($(LOADADDR),) - UIMAGE_LOADADDR=$(LOADADDR) +quiet_cmd_uimage = UIMAGE $@ + cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \ + -C none -a $(LOADADDR) -e $(STARTADDR) \ + -n 'Linux-$(KERNELRELEASE)' -d $< $@ + +ifeq ($(CONFIG_ZBOOT_ROM),y) +$(obj)/uImage: LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT) else - ifeq ($(CONFIG_ZBOOT_ROM),y) - UIMAGE_LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT) - else - UIMAGE_LOADADDR=$(ZRELADDR) - endif +$(obj)/uImage: LOADADDR=$(ZRELADDR) endif +$(obj)/uImage: STARTADDR=$(LOADADDR) + check_for_multiple_loadaddr = \ -if [ $(words $(UIMAGE_LOADADDR)) -gt 1 ]; then \ - echo 'multiple load addresses: $(UIMAGE_LOADADDR)'; \ +if [ $(words $(LOADADDR)) -gt 1 ]; then \ + echo 'multiple load addresses: $(LOADADDR)'; \ echo 'This is incompatible with uImages'; \ echo 'Specify LOADADDR on the commandline to build an uImage'; \ false; \ diff --git a/trunk/arch/arm/boot/compressed/atags_to_fdt.c b/trunk/arch/arm/boot/compressed/atags_to_fdt.c index 797f04bedb47..6ce11c481178 100644 --- a/trunk/arch/arm/boot/compressed/atags_to_fdt.c +++ b/trunk/arch/arm/boot/compressed/atags_to_fdt.c @@ -77,8 +77,6 @@ int atags_to_fdt(void *atag_list, void *fdt, int total_space) } else if (atag->hdr.tag == ATAG_MEM) { if (memcount >= sizeof(mem_reg_property)/4) continue; - if (!atag->u.mem.size) - continue; mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start); mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size); } else if (atag->hdr.tag == ATAG_INITRD2) { diff --git a/trunk/arch/arm/boot/compressed/head.S b/trunk/arch/arm/boot/compressed/head.S index dc7e8ce8e6be..5f6045f1766c 100644 --- a/trunk/arch/arm/boot/compressed/head.S +++ b/trunk/arch/arm/boot/compressed/head.S @@ -273,7 +273,7 @@ restart: adr r0, LC0 add r0, r0, #0x100 mov r1, r6 sub r2, sp, r6 - bleq atags_to_fdt + blne atags_to_fdt ldmfd sp!, {r0-r3, ip, lr} sub sp, sp, #0x10000 diff --git a/trunk/arch/arm/boot/dts/at91sam9g20.dtsi b/trunk/arch/arm/boot/dts/at91sam9g20.dtsi index 773ef484037a..92f36627e7f8 100644 --- a/trunk/arch/arm/boot/dts/at91sam9g20.dtsi +++ b/trunk/arch/arm/boot/dts/at91sam9g20.dtsi @@ -35,7 +35,7 @@ }; }; - memory { + memory@20000000 { reg = <0x20000000 0x08000000>; }; @@ -55,6 +55,7 @@ #interrupt-cells = <2>; compatible = "atmel,at91rm9200-aic"; interrupt-controller; + interrupt-parent; reg = <0xfffff000 0x200>; }; diff --git a/trunk/arch/arm/boot/dts/at91sam9g25ek.dts b/trunk/arch/arm/boot/dts/at91sam9g25ek.dts index 7829a4d0cb22..ac0dc0031dda 100644 --- a/trunk/arch/arm/boot/dts/at91sam9g25ek.dts +++ b/trunk/arch/arm/boot/dts/at91sam9g25ek.dts @@ -37,8 +37,8 @@ usb0: ohci@00600000 { status = "okay"; num-ports = <2>; - atmel,vbus-gpio = <&pioD 19 1 - &pioD 20 1 + atmel,vbus-gpio = <&pioD 19 0 + &pioD 20 0 >; }; diff --git a/trunk/arch/arm/boot/dts/at91sam9g45.dtsi b/trunk/arch/arm/boot/dts/at91sam9g45.dtsi index c8042147eaa2..3d0c32fb218f 100644 --- a/trunk/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/trunk/arch/arm/boot/dts/at91sam9g45.dtsi @@ -36,7 +36,7 @@ }; }; - memory { + memory@70000000 { reg = <0x70000000 0x10000000>; }; @@ -56,6 +56,7 @@ #interrupt-cells = <2>; compatible = "atmel,at91rm9200-aic"; interrupt-controller; + interrupt-parent; reg = <0xfffff000 0x200>; }; diff --git a/trunk/arch/arm/boot/dts/at91sam9m10g45ek.dts b/trunk/arch/arm/boot/dts/at91sam9m10g45ek.dts index a3633bd13111..c4c8ae4123d5 100644 --- a/trunk/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/trunk/arch/arm/boot/dts/at91sam9m10g45ek.dts @@ -17,7 +17,7 @@ bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2"; }; - memory { + memory@70000000 { reg = <0x70000000 0x4000000>; }; @@ -73,8 +73,8 @@ usb0: ohci@00700000 { status = "okay"; num-ports = <2>; - atmel,vbus-gpio = <&pioD 1 1 - &pioD 3 1>; + atmel,vbus-gpio = <&pioD 1 0 + &pioD 3 0>; }; usb1: ehci@00800000 { diff --git a/trunk/arch/arm/boot/dts/at91sam9x5.dtsi b/trunk/arch/arm/boot/dts/at91sam9x5.dtsi index dd4ed748469a..c111001f254e 100644 --- a/trunk/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/trunk/arch/arm/boot/dts/at91sam9x5.dtsi @@ -34,7 +34,7 @@ }; }; - memory { + memory@20000000 { reg = <0x20000000 0x10000000>; }; @@ -54,6 +54,7 @@ #interrupt-cells = <2>; compatible = "atmel,at91rm9200-aic"; interrupt-controller; + interrupt-parent; reg = <0xfffff000 0x200>; }; @@ -200,8 +201,8 @@ >; atmel,nand-addr-offset = <21>; atmel,nand-cmd-offset = <22>; - gpios = <&pioD 5 0 - &pioD 4 0 + gpios = <&pioC 8 0 + &pioC 14 0 0 >; status = "disabled"; diff --git a/trunk/arch/arm/boot/dts/at91sam9x5cm.dtsi b/trunk/arch/arm/boot/dts/at91sam9x5cm.dtsi index 31e7be23703d..67936f83c694 100644 --- a/trunk/arch/arm/boot/dts/at91sam9x5cm.dtsi +++ b/trunk/arch/arm/boot/dts/at91sam9x5cm.dtsi @@ -8,7 +8,7 @@ */ / { - memory { + memory@20000000 { reg = <0x20000000 0x8000000>; }; diff --git a/trunk/arch/arm/boot/dts/db8500.dtsi b/trunk/arch/arm/boot/dts/db8500.dtsi index 14bc30705099..d73dce645667 100644 --- a/trunk/arch/arm/boot/dts/db8500.dtsi +++ b/trunk/arch/arm/boot/dts/db8500.dtsi @@ -24,6 +24,7 @@ #interrupt-cells = <3>; #address-cells = <1>; interrupt-controller; + interrupt-parent; reg = <0xa0411000 0x1000>, <0xa0410100 0x100>; }; diff --git a/trunk/arch/arm/boot/dts/highbank.dts b/trunk/arch/arm/boot/dts/highbank.dts index 83e72294aefb..37c0ff9c8b90 100644 --- a/trunk/arch/arm/boot/dts/highbank.dts +++ b/trunk/arch/arm/boot/dts/highbank.dts @@ -89,6 +89,7 @@ #size-cells = <0>; #address-cells = <1>; interrupt-controller; + interrupt-parent; reg = <0xfff11000 0x1000>, <0xfff10100 0x100>; }; diff --git a/trunk/arch/arm/boot/dts/msm8660-surf.dts b/trunk/arch/arm/boot/dts/msm8660-surf.dts index 45bc4bb04e57..15ded0deaa79 100644 --- a/trunk/arch/arm/boot/dts/msm8660-surf.dts +++ b/trunk/arch/arm/boot/dts/msm8660-surf.dts @@ -10,7 +10,7 @@ intc: interrupt-controller@02080000 { compatible = "qcom,msm-8660-qgic"; interrupt-controller; - #interrupt-cells = <3>; + #interrupt-cells = <1>; reg = < 0x02080000 0x1000 >, < 0x02081000 0x1000 >; }; @@ -19,6 +19,6 @@ compatible = "qcom,msm-hsuart", "qcom,msm-uart"; reg = <0x19c40000 0x1000>, <0x19c00000 0x1000>; - interrupts = <0 195 0x0>; + interrupts = <195>; }; }; diff --git a/trunk/arch/arm/boot/dts/usb_a9g20.dts b/trunk/arch/arm/boot/dts/usb_a9g20.dts index 7c2399c532e5..3b3c4e0fa79f 100644 --- a/trunk/arch/arm/boot/dts/usb_a9g20.dts +++ b/trunk/arch/arm/boot/dts/usb_a9g20.dts @@ -16,7 +16,7 @@ bootargs = "mem=64M console=ttyS0,115200 root=/dev/mtdblock5 rw rootfstype=ubifs"; }; - memory { + memory@20000000 { reg = <0x20000000 0x4000000>; }; diff --git a/trunk/arch/arm/boot/dts/versatile-ab.dts b/trunk/arch/arm/boot/dts/versatile-ab.dts index e2fe3195c0d1..0b32925f2147 100644 --- a/trunk/arch/arm/boot/dts/versatile-ab.dts +++ b/trunk/arch/arm/boot/dts/versatile-ab.dts @@ -173,7 +173,7 @@ mmc@5000 { compatible = "arm,primecell"; reg = < 0x5000 0x1000>; - interrupts = <22 34>; + interrupts = <22>; }; kmi@6000 { compatible = "arm,pl050", "arm,primecell"; diff --git a/trunk/arch/arm/boot/dts/versatile-pb.dts b/trunk/arch/arm/boot/dts/versatile-pb.dts index 7e8175269064..166461073b78 100644 --- a/trunk/arch/arm/boot/dts/versatile-pb.dts +++ b/trunk/arch/arm/boot/dts/versatile-pb.dts @@ -41,7 +41,7 @@ mmc@b000 { compatible = "arm,primecell"; reg = <0xb000 0x1000>; - interrupts = <23 34>; + interrupts = <23>; }; }; }; diff --git a/trunk/arch/arm/common/vic.c b/trunk/arch/arm/common/vic.c index 7e288f96cedf..7a66311f3066 100644 --- a/trunk/arch/arm/common/vic.c +++ b/trunk/arch/arm/common/vic.c @@ -427,18 +427,19 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent) /* * Handle each interrupt in a single VIC. Returns non-zero if we've - * handled at least one interrupt. This reads the status register - * before handling each interrupt, which is necessary given that - * handle_IRQ may briefly re-enable interrupts for soft IRQ handling. + * handled at least one interrupt. This does a single read of the + * status register and handles all interrupts in order from LSB first. */ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) { u32 stat, irq; int handled = 0; - while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) { + stat = readl_relaxed(vic->base + VIC_IRQ_STATUS); + while (stat) { irq = ffs(stat) - 1; handle_IRQ(irq_find_mapping(vic->domain, irq), regs); + stat &= ~(1 << irq); handled = 1; } diff --git a/trunk/arch/arm/configs/imx_v4_v5_defconfig b/trunk/arch/arm/configs/imx_v4_v5_defconfig index 6b31cb60daab..b5ac644e12af 100644 --- a/trunk/arch/arm/configs/imx_v4_v5_defconfig +++ b/trunk/arch/arm/configs/imx_v4_v5_defconfig @@ -112,7 +112,6 @@ CONFIG_WATCHDOG=y CONFIG_IMX2_WDT=y CONFIG_MFD_MC13XXX=y CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_MC13783=y CONFIG_REGULATOR_MC13892=y CONFIG_FB=y diff --git a/trunk/arch/arm/configs/mini2440_defconfig b/trunk/arch/arm/configs/mini2440_defconfig index 082175c54e7c..42da9183acc8 100644 --- a/trunk/arch/arm/configs/mini2440_defconfig +++ b/trunk/arch/arm/configs/mini2440_defconfig @@ -14,8 +14,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set CONFIG_BLK_DEV_INTEGRITY=y CONFIG_ARCH_S3C24XX=y -# CONFIG_CPU_S3C2410 is not set -CONFIG_CPU_S3C2440=y CONFIG_S3C_ADC=y CONFIG_S3C24XX_PWM=y CONFIG_MACH_MINI2440=y diff --git a/trunk/arch/arm/configs/u8500_defconfig b/trunk/arch/arm/configs/u8500_defconfig index 7e84f453e8a6..889d73ac1ae1 100644 --- a/trunk/arch/arm/configs/u8500_defconfig +++ b/trunk/arch/arm/configs/u8500_defconfig @@ -8,6 +8,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set CONFIG_ARCH_U8500=y +CONFIG_UX500_SOC_DB5500=y +CONFIG_UX500_SOC_DB8500=y CONFIG_MACH_HREFV60=y CONFIG_MACH_SNOWBALL=y CONFIG_MACH_U5500=y @@ -37,6 +39,7 @@ CONFIG_CAIF=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_MISC_DEVICES=y CONFIG_AB8500_PWM=y CONFIG_SENSORS_BH1780=y CONFIG_NETDEVICES=y @@ -62,18 +65,16 @@ CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_NOMADIK=y +CONFIG_I2C=y +CONFIG_I2C_NOMADIK=y CONFIG_SPI=y CONFIG_SPI_PL022=y CONFIG_GPIO_STMPE=y CONFIG_GPIO_TC3589X=y -CONFIG_POWER_SUPPLY=y -CONFIG_AB8500_BM=y -CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL=y CONFIG_MFD_STMPE=y CONFIG_MFD_TC3589X=y CONFIG_AB5500_CORE=y CONFIG_AB8500_CORE=y -CONFIG_REGULATOR=y CONFIG_REGULATOR_AB8500=y # CONFIG_HID_SUPPORT is not set CONFIG_USB_GADGET=y diff --git a/trunk/arch/arm/include/asm/barrier.h b/trunk/arch/arm/include/asm/barrier.h index 05112380dc53..44f4a09ff37b 100644 --- a/trunk/arch/arm/include/asm/barrier.h +++ b/trunk/arch/arm/include/asm/barrier.h @@ -2,7 +2,6 @@ #define __ASM_BARRIER_H #ifndef __ASSEMBLY__ -#include #define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t"); @@ -40,6 +39,7 @@ #ifdef CONFIG_ARCH_HAS_BARRIERS #include #elif defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP) +#include #define mb() do { dsb(); outer_sync(); } while (0) #define rmb() dsb() #define wmb() mb() diff --git a/trunk/arch/arm/include/asm/cpuidle.h b/trunk/arch/arm/include/asm/cpuidle.h deleted file mode 100644 index 2fca60ab513a..000000000000 --- a/trunk/arch/arm/include/asm/cpuidle.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __ASM_ARM_CPUIDLE_H -#define __ASM_ARM_CPUIDLE_H - -#ifdef CONFIG_CPU_IDLE -extern int arm_cpuidle_simple_enter(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index); -#else -static inline int arm_cpuidle_simple_enter(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index) { return -ENODEV; } -#endif - -/* Common ARM WFI state */ -#define ARM_CPUIDLE_WFI_STATE_PWR(p) {\ - .enter = arm_cpuidle_simple_enter,\ - .exit_latency = 1,\ - .target_residency = 1,\ - .power_usage = p,\ - .flags = CPUIDLE_FLAG_TIME_VALID,\ - .name = "WFI",\ - .desc = "ARM WFI",\ -} - -/* - * in case power_specified == 1, give a default WFI power value needed - * by some governors - */ -#define ARM_CPUIDLE_WFI_STATE ARM_CPUIDLE_WFI_STATE_PWR(UINT_MAX) - -#endif diff --git a/trunk/arch/arm/include/asm/io.h b/trunk/arch/arm/include/asm/io.h index 9af5563dd3eb..df0ac0bb39aa 100644 --- a/trunk/arch/arm/include/asm/io.h +++ b/trunk/arch/arm/include/asm/io.h @@ -119,7 +119,7 @@ static inline void __iomem *__typesafe_io(unsigned long addr) #ifdef CONFIG_NEED_MACH_IO_H #include #else -#define __io(a) __typesafe_io((a) & IO_SPACE_LIMIT) +#define __io(a) ({ (void)(a); __typesafe_io(0); }) #endif /* diff --git a/trunk/arch/arm/include/asm/jump_label.h b/trunk/arch/arm/include/asm/jump_label.h index bfc198c75913..5c5ca2ea62b0 100644 --- a/trunk/arch/arm/include/asm/jump_label.h +++ b/trunk/arch/arm/include/asm/jump_label.h @@ -14,7 +14,7 @@ #define JUMP_LABEL_NOP "nop" #endif -static __always_inline bool arch_static_branch(struct static_key *key) +static __always_inline bool arch_static_branch(struct jump_label_key *key) { asm goto("1:\n\t" JUMP_LABEL_NOP "\n\t" diff --git a/trunk/arch/arm/include/asm/thread_info.h b/trunk/arch/arm/include/asm/thread_info.h index 0f04d84582e1..d4c24d412a8d 100644 --- a/trunk/arch/arm/include/asm/thread_info.h +++ b/trunk/arch/arm/include/asm/thread_info.h @@ -118,13 +118,6 @@ extern void iwmmxt_task_switch(struct thread_info *); extern void vfp_sync_hwstate(struct thread_info *); extern void vfp_flush_hwstate(struct thread_info *); -struct user_vfp; -struct user_vfp_exc; - -extern int vfp_preserve_user_clear_hwstate(struct user_vfp __user *, - struct user_vfp_exc __user *); -extern int vfp_restore_user_hwstate(struct user_vfp __user *, - struct user_vfp_exc __user *); #endif /* diff --git a/trunk/arch/arm/include/asm/tls.h b/trunk/arch/arm/include/asm/tls.h index 73409e6c0251..60843eb0f61c 100644 --- a/trunk/arch/arm/include/asm/tls.h +++ b/trunk/arch/arm/include/asm/tls.h @@ -7,8 +7,6 @@ .macro set_tls_v6k, tp, tmp1, tmp2 mcr p15, 0, \tp, c13, c0, 3 @ set TLS register - mov \tmp1, #0 - mcr p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register .endm .macro set_tls_v6, tp, tmp1, tmp2 @@ -17,8 +15,6 @@ mov \tmp2, #0xffff0fff tst \tmp1, #HWCAP_TLS @ hardware TLS available? mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register - movne \tmp1, #0 - mcrne p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0 .endm diff --git a/trunk/arch/arm/kernel/Makefile b/trunk/arch/arm/kernel/Makefile index 7b787d642af4..8269d8928742 100644 --- a/trunk/arch/arm/kernel/Makefile +++ b/trunk/arch/arm/kernel/Makefile @@ -23,7 +23,7 @@ obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o obj-$(CONFIG_LEDS) += leds.o obj-$(CONFIG_OC_ETM) += etm.o -obj-$(CONFIG_CPU_IDLE) += cpuidle.o + obj-$(CONFIG_ISA_DMA_API) += dma.o obj-$(CONFIG_FIQ) += fiq.o fiqasm.o obj-$(CONFIG_MODULES) += armksyms.o module.o diff --git a/trunk/arch/arm/kernel/bios32.c b/trunk/arch/arm/kernel/bios32.c index ede5f7741c42..632df9a66f8c 100644 --- a/trunk/arch/arm/kernel/bios32.c +++ b/trunk/arch/arm/kernel/bios32.c @@ -299,6 +299,7 @@ static inline int pdev_bad_for_parity(struct pci_dev *dev) */ void pcibios_fixup_bus(struct pci_bus *bus) { + struct pci_sys_data *root = bus->sysdata; struct pci_dev *dev; u16 features = PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_FAST_BACK; diff --git a/trunk/arch/arm/kernel/cpuidle.c b/trunk/arch/arm/kernel/cpuidle.c deleted file mode 100644 index 89545f6c8403..000000000000 --- a/trunk/arch/arm/kernel/cpuidle.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2012 Linaro Ltd. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include -#include - -int arm_cpuidle_simple_enter(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index) -{ - cpu_do_idle(); - - return index; -} diff --git a/trunk/arch/arm/kernel/insn.c b/trunk/arch/arm/kernel/insn.c index b760340b7014..ab312e516546 100644 --- a/trunk/arch/arm/kernel/insn.c +++ b/trunk/arch/arm/kernel/insn.c @@ -1,4 +1,3 @@ -#include #include #include diff --git a/trunk/arch/arm/kernel/irq.c b/trunk/arch/arm/kernel/irq.c index 8349d4e97e2b..71ccdbfed662 100644 --- a/trunk/arch/arm/kernel/irq.c +++ b/trunk/arch/arm/kernel/irq.c @@ -155,10 +155,10 @@ static bool migrate_one_irq(struct irq_desc *desc) } c = irq_data_get_irq_chip(d); - if (!c->irq_set_affinity) + if (c->irq_set_affinity) + c->irq_set_affinity(d, affinity, true); + else pr_debug("IRQ%u: unable to set affinity\n", d->irq); - else if (c->irq_set_affinity(d, affinity, true) == IRQ_SET_MASK_OK && ret) - cpumask_copy(d->affinity, affinity); return ret; } diff --git a/trunk/arch/arm/kernel/kprobes.c b/trunk/arch/arm/kernel/kprobes.c index 4dd41fc9e235..ab1869dac97a 100644 --- a/trunk/arch/arm/kernel/kprobes.c +++ b/trunk/arch/arm/kernel/kprobes.c @@ -152,7 +152,7 @@ int __kprobes __arch_disarm_kprobe(void *p) void __kprobes arch_disarm_kprobe(struct kprobe *p) { - stop_machine(__arch_disarm_kprobe, p, cpu_online_mask); + stop_machine(__arch_disarm_kprobe, p, &cpu_online_map); } void __kprobes arch_remove_kprobe(struct kprobe *p) diff --git a/trunk/arch/arm/kernel/ptrace.c b/trunk/arch/arm/kernel/ptrace.c index 80abafb9bf33..45956c9d0ef0 100644 --- a/trunk/arch/arm/kernel/ptrace.c +++ b/trunk/arch/arm/kernel/ptrace.c @@ -256,7 +256,7 @@ static int ptrace_read_user(struct task_struct *tsk, unsigned long off, { unsigned long tmp; - if (off & 3) + if (off & 3 || off >= sizeof(struct user)) return -EIO; tmp = 0; @@ -268,8 +268,6 @@ static int ptrace_read_user(struct task_struct *tsk, unsigned long off, tmp = tsk->mm->end_code; else if (off < sizeof(struct pt_regs)) tmp = get_user_reg(tsk, off >> 2); - else if (off >= sizeof(struct user)) - return -EIO; return put_user(tmp, ret); } diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index ebfac782593f..b91411371ae1 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -523,21 +523,7 @@ int __init arm_add_memory(phys_addr_t start, unsigned long size) */ size -= start & ~PAGE_MASK; bank->start = PAGE_ALIGN(start); - -#ifndef CONFIG_LPAE - if (bank->start + size < bank->start) { - printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in " - "32-bit physical address space\n", (long long)start); - /* - * To ensure bank->start + bank->size is representable in - * 32 bits, we use ULONG_MAX as the upper limit rather than 4GB. - * This means we lose a page after masking. - */ - size = ULONG_MAX - bank->start; - } -#endif - - bank->size = size & PAGE_MASK; + bank->size = size & PAGE_MASK; /* * Check whether this memory region has non-zero size or diff --git a/trunk/arch/arm/kernel/signal.c b/trunk/arch/arm/kernel/signal.c index d68d1b694680..7cb532fc8aa4 100644 --- a/trunk/arch/arm/kernel/signal.c +++ b/trunk/arch/arm/kernel/signal.c @@ -180,23 +180,44 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame) static int preserve_vfp_context(struct vfp_sigframe __user *frame) { + struct thread_info *thread = current_thread_info(); + struct vfp_hard_struct *h = &thread->vfpstate.hard; const unsigned long magic = VFP_MAGIC; const unsigned long size = VFP_STORAGE_SIZE; int err = 0; + vfp_sync_hwstate(thread); __put_user_error(magic, &frame->magic, err); __put_user_error(size, &frame->size, err); - if (err) - return -EFAULT; + /* + * Copy the floating point registers. There can be unused + * registers see asm/hwcap.h for details. + */ + err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs, + sizeof(h->fpregs)); + /* + * Copy the status and control register. + */ + __put_user_error(h->fpscr, &frame->ufp.fpscr, err); - return vfp_preserve_user_clear_hwstate(&frame->ufp, &frame->ufp_exc); + /* + * Copy the exception registers. + */ + __put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err); + __put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); + __put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); + + return err ? -EFAULT : 0; } static int restore_vfp_context(struct vfp_sigframe __user *frame) { + struct thread_info *thread = current_thread_info(); + struct vfp_hard_struct *h = &thread->vfpstate.hard; unsigned long magic; unsigned long size; + unsigned long fpexc; int err = 0; __get_user_error(magic, &frame->magic, err); @@ -207,7 +228,33 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame) if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE) return -EINVAL; - return vfp_restore_user_hwstate(&frame->ufp, &frame->ufp_exc); + vfp_flush_hwstate(thread); + + /* + * Copy the floating point registers. There can be unused + * registers see asm/hwcap.h for details. + */ + err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs, + sizeof(h->fpregs)); + /* + * Copy the status and control register. + */ + __get_user_error(h->fpscr, &frame->ufp.fpscr, err); + + /* + * Sanitise and restore the exception registers. + */ + __get_user_error(fpexc, &frame->ufp_exc.fpexc, err); + /* Ensure the VFP is enabled. */ + fpexc |= FPEXC_EN; + /* Ensure FPINST2 is invalid and the exception flag is cleared. */ + fpexc &= ~(FPEXC_EX | FPEXC_FP2V); + h->fpexc = fpexc; + + __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); + __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); + + return err ? -EFAULT : 0; } #endif diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index f6a4d32b0421..2cee7d1eb958 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -349,7 +349,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) * re-initialize the map in platform_smp_prepare_cpus() if * present != possible (e.g. physical hotplug). */ - init_cpu_present(cpu_possible_mask); + init_cpu_present(&cpu_possible_map); /* * Initialise the SCU if there are more than one CPU @@ -510,6 +510,10 @@ static void ipi_cpu_stop(unsigned int cpu) local_fiq_disable(); local_irq_disable(); +#ifdef CONFIG_HOTPLUG_CPU + platform_cpu_kill(cpu); +#endif + while (1) cpu_relax(); } @@ -572,25 +576,16 @@ void smp_send_reschedule(int cpu) smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); } -#ifdef CONFIG_HOTPLUG_CPU -static void smp_kill_cpus(cpumask_t *mask) -{ - unsigned int cpu; - for_each_cpu(cpu, mask) - platform_cpu_kill(cpu); -} -#else -static void smp_kill_cpus(cpumask_t *mask) { } -#endif - void smp_send_stop(void) { unsigned long timeout; - struct cpumask mask; - cpumask_copy(&mask, cpu_online_mask); - cpumask_clear_cpu(smp_processor_id(), &mask); - smp_cross_call(&mask, IPI_CPU_STOP); + if (num_online_cpus() > 1) { + cpumask_t mask = cpu_online_map; + cpu_clear(smp_processor_id(), mask); + + smp_cross_call(&mask, IPI_CPU_STOP); + } /* Wait up to one second for other CPUs to stop */ timeout = USEC_PER_SEC; @@ -599,8 +594,6 @@ void smp_send_stop(void) if (num_online_cpus() > 1) pr_warning("SMP: failed to stop secondary CPUs\n"); - - smp_kill_cpus(&mask); } /* diff --git a/trunk/arch/arm/mach-at91/at91rm9200_devices.c b/trunk/arch/arm/mach-at91/at91rm9200_devices.c index 05774e5b1cba..99ce5c955e39 100644 --- a/trunk/arch/arm/mach-at91/at91rm9200_devices.c +++ b/trunk/arch/arm/mach-at91/at91rm9200_devices.c @@ -1173,6 +1173,7 @@ void __init at91_add_device_serial(void) printk(KERN_INFO "AT91: No default serial console defined.\n"); } #else +void __init __deprecated at91_init_serial(struct at91_uart_config *config) {} void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} void __init at91_set_serial_console(unsigned portnr) {} void __init at91_add_device_serial(void) {} diff --git a/trunk/arch/arm/mach-at91/at91rm9200_time.c b/trunk/arch/arm/mach-at91/at91rm9200_time.c index 104ca40d8d18..dd7f782b0b91 100644 --- a/trunk/arch/arm/mach-at91/at91rm9200_time.c +++ b/trunk/arch/arm/mach-at91/at91rm9200_time.c @@ -23,7 +23,6 @@ #include #include #include -#include #include @@ -177,7 +176,6 @@ static struct clock_event_device clkevt = { }; void __iomem *at91_st_base; -EXPORT_SYMBOL_GPL(at91_st_base); void __init at91rm9200_ioremap_st(u32 addr) { diff --git a/trunk/arch/arm/mach-at91/at91sam9260_devices.c b/trunk/arch/arm/mach-at91/at91sam9260_devices.c index 5652dde4bbe2..7e5651ee9f85 100644 --- a/trunk/arch/arm/mach-at91/at91sam9260_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9260_devices.c @@ -598,9 +598,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) else cs_pin = spi1_standard_cs[devices[i].chip_select]; - if (!gpio_is_valid(cs_pin)) - continue; - if (devices[i].bus_num == 0) enable_spi0 = 1; else diff --git a/trunk/arch/arm/mach-at91/at91sam9261_devices.c b/trunk/arch/arm/mach-at91/at91sam9261_devices.c index 4db961a93085..096da87dc00d 100644 --- a/trunk/arch/arm/mach-at91/at91sam9261_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9261_devices.c @@ -415,9 +415,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) else cs_pin = spi1_standard_cs[devices[i].chip_select]; - if (!gpio_is_valid(cs_pin)) - continue; - if (devices[i].bus_num == 0) enable_spi0 = 1; else diff --git a/trunk/arch/arm/mach-at91/at91sam9263_devices.c b/trunk/arch/arm/mach-at91/at91sam9263_devices.c index fe99206de880..53688c46f956 100644 --- a/trunk/arch/arm/mach-at91/at91sam9263_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9263_devices.c @@ -72,8 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable VBus control for UHP ports */ for (i = 0; i < data->ports; i++) { if (gpio_is_valid(data->vbus_pin[i])) - at91_set_gpio_output(data->vbus_pin[i], - data->vbus_pin_active_low[i]); + at91_set_gpio_output(data->vbus_pin[i], 0); } /* Enable overcurrent notification */ @@ -672,9 +671,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) else cs_pin = spi1_standard_cs[devices[i].chip_select]; - if (!gpio_is_valid(cs_pin)) - continue; - if (devices[i].bus_num == 0) enable_spi0 = 1; else diff --git a/trunk/arch/arm/mach-at91/at91sam9g45_devices.c b/trunk/arch/arm/mach-at91/at91sam9g45_devices.c index 6b008aee1dff..698479f1e197 100644 --- a/trunk/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9g45_devices.c @@ -127,13 +127,12 @@ void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) /* Enable VBus control for UHP ports */ for (i = 0; i < data->ports; i++) { if (gpio_is_valid(data->vbus_pin[i])) - at91_set_gpio_output(data->vbus_pin[i], - data->vbus_pin_active_low[i]); + at91_set_gpio_output(data->vbus_pin[i], 0); } /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (gpio_is_valid(data->overcurrent_pin[i])) + if (data->overcurrent_pin[i]) at91_set_gpio_input(data->overcurrent_pin[i], 1); } @@ -189,8 +188,7 @@ void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) /* Enable VBus control for UHP ports */ for (i = 0; i < data->ports; i++) { if (gpio_is_valid(data->vbus_pin[i])) - at91_set_gpio_output(data->vbus_pin[i], - data->vbus_pin_active_low[i]); + at91_set_gpio_output(data->vbus_pin[i], 0); } usbh_ehci_data = *data; @@ -787,9 +785,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) else cs_pin = spi1_standard_cs[devices[i].chip_select]; - if (!gpio_is_valid(cs_pin)) - continue; - if (devices[i].bus_num == 0) enable_spi0 = 1; else diff --git a/trunk/arch/arm/mach-at91/at91sam9rl_devices.c b/trunk/arch/arm/mach-at91/at91sam9rl_devices.c index fe4ae22e8561..eda72e83037d 100644 --- a/trunk/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9rl_devices.c @@ -419,9 +419,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) else cs_pin = spi_standard_cs[devices[i].chip_select]; - if (!gpio_is_valid(cs_pin)) - continue; - /* enable chip-select pin */ at91_set_gpio_output(cs_pin, 1); diff --git a/trunk/arch/arm/mach-at91/at91sam9x5.c b/trunk/arch/arm/mach-at91/at91sam9x5.c index 13c8cae60462..b6831eeb7b76 100644 --- a/trunk/arch/arm/mach-at91/at91sam9x5.c +++ b/trunk/arch/arm/mach-at91/at91sam9x5.c @@ -223,8 +223,6 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk), CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb0_clk), CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk), - CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma0_clk), - CLKDEV_CON_DEV_ID("dma_clk", "ffffee00.dma-controller", &dma1_clk), CLKDEV_CON_ID("pioA", &pioAB_clk), CLKDEV_CON_ID("pioB", &pioAB_clk), CLKDEV_CON_ID("pioC", &pioCD_clk), diff --git a/trunk/arch/arm/mach-at91/at91x40.c b/trunk/arch/arm/mach-at91/at91x40.c index d62fe090d814..5400a1d65035 100644 --- a/trunk/arch/arm/mach-at91/at91x40.c +++ b/trunk/arch/arm/mach-at91/at91x40.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-at91/board-rm9200ek.c b/trunk/arch/arm/mach-at91/board-rm9200ek.c index b2e4fe21f346..11cbaa8946fe 100644 --- a/trunk/arch/arm/mach-at91/board-rm9200ek.c +++ b/trunk/arch/arm/mach-at91/board-rm9200ek.c @@ -117,7 +117,7 @@ static struct i2c_board_info __initdata ek_i2c_devices[] = { }; #define EK_FLASH_BASE AT91_CHIPSELECT_0 -#define EK_FLASH_SIZE SZ_8M +#define EK_FLASH_SIZE SZ_2M static struct physmap_flash_data ek_flash_data = { .width = 2, diff --git a/trunk/arch/arm/mach-at91/board-sam9261ek.c b/trunk/arch/arm/mach-at91/board-sam9261ek.c index 065fed342424..c3f994462864 100644 --- a/trunk/arch/arm/mach-at91/board-sam9261ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9261ek.c @@ -85,6 +85,8 @@ static struct resource dm9000_resource[] = { .flags = IORESOURCE_MEM }, [2] = { + .start = AT91_PIN_PC11, + .end = AT91_PIN_PC11, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE, } @@ -128,8 +130,6 @@ static struct sam9_smc_config __initdata dm9000_smc_config = { static void __init ek_add_device_dm9000(void) { - struct resource *r = &dm9000_resource[2]; - /* Configure chip-select 2 (DM9000) */ sam9_smc_configure(0, 2, &dm9000_smc_config); @@ -139,7 +139,6 @@ static void __init ek_add_device_dm9000(void) /* Configure Interrupt pin as input, no pull-up */ at91_set_gpio_input(AT91_PIN_PC11, 0); - r->start = r->end = gpio_to_irq(AT91_PIN_PC11); platform_device_register(&dm9000_device); } #else diff --git a/trunk/arch/arm/mach-at91/board-sam9263ek.c b/trunk/arch/arm/mach-at91/board-sam9263ek.c index 2ffe50f3a9e9..66f0ddf4b2ae 100644 --- a/trunk/arch/arm/mach-at91/board-sam9263ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9263ek.c @@ -74,7 +74,6 @@ static void __init ek_init_early(void) static struct at91_usbh_data __initdata ek_usbh_data = { .ports = 2, .vbus_pin = { AT91_PIN_PA24, AT91_PIN_PA21 }, - .vbus_pin_active_low = {1, 1}, .overcurrent_pin= {-EINVAL, -EINVAL}, }; diff --git a/trunk/arch/arm/mach-at91/board-sam9m10g45ek.c b/trunk/arch/arm/mach-at91/board-sam9m10g45ek.c index c88e908ddd82..e1bea73e6b30 100644 --- a/trunk/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9m10g45ek.c @@ -71,7 +71,6 @@ static void __init ek_init_early(void) static struct at91_usbh_data __initdata ek_usbh_hs_data = { .ports = 2, .vbus_pin = {AT91_PIN_PD1, AT91_PIN_PD3}, - .vbus_pin_active_low = {1, 1}, .overcurrent_pin= {-EINVAL, -EINVAL}, }; diff --git a/trunk/arch/arm/mach-at91/clock.c b/trunk/arch/arm/mach-at91/clock.c index 6b692824c988..a0f4d7424cdc 100644 --- a/trunk/arch/arm/mach-at91/clock.c +++ b/trunk/arch/arm/mach-at91/clock.c @@ -35,7 +35,6 @@ #include "generic.h" void __iomem *at91_pmc_base; -EXPORT_SYMBOL_GPL(at91_pmc_base); /* * There's a lot more which can be done with clocks, including cpufreq diff --git a/trunk/arch/arm/mach-at91/cpuidle.c b/trunk/arch/arm/mach-at91/cpuidle.c index ece1f9aefb47..555d956b3a57 100644 --- a/trunk/arch/arm/mach-at91/cpuidle.c +++ b/trunk/arch/arm/mach-at91/cpuidle.c @@ -17,10 +17,9 @@ #include #include #include +#include #include #include -#include -#include #include "pm.h" @@ -28,39 +27,61 @@ static DEFINE_PER_CPU(struct cpuidle_device, at91_cpuidle_device); +static struct cpuidle_driver at91_idle_driver = { + .name = "at91_idle", + .owner = THIS_MODULE, +}; + /* Actual code that puts the SoC in different idle states */ static int at91_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - at91_standby(); + struct timeval before, after; + int idle_time; + + local_irq_disable(); + do_gettimeofday(&before); + if (index == 0) + /* Wait for interrupt state */ + cpu_do_idle(); + else if (index == 1) + at91_standby(); + do_gettimeofday(&after); + local_irq_enable(); + idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + + (after.tv_usec - before.tv_usec); + + dev->last_residency = idle_time; return index; } -static struct cpuidle_driver at91_idle_driver = { - .name = "at91_idle", - .owner = THIS_MODULE, - .en_core_tk_irqen = 1, - .states[0] = ARM_CPUIDLE_WFI_STATE, - .states[1] = { - .enter = at91_enter_idle, - .exit_latency = 10, - .target_residency = 100000, - .flags = CPUIDLE_FLAG_TIME_VALID, - .name = "RAM_SR", - .desc = "WFI and DDR Self Refresh", - }, - .state_count = AT91_MAX_STATES, -}; - /* Initialize CPU idle by registering the idle states */ static int at91_init_cpuidle(void) { struct cpuidle_device *device; + struct cpuidle_driver *driver = &at91_idle_driver; device = &per_cpu(at91_cpuidle_device, smp_processor_id()); device->state_count = AT91_MAX_STATES; + driver->state_count = AT91_MAX_STATES; + + /* Wait for interrupt state */ + driver->states[0].enter = at91_enter_idle; + driver->states[0].exit_latency = 1; + driver->states[0].target_residency = 10000; + driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID; + strcpy(driver->states[0].name, "WFI"); + strcpy(driver->states[0].desc, "Wait for interrupt"); + + /* Wait for interrupt and RAM self refresh state */ + driver->states[1].enter = at91_enter_idle; + driver->states[1].exit_latency = 10; + driver->states[1].target_residency = 10000; + driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID; + strcpy(driver->states[1].name, "RAM_SR"); + strcpy(driver->states[1].desc, "WFI and RAM Self Refresh"); cpuidle_register_driver(&at91_idle_driver); diff --git a/trunk/arch/arm/mach-at91/include/mach/at91_pmc.h b/trunk/arch/arm/mach-at91/include/mach/at91_pmc.h index ea2c57a86ca6..36604782a78f 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91_pmc.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91_pmc.h @@ -25,7 +25,7 @@ extern void __iomem *at91_pmc_base; #define at91_pmc_write(field, value) \ __raw_writel(value, at91_pmc_base + field) #else -.extern at91_pmc_base +.extern at91_aic_base #endif #define AT91_PMC_SCER 0x00 /* System Clock Enable Register */ diff --git a/trunk/arch/arm/mach-at91/include/mach/board.h b/trunk/arch/arm/mach-at91/include/mach/board.h index 49a821192c65..544a5d5ce416 100644 --- a/trunk/arch/arm/mach-at91/include/mach/board.h +++ b/trunk/arch/arm/mach-at91/include/mach/board.h @@ -86,15 +86,14 @@ extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *d extern void __init at91_add_device_eth(struct macb_platform_data *data); /* USB Host */ -#define AT91_MAX_USBH_PORTS 3 struct at91_usbh_data { - int vbus_pin[AT91_MAX_USBH_PORTS]; /* port power-control pin */ - int overcurrent_pin[AT91_MAX_USBH_PORTS]; - u8 ports; /* number of ports on root hub */ + u8 ports; /* number of ports on root hub */ + int vbus_pin[2]; /* port power-control pin */ + u8 vbus_pin_active_low[2]; u8 overcurrent_supported; - u8 vbus_pin_active_low[AT91_MAX_USBH_PORTS]; - u8 overcurrent_status[AT91_MAX_USBH_PORTS]; - u8 overcurrent_changed[AT91_MAX_USBH_PORTS]; + int overcurrent_pin[2]; + u8 overcurrent_status[2]; + u8 overcurrent_changed[2]; }; extern void __init at91_add_device_usbh(struct at91_usbh_data *data); extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data); diff --git a/trunk/arch/arm/mach-at91/include/mach/io.h b/trunk/arch/arm/mach-at91/include/mach/io.h deleted file mode 100644 index 2d9ca0455745..000000000000 --- a/trunk/arch/arm/mach-at91/include/mach/io.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * arch/arm/mach-at91/include/mach/io.h - * - * Copyright (C) 2003 SAN People - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __ASM_ARCH_IO_H -#define __ASM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xFFFFFFFF -#define __io(a) __typesafe_io(a) - -#endif diff --git a/trunk/arch/arm/mach-at91/setup.c b/trunk/arch/arm/mach-at91/setup.c index f44a2e7272e3..1083739e3065 100644 --- a/trunk/arch/arm/mach-at91/setup.c +++ b/trunk/arch/arm/mach-at91/setup.c @@ -11,7 +11,6 @@ #include #include -#include #include #include @@ -54,7 +53,6 @@ void __init at91_init_interrupts(unsigned int *priority) } void __iomem *at91_ramc_base[2]; -EXPORT_SYMBOL_GPL(at91_ramc_base); void __init at91_ioremap_ramc(int id, u32 addr, u32 size) { @@ -293,7 +291,6 @@ void __init at91_ioremap_rstc(u32 base_addr) } void __iomem *at91_matrix_base; -EXPORT_SYMBOL_GPL(at91_matrix_base); void __init at91_ioremap_matrix(u32 base_addr) { diff --git a/trunk/arch/arm/mach-bcmring/core.c b/trunk/arch/arm/mach-bcmring/core.c index adbfb1994582..22e4e0a28ad1 100644 --- a/trunk/arch/arm/mach-bcmring/core.c +++ b/trunk/arch/arm/mach-bcmring/core.c @@ -52,8 +52,8 @@ #include #include -static AMBA_APB_DEVICE(uartA, "uartA", 0, MM_ADDR_IO_UARTA, {IRQ_UARTA}, NULL); -static AMBA_APB_DEVICE(uartB, "uartB", 0, MM_ADDR_IO_UARTB, {IRQ_UARTB}, NULL); +static AMBA_APB_DEVICE(uartA, "uarta", MM_ADDR_IO_UARTA, { IRQ_UARTA }, NULL); +static AMBA_APB_DEVICE(uartB, "uartb", MM_ADDR_IO_UARTB, { IRQ_UARTB }, NULL); static struct clk pll1_clk = { .name = "PLL1", diff --git a/trunk/arch/arm/mach-clps711x/edb7211-mm.c b/trunk/arch/arm/mach-clps711x/edb7211-mm.c index 4372f06c9929..0bea1454ae03 100644 --- a/trunk/arch/arm/mach-clps711x/edb7211-mm.c +++ b/trunk/arch/arm/mach-clps711x/edb7211-mm.c @@ -21,7 +21,6 @@ */ #include #include -#include #include #include diff --git a/trunk/arch/arm/mach-davinci/cpuidle.c b/trunk/arch/arm/mach-davinci/cpuidle.c index 9107691adbdb..a30c7c5a6d83 100644 --- a/trunk/arch/arm/mach-davinci/cpuidle.c +++ b/trunk/arch/arm/mach-davinci/cpuidle.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -31,43 +30,12 @@ struct davinci_ops { u32 flags; }; -/* Actual code that puts the SoC in different idle states */ -static int davinci_enter_idle(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; - struct davinci_ops *ops = cpuidle_get_statedata(state_usage); - - if (ops && ops->enter) - ops->enter(ops->flags); - - index = cpuidle_wrap_enter(dev, drv, index, - arm_cpuidle_simple_enter); - - if (ops && ops->exit) - ops->exit(ops->flags); - - return index; -} - /* fields in davinci_ops.flags */ #define DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN BIT(0) static struct cpuidle_driver davinci_idle_driver = { - .name = "cpuidle-davinci", - .owner = THIS_MODULE, - .en_core_tk_irqen = 1, - .states[0] = ARM_CPUIDLE_WFI_STATE, - .states[1] = { - .enter = davinci_enter_idle, - .exit_latency = 10, - .target_residency = 100000, - .flags = CPUIDLE_FLAG_TIME_VALID, - .name = "DDR SR", - .desc = "WFI and DDR Self Refresh", - }, - .state_count = DAVINCI_CPUIDLE_MAX_STATES, + .name = "cpuidle-davinci", + .owner = THIS_MODULE, }; static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device); @@ -109,10 +77,41 @@ static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = { }, }; +/* Actual code that puts the SoC in different idle states */ +static int davinci_enter_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; + struct davinci_ops *ops = cpuidle_get_statedata(state_usage); + struct timeval before, after; + int idle_time; + + local_irq_disable(); + do_gettimeofday(&before); + + if (ops && ops->enter) + ops->enter(ops->flags); + /* Wait for interrupt state */ + cpu_do_idle(); + if (ops && ops->exit) + ops->exit(ops->flags); + + do_gettimeofday(&after); + local_irq_enable(); + idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + + (after.tv_usec - before.tv_usec); + + dev->last_residency = idle_time; + + return index; +} + static int __init davinci_cpuidle_probe(struct platform_device *pdev) { int ret; struct cpuidle_device *device; + struct cpuidle_driver *driver = &davinci_idle_driver; struct davinci_cpuidle_config *pdata = pdev->dev.platform_data; device = &per_cpu(davinci_cpuidle_device, smp_processor_id()); @@ -124,11 +123,27 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev) ddr2_reg_base = pdata->ddr2_ctlr_base; + /* Wait for interrupt state */ + driver->states[0].enter = davinci_enter_idle; + driver->states[0].exit_latency = 1; + driver->states[0].target_residency = 10000; + driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID; + strcpy(driver->states[0].name, "WFI"); + strcpy(driver->states[0].desc, "Wait for interrupt"); + + /* Wait for interrupt and DDR self refresh state */ + driver->states[1].enter = davinci_enter_idle; + driver->states[1].exit_latency = 10; + driver->states[1].target_residency = 10000; + driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID; + strcpy(driver->states[1].name, "DDR SR"); + strcpy(driver->states[1].desc, "WFI and DDR Self Refresh"); if (pdata->ddr2_pdown) davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN; cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]); device->state_count = DAVINCI_CPUIDLE_MAX_STATES; + driver->state_count = DAVINCI_CPUIDLE_MAX_STATES; ret = cpuidle_register_driver(&davinci_idle_driver); if (ret) { diff --git a/trunk/arch/arm/mach-exynos/Kconfig b/trunk/arch/arm/mach-exynos/Kconfig index e81c35f936b5..0491ceef1cda 100644 --- a/trunk/arch/arm/mach-exynos/Kconfig +++ b/trunk/arch/arm/mach-exynos/Kconfig @@ -368,7 +368,6 @@ comment "Flattened Device Tree based board for EXYNOS SoCs" config MACH_EXYNOS4_DT bool "Samsung Exynos4 Machine using device tree" - depends on ARCH_EXYNOS4 select CPU_EXYNOS4210 select USE_OF select ARM_AMBA @@ -381,7 +380,6 @@ config MACH_EXYNOS4_DT config MACH_EXYNOS5_DT bool "SAMSUNG EXYNOS5 Machine using device tree" - depends on ARCH_EXYNOS5 select SOC_EXYNOS5250 select USE_OF select ARM_AMBA diff --git a/trunk/arch/arm/mach-exynos/clock-exynos4.c b/trunk/arch/arm/mach-exynos/clock-exynos4.c index 6efd1e5919fd..df54c2a92225 100644 --- a/trunk/arch/arm/mach-exynos/clock-exynos4.c +++ b/trunk/arch/arm/mach-exynos/clock-exynos4.c @@ -497,25 +497,25 @@ static struct clk exynos4_init_clocks_off[] = { .ctrlbit = (1 << 3), }, { .name = "hsmmc", - .devname = "exynos4-sdhci.0", + .devname = "s3c-sdhci.0", .parent = &exynos4_clk_aclk_133.clk, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit = (1 << 5), }, { .name = "hsmmc", - .devname = "exynos4-sdhci.1", + .devname = "s3c-sdhci.1", .parent = &exynos4_clk_aclk_133.clk, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit = (1 << 6), }, { .name = "hsmmc", - .devname = "exynos4-sdhci.2", + .devname = "s3c-sdhci.2", .parent = &exynos4_clk_aclk_133.clk, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit = (1 << 7), }, { .name = "hsmmc", - .devname = "exynos4-sdhci.3", + .devname = "s3c-sdhci.3", .parent = &exynos4_clk_aclk_133.clk, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit = (1 << 8), @@ -1202,7 +1202,7 @@ static struct clksrc_clk exynos4_clk_sclk_uart3 = { static struct clksrc_clk exynos4_clk_sclk_mmc0 = { .clk = { .name = "sclk_mmc", - .devname = "exynos4-sdhci.0", + .devname = "s3c-sdhci.0", .parent = &exynos4_clk_dout_mmc0.clk, .enable = exynos4_clksrc_mask_fsys_ctrl, .ctrlbit = (1 << 0), @@ -1213,7 +1213,7 @@ static struct clksrc_clk exynos4_clk_sclk_mmc0 = { static struct clksrc_clk exynos4_clk_sclk_mmc1 = { .clk = { .name = "sclk_mmc", - .devname = "exynos4-sdhci.1", + .devname = "s3c-sdhci.1", .parent = &exynos4_clk_dout_mmc1.clk, .enable = exynos4_clksrc_mask_fsys_ctrl, .ctrlbit = (1 << 4), @@ -1224,7 +1224,7 @@ static struct clksrc_clk exynos4_clk_sclk_mmc1 = { static struct clksrc_clk exynos4_clk_sclk_mmc2 = { .clk = { .name = "sclk_mmc", - .devname = "exynos4-sdhci.2", + .devname = "s3c-sdhci.2", .parent = &exynos4_clk_dout_mmc2.clk, .enable = exynos4_clksrc_mask_fsys_ctrl, .ctrlbit = (1 << 8), @@ -1235,7 +1235,7 @@ static struct clksrc_clk exynos4_clk_sclk_mmc2 = { static struct clksrc_clk exynos4_clk_sclk_mmc3 = { .clk = { .name = "sclk_mmc", - .devname = "exynos4-sdhci.3", + .devname = "s3c-sdhci.3", .parent = &exynos4_clk_dout_mmc3.clk, .enable = exynos4_clksrc_mask_fsys_ctrl, .ctrlbit = (1 << 12), @@ -1340,10 +1340,10 @@ static struct clk_lookup exynos4_clk_lookup[] = { CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos4_clk_sclk_uart1.clk), CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos4_clk_sclk_uart2.clk), CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos4_clk_sclk_uart3.clk), - CLKDEV_INIT("exynos4-sdhci.0", "mmc_busclk.2", &exynos4_clk_sclk_mmc0.clk), - CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &exynos4_clk_sclk_mmc1.clk), - CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &exynos4_clk_sclk_mmc2.clk), - CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &exynos4_clk_sclk_mmc3.clk), + CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &exynos4_clk_sclk_mmc0.clk), + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &exynos4_clk_sclk_mmc1.clk), + CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &exynos4_clk_sclk_mmc2.clk), + CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &exynos4_clk_sclk_mmc3.clk), CLKDEV_INIT("exynos4-fb.0", "lcd", &exynos4_clk_fimd0), CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos4_clk_pdma0), CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos4_clk_pdma1), diff --git a/trunk/arch/arm/mach-exynos/clock-exynos5.c b/trunk/arch/arm/mach-exynos/clock-exynos5.c index 5cd7a8b8868c..d013982d0f8e 100644 --- a/trunk/arch/arm/mach-exynos/clock-exynos5.c +++ b/trunk/arch/arm/mach-exynos/clock-exynos5.c @@ -455,25 +455,25 @@ static struct clk exynos5_init_clocks_off[] = { .ctrlbit = (1 << 20), }, { .name = "hsmmc", - .devname = "exynos4-sdhci.0", + .devname = "s3c-sdhci.0", .parent = &exynos5_clk_aclk_200.clk, .enable = exynos5_clk_ip_fsys_ctrl, .ctrlbit = (1 << 12), }, { .name = "hsmmc", - .devname = "exynos4-sdhci.1", + .devname = "s3c-sdhci.1", .parent = &exynos5_clk_aclk_200.clk, .enable = exynos5_clk_ip_fsys_ctrl, .ctrlbit = (1 << 13), }, { .name = "hsmmc", - .devname = "exynos4-sdhci.2", + .devname = "s3c-sdhci.2", .parent = &exynos5_clk_aclk_200.clk, .enable = exynos5_clk_ip_fsys_ctrl, .ctrlbit = (1 << 14), }, { .name = "hsmmc", - .devname = "exynos4-sdhci.3", + .devname = "s3c-sdhci.3", .parent = &exynos5_clk_aclk_200.clk, .enable = exynos5_clk_ip_fsys_ctrl, .ctrlbit = (1 << 15), @@ -813,7 +813,7 @@ static struct clksrc_clk exynos5_clk_sclk_uart3 = { static struct clksrc_clk exynos5_clk_sclk_mmc0 = { .clk = { .name = "sclk_mmc", - .devname = "exynos4-sdhci.0", + .devname = "s3c-sdhci.0", .parent = &exynos5_clk_dout_mmc0.clk, .enable = exynos5_clksrc_mask_fsys_ctrl, .ctrlbit = (1 << 0), @@ -824,7 +824,7 @@ static struct clksrc_clk exynos5_clk_sclk_mmc0 = { static struct clksrc_clk exynos5_clk_sclk_mmc1 = { .clk = { .name = "sclk_mmc", - .devname = "exynos4-sdhci.1", + .devname = "s3c-sdhci.1", .parent = &exynos5_clk_dout_mmc1.clk, .enable = exynos5_clksrc_mask_fsys_ctrl, .ctrlbit = (1 << 4), @@ -835,7 +835,7 @@ static struct clksrc_clk exynos5_clk_sclk_mmc1 = { static struct clksrc_clk exynos5_clk_sclk_mmc2 = { .clk = { .name = "sclk_mmc", - .devname = "exynos4-sdhci.2", + .devname = "s3c-sdhci.2", .parent = &exynos5_clk_dout_mmc2.clk, .enable = exynos5_clksrc_mask_fsys_ctrl, .ctrlbit = (1 << 8), @@ -846,7 +846,7 @@ static struct clksrc_clk exynos5_clk_sclk_mmc2 = { static struct clksrc_clk exynos5_clk_sclk_mmc3 = { .clk = { .name = "sclk_mmc", - .devname = "exynos4-sdhci.3", + .devname = "s3c-sdhci.3", .parent = &exynos5_clk_dout_mmc3.clk, .enable = exynos5_clksrc_mask_fsys_ctrl, .ctrlbit = (1 << 12), @@ -990,10 +990,10 @@ static struct clk_lookup exynos5_clk_lookup[] = { CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos5_clk_sclk_uart1.clk), CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos5_clk_sclk_uart2.clk), CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos5_clk_sclk_uart3.clk), - CLKDEV_INIT("exynos4-sdhci.0", "mmc_busclk.2", &exynos5_clk_sclk_mmc0.clk), - CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &exynos5_clk_sclk_mmc1.clk), - CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &exynos5_clk_sclk_mmc2.clk), - CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &exynos5_clk_sclk_mmc3.clk), + CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &exynos5_clk_sclk_mmc0.clk), + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &exynos5_clk_sclk_mmc1.clk), + CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &exynos5_clk_sclk_mmc2.clk), + CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &exynos5_clk_sclk_mmc3.clk), CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos5_clk_pdma0), CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos5_clk_pdma1), CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos5_clk_mdma1), diff --git a/trunk/arch/arm/mach-exynos/common.c b/trunk/arch/arm/mach-exynos/common.c index 5ccd6e80a607..e6cc50e94a58 100644 --- a/trunk/arch/arm/mach-exynos/common.c +++ b/trunk/arch/arm/mach-exynos/common.c @@ -326,11 +326,6 @@ static void __init exynos4_map_io(void) s3c_fimc_setname(2, "exynos4-fimc"); s3c_fimc_setname(3, "exynos4-fimc"); - s3c_sdhci_setname(0, "exynos4-sdhci"); - s3c_sdhci_setname(1, "exynos4-sdhci"); - s3c_sdhci_setname(2, "exynos4-sdhci"); - s3c_sdhci_setname(3, "exynos4-sdhci"); - /* The I2C bus controllers are directly compatible with s3c2440 */ s3c_i2c0_setname("s3c2440-i2c"); s3c_i2c1_setname("s3c2440-i2c"); @@ -349,11 +344,6 @@ static void __init exynos5_map_io(void) s3c_device_i2c0.resource[1].start = EXYNOS5_IRQ_IIC; s3c_device_i2c0.resource[1].end = EXYNOS5_IRQ_IIC; - s3c_sdhci_setname(0, "exynos4-sdhci"); - s3c_sdhci_setname(1, "exynos4-sdhci"); - s3c_sdhci_setname(2, "exynos4-sdhci"); - s3c_sdhci_setname(3, "exynos4-sdhci"); - /* The I2C bus controllers are directly compatible with s3c2440 */ s3c_i2c0_setname("s3c2440-i2c"); s3c_i2c1_setname("s3c2440-i2c"); @@ -547,9 +537,7 @@ void __init exynos5_init_irq(void) { int irq; -#ifdef CONFIG_OF - of_irq_init(exynos4_dt_irq_match); -#endif + gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); for (irq = 0; irq < EXYNOS5_MAX_COMBINER_NR; irq++) { combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), @@ -595,11 +583,10 @@ core_initcall(exynos_core_init); #ifdef CONFIG_CACHE_L2X0 static int __init exynos4_l2x0_cache_init(void) { - int ret; - if (soc_is_exynos5250()) return 0; + int ret; ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK); if (!ret) { l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs); diff --git a/trunk/arch/arm/mach-exynos/dev-dwmci.c b/trunk/arch/arm/mach-exynos/dev-dwmci.c index 79035018fb74..b025db4bf602 100644 --- a/trunk/arch/arm/mach-exynos/dev-dwmci.c +++ b/trunk/arch/arm/mach-exynos/dev-dwmci.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -34,8 +33,16 @@ static int exynos4_dwmci_init(u32 slot_id, irq_handler_t handler, void *data) } static struct resource exynos4_dwmci_resource[] = { - [0] = DEFINE_RES_MEM(EXYNOS4_PA_DWMCI, SZ_4K), - [1] = DEFINE_RES_IRQ(EXYNOS4_IRQ_DWMCI), + [0] = { + .start = EXYNOS4_PA_DWMCI, + .end = EXYNOS4_PA_DWMCI + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_DWMCI, + .end = IRQ_DWMCI, + .flags = IORESOURCE_IRQ, + } }; static struct dw_mci_board exynos4_dwci_pdata = { diff --git a/trunk/arch/arm/mach-exynos/dma.c b/trunk/arch/arm/mach-exynos/dma.c index 69aaa4503205..3983abee4264 100644 --- a/trunk/arch/arm/mach-exynos/dma.c +++ b/trunk/arch/arm/mach-exynos/dma.c @@ -35,6 +35,8 @@ #include #include +static u64 dma_dmamask = DMA_BIT_MASK(32); + static u8 exynos4210_pdma0_peri[] = { DMACH_PCM0_RX, DMACH_PCM0_TX, diff --git a/trunk/arch/arm/mach-exynos/include/mach/debug-macro.S b/trunk/arch/arm/mach-exynos/include/mach/debug-macro.S index e0c86ea475e7..6c857ff0b5d8 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/debug-macro.S +++ b/trunk/arch/arm/mach-exynos/include/mach/debug-macro.S @@ -21,9 +21,10 @@ */ .macro addruart, rp, rv, tmp - mrc p15, 0, \tmp, c0, c0, 0 - and \tmp, \tmp, #0xf0 - teq \tmp, #0xf0 @@ A15 + mov \rp, #0x10000000 + ldr \rp, [\rp, #0x0] + and \rp, \rp, #0xf00000 + teq \rp, #0x500000 @@ EXYNOS5 ldreq \rp, =EXYNOS5_PA_UART movne \rp, #EXYNOS4_PA_UART @@ EXYNOS4 ldr \rv, =S3C_VA_UART diff --git a/trunk/arch/arm/mach-exynos/include/mach/irqs.h b/trunk/arch/arm/mach-exynos/include/mach/irqs.h index 591e78521a9f..9bee8535d9e0 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/irqs.h +++ b/trunk/arch/arm/mach-exynos/include/mach/irqs.h @@ -212,8 +212,6 @@ #define IRQ_MFC EXYNOS4_IRQ_MFC #define IRQ_SDO EXYNOS4_IRQ_SDO -#define IRQ_I2S0 EXYNOS4_IRQ_I2S0 - #define IRQ_ADC EXYNOS4_IRQ_ADC0 #define IRQ_TC EXYNOS4_IRQ_PEN0 diff --git a/trunk/arch/arm/mach-exynos/include/mach/map.h b/trunk/arch/arm/mach-exynos/include/mach/map.h index 6e6d11ff352a..024d38ff1718 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/map.h +++ b/trunk/arch/arm/mach-exynos/include/mach/map.h @@ -89,10 +89,6 @@ #define EXYNOS4_PA_MDMA1 0x12840000 #define EXYNOS4_PA_PDMA0 0x12680000 #define EXYNOS4_PA_PDMA1 0x12690000 -#define EXYNOS5_PA_MDMA0 0x10800000 -#define EXYNOS5_PA_MDMA1 0x11C10000 -#define EXYNOS5_PA_PDMA0 0x121A0000 -#define EXYNOS5_PA_PDMA1 0x121B0000 #define EXYNOS4_PA_SYSMMU_MDMA 0x10A40000 #define EXYNOS4_PA_SYSMMU_SSS 0x10A50000 diff --git a/trunk/arch/arm/mach-exynos/include/mach/regs-clock.h b/trunk/arch/arm/mach-exynos/include/mach/regs-clock.h index d9578a58ae7f..e141c1fd68d8 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/regs-clock.h +++ b/trunk/arch/arm/mach-exynos/include/mach/regs-clock.h @@ -255,15 +255,9 @@ /* For EXYNOS5250 */ -#define EXYNOS5_APLL_LOCK EXYNOS_CLKREG(0x00000) #define EXYNOS5_APLL_CON0 EXYNOS_CLKREG(0x00100) #define EXYNOS5_CLKSRC_CPU EXYNOS_CLKREG(0x00200) -#define EXYNOS5_CLKMUX_STATCPU EXYNOS_CLKREG(0x00400) #define EXYNOS5_CLKDIV_CPU0 EXYNOS_CLKREG(0x00500) -#define EXYNOS5_CLKDIV_CPU1 EXYNOS_CLKREG(0x00504) -#define EXYNOS5_CLKDIV_STATCPU0 EXYNOS_CLKREG(0x00600) -#define EXYNOS5_CLKDIV_STATCPU1 EXYNOS_CLKREG(0x00604) - #define EXYNOS5_MPLL_CON0 EXYNOS_CLKREG(0x04100) #define EXYNOS5_CLKSRC_CORE1 EXYNOS_CLKREG(0x04204) diff --git a/trunk/arch/arm/mach-exynos/include/mach/uncompress.h b/trunk/arch/arm/mach-exynos/include/mach/uncompress.h index 2979995d5a6a..493f4f365ddf 100644 --- a/trunk/arch/arm/mach-exynos/include/mach/uncompress.h +++ b/trunk/arch/arm/mach-exynos/include/mach/uncompress.h @@ -20,24 +20,9 @@ volatile u8 *uart_base; #include -static unsigned int __raw_readl(unsigned int ptr) -{ - return *((volatile unsigned int *)ptr); -} - static void arch_detect_cpu(void) { - u32 chip_id = __raw_readl(EXYNOS_PA_CHIPID); - - /* - * product_id is bits 31:12 - * bits 23:20 describe the exynosX family - * - */ - chip_id >>= 20; - chip_id &= 0xf; - - if (chip_id == 0x5) + if (machine_is_smdk5250()) uart_base = (volatile u8 *)EXYNOS5_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT); else uart_base = (volatile u8 *)EXYNOS4_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT); diff --git a/trunk/arch/arm/mach-exynos/mach-exynos5-dt.c b/trunk/arch/arm/mach-exynos/mach-exynos5-dt.c index 4711c8920e37..0d26f50081ad 100644 --- a/trunk/arch/arm/mach-exynos/mach-exynos5-dt.c +++ b/trunk/arch/arm/mach-exynos/mach-exynos5-dt.c @@ -45,7 +45,7 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = { "exynos4210-uart.3", NULL), OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL), OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL), - OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL), + OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.2", NULL), {}, }; diff --git a/trunk/arch/arm/mach-exynos/mach-nuri.c b/trunk/arch/arm/mach-exynos/mach-nuri.c index ed90aef404c3..b3982c867c9c 100644 --- a/trunk/arch/arm/mach-exynos/mach-nuri.c +++ b/trunk/arch/arm/mach-exynos/mach-nuri.c @@ -112,7 +112,6 @@ static struct s3c_sdhci_platdata nuri_hsmmc0_data __initdata = { .host_caps = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | MMC_CAP_ERASE), - .host_caps2 = MMC_CAP2_BROKEN_VOLTAGE, .cd_type = S3C_SDHCI_CD_PERMANENT, .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, }; @@ -308,7 +307,49 @@ static struct i2c_board_info i2c1_devs[] __initdata = { }; /* TSP */ +static u8 mxt_init_vals[] = { + /* MXT_GEN_COMMAND(6) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* MXT_GEN_POWER(7) */ + 0x20, 0xff, 0x32, + /* MXT_GEN_ACQUIRE(8) */ + 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23, + /* MXT_TOUCH_MULTI(9) */ + 0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, + /* MXT_TOUCH_KEYARRAY(15) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, + /* MXT_SPT_GPIOPWM(19) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* MXT_PROCI_GRIPFACE(20) */ + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04, + 0x0f, 0x0a, + /* MXT_PROCG_NOISE(22) */ + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00, + 0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03, + /* MXT_TOUCH_PROXIMITY(23) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + /* MXT_PROCI_ONETOUCH(24) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* MXT_SPT_SELFTEST(25) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + /* MXT_PROCI_TWOTOUCH(27) */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* MXT_SPT_CTECONFIG(28) */ + 0x00, 0x00, 0x02, 0x08, 0x10, 0x00, +}; + static struct mxt_platform_data mxt_platform_data = { + .config = mxt_init_vals, + .config_length = ARRAY_SIZE(mxt_init_vals), + .x_line = 18, .y_line = 11, .x_size = 1024, @@ -530,7 +571,7 @@ static struct regulator_init_data __initdata max8997_ldo7_data = { static struct regulator_init_data __initdata max8997_ldo8_data = { .constraints = { - .name = "VUSB+VDAC_3.3V_C210", + .name = "VUSB/VDAC_3.3V_C210", .min_uV = 3300000, .max_uV = 3300000, .valid_ops_mask = REGULATOR_CHANGE_STATUS, @@ -1306,7 +1347,6 @@ static struct platform_device *nuri_devices[] __initdata = { static void __init nuri_map_io(void) { - clk_xusbxti.rate = 24000000; exynos_init_io(NULL, 0); s3c24xx_init_clocks(24000000); s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs)); @@ -1339,6 +1379,7 @@ static void __init nuri_machine_init(void) nuri_camera_init(); nuri_ehci_init(); + clk_xusbxti.rate = 24000000; /* Last */ platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices)); diff --git a/trunk/arch/arm/mach-exynos/mach-universal_c210.c b/trunk/arch/arm/mach-exynos/mach-universal_c210.c index cb2b027f09a6..6bb9dbdd73fd 100644 --- a/trunk/arch/arm/mach-exynos/mach-universal_c210.c +++ b/trunk/arch/arm/mach-exynos/mach-universal_c210.c @@ -29,7 +29,6 @@ #include #include -#include #include #include #include @@ -747,7 +746,6 @@ static struct s3c_sdhci_platdata universal_hsmmc0_data __initdata = { .max_width = 8, .host_caps = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), - .host_caps2 = MMC_CAP2_BROKEN_VOLTAGE, .cd_type = S3C_SDHCI_CD_PERMANENT, .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, }; @@ -1059,7 +1057,6 @@ static struct platform_device *universal_devices[] __initdata = { static void __init universal_map_io(void) { - clk_xusbxti.rate = 24000000; exynos_init_io(NULL, 0); s3c24xx_init_clocks(24000000); s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs)); diff --git a/trunk/arch/arm/mach-h720x/common.c b/trunk/arch/arm/mach-h720x/common.c index aa1331e86bcf..e756d1ac00c2 100644 --- a/trunk/arch/arm/mach-h720x/common.c +++ b/trunk/arch/arm/mach-h720x/common.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-imx/clock-imx27.c b/trunk/arch/arm/mach-imx/clock-imx27.c index 98e04f5a87dd..b9a95ed75553 100644 --- a/trunk/arch/arm/mach-imx/clock-imx27.c +++ b/trunk/arch/arm/mach-imx/clock-imx27.c @@ -662,7 +662,6 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "dma", dma_clk) _REGISTER_CLOCK(NULL, "rtic", rtic_clk) _REGISTER_CLOCK(NULL, "brom", brom_clk) - _REGISTER_CLOCK(NULL, "emma", emma_clk) _REGISTER_CLOCK("m2m-emmaprp.0", NULL, emma_clk) _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk) _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk) diff --git a/trunk/arch/arm/mach-imx/clock-imx35.c b/trunk/arch/arm/mach-imx/clock-imx35.c index e56c1a83eee3..1e279af656ad 100644 --- a/trunk/arch/arm/mach-imx/clock-imx35.c +++ b/trunk/arch/arm/mach-imx/clock-imx35.c @@ -483,7 +483,7 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk) _REGISTER_CLOCK(NULL, "max", max_clk) _REGISTER_CLOCK(NULL, "audmux", audmux_clk) - _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk) + _REGISTER_CLOCK(NULL, "csi", csi_clk) _REGISTER_CLOCK(NULL, "iim", iim_clk) _REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk) _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) diff --git a/trunk/arch/arm/mach-imx/imx27-dt.c b/trunk/arch/arm/mach-imx/imx27-dt.c index ed38d03c61f2..861ceb8232d6 100644 --- a/trunk/arch/arm/mach-imx/imx27-dt.c +++ b/trunk/arch/arm/mach-imx/imx27-dt.c @@ -35,7 +35,7 @@ static const struct of_dev_auxdata imx27_auxdata_lookup[] __initconst = { static int __init imx27_avic_add_irq_domain(struct device_node *np, struct device_node *interrupt_parent) { - irq_domain_add_legacy(np, 64, 0, 0, &irq_domain_simple_ops, NULL); + irq_domain_add_simple(np, 0); return 0; } @@ -44,9 +44,7 @@ static int __init imx27_gpio_add_irq_domain(struct device_node *np, { static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; - gpio_irq_base -= 32; - irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, - NULL); + irq_domain_add_simple(np, gpio_irq_base); return 0; } diff --git a/trunk/arch/arm/mach-imx/mach-armadillo5x0.c b/trunk/arch/arm/mach-imx/mach-armadillo5x0.c index c650145d1646..27bc27e6ea41 100644 --- a/trunk/arch/arm/mach-imx/mach-armadillo5x0.c +++ b/trunk/arch/arm/mach-imx/mach-armadillo5x0.c @@ -38,8 +38,6 @@ #include #include #include -#include -#include #include #include @@ -481,11 +479,6 @@ static struct platform_device *devices[] __initdata = { &armadillo5x0_smc911x_device, }; -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vdd33a", "smsc911x"), - REGULATOR_SUPPLY("vddvario", "smsc911x"), -}; - /* * Perform board specific initializations */ @@ -496,8 +489,6 @@ static void __init armadillo5x0_init(void) mxc_iomux_setup_multiple_pins(armadillo5x0_pins, ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0"); - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - platform_add_devices(devices, ARRAY_SIZE(devices)); imx_add_gpio_keys(&armadillo5x0_button_data); imx31_add_imx_i2c1(NULL); diff --git a/trunk/arch/arm/mach-imx/mach-kzm_arm11_01.c b/trunk/arch/arm/mach-imx/mach-kzm_arm11_01.c index 15a26e908260..fc78e8071cd1 100644 --- a/trunk/arch/arm/mach-imx/mach-kzm_arm11_01.c +++ b/trunk/arch/arm/mach-imx/mach-kzm_arm11_01.c @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include #include @@ -168,11 +166,6 @@ static struct platform_device kzm_smsc9118_device = { }, }; -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vdd33a", "smsc911x"), - REGULATOR_SUPPLY("vddvario", "smsc911x"), -}; - static int __init kzm_init_smsc9118(void) { /* @@ -182,8 +175,6 @@ static int __init kzm_init_smsc9118(void) gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2), "smsc9118-int"); gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2)); - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - return platform_device_register(&kzm_smsc9118_device); } #else diff --git a/trunk/arch/arm/mach-imx/mach-mx31lilly.c b/trunk/arch/arm/mach-imx/mach-mx31lilly.c index 83714b0cc290..02401bbd6d53 100644 --- a/trunk/arch/arm/mach-imx/mach-mx31lilly.c +++ b/trunk/arch/arm/mach-imx/mach-mx31lilly.c @@ -34,8 +34,6 @@ #include #include #include -#include -#include #include #include @@ -244,11 +242,6 @@ static struct platform_device *devices[] __initdata = { static int mx31lilly_baseboard; core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444); -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vdd33a", "smsc911x"), - REGULATOR_SUPPLY("vddvario", "smsc911x"), -}; - static void __init mx31lilly_board_init(void) { imx31_soc_init(); @@ -287,8 +280,6 @@ static void __init mx31lilly_board_init(void) imx31_add_spi_imx1(&spi1_pdata); spi_register_board_info(&mc13783_dev, 1); - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - platform_add_devices(devices, ARRAY_SIZE(devices)); /* USB */ diff --git a/trunk/arch/arm/mach-imx/mach-mx31lite.c b/trunk/arch/arm/mach-imx/mach-mx31lite.c index 0abef5f13df5..ef80751712e7 100644 --- a/trunk/arch/arm/mach-imx/mach-mx31lite.c +++ b/trunk/arch/arm/mach-imx/mach-mx31lite.c @@ -29,8 +29,6 @@ #include #include #include -#include -#include #include #include @@ -228,11 +226,6 @@ void __init mx31lite_map_io(void) static int mx31lite_baseboard; core_param(mx31lite_baseboard, mx31lite_baseboard, int, 0444); -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vdd33a", "smsc911x"), - REGULATOR_SUPPLY("vddvario", "smsc911x"), -}; - static void __init mx31lite_init(void) { int ret; @@ -266,8 +259,6 @@ static void __init mx31lite_init(void) if (usbh2_pdata.otg) imx31_add_mxc_ehci_hs(2, &usbh2_pdata); - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); - /* SMSC9117 IRQ pin */ ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_SFS6), "sms9117-irq"); if (ret) diff --git a/trunk/arch/arm/mach-imx/mach-mx35_3ds.c b/trunk/arch/arm/mach-imx/mach-mx35_3ds.c index 6ae51c6b95b7..e14291d89e4f 100644 --- a/trunk/arch/arm/mach-imx/mach-mx35_3ds.c +++ b/trunk/arch/arm/mach-imx/mach-mx35_3ds.c @@ -97,7 +97,7 @@ static struct i2c_board_info __initdata i2c_devices_3ds[] = { static int lcd_power_gpio = -ENXIO; static int mc9s08dz60_gpiochip_match(struct gpio_chip *chip, - const void *data) + void *data) { return !strcmp(chip->label, data); } diff --git a/trunk/arch/arm/mach-imx/mach-mx53_ard.c b/trunk/arch/arm/mach-imx/mach-mx53_ard.c index 05641980dc5e..753f4fc9ec04 100644 --- a/trunk/arch/arm/mach-imx/mach-mx53_ard.c +++ b/trunk/arch/arm/mach-imx/mach-mx53_ard.c @@ -23,8 +23,6 @@ #include #include #include -#include -#include #include #include @@ -216,11 +214,6 @@ static int weim_cs_config(void) return 0; } -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vdd33a", "smsc911x"), - REGULATOR_SUPPLY("vddvario", "smsc911x"), -}; - void __init imx53_ard_common_init(void) { mxc_iomux_v3_setup_multiple_pads(mx53_ard_pads, @@ -239,7 +232,6 @@ static void __init mx53_ard_board_init(void) imx53_ard_common_init(); mx53_ard_io_init(); - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); platform_add_devices(devices, ARRAY_SIZE(devices)); imx53_add_sdhci_esdhc_imx(0, &mx53_ard_sd1_data); diff --git a/trunk/arch/arm/mach-imx/mm-imx3.c b/trunk/arch/arm/mach-imx/mm-imx3.c index 74127389e7ab..d534d7f988e0 100644 --- a/trunk/arch/arm/mach-imx/mm-imx3.c +++ b/trunk/arch/arm/mach-imx/mm-imx3.c @@ -21,7 +21,6 @@ #include #include -#include #include #include diff --git a/trunk/arch/arm/mach-imx/mm-imx5.c b/trunk/arch/arm/mach-imx/mm-imx5.c index e10f3914fcfe..51af9fa56944 100644 --- a/trunk/arch/arm/mach-imx/mm-imx5.c +++ b/trunk/arch/arm/mach-imx/mm-imx5.c @@ -15,7 +15,6 @@ #include #include -#include #include #include @@ -35,7 +34,7 @@ static void imx5_idle(void) } clk_enable(gpc_dvfs_clk); mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); - if (!tzic_enable_wake()) + if (tzic_enable_wake() != 0) cpu_do_idle(); clk_disable(gpc_dvfs_clk); } diff --git a/trunk/arch/arm/mach-ixp23xx/core.c b/trunk/arch/arm/mach-ixp23xx/core.c index d34542425990..d2c2dc35cbdd 100644 --- a/trunk/arch/arm/mach-ixp23xx/core.c +++ b/trunk/arch/arm/mach-ixp23xx/core.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/arm/mach-ixp4xx/common.c b/trunk/arch/arm/mach-ixp4xx/common.c index ebbd7fc90eb4..c60e7b86192c 100644 --- a/trunk/arch/arm/mach-ixp4xx/common.c +++ b/trunk/arch/arm/mach-ixp4xx/common.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/arm/mach-kirkwood/cpuidle.c b/trunk/arch/arm/mach-kirkwood/cpuidle.c index 0f1710941878..7088180b018b 100644 --- a/trunk/arch/arm/mach-kirkwood/cpuidle.c +++ b/trunk/arch/arm/mach-kirkwood/cpuidle.c @@ -20,47 +20,77 @@ #include #include #include -#include #include #define KIRKWOOD_MAX_STATES 2 +static struct cpuidle_driver kirkwood_idle_driver = { + .name = "kirkwood_idle", + .owner = THIS_MODULE, +}; + +static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device); + /* Actual code that puts the SoC in different idle states */ static int kirkwood_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - writel(0x7, DDR_OPERATION_BASE); - cpu_do_idle(); + struct timeval before, after; + int idle_time; - return index; -} + local_irq_disable(); + do_gettimeofday(&before); + if (index == 0) + /* Wait for interrupt state */ + cpu_do_idle(); + else if (index == 1) { + /* + * Following write will put DDR in self refresh. + * Note that we have 256 cycles before DDR puts it + * self in self-refresh, so the wait-for-interrupt + * call afterwards won't get the DDR from self refresh + * mode. + */ + writel(0x7, DDR_OPERATION_BASE); + cpu_do_idle(); + } + do_gettimeofday(&after); + local_irq_enable(); + idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + + (after.tv_usec - before.tv_usec); -static struct cpuidle_driver kirkwood_idle_driver = { - .name = "kirkwood_idle", - .owner = THIS_MODULE, - .en_core_tk_irqen = 1, - .states[0] = ARM_CPUIDLE_WFI_STATE, - .states[1] = { - .enter = kirkwood_enter_idle, - .exit_latency = 10, - .target_residency = 100000, - .flags = CPUIDLE_FLAG_TIME_VALID, - .name = "DDR SR", - .desc = "WFI and DDR Self Refresh", - }, - .state_count = KIRKWOOD_MAX_STATES, -}; + /* Update last residency */ + dev->last_residency = idle_time; -static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device); + return index; +} /* Initialize CPU idle by registering the idle states */ static int kirkwood_init_cpuidle(void) { struct cpuidle_device *device; + struct cpuidle_driver *driver = &kirkwood_idle_driver; device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id()); device->state_count = KIRKWOOD_MAX_STATES; + driver->state_count = KIRKWOOD_MAX_STATES; + + /* Wait for interrupt state */ + driver->states[0].enter = kirkwood_enter_idle; + driver->states[0].exit_latency = 1; + driver->states[0].target_residency = 10000; + driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID; + strcpy(driver->states[0].name, "WFI"); + strcpy(driver->states[0].desc, "Wait for interrupt"); + + /* Wait for interrupt and DDR self refresh state */ + driver->states[1].enter = kirkwood_enter_idle; + driver->states[1].exit_latency = 10; + driver->states[1].target_residency = 10000; + driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID; + strcpy(driver->states[1].name, "DDR SR"); + strcpy(driver->states[1].desc, "WFI and DDR Self Refresh"); cpuidle_register_driver(&kirkwood_idle_driver); if (cpuidle_register_device(device)) { diff --git a/trunk/arch/arm/mach-msm/board-halibut.c b/trunk/arch/arm/mach-msm/board-halibut.c index 26aac363a064..3698a370d636 100644 --- a/trunk/arch/arm/mach-msm/board-halibut.c +++ b/trunk/arch/arm/mach-msm/board-halibut.c @@ -86,6 +86,9 @@ static void __init halibut_init(void) static void __init halibut_fixup(struct tag *tags, char **cmdline, struct meminfo *mi) { + mi->nr_banks=1; + mi->bank[0].start = PHYS_OFFSET; + mi->bank[0].size = (101*1024*1024); } static void __init halibut_map_io(void) diff --git a/trunk/arch/arm/mach-msm/board-msm8x60.c b/trunk/arch/arm/mach-msm/board-msm8x60.c index fb3496a52ef4..962e71169750 100644 --- a/trunk/arch/arm/mach-msm/board-msm8x60.c +++ b/trunk/arch/arm/mach-msm/board-msm8x60.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -50,22 +49,10 @@ static void __init msm8x60_map_io(void) msm_map_msm8x60_io(); } -#ifdef CONFIG_OF -static struct of_device_id msm_dt_gic_match[] __initdata = { - { .compatible = "qcom,msm-8660-qgic", .data = gic_of_init }, - {} -}; -#endif - static void __init msm8x60_init_irq(void) { - if (!of_have_populated_dt()) - gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE, - (void *)MSM_QGIC_CPU_BASE); -#ifdef CONFIG_OF - else - of_irq_init(msm_dt_gic_match); -#endif + gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE, + (void *)MSM_QGIC_CPU_BASE); /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */ writel(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4); @@ -86,8 +73,16 @@ static struct of_dev_auxdata msm_auxdata_lookup[] __initdata = { {} }; +static struct of_device_id msm_dt_gic_match[] __initdata = { + { .compatible = "qcom,msm-8660-qgic", }, + {} +}; + static void __init msm8x60_dt_init(void) { + irq_domain_generate_simple(msm_dt_gic_match, MSM8X60_QGIC_DIST_PHYS, + GIC_SPI_START); + if (of_machine_is_compatible("qcom,msm8660-surf")) { printk(KERN_INFO "Init surf UART registers\n"); msm8x60_init_uart12dm(); diff --git a/trunk/arch/arm/mach-msm/board-trout-panel.c b/trunk/arch/arm/mach-msm/board-trout-panel.c index 89bf6b426699..25105c1027fe 100644 --- a/trunk/arch/arm/mach-msm/board-trout-panel.c +++ b/trunk/arch/arm/mach-msm/board-trout-panel.c @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/trunk/arch/arm/mach-msm/board-trout.c b/trunk/arch/arm/mach-msm/board-trout.c index d4060a37e23d..5414f76ec0a9 100644 --- a/trunk/arch/arm/mach-msm/board-trout.c +++ b/trunk/arch/arm/mach-msm/board-trout.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-msm/include/mach/uncompress.h b/trunk/arch/arm/mach-msm/include/mach/uncompress.h index c14011fe832d..169a84007456 100644 --- a/trunk/arch/arm/mach-msm/include/mach/uncompress.h +++ b/trunk/arch/arm/mach-msm/include/mach/uncompress.h @@ -16,7 +16,6 @@ #ifndef __ASM_ARCH_MSM_UNCOMPRESS_H #define __ASM_ARCH_MSM_UNCOMPRESS_H -#include #include #include diff --git a/trunk/arch/arm/mach-msm/proc_comm.c b/trunk/arch/arm/mach-msm/proc_comm.c index 9980dc736e7b..67e701c7f183 100644 --- a/trunk/arch/arm/mach-msm/proc_comm.c +++ b/trunk/arch/arm/mach-msm/proc_comm.c @@ -121,7 +121,7 @@ int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2) * and unknown state. This function should be called early to * wait on the ARM9. */ -void __devinit proc_comm_boot_wait(void) +void __init proc_comm_boot_wait(void) { void __iomem *base = MSM_SHARED_RAM_BASE; diff --git a/trunk/arch/arm/mach-msm/smd_debug.c b/trunk/arch/arm/mach-msm/smd_debug.c index c56df9e932ae..0c56a5aaf588 100644 --- a/trunk/arch/arm/mach-msm/smd_debug.c +++ b/trunk/arch/arm/mach-msm/smd_debug.c @@ -203,9 +203,15 @@ static ssize_t debug_read(struct file *file, char __user *buf, return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize); } +static int debug_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static const struct file_operations debug_ops = { .read = debug_read, - .open = simple_open, + .open = debug_open, .llseek = default_llseek, }; diff --git a/trunk/include/linux/fsl/mxs-dma.h b/trunk/arch/arm/mach-mxs/include/mach/dma.h similarity index 100% rename from trunk/include/linux/fsl/mxs-dma.h rename to trunk/arch/arm/mach-mxs/include/mach/dma.h diff --git a/trunk/arch/arm/mach-omap1/flash.c b/trunk/arch/arm/mach-omap1/flash.c index 401eb3c080c2..f9bf78d4fdfb 100644 --- a/trunk/arch/arm/mach-omap1/flash.c +++ b/trunk/arch/arm/mach-omap1/flash.c @@ -17,12 +17,20 @@ void omap1_set_vpp(struct platform_device *pdev, int enable) { + static int count; u32 l; - l = omap_readl(EMIFS_CONFIG); - if (enable) - l |= OMAP_EMIFS_CONFIG_WP; - else - l &= ~OMAP_EMIFS_CONFIG_WP; - omap_writel(l, EMIFS_CONFIG); + if (enable) { + if (count++ == 0) { + l = omap_readl(EMIFS_CONFIG); + l |= OMAP_EMIFS_CONFIG_WP; + omap_writel(l, EMIFS_CONFIG); + } + } else { + if (count && (--count == 0)) { + l = omap_readl(EMIFS_CONFIG); + l &= ~OMAP_EMIFS_CONFIG_WP; + omap_writel(l, EMIFS_CONFIG); + } + } } diff --git a/trunk/arch/arm/mach-omap1/include/mach/io.h b/trunk/arch/arm/mach-omap1/include/mach/io.h deleted file mode 100644 index ce4f8005b26f..000000000000 --- a/trunk/arch/arm/mach-omap1/include/mach/io.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * arch/arm/mach-omap1/include/mach/io.h - * - * IO definitions for TI OMAP processors and boards - * - * Copied from arch/arm/mach-sa1100/include/mach/io.h - * Copyright (C) 1997-1999 Russell King - * - * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Modifications: - * 06-12-1997 RMK Created. - * 07-04-1999 RMK Major cleanup - */ - -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -/* - * We don't actually have real ISA nor PCI buses, but there is so many - * drivers out there that might just work if we fake them... - */ -#define __io(a) __typesafe_io(a) - -#endif diff --git a/trunk/arch/arm/mach-omap1/mux.c b/trunk/arch/arm/mach-omap1/mux.c index e9cc52d4cb28..087dba0df47e 100644 --- a/trunk/arch/arm/mach-omap1/mux.c +++ b/trunk/arch/arm/mach-omap1/mux.c @@ -27,7 +27,6 @@ #include #include -#include #include diff --git a/trunk/arch/arm/mach-omap1/timer.c b/trunk/arch/arm/mach-omap1/timer.c index fb202af01d0d..6e90665a7c47 100644 --- a/trunk/arch/arm/mach-omap1/timer.c +++ b/trunk/arch/arm/mach-omap1/timer.c @@ -47,9 +47,9 @@ static int omap1_dm_timer_set_src(struct platform_device *pdev, int n = (pdev->id - 1) << 1; u32 l; - l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n); + l = __raw_readl(MOD_CONF_CTRL_1) & ~(0x03 << n); l |= source << n; - omap_writel(l, MOD_CONF_CTRL_1); + __raw_writel(l, MOD_CONF_CTRL_1); return 0; } diff --git a/trunk/arch/arm/mach-omap2/board-4430sdp.c b/trunk/arch/arm/mach-omap2/board-4430sdp.c index 130ab00c09a2..a39fc4bbd2b8 100644 --- a/trunk/arch/arm/mach-omap2/board-4430sdp.c +++ b/trunk/arch/arm/mach-omap2/board-4430sdp.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -561,7 +560,7 @@ static struct regulator_init_data sdp4430_vusim = { }, }; -static struct twl6040_codec_data twl6040_codec = { +static struct twl4030_codec_data twl6040_codec = { /* single-step ramp for headset and handsfree */ .hs_left_step = 0x0f, .hs_right_step = 0x0f, @@ -569,7 +568,7 @@ static struct twl6040_codec_data twl6040_codec = { .hf_right_step = 0x1d, }; -static struct twl6040_vibra_data twl6040_vibra = { +static struct twl4030_vibra_data twl6040_vibra = { .vibldrv_res = 8, .vibrdrv_res = 3, .viblmotor_res = 10, @@ -578,14 +577,16 @@ static struct twl6040_vibra_data twl6040_vibra = { .vddvibr_uV = 0, /* fixed volt supply - VBAT */ }; -static struct twl6040_platform_data twl6040_data = { +static struct twl4030_audio_data twl6040_audio = { .codec = &twl6040_codec, .vibra = &twl6040_vibra, .audpwron_gpio = 127, + .naudint_irq = OMAP44XX_IRQ_SYS_2N, .irq_base = TWL6040_CODEC_IRQ_BASE, }; static struct twl4030_platform_data sdp4430_twldata = { + .audio = &twl6040_audio, /* Regulators */ .vusim = &sdp4430_vusim, .vaux1 = &sdp4430_vaux1, @@ -616,8 +617,7 @@ static int __init omap4_i2c_init(void) TWL_COMMON_REGULATOR_VCXIO | TWL_COMMON_REGULATOR_VUSB | TWL_COMMON_REGULATOR_CLK32KG); - omap4_pmic_init("twl6030", &sdp4430_twldata, - &twl6040_data, OMAP44XX_IRQ_SYS_2N); + omap4_pmic_init("twl6030", &sdp4430_twldata); omap_register_i2c_bus(2, 400, NULL, 0); omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo, ARRAY_SIZE(sdp4430_i2c_3_boardinfo)); diff --git a/trunk/arch/arm/mach-omap2/board-cm-t35.c b/trunk/arch/arm/mach-omap2/board-cm-t35.c index 909a8b91b564..41b0a2fe0b04 100644 --- a/trunk/arch/arm/mach-omap2/board-cm-t35.c +++ b/trunk/arch/arm/mach-omap2/board-cm-t35.c @@ -26,7 +26,6 @@ #include #include -#include #include #include @@ -82,23 +81,8 @@ static struct omap_smsc911x_platform_data sb_t35_smsc911x_cfg = { .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, }; -static struct regulator_consumer_supply cm_t35_smsc911x_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x.0"), - REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), -}; - -static struct regulator_consumer_supply sb_t35_smsc911x_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x.1"), - REGULATOR_SUPPLY("vdd33a", "smsc911x.1"), -}; - static void __init cm_t35_init_ethernet(void) { - regulator_register_fixed(0, cm_t35_smsc911x_supplies, - ARRAY_SIZE(cm_t35_smsc911x_supplies)); - regulator_register_fixed(1, sb_t35_smsc911x_supplies, - ARRAY_SIZE(sb_t35_smsc911x_supplies)); - gpmc_smsc911x_init(&cm_t35_smsc911x_cfg); gpmc_smsc911x_init(&sb_t35_smsc911x_cfg); } diff --git a/trunk/arch/arm/mach-omap2/board-generic.c b/trunk/arch/arm/mach-omap2/board-generic.c index 098d183a0086..74e1687b5170 100644 --- a/trunk/arch/arm/mach-omap2/board-generic.c +++ b/trunk/arch/arm/mach-omap2/board-generic.c @@ -137,7 +137,7 @@ static struct twl4030_platform_data sdp4430_twldata = { static void __init omap4_i2c_init(void) { - omap4_pmic_init("twl6030", &sdp4430_twldata, NULL, 0); + omap4_pmic_init("twl6030", &sdp4430_twldata); } static void __init omap4_init(void) diff --git a/trunk/arch/arm/mach-omap2/board-igep0020.c b/trunk/arch/arm/mach-omap2/board-igep0020.c index 930c0d380435..e558800adfdf 100644 --- a/trunk/arch/arm/mach-omap2/board-igep0020.c +++ b/trunk/arch/arm/mach-omap2/board-igep0020.c @@ -634,14 +634,8 @@ static void __init igep_wlan_bt_init(void) static inline void __init igep_wlan_bt_init(void) { } #endif -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x.0"), - REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), -}; - static void __init igep_init(void) { - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); /* Get IGEP2 hardware revision */ diff --git a/trunk/arch/arm/mach-omap2/board-ldp.c b/trunk/arch/arm/mach-omap2/board-ldp.c index 1b6049567ab4..d50a562adfa0 100644 --- a/trunk/arch/arm/mach-omap2/board-ldp.c +++ b/trunk/arch/arm/mach-omap2/board-ldp.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -411,14 +410,8 @@ static struct mtd_partition ldp_nand_partitions[] = { }; -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x.0"), - REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), -}; - static void __init omap_ldp_init(void) { - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); ldp_init_smsc911x(); omap_i2c_init(); diff --git a/trunk/arch/arm/mach-omap2/board-omap3evm.c b/trunk/arch/arm/mach-omap2/board-omap3evm.c index 49df12735b41..4c90f078abe1 100644 --- a/trunk/arch/arm/mach-omap2/board-omap3evm.c +++ b/trunk/arch/arm/mach-omap2/board-omap3evm.c @@ -114,6 +114,15 @@ static struct omap_smsc911x_platform_data smsc911x_cfg = { static inline void __init omap3evm_init_smsc911x(void) { + struct clk *l3ck; + unsigned int rate; + + l3ck = clk_get(NULL, "l3_ck"); + if (IS_ERR(l3ck)) + rate = 100000000; + else + rate = clk_get_rate(l3ck); + /* Configure ethernet controller reset gpio */ if (cpu_is_omap3430()) { if (get_omap3_evm_rev() == OMAP3EVM_BOARD_GEN_1) @@ -623,15 +632,9 @@ static void __init omap3_evm_wl12xx_init(void) #endif } -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x.0"), - REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), -}; - static void __init omap3_evm_init(void) { omap3_evm_get_revision(); - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); if (cpu_is_omap3630()) omap3_mux_init(omap36x_board_mux, OMAP_PACKAGE_CBB); diff --git a/trunk/arch/arm/mach-omap2/board-omap3logic.c b/trunk/arch/arm/mach-omap2/board-omap3logic.c index 9b3c141ff51b..4a7d8c8a75da 100644 --- a/trunk/arch/arm/mach-omap2/board-omap3logic.c +++ b/trunk/arch/arm/mach-omap2/board-omap3logic.c @@ -23,7 +23,6 @@ #include #include -#include #include #include @@ -189,14 +188,8 @@ static struct omap_board_mux board_mux[] __initdata = { }; #endif -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x.0"), - REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), -}; - static void __init omap3logic_init(void) { - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); omap3torpedo_fix_pbias_voltage(); omap3logic_i2c_init(); diff --git a/trunk/arch/arm/mach-omap2/board-omap3stalker.c b/trunk/arch/arm/mach-omap2/board-omap3stalker.c index 4dffc95bddd2..641004380795 100644 --- a/trunk/arch/arm/mach-omap2/board-omap3stalker.c +++ b/trunk/arch/arm/mach-omap2/board-omap3stalker.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -73,6 +72,15 @@ static struct omap_smsc911x_platform_data smsc911x_cfg = { static inline void __init omap3stalker_init_eth(void) { + struct clk *l3ck; + unsigned int rate; + + l3ck = clk_get(NULL, "l3_ck"); + if (IS_ERR(l3ck)) + rate = 100000000; + else + rate = clk_get_rate(l3ck); + omap_mux_init_gpio(19, OMAP_PIN_INPUT_PULLUP); gpmc_smsc911x_init(&smsc911x_cfg); } @@ -411,14 +419,8 @@ static struct omap_board_mux board_mux[] __initdata = { }; #endif -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x.0"), - REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), -}; - static void __init omap3_stalker_init(void) { - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); omap3_mux_init(board_mux, OMAP_PACKAGE_CUS); omap_board_config = omap3_stalker_config; omap_board_config_size = ARRAY_SIZE(omap3_stalker_config); diff --git a/trunk/arch/arm/mach-omap2/board-omap4panda.c b/trunk/arch/arm/mach-omap2/board-omap4panda.c index 1b782ba53433..d8c0e89f0126 100644 --- a/trunk/arch/arm/mach-omap2/board-omap4panda.c +++ b/trunk/arch/arm/mach-omap2/board-omap4panda.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -285,7 +284,7 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) return 0; } -static struct twl6040_codec_data twl6040_codec = { +static struct twl4030_codec_data twl6040_codec = { /* single-step ramp for headset and handsfree */ .hs_left_step = 0x0f, .hs_right_step = 0x0f, @@ -293,14 +292,17 @@ static struct twl6040_codec_data twl6040_codec = { .hf_right_step = 0x1d, }; -static struct twl6040_platform_data twl6040_data = { +static struct twl4030_audio_data twl6040_audio = { .codec = &twl6040_codec, .audpwron_gpio = 127, + .naudint_irq = OMAP44XX_IRQ_SYS_2N, .irq_base = TWL6040_CODEC_IRQ_BASE, }; /* Panda board uses the common PMIC configuration */ -static struct twl4030_platform_data omap4_panda_twldata; +static struct twl4030_platform_data omap4_panda_twldata = { + .audio = &twl6040_audio, +}; /* * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM @@ -324,8 +326,7 @@ static int __init omap4_panda_i2c_init(void) TWL_COMMON_REGULATOR_VCXIO | TWL_COMMON_REGULATOR_VUSB | TWL_COMMON_REGULATOR_CLK32KG); - omap4_pmic_init("twl6030", &omap4_panda_twldata, - &twl6040_data, OMAP44XX_IRQ_SYS_2N); + omap4_pmic_init("twl6030", &omap4_panda_twldata); omap_register_i2c_bus(2, 400, NULL, 0); /* * Bus 3 is attached to the DVI port where devices like the pico DLP diff --git a/trunk/arch/arm/mach-omap2/board-overo.c b/trunk/arch/arm/mach-omap2/board-overo.c index 33aa3910b09e..668533e2a379 100644 --- a/trunk/arch/arm/mach-omap2/board-overo.c +++ b/trunk/arch/arm/mach-omap2/board-overo.c @@ -498,18 +498,10 @@ static struct gpio overo_bt_gpios[] __initdata = { { OVERO_GPIO_BT_NRESET, GPIOF_OUT_INIT_HIGH, "lcd bl enable" }, }; -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x.0"), - REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), - REGULATOR_SUPPLY("vddvario", "smsc911x.1"), - REGULATOR_SUPPLY("vdd33a", "smsc911x.1"), -}; - static void __init overo_init(void) { int ret; - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); omap_hsmmc_init(mmc); overo_i2c_init(); diff --git a/trunk/arch/arm/mach-omap2/board-zoom-debugboard.c b/trunk/arch/arm/mach-omap2/board-zoom-debugboard.c index f64f44173061..1e8540eabde9 100644 --- a/trunk/arch/arm/mach-omap2/board-zoom-debugboard.c +++ b/trunk/arch/arm/mach-omap2/board-zoom-debugboard.c @@ -14,9 +14,6 @@ #include #include -#include -#include - #include #include @@ -120,17 +117,11 @@ static struct platform_device *zoom_devices[] __initdata = { &zoom_debugboard_serial_device, }; -static struct regulator_consumer_supply dummy_supplies[] = { - REGULATOR_SUPPLY("vddvario", "smsc911x.0"), - REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), -}; - int __init zoom_debugboard_init(void) { if (!omap_zoom_debugboard_detect()) return 0; - regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); zoom_init_smsc911x(); zoom_init_quaduart(); return platform_add_devices(zoom_devices, ARRAY_SIZE(zoom_devices)); diff --git a/trunk/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/trunk/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c index 3d9d746b221a..7072e0d651b1 100644 --- a/trunk/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c +++ b/trunk/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c @@ -165,3 +165,83 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate) return 0; } + +#ifdef CONFIG_CPU_FREQ +/* + * Walk PRCM rate table and fillout cpufreq freq_table + * XXX This should be replaced by an OPP layer in the near future + */ +static struct cpufreq_frequency_table *freq_table; + +void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table) +{ + const struct prcm_config *prcm; + int i = 0; + int tbl_sz = 0; + + if (!cpu_is_omap24xx()) + return; + + for (prcm = rate_table; prcm->mpu_speed; prcm++) { + if (!(prcm->flags & cpu_mask)) + continue; + if (prcm->xtal_speed != sclk->rate) + continue; + + /* don't put bypass rates in table */ + if (prcm->dpll_speed == prcm->xtal_speed) + continue; + + tbl_sz++; + } + + /* + * XXX Ensure that we're doing what CPUFreq expects for this error + * case and the following one + */ + if (tbl_sz == 0) { + pr_warning("%s: no matching entries in rate_table\n", + __func__); + return; + } + + /* Include the CPUFREQ_TABLE_END terminator entry */ + tbl_sz++; + + freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * tbl_sz, + GFP_ATOMIC); + if (!freq_table) { + pr_err("%s: could not kzalloc frequency table\n", __func__); + return; + } + + for (prcm = rate_table; prcm->mpu_speed; prcm++) { + if (!(prcm->flags & cpu_mask)) + continue; + if (prcm->xtal_speed != sclk->rate) + continue; + + /* don't put bypass rates in table */ + if (prcm->dpll_speed == prcm->xtal_speed) + continue; + + freq_table[i].index = i; + freq_table[i].frequency = prcm->mpu_speed / 1000; + i++; + } + + freq_table[i].index = i; + freq_table[i].frequency = CPUFREQ_TABLE_END; + + *table = &freq_table[0]; +} + +void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) +{ + if (!cpu_is_omap24xx()) + return; + + kfree(freq_table); +} + +#endif diff --git a/trunk/arch/arm/mach-omap2/clock.c b/trunk/arch/arm/mach-omap2/clock.c index d9f4931513f9..f57ed5baeccf 100644 --- a/trunk/arch/arm/mach-omap2/clock.c +++ b/trunk/arch/arm/mach-omap2/clock.c @@ -536,5 +536,10 @@ struct clk_functions omap2_clk_functions = { .clk_set_rate = omap2_clk_set_rate, .clk_set_parent = omap2_clk_set_parent, .clk_disable_unused = omap2_clk_disable_unused, +#ifdef CONFIG_CPU_FREQ + /* These will be removed when the OPP code is integrated */ + .clk_init_cpufreq_table = omap2_clk_init_cpufreq_table, + .clk_exit_cpufreq_table = omap2_clk_exit_cpufreq_table, +#endif }; diff --git a/trunk/arch/arm/mach-omap2/clock.h b/trunk/arch/arm/mach-omap2/clock.h index a1bb23a23351..b8c2a686481c 100644 --- a/trunk/arch/arm/mach-omap2/clock.h +++ b/trunk/arch/arm/mach-omap2/clock.h @@ -146,6 +146,14 @@ extern const struct clksel_rate gpt_sys_rates[]; extern const struct clksel_rate gfx_l3_rates[]; extern const struct clksel_rate dsp_ick_rates[]; +#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ) +extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table); +extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table); +#else +#define omap2_clk_init_cpufreq_table 0 +#define omap2_clk_exit_cpufreq_table 0 +#endif + extern const struct clkops clkops_omap2_iclk_dflt_wait; extern const struct clkops clkops_omap2_iclk_dflt; extern const struct clkops clkops_omap2_iclk_idle_only; diff --git a/trunk/arch/arm/mach-omap2/clock3xxx_data.c b/trunk/arch/arm/mach-omap2/clock3xxx_data.c index f4a626f7c79e..480fb8f09aed 100644 --- a/trunk/arch/arm/mach-omap2/clock3xxx_data.c +++ b/trunk/arch/arm/mach-omap2/clock3xxx_data.c @@ -747,7 +747,7 @@ static struct clk dpll4_m3_ck = { .parent = &dpll4_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL), - .clksel_mask = OMAP3630_CLKSEL_TV_MASK, + .clksel_mask = OMAP3430_CLKSEL_TV_MASK, .clksel = dpll4_clksel, .clkdm_name = "dpll4_clkdm", .recalc = &omap2_clksel_recalc, @@ -832,7 +832,7 @@ static struct clk dpll4_m4_ck = { .parent = &dpll4_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL), - .clksel_mask = OMAP3630_CLKSEL_DSS1_MASK, + .clksel_mask = OMAP3430_CLKSEL_DSS1_MASK, .clksel = dpll4_clksel, .clkdm_name = "dpll4_clkdm", .recalc = &omap2_clksel_recalc, @@ -859,7 +859,7 @@ static struct clk dpll4_m5_ck = { .parent = &dpll4_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL), - .clksel_mask = OMAP3630_CLKSEL_CAM_MASK, + .clksel_mask = OMAP3430_CLKSEL_CAM_MASK, .clksel = dpll4_clksel, .clkdm_name = "dpll4_clkdm", .set_rate = &omap2_clksel_set_rate, @@ -886,7 +886,7 @@ static struct clk dpll4_m6_ck = { .parent = &dpll4_ck, .init = &omap2_init_clksel_parent, .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1), - .clksel_mask = OMAP3630_DIV_DPLL4_MASK, + .clksel_mask = OMAP3430_DIV_DPLL4_MASK, .clksel = dpll4_clksel, .clkdm_name = "dpll4_clkdm", .recalc = &omap2_clksel_recalc, @@ -1394,7 +1394,6 @@ static struct clk cpefuse_fck = { .name = "cpefuse_fck", .ops = &clkops_omap2_dflt, .parent = &sys_ck, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3), .enable_bit = OMAP3430ES2_EN_CPEFUSE_SHIFT, .recalc = &followparent_recalc, @@ -1404,7 +1403,6 @@ static struct clk ts_fck = { .name = "ts_fck", .ops = &clkops_omap2_dflt, .parent = &omap_32k_fck, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3), .enable_bit = OMAP3430ES2_EN_TS_SHIFT, .recalc = &followparent_recalc, @@ -1414,7 +1412,6 @@ static struct clk usbtll_fck = { .name = "usbtll_fck", .ops = &clkops_omap2_dflt_wait, .parent = &dpll5_m2_ck, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3), .enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT, .recalc = &followparent_recalc, @@ -1620,7 +1617,6 @@ static struct clk fshostusb_fck = { .name = "fshostusb_fck", .ops = &clkops_omap2_dflt_wait, .parent = &core_48m_fck, - .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430ES1_EN_FSHOSTUSB_SHIFT, .recalc = &followparent_recalc, @@ -2047,7 +2043,6 @@ static struct clk omapctrl_ick = { .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), .enable_bit = OMAP3430_EN_OMAPCTRL_SHIFT, .flags = ENABLE_ON_INIT, - .clkdm_name = "core_l4_clkdm", .recalc = &followparent_recalc, }; @@ -2099,7 +2094,6 @@ static struct clk usb_l4_ick = { .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), .clksel_mask = OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK, .clksel = usb_l4_clksel, - .clkdm_name = "core_l4_clkdm", .recalc = &omap2_clksel_recalc, }; @@ -3473,8 +3467,8 @@ static struct omap_clk omap3xxx_clks[] = { CLK(NULL, "ipss_ick", &ipss_ick, CK_AM35XX), CLK(NULL, "rmii_ck", &rmii_ck, CK_AM35XX), CLK(NULL, "pclk_ck", &pclk_ck, CK_AM35XX), - CLK("davinci_emac", NULL, &emac_ick, CK_AM35XX), - CLK("davinci_mdio.0", NULL, &emac_fck, CK_AM35XX), + CLK("davinci_emac", "emac_clk", &emac_ick, CK_AM35XX), + CLK("davinci_emac", "phy_clk", &emac_fck, CK_AM35XX), CLK("vpfe-capture", "master", &vpfe_ick, CK_AM35XX), CLK("vpfe-capture", "slave", &vpfe_fck, CK_AM35XX), CLK("musb-am35x", "ick", &hsotgusb_ick_am35xx, CK_AM35XX), diff --git a/trunk/arch/arm/mach-omap2/clock44xx_data.c b/trunk/arch/arm/mach-omap2/clock44xx_data.c index fa6ea65ad44b..c03c1108468e 100644 --- a/trunk/arch/arm/mach-omap2/clock44xx_data.c +++ b/trunk/arch/arm/mach-omap2/clock44xx_data.c @@ -957,8 +957,8 @@ static struct dpll_data dpll_usb_dd = { .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_USB, .idlest_reg = OMAP4430_CM_IDLEST_DPLL_USB, - .mult_mask = OMAP4430_DPLL_MULT_USB_MASK, - .div1_mask = OMAP4430_DPLL_DIV_0_7_MASK, + .mult_mask = OMAP4430_DPLL_MULT_MASK, + .div1_mask = OMAP4430_DPLL_DIV_MASK, .enable_mask = OMAP4430_DPLL_EN_MASK, .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK, .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK, @@ -978,7 +978,6 @@ static struct clk dpll_usb_ck = { .recalc = &omap3_dpll_recalc, .round_rate = &omap2_dpll_round_rate, .set_rate = &omap3_noncore_dpll_set_rate, - .clkdm_name = "l3_init_clkdm", }; static struct clk dpll_usb_clkdcoldo_ck = { diff --git a/trunk/arch/arm/mach-omap2/clockdomains44xx_data.c b/trunk/arch/arm/mach-omap2/clockdomains44xx_data.c index bd7ed13515cc..9299ac291d28 100644 --- a/trunk/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/trunk/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -390,7 +390,7 @@ static struct clockdomain emu_sys_44xx_clkdm = { .prcm_partition = OMAP4430_PRM_PARTITION, .cm_inst = OMAP4430_PRM_EMU_CM_INST, .clkdm_offs = OMAP4430_PRM_EMU_CM_EMU_CDOFFS, - .flags = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_FORCE_WAKEUP, + .flags = CLKDM_CAN_HWSUP, }; static struct clockdomain l3_dma_44xx_clkdm = { diff --git a/trunk/arch/arm/mach-omap2/cpuidle34xx.c b/trunk/arch/arm/mach-omap2/cpuidle34xx.c index 535866489ce3..464cffde58fe 100644 --- a/trunk/arch/arm/mach-omap2/cpuidle34xx.c +++ b/trunk/arch/arm/mach-omap2/cpuidle34xx.c @@ -87,14 +87,29 @@ static int _cpuidle_deny_idle(struct powerdomain *pwrdm, return 0; } -static int __omap3_enter_idle(struct cpuidle_device *dev, +/** + * omap3_enter_idle - Programs OMAP3 to enter the specified state + * @dev: cpuidle device + * @drv: cpuidle driver + * @index: the index of state to be entered + * + * Called from the CPUidle framework to program the device to the + * specified target state selected by the governor. + */ +static int omap3_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct omap3_idle_statedata *cx = cpuidle_get_statedata(&dev->states_usage[index]); + struct timespec ts_preidle, ts_postidle, ts_idle; u32 mpu_state = cx->mpu_state, core_state = cx->core_state; + int idle_time; + + /* Used to keep track of the total time in idle */ + getnstimeofday(&ts_preidle); + local_irq_disable(); local_fiq_disable(); pwrdm_set_next_pwrst(mpu_pd, mpu_state); @@ -133,26 +148,19 @@ static int __omap3_enter_idle(struct cpuidle_device *dev, } return_sleep_time: + getnstimeofday(&ts_postidle); + ts_idle = timespec_sub(ts_postidle, ts_preidle); + local_irq_enable(); local_fiq_enable(); - return index; -} + idle_time = ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * \ + USEC_PER_SEC; -/** - * omap3_enter_idle - Programs OMAP3 to enter the specified state - * @dev: cpuidle device - * @drv: cpuidle driver - * @index: the index of state to be entered - * - * Called from the CPUidle framework to program the device to the - * specified target state selected by the governor. - */ -static inline int omap3_enter_idle(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - return cpuidle_wrap_enter(dev, drv, index, __omap3_enter_idle); + /* Update cpuidle counters */ + dev->last_residency = idle_time; + + return index; } /** diff --git a/trunk/arch/arm/mach-omap2/cpuidle44xx.c b/trunk/arch/arm/mach-omap2/cpuidle44xx.c index f386cbe9c889..72e018b9b260 100644 --- a/trunk/arch/arm/mach-omap2/cpuidle44xx.c +++ b/trunk/arch/arm/mach-omap2/cpuidle44xx.c @@ -62,9 +62,15 @@ static int omap4_enter_idle(struct cpuidle_device *dev, { struct omap4_idle_statedata *cx = cpuidle_get_statedata(&dev->states_usage[index]); + struct timespec ts_preidle, ts_postidle, ts_idle; u32 cpu1_state; + int idle_time; int cpu_id = smp_processor_id(); + /* Used to keep track of the total time in idle */ + getnstimeofday(&ts_preidle); + + local_irq_disable(); local_fiq_disable(); /* @@ -122,17 +128,26 @@ static int omap4_enter_idle(struct cpuidle_device *dev, if (index > 0) clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id); + getnstimeofday(&ts_postidle); + ts_idle = timespec_sub(ts_postidle, ts_preidle); + + local_irq_enable(); local_fiq_enable(); + idle_time = ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * \ + USEC_PER_SEC; + + /* Update cpuidle counters */ + dev->last_residency = idle_time; + return index; } DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev); struct cpuidle_driver omap4_idle_driver = { - .name = "omap4_idle", - .owner = THIS_MODULE, - .en_core_tk_irqen = 1, + .name = "omap4_idle", + .owner = THIS_MODULE, }; static inline void _fill_cstate(struct cpuidle_driver *drv, diff --git a/trunk/arch/arm/mach-omap2/gpmc-smsc911x.c b/trunk/arch/arm/mach-omap2/gpmc-smsc911x.c index b6c77be3e8f7..5e5880d6d099 100644 --- a/trunk/arch/arm/mach-omap2/gpmc-smsc911x.c +++ b/trunk/arch/arm/mach-omap2/gpmc-smsc911x.c @@ -19,11 +19,15 @@ #include #include #include +#include +#include #include #include #include +static struct omap_smsc911x_platform_data *gpmc_cfg; + static struct resource gpmc_smsc911x_resources[] = { [0] = { .flags = IORESOURCE_MEM, @@ -37,6 +41,51 @@ static struct smsc911x_platform_config gpmc_smsc911x_config = { .phy_interface = PHY_INTERFACE_MODE_MII, .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .flags = SMSC911X_USE_16BIT, +}; + +static struct regulator_consumer_supply gpmc_smsc911x_supply[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x.0"), + REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), +}; + +/* Generic regulator definition to satisfy smsc911x */ +static struct regulator_init_data gpmc_smsc911x_reg_init_data = { + .constraints = { + .min_uV = 3300000, + .max_uV = 3300000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(gpmc_smsc911x_supply), + .consumer_supplies = gpmc_smsc911x_supply, +}; + +static struct fixed_voltage_config gpmc_smsc911x_fixed_reg_data = { + .supply_name = "gpmc_smsc911x", + .microvolts = 3300000, + .gpio = -EINVAL, + .startup_delay = 0, + .enable_high = 0, + .enabled_at_boot = 1, + .init_data = &gpmc_smsc911x_reg_init_data, +}; + +/* + * Platform device id of 42 is a temporary fix to avoid conflicts + * with other reg-fixed-voltage devices. The real fix should + * involve the driver core providing a way of dynamically + * assigning a unique id on registration for platform devices + * in the same name space. + */ +static struct platform_device gpmc_smsc911x_regulator = { + .name = "reg-fixed-voltage", + .id = 42, + .dev = { + .platform_data = &gpmc_smsc911x_fixed_reg_data, + }, }; /* @@ -44,12 +93,23 @@ static struct smsc911x_platform_config gpmc_smsc911x_config = { * assume that pin multiplexing is done in the board-*.c file, * or in the bootloader. */ -void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *gpmc_cfg) +void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *board_data) { struct platform_device *pdev; unsigned long cs_mem_base; int ret; + gpmc_cfg = board_data; + + if (!gpmc_cfg->id) { + ret = platform_device_register(&gpmc_smsc911x_regulator); + if (ret < 0) { + pr_err("Unable to register smsc911x regulators: %d\n", + ret); + return; + } + } + if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) { pr_err("Failed to request GPMC mem region\n"); return; @@ -79,7 +139,8 @@ void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *gpmc_cfg) gpio_set_value(gpmc_cfg->gpio_reset, 1); } - gpmc_smsc911x_config.flags = gpmc_cfg->flags ? : SMSC911X_USE_16BIT; + if (gpmc_cfg->flags) + gpmc_smsc911x_config.flags = gpmc_cfg->flags; pdev = platform_device_register_resndata(NULL, "smsc911x", gpmc_cfg->id, gpmc_smsc911x_resources, ARRAY_SIZE(gpmc_smsc911x_resources), diff --git a/trunk/arch/arm/mach-omap2/hsmmc.c b/trunk/arch/arm/mach-omap2/hsmmc.c index b0268eaffe13..100db6217f39 100644 --- a/trunk/arch/arm/mach-omap2/hsmmc.c +++ b/trunk/arch/arm/mach-omap2/hsmmc.c @@ -506,13 +506,6 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo, if (oh->dev_attr != NULL) { mmc_dev_attr = oh->dev_attr; mmc_data->controller_flags = mmc_dev_attr->flags; - /* - * erratum 2.1.1.128 doesn't apply if board has - * a transceiver is attached - */ - if (hsmmcinfo->transceiver) - mmc_data->controller_flags &= - ~OMAP_HSMMC_BROKEN_MULTIBLOCK_READ; } pdev = platform_device_alloc(name, ctrl_nr - 1); diff --git a/trunk/arch/arm/mach-omap2/include/mach/barriers.h b/trunk/arch/arm/mach-omap2/include/mach/barriers.h index 1c582a8592b9..4fa72c7cc7cd 100644 --- a/trunk/arch/arm/mach-omap2/include/mach/barriers.h +++ b/trunk/arch/arm/mach-omap2/include/mach/barriers.h @@ -22,8 +22,6 @@ #ifndef __MACH_BARRIERS_H #define __MACH_BARRIERS_H -#include - extern void omap_bus_sync(void); #define rmb() dsb() diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod.c b/trunk/arch/arm/mach-omap2/omap_hwmod.c index 7144ae651d3d..eba6cd3816f5 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod.c @@ -1395,7 +1395,7 @@ static int _read_hardreset(struct omap_hwmod *oh, const char *name) */ static int _ocp_softreset(struct omap_hwmod *oh) { - u32 v, softrst_mask; + u32 v; int c = 0; int ret = 0; @@ -1422,21 +1422,16 @@ static int _ocp_softreset(struct omap_hwmod *oh) goto dis_opt_clks; _write_sysconfig(v, oh); - if (oh->class->sysc->srst_udelay) - udelay(oh->class->sysc->srst_udelay); - if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS) omap_test_timeout((omap_hwmod_read(oh, oh->class->sysc->syss_offs) & SYSS_RESETDONE_MASK), MAX_MODULE_SOFTRESET_WAIT, c); - else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { - softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift); + else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) omap_test_timeout(!(omap_hwmod_read(oh, oh->class->sysc->sysc_offs) - & softrst_mask), + & SYSC_TYPE2_SOFTRESET_MASK), MAX_MODULE_SOFTRESET_WAIT, c); - } if (c == MAX_MODULE_SOFTRESET_WAIT) pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", @@ -1482,11 +1477,6 @@ static int _reset(struct omap_hwmod *oh) ret = (oh->class->reset) ? oh->class->reset(oh) : _ocp_softreset(oh); - if (oh->class->sysc) { - _update_sysc_cache(oh); - _enable_sysc(oh); - } - return ret; } @@ -1796,9 +1786,20 @@ static int _setup(struct omap_hwmod *oh, void *data) return 0; } - if (!(oh->flags & HWMOD_INIT_NO_RESET)) + if (!(oh->flags & HWMOD_INIT_NO_RESET)) { _reset(oh); + /* + * OCP_SYSCONFIG bits need to be reprogrammed after a softreset. + * The _enable() function should be split to + * avoid the rewrite of the OCP_SYSCONFIG register. + */ + if (oh->class->sysc) { + _update_sysc_cache(oh); + _enable_sysc(oh); + } + } + postsetup_state = oh->_postsetup_state; if (postsetup_state == _HWMOD_STATE_UNKNOWN) postsetup_state = _HWMOD_STATE_ENABLED; @@ -2462,28 +2463,26 @@ int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh, * @oh: struct omap_hwmod * * * Sets the module OCP socket ENAWAKEUP bit to allow the module to - * send wakeups to the PRCM, and enable I/O ring wakeup events for - * this IP block if it has dynamic mux entries. Eventually this - * should set PRCM wakeup registers to cause the PRCM to receive - * wakeup events from the module. Does not set any wakeup routing - * registers beyond this point - if the module is to wake up any other - * module or subsystem, that must be set separately. Called by - * omap_device code. Returns -EINVAL on error or 0 upon success. + * send wakeups to the PRCM. Eventually this should sets PRCM wakeup + * registers to cause the PRCM to receive wakeup events from the + * module. Does not set any wakeup routing registers beyond this + * point - if the module is to wake up any other module or subsystem, + * that must be set separately. Called by omap_device code. Returns + * -EINVAL on error or 0 upon success. */ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh) { unsigned long flags; u32 v; - spin_lock_irqsave(&oh->_lock, flags); - - if (oh->class->sysc && - (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) { - v = oh->_sysc_cache; - _enable_wakeup(oh, &v); - _write_sysconfig(v, oh); - } + if (!oh->class->sysc || + !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) + return -EINVAL; + spin_lock_irqsave(&oh->_lock, flags); + v = oh->_sysc_cache; + _enable_wakeup(oh, &v); + _write_sysconfig(v, oh); _set_idle_ioring_wakeup(oh, true); spin_unlock_irqrestore(&oh->_lock, flags); @@ -2495,28 +2494,26 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh) * @oh: struct omap_hwmod * * * Clears the module OCP socket ENAWAKEUP bit to prevent the module - * from sending wakeups to the PRCM, and disable I/O ring wakeup - * events for this IP block if it has dynamic mux entries. Eventually - * this should clear PRCM wakeup registers to cause the PRCM to ignore - * wakeup events from the module. Does not set any wakeup routing - * registers beyond this point - if the module is to wake up any other - * module or subsystem, that must be set separately. Called by - * omap_device code. Returns -EINVAL on error or 0 upon success. + * from sending wakeups to the PRCM. Eventually this should clear + * PRCM wakeup registers to cause the PRCM to ignore wakeup events + * from the module. Does not set any wakeup routing registers beyond + * this point - if the module is to wake up any other module or + * subsystem, that must be set separately. Called by omap_device + * code. Returns -EINVAL on error or 0 upon success. */ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh) { unsigned long flags; u32 v; - spin_lock_irqsave(&oh->_lock, flags); - - if (oh->class->sysc && - (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) { - v = oh->_sysc_cache; - _disable_wakeup(oh, &v); - _write_sysconfig(v, oh); - } + if (!oh->class->sysc || + !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) + return -EINVAL; + spin_lock_irqsave(&oh->_lock, flags); + v = oh->_sysc_cache; + _disable_wakeup(oh, &v); + _write_sysconfig(v, oh); _set_idle_ioring_wakeup(oh, false); spin_unlock_irqrestore(&oh->_lock, flags); diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_2420_data.c index a6bde34e443a..a5409ce3f323 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -1000,6 +1000,7 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__dss_venc = { .flags = OMAP_FIREWALL_L4, } }, + .flags = OCPIF_SWSUP_IDLE, .user = OCP_USER_MPU | OCP_USER_SDMA, }; diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_2430_data.c index 04a3885f4475..c4f56cb60d7d 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -1049,6 +1049,7 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__dss_venc = { .slave = &omap2430_dss_venc_hwmod, .clk = "dss_ick", .addr = omap2_dss_venc_addrs, + .flags = OCPIF_SWSUP_IDLE, .user = OCP_USER_MPU | OCP_USER_SDMA, }; diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index db86ce90c69f..34b9766d1d23 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1676,6 +1676,7 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_venc = { .flags = OMAP_FIREWALL_L4, } }, + .flags = OCPIF_SWSUP_IDLE, .user = OCP_USER_MPU | OCP_USER_SDMA, }; diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 6abc75753e42..08daa5e0eb5f 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -2594,15 +2594,6 @@ static struct omap_hwmod omap44xx_ipu_hwmod = { static struct omap_hwmod_class_sysconfig omap44xx_iss_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - /* - * ISS needs 100 OCP clk cycles delay after a softreset before - * accessing sysconfig again. - * The lowest frequency at the moment for L3 bus is 100 MHz, so - * 1usec delay is needed. Add an x2 margin to be safe (2 usecs). - * - * TODO: Indicate errata when available. - */ - .srst_udelay = 2, .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | @@ -3005,11 +2996,6 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp1_slaves[] = { &omap44xx_l4_abe__mcbsp1_dma, }; -static struct omap_hwmod_opt_clk mcbsp1_opt_clks[] = { - { .role = "pad_fck", .clk = "pad_clks_ck" }, - { .role = "prcm_clk", .clk = "mcbsp1_sync_mux_ck" }, -}; - static struct omap_hwmod omap44xx_mcbsp1_hwmod = { .name = "mcbsp1", .class = &omap44xx_mcbsp_hwmod_class, @@ -3026,8 +3012,6 @@ static struct omap_hwmod omap44xx_mcbsp1_hwmod = { }, .slaves = omap44xx_mcbsp1_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp1_slaves), - .opt_clks = mcbsp1_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(mcbsp1_opt_clks), }; /* mcbsp2 */ @@ -3087,11 +3071,6 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp2_slaves[] = { &omap44xx_l4_abe__mcbsp2_dma, }; -static struct omap_hwmod_opt_clk mcbsp2_opt_clks[] = { - { .role = "pad_fck", .clk = "pad_clks_ck" }, - { .role = "prcm_clk", .clk = "mcbsp2_sync_mux_ck" }, -}; - static struct omap_hwmod omap44xx_mcbsp2_hwmod = { .name = "mcbsp2", .class = &omap44xx_mcbsp_hwmod_class, @@ -3108,8 +3087,6 @@ static struct omap_hwmod omap44xx_mcbsp2_hwmod = { }, .slaves = omap44xx_mcbsp2_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp2_slaves), - .opt_clks = mcbsp2_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(mcbsp2_opt_clks), }; /* mcbsp3 */ @@ -3169,11 +3146,6 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp3_slaves[] = { &omap44xx_l4_abe__mcbsp3_dma, }; -static struct omap_hwmod_opt_clk mcbsp3_opt_clks[] = { - { .role = "pad_fck", .clk = "pad_clks_ck" }, - { .role = "prcm_clk", .clk = "mcbsp3_sync_mux_ck" }, -}; - static struct omap_hwmod omap44xx_mcbsp3_hwmod = { .name = "mcbsp3", .class = &omap44xx_mcbsp_hwmod_class, @@ -3190,8 +3162,6 @@ static struct omap_hwmod omap44xx_mcbsp3_hwmod = { }, .slaves = omap44xx_mcbsp3_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp3_slaves), - .opt_clks = mcbsp3_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(mcbsp3_opt_clks), }; /* mcbsp4 */ @@ -3230,11 +3200,6 @@ static struct omap_hwmod_ocp_if *omap44xx_mcbsp4_slaves[] = { &omap44xx_l4_per__mcbsp4, }; -static struct omap_hwmod_opt_clk mcbsp4_opt_clks[] = { - { .role = "pad_fck", .clk = "pad_clks_ck" }, - { .role = "prcm_clk", .clk = "mcbsp4_sync_mux_ck" }, -}; - static struct omap_hwmod omap44xx_mcbsp4_hwmod = { .name = "mcbsp4", .class = &omap44xx_mcbsp_hwmod_class, @@ -3251,8 +3216,6 @@ static struct omap_hwmod omap44xx_mcbsp4_hwmod = { }, .slaves = omap44xx_mcbsp4_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp4_slaves), - .opt_clks = mcbsp4_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(mcbsp4_opt_clks), }; /* diff --git a/trunk/arch/arm/mach-omap2/opp.c b/trunk/arch/arm/mach-omap2/opp.c index de6d46451746..9262a6b47702 100644 --- a/trunk/arch/arm/mach-omap2/opp.c +++ b/trunk/arch/arm/mach-omap2/opp.c @@ -64,10 +64,10 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def, } oh = omap_hwmod_lookup(opp_def->hwmod_name); if (!oh || !oh->od) { - pr_debug("%s: no hwmod or odev for %s, [%d] " + pr_warn("%s: no hwmod or odev for %s, [%d] " "cannot add OPPs.\n", __func__, opp_def->hwmod_name, i); - continue; + return -EINVAL; } dev = &oh->od->pdev->dev; diff --git a/trunk/arch/arm/mach-omap2/pm34xx.c b/trunk/arch/arm/mach-omap2/pm34xx.c index 703bd1099259..238defc6f6df 100644 --- a/trunk/arch/arm/mach-omap2/pm34xx.c +++ b/trunk/arch/arm/mach-omap2/pm34xx.c @@ -153,7 +153,8 @@ static void omap3_save_secure_ram_context(void) pwrdm_set_next_pwrst(mpu_pwrdm, mpu_next_state); /* Following is for error tracking, it should not happen */ if (ret) { - pr_err("save_secure_sram() returns %08x\n", ret); + printk(KERN_ERR "save_secure_sram() returns %08x\n", + ret); while (1) ; } @@ -288,7 +289,7 @@ void omap_sram_idle(void) break; default: /* Invalid state */ - pr_err("Invalid mpu state in sram_idle\n"); + printk(KERN_ERR "Invalid mpu state in sram_idle\n"); return; } @@ -438,17 +439,18 @@ static int omap3_pm_suspend(void) list_for_each_entry(pwrst, &pwrst_list, node) { state = pwrdm_read_prev_pwrst(pwrst->pwrdm); if (state > pwrst->next_state) { - pr_info("Powerdomain (%s) didn't enter " - "target state %d\n", + printk(KERN_INFO "Powerdomain (%s) didn't enter " + "target state %d\n", pwrst->pwrdm->name, pwrst->next_state); ret = -1; } omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); } if (ret) - pr_err("Could not enter target state in pm_suspend\n"); + printk(KERN_ERR "Could not enter target state in pm_suspend\n"); else - pr_info("Successfully put all powerdomains to target state\n"); + printk(KERN_INFO "Successfully put all powerdomains " + "to target state\n"); return ret; } @@ -732,22 +734,21 @@ static int __init omap3_pm_init(void) if (ret) { pr_err("pm: Failed to request pm_io irq\n"); - goto err2; + goto err1; } ret = pwrdm_for_each(pwrdms_setup, NULL); if (ret) { - pr_err("Failed to setup powerdomains\n"); - goto err3; + printk(KERN_ERR "Failed to setup powerdomains\n"); + goto err2; } (void) clkdm_for_each(omap_pm_clkdms_setup, NULL); mpu_pwrdm = pwrdm_lookup("mpu_pwrdm"); if (mpu_pwrdm == NULL) { - pr_err("Failed to get mpu_pwrdm\n"); - ret = -EINVAL; - goto err3; + printk(KERN_ERR "Failed to get mpu_pwrdm\n"); + goto err2; } neon_pwrdm = pwrdm_lookup("neon_pwrdm"); @@ -780,8 +781,8 @@ static int __init omap3_pm_init(void) omap3_secure_ram_storage = kmalloc(0x803F, GFP_KERNEL); if (!omap3_secure_ram_storage) - pr_err("Memory allocation failed when " - "allocating for secure sram context\n"); + printk(KERN_ERR "Memory allocation failed when" + "allocating for secure sram context\n"); local_irq_disable(); local_fiq_disable(); @@ -795,17 +796,14 @@ static int __init omap3_pm_init(void) } omap3_save_scratchpad_contents(); +err1: return ret; - -err3: +err2: + free_irq(INT_34XX_PRCM_MPU_IRQ, NULL); list_for_each_entry_safe(pwrst, tmp, &pwrst_list, node) { list_del(&pwrst->node); kfree(pwrst); } - free_irq(omap_prcm_event_to_irq("io"), omap3_pm_init); -err2: - free_irq(omap_prcm_event_to_irq("wkup"), NULL); -err1: return ret; } diff --git a/trunk/arch/arm/mach-omap2/pm44xx.c b/trunk/arch/arm/mach-omap2/pm44xx.c index 885625352429..9ccaadc2cf07 100644 --- a/trunk/arch/arm/mach-omap2/pm44xx.c +++ b/trunk/arch/arm/mach-omap2/pm44xx.c @@ -144,7 +144,7 @@ static void omap_default_idle(void) static int __init omap4_pm_init(void) { int ret; - struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm, *l4wkup; + struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm; struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm; if (!cpu_is_omap44xx()) @@ -168,19 +168,14 @@ static int __init omap4_pm_init(void) * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as * expected. The hardware recommendation is to enable static * dependencies for these to avoid system lock ups or random crashes. - * The L4 wakeup depedency is added to workaround the OCP sync hardware - * BUG with 32K synctimer which lead to incorrect timer value read - * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which - * are part of L4 wakeup clockdomain. */ mpuss_clkdm = clkdm_lookup("mpuss_clkdm"); emif_clkdm = clkdm_lookup("l3_emif_clkdm"); l3_1_clkdm = clkdm_lookup("l3_1_clkdm"); l3_2_clkdm = clkdm_lookup("l3_2_clkdm"); l4_per_clkdm = clkdm_lookup("l4_per_clkdm"); - l4wkup = clkdm_lookup("l4_wkup_clkdm"); ducati_clkdm = clkdm_lookup("ducati_clkdm"); - if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || (!l4wkup) || + if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || (!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per_clkdm)) goto err2; @@ -188,7 +183,6 @@ static int __init omap4_pm_init(void) ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm); ret |= clkdm_add_wkdep(mpuss_clkdm, l3_2_clkdm); ret |= clkdm_add_wkdep(mpuss_clkdm, l4_per_clkdm); - ret |= clkdm_add_wkdep(mpuss_clkdm, l4wkup); ret |= clkdm_add_wkdep(ducati_clkdm, l3_1_clkdm); ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm); if (ret) { diff --git a/trunk/arch/arm/mach-omap2/powerdomain.c b/trunk/arch/arm/mach-omap2/powerdomain.c index 96ad3dbeac34..8a18d1bd61c8 100644 --- a/trunk/arch/arm/mach-omap2/powerdomain.c +++ b/trunk/arch/arm/mach-omap2/powerdomain.c @@ -972,13 +972,7 @@ int pwrdm_wait_transition(struct powerdomain *pwrdm) int pwrdm_state_switch(struct powerdomain *pwrdm) { - int ret; - - ret = pwrdm_wait_transition(pwrdm); - if (!ret) - ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); - - return ret; + return _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); } int pwrdm_clkdm_state_switch(struct clockdomain *clkdm) diff --git a/trunk/arch/arm/mach-omap2/prm44xx.c b/trunk/arch/arm/mach-omap2/prm44xx.c index f106d21ff581..eac623c7c3d8 100644 --- a/trunk/arch/arm/mach-omap2/prm44xx.c +++ b/trunk/arch/arm/mach-omap2/prm44xx.c @@ -147,9 +147,8 @@ static inline u32 _read_pending_irq_reg(u16 irqen_offs, u16 irqst_offs) u32 mask, st; /* XXX read mask from RAM? */ - mask = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, - irqen_offs); - st = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, irqst_offs); + mask = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, irqen_offs); + st = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, irqst_offs); return mask & st; } @@ -181,7 +180,7 @@ void omap44xx_prm_read_pending_irqs(unsigned long *events) */ void omap44xx_prm_ocp_barrier(void) { - omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, + omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, OMAP4_REVISION_PRM_OFFSET); } @@ -199,19 +198,19 @@ void omap44xx_prm_ocp_barrier(void) void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) { saved_mask[0] = - omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, + omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IRQSTATUS_MPU_OFFSET); saved_mask[1] = - omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, + omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET); - omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, + omap4_prm_write_inst_reg(0, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IRQENABLE_MPU_OFFSET); - omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, + omap4_prm_write_inst_reg(0, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); /* OCP barrier */ - omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, + omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, OMAP4_REVISION_PRM_OFFSET); } @@ -227,9 +226,9 @@ void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) */ void omap44xx_prm_restore_irqen(u32 *saved_mask) { - omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_OCP_SOCKET_INST, + omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IRQENABLE_MPU_OFFSET); - omap4_prm_write_inst_reg(saved_mask[1], OMAP4430_PRM_OCP_SOCKET_INST, + omap4_prm_write_inst_reg(saved_mask[1], OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); } diff --git a/trunk/arch/arm/mach-omap2/prm_common.c b/trunk/arch/arm/mach-omap2/prm_common.c index d28f848897d6..873b51d494ea 100644 --- a/trunk/arch/arm/mach-omap2/prm_common.c +++ b/trunk/arch/arm/mach-omap2/prm_common.c @@ -290,7 +290,7 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) goto err; } - for (i = 0; i < irq_setup->nr_regs; i++) { + for (i = 0; i <= irq_setup->nr_regs; i++) { gc = irq_alloc_generic_chip("PRCM", 1, irq_setup->base_irq + i * 32, prm_base, handle_level_irq); diff --git a/trunk/arch/arm/mach-omap2/serial.c b/trunk/arch/arm/mach-omap2/serial.c index 9fc2f44188cb..0cdd359a128e 100644 --- a/trunk/arch/arm/mach-omap2/serial.c +++ b/trunk/arch/arm/mach-omap2/serial.c @@ -108,14 +108,8 @@ static void omap_uart_set_noidle(struct platform_device *pdev) static void omap_uart_set_smartidle(struct platform_device *pdev) { struct omap_device *od = to_omap_device(pdev); - u8 idlemode; - if (od->hwmods[0]->class->sysc->idlemodes & SIDLE_SMART_WKUP) - idlemode = HWMOD_IDLEMODE_SMART_WKUP; - else - idlemode = HWMOD_IDLEMODE_SMART; - - omap_hwmod_set_slave_idlemode(od->hwmods[0], idlemode); + omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_SMART); } #else @@ -126,8 +120,124 @@ static void omap_uart_set_smartidle(struct platform_device *pdev) {} #endif /* CONFIG_PM */ #ifdef CONFIG_OMAP_MUX +static struct omap_device_pad default_uart1_pads[] __initdata = { + { + .name = "uart1_cts.uart1_cts", + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, + { + .name = "uart1_rts.uart1_rts", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart1_tx.uart1_tx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart1_rx.uart1_rx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, +}; + +static struct omap_device_pad default_uart2_pads[] __initdata = { + { + .name = "uart2_cts.uart2_cts", + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, + { + .name = "uart2_rts.uart2_rts", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart2_tx.uart2_tx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart2_rx.uart2_rx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, +}; + +static struct omap_device_pad default_uart3_pads[] __initdata = { + { + .name = "uart3_cts_rctx.uart3_cts_rctx", + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, + { + .name = "uart3_rts_sd.uart3_rts_sd", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart3_tx_irtx.uart3_tx_irtx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart3_rx_irrx.uart3_rx_irrx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0, + .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0, + }, +}; + +static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = { + { + .name = "gpmc_wait2.uart4_tx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "gpmc_wait3.uart4_rx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE2, + .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE2, + }, +}; + +static struct omap_device_pad default_omap4_uart4_pads[] __initdata = { + { + .name = "uart4_tx.uart4_tx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart4_rx.uart4_rx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0, + .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0, + }, +}; + static void omap_serial_fill_default_pads(struct omap_board_data *bdata) { + switch (bdata->id) { + case 0: + bdata->pads = default_uart1_pads; + bdata->pads_cnt = ARRAY_SIZE(default_uart1_pads); + break; + case 1: + bdata->pads = default_uart2_pads; + bdata->pads_cnt = ARRAY_SIZE(default_uart2_pads); + break; + case 2: + bdata->pads = default_uart3_pads; + bdata->pads_cnt = ARRAY_SIZE(default_uart3_pads); + break; + case 3: + if (cpu_is_omap44xx()) { + bdata->pads = default_omap4_uart4_pads; + bdata->pads_cnt = + ARRAY_SIZE(default_omap4_uart4_pads); + } else if (cpu_is_omap3630()) { + bdata->pads = default_omap36xx_uart4_pads; + bdata->pads_cnt = + ARRAY_SIZE(default_omap36xx_uart4_pads); + } + break; + default: + break; + } } #else static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {} diff --git a/trunk/arch/arm/mach-omap2/twl-common.c b/trunk/arch/arm/mach-omap2/twl-common.c index 7a7b89304c48..4b57757bf9d1 100644 --- a/trunk/arch/arm/mach-omap2/twl-common.c +++ b/trunk/arch/arm/mach-omap2/twl-common.c @@ -37,16 +37,6 @@ static struct i2c_board_info __initdata pmic_i2c_board_info = { .flags = I2C_CLIENT_WAKE, }; -static struct i2c_board_info __initdata omap4_i2c1_board_info[] = { - { - .addr = 0x48, - .flags = I2C_CLIENT_WAKE, - }, - { - I2C_BOARD_INFO("twl6040", 0x4b), - }, -}; - void __init omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq, struct twl4030_platform_data *pmic_data) @@ -59,31 +49,14 @@ void __init omap_pmic_init(int bus, u32 clkrate, omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1); } -void __init omap4_pmic_init(const char *pmic_type, - struct twl4030_platform_data *pmic_data, - struct twl6040_platform_data *twl6040_data, int twl6040_irq) -{ - /* PMIC part*/ - strncpy(omap4_i2c1_board_info[0].type, pmic_type, - sizeof(omap4_i2c1_board_info[0].type)); - omap4_i2c1_board_info[0].irq = OMAP44XX_IRQ_SYS_1N; - omap4_i2c1_board_info[0].platform_data = pmic_data; - - /* TWL6040 audio IC part */ - omap4_i2c1_board_info[1].irq = twl6040_irq; - omap4_i2c1_board_info[1].platform_data = twl6040_data; - - omap_register_i2c_bus(1, 400, omap4_i2c1_board_info, 2); - -} - void __init omap_pmic_late_init(void) { /* Init the OMAP TWL parameters (if PMIC has been registerd) */ - if (pmic_i2c_board_info.irq) - omap3_twl_init(); - if (omap4_i2c1_board_info[0].irq) - omap4_twl_init(); + if (!pmic_i2c_board_info.irq) + return; + + omap3_twl_init(); + omap4_twl_init(); } #if defined(CONFIG_ARCH_OMAP3) diff --git a/trunk/arch/arm/mach-omap2/twl-common.h b/trunk/arch/arm/mach-omap2/twl-common.h index 09627483a57f..275dde8cb27a 100644 --- a/trunk/arch/arm/mach-omap2/twl-common.h +++ b/trunk/arch/arm/mach-omap2/twl-common.h @@ -29,7 +29,6 @@ struct twl4030_platform_data; -struct twl6040_platform_data; void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq, struct twl4030_platform_data *pmic_data); @@ -47,9 +46,12 @@ static inline void omap3_pmic_init(const char *pmic_type, omap_pmic_init(1, 2600, pmic_type, INT_34XX_SYS_NIRQ, pmic_data); } -void omap4_pmic_init(const char *pmic_type, - struct twl4030_platform_data *pmic_data, - struct twl6040_platform_data *audio_data, int twl6040_irq); +static inline void omap4_pmic_init(const char *pmic_type, + struct twl4030_platform_data *pmic_data) +{ + /* Phoenix Audio IC needs I2C1 to start with 400 KHz or less */ + omap_pmic_init(1, 400, pmic_type, OMAP44XX_IRQ_SYS_1N, pmic_data); +} void omap3_pmic_get_config(struct twl4030_platform_data *pmic_data, u32 pdata_flags, u32 regulators_flags); diff --git a/trunk/arch/arm/mach-omap2/usb-host.c b/trunk/arch/arm/mach-omap2/usb-host.c index dde8a11f47d5..f51348dafafd 100644 --- a/trunk/arch/arm/mach-omap2/usb-host.c +++ b/trunk/arch/arm/mach-omap2/usb-host.c @@ -54,7 +54,7 @@ static struct omap_device_pm_latency omap_uhhtll_latency[] = { /* * setup_ehci_io_mux - initialize IO pad mux for USBHOST */ -static void __init setup_ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) +static void setup_ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) { switch (port_mode[0]) { case OMAP_EHCI_PORT_MODE_PHY: @@ -197,8 +197,7 @@ static void __init setup_ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) return; } -static -void __init setup_4430ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) +static void setup_4430ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) { switch (port_mode[0]) { case OMAP_EHCI_PORT_MODE_PHY: @@ -316,7 +315,7 @@ void __init setup_4430ehci_io_mux(const enum usbhs_omap_port_mode *port_mode) } } -static void __init setup_ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) +static void setup_ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) { switch (port_mode[0]) { case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: @@ -413,8 +412,7 @@ static void __init setup_ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) } } -static -void __init setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) +static void setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) { switch (port_mode[0]) { case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0: diff --git a/trunk/arch/arm/mach-pxa/Kconfig b/trunk/arch/arm/mach-pxa/Kconfig index fe2d1f80ef50..109ccd2a8885 100644 --- a/trunk/arch/arm/mach-pxa/Kconfig +++ b/trunk/arch/arm/mach-pxa/Kconfig @@ -113,7 +113,6 @@ config MACH_ARMCORE select IWMMXT select PXA25x select MIGHT_HAVE_PCI - select NEED_MACH_IO_H if PCI config MACH_EM_X270 bool "CompuLab EM-x270 platform" diff --git a/trunk/arch/arm/mach-pxa/include/mach/io.h b/trunk/arch/arm/mach-pxa/include/mach/io.h deleted file mode 100644 index cd78b7fe3567..000000000000 --- a/trunk/arch/arm/mach-pxa/include/mach/io.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * arch/arm/mach-pxa/include/mach/io.h - * - * Copied from asm/arch/sa1100/io.h - */ -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -#define IO_SPACE_LIMIT 0xffffffff - -/* - * We don't actually have real ISA nor PCI buses, but there is so many - * drivers out there that might just work if we fake them... - */ -#define __io(a) __typesafe_io(a) - -#endif diff --git a/trunk/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h b/trunk/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h index cbf51ae81855..c54cef25895c 100644 --- a/trunk/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h +++ b/trunk/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h @@ -17,7 +17,6 @@ * * bit 23 - Input/Output (PXA2xx specific) * bit 24 - Wakeup Enable(PXA2xx specific) - * bit 25 - Keep Output (PXA2xx specific) */ #define MFP_DIR_IN (0x0 << 23) @@ -26,12 +25,6 @@ #define MFP_DIR(x) (((x) >> 23) & 0x1) #define MFP_LPM_CAN_WAKEUP (0x1 << 24) - -/* - * MFP_LPM_KEEP_OUTPUT must be specified for pins that need to - * retain their last output level (low or high). - * Note: MFP_LPM_KEEP_OUTPUT has no effect on pins configured for input. - */ #define MFP_LPM_KEEP_OUTPUT (0x1 << 25) #define WAKEUP_ON_EDGE_RISE (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_RISE) diff --git a/trunk/arch/arm/mach-pxa/mfp-pxa2xx.c b/trunk/arch/arm/mach-pxa/mfp-pxa2xx.c index ef0426a159d4..b0a842887780 100644 --- a/trunk/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/trunk/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -33,8 +33,6 @@ #define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) #define GPLR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5)) #define GPDR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x0c) -#define GPSR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x18) -#define GPCR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x24) #define PWER_WE35 (1 << 24) @@ -350,7 +348,6 @@ static inline void pxa27x_mfp_init(void) {} #ifdef CONFIG_PM static unsigned long saved_gafr[2][4]; static unsigned long saved_gpdr[4]; -static unsigned long saved_gplr[4]; static unsigned long saved_pgsr[4]; static int pxa2xx_mfp_suspend(void) @@ -369,26 +366,14 @@ static int pxa2xx_mfp_suspend(void) } for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) { + saved_gafr[0][i] = GAFR_L(i); saved_gafr[1][i] = GAFR_U(i); saved_gpdr[i] = GPDR(i * 32); - saved_gplr[i] = GPLR(i * 32); saved_pgsr[i] = PGSR(i); - GPSR(i * 32) = PGSR(i); - GPCR(i * 32) = ~PGSR(i); - } - - /* set GPDR bits taking into account MFP_LPM_KEEP_OUTPUT */ - for (i = 0; i < pxa_last_gpio; i++) { - if ((gpdr_lpm[gpio_to_bank(i)] & GPIO_bit(i)) || - ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) && - (saved_gpdr[gpio_to_bank(i)] & GPIO_bit(i)))) - GPDR(i) |= GPIO_bit(i); - else - GPDR(i) &= ~GPIO_bit(i); + GPDR(i * 32) = gpdr_lpm[i]; } - return 0; } @@ -399,8 +384,6 @@ static void pxa2xx_mfp_resume(void) for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) { GAFR_L(i) = saved_gafr[0][i]; GAFR_U(i) = saved_gafr[1][i]; - GPSR(i * 32) = saved_gplr[i]; - GPCR(i * 32) = ~saved_gplr[i]; GPDR(i * 32) = saved_gpdr[i]; PGSR(i) = saved_pgsr[i]; } diff --git a/trunk/arch/arm/mach-pxa/pxa27x.c b/trunk/arch/arm/mach-pxa/pxa27x.c index 4726c246dcdc..6bce78edce7a 100644 --- a/trunk/arch/arm/mach-pxa/pxa27x.c +++ b/trunk/arch/arm/mach-pxa/pxa27x.c @@ -421,11 +421,8 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info) pxa_register_device(&pxa27x_device_i2c_power, info); } -static struct pxa_gpio_platform_data pxa27x_gpio_info __initdata = { - .gpio_set_wake = gpio_set_wake, -}; - static struct platform_device *devices[] __initdata = { + &pxa_device_gpio, &pxa27x_device_udc, &pxa_device_pmu, &pxa_device_i2s, @@ -461,7 +458,6 @@ static int __init pxa27x_init(void) register_syscore_ops(&pxa2xx_mfp_syscore_ops); register_syscore_ops(&pxa2xx_clock_syscore_ops); - pxa_register_device(&pxa_device_gpio, &pxa27x_gpio_info); ret = platform_add_devices(devices, ARRAY_SIZE(devices)); } diff --git a/trunk/arch/arm/mach-pxa/raumfeld.c b/trunk/arch/arm/mach-pxa/raumfeld.c index 5905ed130e94..7d691e51cb54 100644 --- a/trunk/arch/arm/mach-pxa/raumfeld.c +++ b/trunk/arch/arm/mach-pxa/raumfeld.c @@ -43,8 +43,6 @@ #include #include -#include - #include #include diff --git a/trunk/arch/arm/mach-s3c24xx/Kconfig b/trunk/arch/arm/mach-s3c24xx/Kconfig index b34287ab5afd..0f3a327ebcaa 100644 --- a/trunk/arch/arm/mach-s3c24xx/Kconfig +++ b/trunk/arch/arm/mach-s3c24xx/Kconfig @@ -111,6 +111,10 @@ config S3C24XX_SETUP_TS help Compile in platform device definition for Samsung TouchScreen. +# cpu-specific sections + +if CPU_S3C2410 + config S3C2410_DMA bool depends on S3C24XX_DMA && (CPU_S3C2410 || CPU_S3C2442) @@ -123,10 +127,6 @@ config S3C2410_PM help Power Management code common to S3C2410 and better -# cpu-specific sections - -if CPU_S3C2410 - config S3C24XX_SIMTEC_NOR bool help diff --git a/trunk/arch/arm/mach-s3c24xx/common.h b/trunk/arch/arm/mach-s3c24xx/common.h deleted file mode 100644 index c2f596e7bc2d..000000000000 --- a/trunk/arch/arm/mach-s3c24xx/common.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2012 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * Common Header for S3C24XX SoCs - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __ARCH_ARM_MACH_S3C24XX_COMMON_H -#define __ARCH_ARM_MACH_S3C24XX_COMMON_H __FILE__ - -void s3c2410_restart(char mode, const char *cmd); -void s3c244x_restart(char mode, const char *cmd); - -#endif /* __ARCH_ARM_MACH_S3C24XX_COMMON_H */ diff --git a/trunk/arch/arm/mach-s3c24xx/simtec-nor.c b/trunk/arch/arm/mach-s3c24xx/simtec-nor.c index b9d6d4f92c03..2119ca6a73bc 100644 --- a/trunk/arch/arm/mach-s3c24xx/simtec-nor.c +++ b/trunk/arch/arm/mach-s3c24xx/simtec-nor.c @@ -35,7 +35,9 @@ static void simtec_nor_vpp(struct platform_device *pdev, int vpp) { unsigned int val; + unsigned long flags; + local_irq_save(flags); val = __raw_readb(BAST_VA_CTRL3); printk(KERN_DEBUG "%s(%d)\n", __func__, vpp); @@ -46,6 +48,7 @@ static void simtec_nor_vpp(struct platform_device *pdev, int vpp) val &= ~BAST_CPLD_CTRL3_ROMWEN; __raw_writeb(val, BAST_VA_CTRL3); + local_irq_restore(flags); } static struct physmap_flash_data simtec_nor_pdata = { diff --git a/trunk/arch/arm/mach-s5pv210/dma.c b/trunk/arch/arm/mach-s5pv210/dma.c index b8337e248b09..86ce62f66190 100644 --- a/trunk/arch/arm/mach-s5pv210/dma.c +++ b/trunk/arch/arm/mach-s5pv210/dma.c @@ -33,6 +33,8 @@ #include #include +static u64 dma_dmamask = DMA_BIT_MASK(32); + static u8 pdma0_peri[] = { DMACH_UART0_RX, DMACH_UART0_TX, diff --git a/trunk/arch/arm/mach-s5pv210/mach-aquila.c b/trunk/arch/arm/mach-s5pv210/mach-aquila.c index 48d018f2332b..a9ea64e0da0d 100644 --- a/trunk/arch/arm/mach-s5pv210/mach-aquila.c +++ b/trunk/arch/arm/mach-s5pv210/mach-aquila.c @@ -484,8 +484,8 @@ static struct wm8994_pdata wm8994_platform_data = { .gpio_defaults[8] = 0x0100, .gpio_defaults[9] = 0x0100, .gpio_defaults[10] = 0x0100, - .ldo[0] = { S5PV210_MP03(6), &wm8994_ldo1_data }, /* XM0FRNB_2 */ - .ldo[1] = { 0, &wm8994_ldo2_data }, + .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */ + .ldo[1] = { 0, NULL, &wm8994_ldo2_data }, }; /* GPIO I2C PMIC */ diff --git a/trunk/arch/arm/mach-s5pv210/mach-goni.c b/trunk/arch/arm/mach-s5pv210/mach-goni.c index 32395664e879..2cf5ed75f390 100644 --- a/trunk/arch/arm/mach-s5pv210/mach-goni.c +++ b/trunk/arch/arm/mach-s5pv210/mach-goni.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -675,8 +674,8 @@ static struct wm8994_pdata wm8994_platform_data = { .gpio_defaults[8] = 0x0100, .gpio_defaults[9] = 0x0100, .gpio_defaults[10] = 0x0100, - .ldo[0] = { S5PV210_MP03(6), &wm8994_ldo1_data }, /* XM0FRNB_2 */ - .ldo[1] = { 0, &wm8994_ldo2_data }, + .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */ + .ldo[1] = { 0, NULL, &wm8994_ldo2_data }, }; /* GPIO I2C PMIC */ @@ -766,7 +765,6 @@ static void __init goni_pmic_init(void) /* MoviNAND */ static struct s3c_sdhci_platdata goni_hsmmc0_data __initdata = { .max_width = 4, - .host_caps2 = MMC_CAP2_BROKEN_VOLTAGE, .cd_type = S3C_SDHCI_CD_PERMANENT, }; diff --git a/trunk/arch/arm/mach-sa1100/collie.c b/trunk/arch/arm/mach-sa1100/collie.c index c7f418b0cde9..48885b7efd6b 100644 --- a/trunk/arch/arm/mach-sa1100/collie.c +++ b/trunk/arch/arm/mach-sa1100/collie.c @@ -313,10 +313,6 @@ static struct sa1100fb_mach_info collie_lcd_info = { .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act, .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2), - -#ifdef CONFIG_BACKLIGHT_LOCOMO - .lcd_power = locomolcd_power -#endif }; static void __init collie_init(void) diff --git a/trunk/arch/arm/mach-sa1100/generic.c b/trunk/arch/arm/mach-sa1100/generic.c index 16be4c56abe3..7c524b4e415d 100644 --- a/trunk/arch/arm/mach-sa1100/generic.c +++ b/trunk/arch/arm/mach-sa1100/generic.c @@ -306,7 +306,7 @@ void sa11x0_register_irda(struct irda_platform_data *irda) } static struct resource sa1100_rtc_resources[] = { - DEFINE_RES_MEM(0x90010000, 0x40), + DEFINE_RES_MEM(0x90010000, 0x9001003f), DEFINE_RES_IRQ_NAMED(IRQ_RTC1Hz, "rtc 1Hz"), DEFINE_RES_IRQ_NAMED(IRQ_RTCAlrm, "rtc alarm"), }; diff --git a/trunk/arch/arm/mach-sa1100/include/mach/collie.h b/trunk/arch/arm/mach-sa1100/include/mach/collie.h index f33679d2d3ee..52acda7061b7 100644 --- a/trunk/arch/arm/mach-sa1100/include/mach/collie.h +++ b/trunk/arch/arm/mach-sa1100/include/mach/collie.h @@ -1,7 +1,7 @@ /* * arch/arm/mach-sa1100/include/mach/collie.h * - * This file contains the hardware specific definitions for Collie + * This file contains the hardware specific definitions for Assabet * Only include this file from SA1100-specific files. * * ChangeLog: @@ -13,7 +13,6 @@ #ifndef __ASM_ARCH_COLLIE_H #define __ASM_ARCH_COLLIE_H -extern void locomolcd_power(int on); #define COLLIE_SCOOP_GPIO_BASE (GPIO_MAX + 1) #define COLLIE_GPIO_CHARGE_ON (COLLIE_SCOOP_GPIO_BASE + 0) diff --git a/trunk/arch/arm/mach-shark/core.c b/trunk/arch/arm/mach-shark/core.c index 2704bcd869cd..6a2a7f2c2557 100644 --- a/trunk/arch/arm/mach-shark/core.c +++ b/trunk/arch/arm/mach-shark/core.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/arm/mach-shmobile/board-mackerel.c b/trunk/arch/arm/mach-shmobile/board-mackerel.c index f49e28abe0ab..a125d4e114ec 100644 --- a/trunk/arch/arm/mach-shmobile/board-mackerel.c +++ b/trunk/arch/arm/mach-shmobile/board-mackerel.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -957,50 +956,6 @@ static struct platform_device fsi_ak4643_device = { }, }; -/* FLCTL */ -static struct mtd_partition nand_partition_info[] = { - { - .name = "system", - .offset = 0, - .size = 128 * 1024 * 1024, - }, - { - .name = "userdata", - .offset = MTDPART_OFS_APPEND, - .size = 256 * 1024 * 1024, - }, - { - .name = "cache", - .offset = MTDPART_OFS_APPEND, - .size = 128 * 1024 * 1024, - }, -}; - -static struct resource nand_flash_resources[] = { - [0] = { - .start = 0xe6a30000, - .end = 0xe6a3009b, - .flags = IORESOURCE_MEM, - } -}; - -static struct sh_flctl_platform_data nand_flash_data = { - .parts = nand_partition_info, - .nr_parts = ARRAY_SIZE(nand_partition_info), - .flcmncr_val = CLK_16B_12L_4H | TYPESEL_SET - | SHBUSSEL | SEL_16BIT | SNAND_E, - .use_holden = 1, -}; - -static struct platform_device nand_flash_device = { - .name = "sh_flctl", - .resource = nand_flash_resources, - .num_resources = ARRAY_SIZE(nand_flash_resources), - .dev = { - .platform_data = &nand_flash_data, - }, -}; - /* * The card detect pin of the top SD/MMC slot (CN7) is active low and is * connected to GPIO A22 of SH7372 (GPIO_PORT41). @@ -1304,7 +1259,6 @@ static struct platform_device *mackerel_devices[] __initdata = { &fsi_device, &fsi_ak4643_device, &fsi_hdmi_device, - &nand_flash_device, &sdhi0_device, #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) &sdhi1_device, @@ -1534,30 +1488,6 @@ static void __init mackerel_init(void) gpio_request(GPIO_FN_MMCCMD0, NULL); gpio_request(GPIO_FN_MMCCLK0, NULL); - /* FLCTL */ - gpio_request(GPIO_FN_D0_NAF0, NULL); - gpio_request(GPIO_FN_D1_NAF1, NULL); - gpio_request(GPIO_FN_D2_NAF2, NULL); - gpio_request(GPIO_FN_D3_NAF3, NULL); - gpio_request(GPIO_FN_D4_NAF4, NULL); - gpio_request(GPIO_FN_D5_NAF5, NULL); - gpio_request(GPIO_FN_D6_NAF6, NULL); - gpio_request(GPIO_FN_D7_NAF7, NULL); - gpio_request(GPIO_FN_D8_NAF8, NULL); - gpio_request(GPIO_FN_D9_NAF9, NULL); - gpio_request(GPIO_FN_D10_NAF10, NULL); - gpio_request(GPIO_FN_D11_NAF11, NULL); - gpio_request(GPIO_FN_D12_NAF12, NULL); - gpio_request(GPIO_FN_D13_NAF13, NULL); - gpio_request(GPIO_FN_D14_NAF14, NULL); - gpio_request(GPIO_FN_D15_NAF15, NULL); - gpio_request(GPIO_FN_FCE0, NULL); - gpio_request(GPIO_FN_WE0_FWE, NULL); - gpio_request(GPIO_FN_FRB, NULL); - gpio_request(GPIO_FN_A4_FOE, NULL); - gpio_request(GPIO_FN_A5_FCDE, NULL); - gpio_request(GPIO_FN_RD_FSC, NULL); - /* enable GPS module (GT-720F) */ gpio_request(GPIO_FN_SCIFA2_TXD1, NULL); gpio_request(GPIO_FN_SCIFA2_RXD1, NULL); @@ -1602,7 +1532,6 @@ static void __init mackerel_init(void) sh7372_add_device_to_domain(&sh7372_a4mp, &fsi_device); sh7372_add_device_to_domain(&sh7372_a3sp, &usbhs0_device); sh7372_add_device_to_domain(&sh7372_a3sp, &usbhs1_device); - sh7372_add_device_to_domain(&sh7372_a3sp, &nand_flash_device); sh7372_add_device_to_domain(&sh7372_a3sp, &sh_mmcif_device); sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi0_device); #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) diff --git a/trunk/arch/arm/mach-shmobile/clock-sh7372.c b/trunk/arch/arm/mach-shmobile/clock-sh7372.c index 94d1f88246d3..de243e3c8392 100644 --- a/trunk/arch/arm/mach-shmobile/clock-sh7372.c +++ b/trunk/arch/arm/mach-shmobile/clock-sh7372.c @@ -511,7 +511,7 @@ enum { MSTP001, MSTP000, MSTP223, MSTP218, MSTP217, MSTP216, MSTP214, MSTP208, MSTP207, MSTP206, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, - MSTP328, MSTP323, MSTP322, MSTP315, MSTP314, MSTP313, MSTP312, + MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312, MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP407, MSTP406, MSTP405, MSTP404, MSTP403, MSTP400, MSTP_NR }; @@ -553,7 +553,6 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */ [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ - [MSTP315] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 15, 0), /* FLCTL*/ [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */ [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */ @@ -654,7 +653,6 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */ CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */ CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */ - CLKDEV_DEV_ID("sh_flctl.0", &mstp_clks[MSTP315]), /* FLCTL */ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */ diff --git a/trunk/arch/arm/mach-shmobile/cpuidle.c b/trunk/arch/arm/mach-shmobile/cpuidle.c index 7e6559105d40..21b09b6455e4 100644 --- a/trunk/arch/arm/mach-shmobile/cpuidle.c +++ b/trunk/arch/arm/mach-shmobile/cpuidle.c @@ -13,7 +13,6 @@ #include #include #include -#include #include static void shmobile_enter_wfi(void) @@ -29,19 +28,37 @@ static int shmobile_cpuidle_enter(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { + ktime_t before, after; + + before = ktime_get(); + + local_irq_disable(); + local_fiq_disable(); + shmobile_cpuidle_modes[index](); + local_irq_enable(); + local_fiq_enable(); + + after = ktime_get(); + dev->last_residency = ktime_to_ns(ktime_sub(after, before)) >> 10; + return index; } static struct cpuidle_device shmobile_cpuidle_dev; static struct cpuidle_driver shmobile_cpuidle_driver = { - .name = "shmobile_cpuidle", - .owner = THIS_MODULE, - .en_core_tk_irqen = 1, - .states[0] = ARM_CPUIDLE_WFI_STATE, - .safe_state_index = 0, /* C1 */ - .state_count = 1, + .name = "shmobile_cpuidle", + .owner = THIS_MODULE, + .states[0] = { + .name = "C1", + .desc = "WFI", + .exit_latency = 1, + .target_residency = 1 * 2, + .flags = CPUIDLE_FLAG_TIME_VALID, + }, + .safe_state_index = 0, /* C1 */ + .state_count = 1, }; void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv); diff --git a/trunk/arch/arm/mach-u300/core.c b/trunk/arch/arm/mach-u300/core.c index 33339745d432..8b90c44d237f 100644 --- a/trunk/arch/arm/mach-u300/core.c +++ b/trunk/arch/arm/mach-u300/core.c @@ -1544,8 +1544,6 @@ static struct fsmc_nand_platform_data nand_platform_data = { .nr_partitions = ARRAY_SIZE(u300_partitions), .options = NAND_SKIP_BBTSCAN, .width = FSMC_NAND_BW8, - .ale_off = PLAT_NAND_ALE, - .cle_off = PLAT_NAND_CLE, }; static struct platform_device nand_device = { @@ -1667,10 +1665,8 @@ void __init u300_init_irq(void) for (i = 0; i < U300_VIC_IRQS_END; i++) set_bit(i, (unsigned long *) &mask[0]); - vic_init((void __iomem *) U300_INTCON0_VBASE, IRQ_U300_INTCON0_START, - mask[0], mask[0]); - vic_init((void __iomem *) U300_INTCON1_VBASE, IRQ_U300_INTCON1_START, - mask[1], mask[1]); + vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0], mask[0]); + vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1], mask[1]); } diff --git a/trunk/arch/arm/mach-u300/i2c.c b/trunk/arch/arm/mach-u300/i2c.c index cb04bd6ab3e7..a38f80238ea9 100644 --- a/trunk/arch/arm/mach-u300/i2c.c +++ b/trunk/arch/arm/mach-u300/i2c.c @@ -146,6 +146,9 @@ static struct ab3100_platform_data ab3100_plf_data = { .min_uV = 1800000, .max_uV = 1800000, .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = + REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, .always_on = 1, .boot_on = 1, }, @@ -157,6 +160,9 @@ static struct ab3100_platform_data ab3100_plf_data = { .min_uV = 2500000, .max_uV = 2500000, .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = + REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, .always_on = 1, .boot_on = 1, }, @@ -224,7 +230,8 @@ static struct ab3100_platform_data ab3100_plf_data = { .max_uV = 1800000, .valid_modes_mask = REGULATOR_MODE_NORMAL, .valid_ops_mask = - REGULATOR_CHANGE_VOLTAGE, + REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, .always_on = 1, .boot_on = 1, }, diff --git a/trunk/arch/arm/mach-u300/include/mach/irqs.h b/trunk/arch/arm/mach-u300/include/mach/irqs.h index ec09c1e07b1a..ee78a26707eb 100644 --- a/trunk/arch/arm/mach-u300/include/mach/irqs.h +++ b/trunk/arch/arm/mach-u300/include/mach/irqs.h @@ -12,101 +12,101 @@ #ifndef __MACH_IRQS_H #define __MACH_IRQS_H -#define IRQ_U300_INTCON0_START 1 -#define IRQ_U300_INTCON1_START 33 +#define IRQ_U300_INTCON0_START 0 +#define IRQ_U300_INTCON1_START 32 /* These are on INTCON0 - 30 lines */ -#define IRQ_U300_IRQ0_EXT 1 -#define IRQ_U300_IRQ1_EXT 2 -#define IRQ_U300_DMA 3 -#define IRQ_U300_VIDEO_ENC_0 4 -#define IRQ_U300_VIDEO_ENC_1 5 -#define IRQ_U300_AAIF_RX 6 -#define IRQ_U300_AAIF_TX 7 -#define IRQ_U300_AAIF_VGPIO 8 -#define IRQ_U300_AAIF_WAKEUP 9 -#define IRQ_U300_PCM_I2S0_FRAME 10 -#define IRQ_U300_PCM_I2S0_FIFO 11 -#define IRQ_U300_PCM_I2S1_FRAME 12 -#define IRQ_U300_PCM_I2S1_FIFO 13 -#define IRQ_U300_XGAM_GAMCON 14 -#define IRQ_U300_XGAM_CDI 15 -#define IRQ_U300_XGAM_CDICON 16 +#define IRQ_U300_IRQ0_EXT 0 +#define IRQ_U300_IRQ1_EXT 1 +#define IRQ_U300_DMA 2 +#define IRQ_U300_VIDEO_ENC_0 3 +#define IRQ_U300_VIDEO_ENC_1 4 +#define IRQ_U300_AAIF_RX 5 +#define IRQ_U300_AAIF_TX 6 +#define IRQ_U300_AAIF_VGPIO 7 +#define IRQ_U300_AAIF_WAKEUP 8 +#define IRQ_U300_PCM_I2S0_FRAME 9 +#define IRQ_U300_PCM_I2S0_FIFO 10 +#define IRQ_U300_PCM_I2S1_FRAME 11 +#define IRQ_U300_PCM_I2S1_FIFO 12 +#define IRQ_U300_XGAM_GAMCON 13 +#define IRQ_U300_XGAM_CDI 14 +#define IRQ_U300_XGAM_CDICON 15 #if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330) /* MMIACC not used on the DB3210 or DB3350 chips */ -#define IRQ_U300_XGAM_MMIACC 17 +#define IRQ_U300_XGAM_MMIACC 16 #endif -#define IRQ_U300_XGAM_PDI 18 -#define IRQ_U300_XGAM_PDICON 19 -#define IRQ_U300_XGAM_GAMEACC 20 -#define IRQ_U300_XGAM_MCIDCT 21 -#define IRQ_U300_APEX 22 -#define IRQ_U300_UART0 23 -#define IRQ_U300_SPI 24 -#define IRQ_U300_TIMER_APP_OS 25 -#define IRQ_U300_TIMER_APP_DD 26 -#define IRQ_U300_TIMER_APP_GP1 27 -#define IRQ_U300_TIMER_APP_GP2 28 -#define IRQ_U300_TIMER_OS 29 -#define IRQ_U300_TIMER_MS 30 -#define IRQ_U300_KEYPAD_KEYBF 31 -#define IRQ_U300_KEYPAD_KEYBR 32 +#define IRQ_U300_XGAM_PDI 17 +#define IRQ_U300_XGAM_PDICON 18 +#define IRQ_U300_XGAM_GAMEACC 19 +#define IRQ_U300_XGAM_MCIDCT 20 +#define IRQ_U300_APEX 21 +#define IRQ_U300_UART0 22 +#define IRQ_U300_SPI 23 +#define IRQ_U300_TIMER_APP_OS 24 +#define IRQ_U300_TIMER_APP_DD 25 +#define IRQ_U300_TIMER_APP_GP1 26 +#define IRQ_U300_TIMER_APP_GP2 27 +#define IRQ_U300_TIMER_OS 28 +#define IRQ_U300_TIMER_MS 29 +#define IRQ_U300_KEYPAD_KEYBF 30 +#define IRQ_U300_KEYPAD_KEYBR 31 /* These are on INTCON1 - 32 lines */ -#define IRQ_U300_GPIO_PORT0 33 -#define IRQ_U300_GPIO_PORT1 34 -#define IRQ_U300_GPIO_PORT2 35 +#define IRQ_U300_GPIO_PORT0 32 +#define IRQ_U300_GPIO_PORT1 33 +#define IRQ_U300_GPIO_PORT2 34 #if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330) || \ defined(CONFIG_MACH_U300_BS335) /* These are for DB3150, DB3200 and DB3350 */ -#define IRQ_U300_WDOG 36 -#define IRQ_U300_EVHIST 37 -#define IRQ_U300_MSPRO 38 -#define IRQ_U300_MMCSD_MCIINTR0 39 -#define IRQ_U300_MMCSD_MCIINTR1 40 -#define IRQ_U300_I2C0 41 -#define IRQ_U300_I2C1 42 -#define IRQ_U300_RTC 43 -#define IRQ_U300_NFIF 44 -#define IRQ_U300_NFIF2 45 +#define IRQ_U300_WDOG 35 +#define IRQ_U300_EVHIST 36 +#define IRQ_U300_MSPRO 37 +#define IRQ_U300_MMCSD_MCIINTR0 38 +#define IRQ_U300_MMCSD_MCIINTR1 39 +#define IRQ_U300_I2C0 40 +#define IRQ_U300_I2C1 41 +#define IRQ_U300_RTC 42 +#define IRQ_U300_NFIF 43 +#define IRQ_U300_NFIF2 44 #endif /* DB3150 and DB3200 have only 45 IRQs */ #if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330) -#define U300_VIC_IRQS_END 46 +#define U300_VIC_IRQS_END 45 #endif /* The DB3350-specific interrupt lines */ #ifdef CONFIG_MACH_U300_BS335 -#define IRQ_U300_ISP_F0 46 -#define IRQ_U300_ISP_F1 47 -#define IRQ_U300_ISP_F2 48 -#define IRQ_U300_ISP_F3 49 -#define IRQ_U300_ISP_F4 50 -#define IRQ_U300_GPIO_PORT3 51 -#define IRQ_U300_SYSCON_PLL_LOCK 52 -#define IRQ_U300_UART1 53 -#define IRQ_U300_GPIO_PORT4 54 -#define IRQ_U300_GPIO_PORT5 55 -#define IRQ_U300_GPIO_PORT6 56 -#define U300_VIC_IRQS_END 57 +#define IRQ_U300_ISP_F0 45 +#define IRQ_U300_ISP_F1 46 +#define IRQ_U300_ISP_F2 47 +#define IRQ_U300_ISP_F3 48 +#define IRQ_U300_ISP_F4 49 +#define IRQ_U300_GPIO_PORT3 50 +#define IRQ_U300_SYSCON_PLL_LOCK 51 +#define IRQ_U300_UART1 52 +#define IRQ_U300_GPIO_PORT4 53 +#define IRQ_U300_GPIO_PORT5 54 +#define IRQ_U300_GPIO_PORT6 55 +#define U300_VIC_IRQS_END 56 #endif /* The DB3210-specific interrupt lines */ #ifdef CONFIG_MACH_U300_BS365 -#define IRQ_U300_GPIO_PORT3 36 -#define IRQ_U300_GPIO_PORT4 37 -#define IRQ_U300_WDOG 38 -#define IRQ_U300_EVHIST 39 -#define IRQ_U300_MSPRO 40 -#define IRQ_U300_MMCSD_MCIINTR0 41 -#define IRQ_U300_MMCSD_MCIINTR1 42 -#define IRQ_U300_I2C0 43 -#define IRQ_U300_I2C1 44 -#define IRQ_U300_RTC 45 -#define IRQ_U300_NFIF 46 -#define IRQ_U300_NFIF2 47 -#define IRQ_U300_SYSCON_PLL_LOCK 48 -#define U300_VIC_IRQS_END 49 +#define IRQ_U300_GPIO_PORT3 35 +#define IRQ_U300_GPIO_PORT4 36 +#define IRQ_U300_WDOG 37 +#define IRQ_U300_EVHIST 38 +#define IRQ_U300_MSPRO 39 +#define IRQ_U300_MMCSD_MCIINTR0 40 +#define IRQ_U300_MMCSD_MCIINTR1 41 +#define IRQ_U300_I2C0 42 +#define IRQ_U300_I2C1 43 +#define IRQ_U300_RTC 44 +#define IRQ_U300_NFIF 45 +#define IRQ_U300_NFIF2 46 +#define IRQ_U300_SYSCON_PLL_LOCK 47 +#define U300_VIC_IRQS_END 48 #endif /* Maximum 8*7 GPIO lines */ @@ -117,6 +117,6 @@ #define IRQ_U300_GPIO_END (U300_VIC_IRQS_END) #endif -#define NR_IRQS (IRQ_U300_GPIO_END - IRQ_U300_INTCON0_START) +#define NR_IRQS (IRQ_U300_GPIO_END) #endif diff --git a/trunk/arch/arm/mach-u300/include/mach/u300-regs.h b/trunk/arch/arm/mach-u300/include/mach/u300-regs.h index 65f87c523892..7b7cba960b69 100644 --- a/trunk/arch/arm/mach-u300/include/mach/u300-regs.h +++ b/trunk/arch/arm/mach-u300/include/mach/u300-regs.h @@ -24,11 +24,6 @@ /* NFIF */ #define U300_NAND_IF_PHYS_BASE 0x9f800000 -/* ALE, CLE offset for FSMC NAND */ -#define PLAT_NAND_CLE (1 << 16) -#define PLAT_NAND_ALE (1 << 17) - - /* AHB Peripherals */ #define U300_AHB_PER_PHYS_BASE 0xa0000000 #define U300_AHB_PER_VIRT_BASE 0xff010000 diff --git a/trunk/arch/arm/mach-ux500/Kconfig b/trunk/arch/arm/mach-ux500/Kconfig index ef7099eea0f2..880d02ec89d4 100644 --- a/trunk/arch/arm/mach-ux500/Kconfig +++ b/trunk/arch/arm/mach-ux500/Kconfig @@ -17,7 +17,6 @@ config UX500_SOC_DB5500 config UX500_SOC_DB8500 bool select MFD_DB8500_PRCMU - select REGULATOR select REGULATOR_DB8500_PRCMU select CPU_FREQ_TABLE if CPU_FREQ diff --git a/trunk/arch/arm/mach-ux500/mbox-db5500.c b/trunk/arch/arm/mach-ux500/mbox-db5500.c index 0127490218cd..2b2d51caf9d8 100644 --- a/trunk/arch/arm/mach-ux500/mbox-db5500.c +++ b/trunk/arch/arm/mach-ux500/mbox-db5500.c @@ -168,7 +168,7 @@ static ssize_t mbox_read_fifo(struct device *dev, return sprintf(buf, "0x%X\n", mbox_value); } -static DEVICE_ATTR(fifo, S_IWUSR | S_IRUGO, mbox_read_fifo, mbox_write_fifo); +static DEVICE_ATTR(fifo, S_IWUGO | S_IRUGO, mbox_read_fifo, mbox_write_fifo); static int mbox_show(struct seq_file *s, void *data) { diff --git a/trunk/arch/arm/mach-ux500/platsmp.c b/trunk/arch/arm/mach-ux500/platsmp.c index eff5842f6232..d2058ef8345f 100644 --- a/trunk/arch/arm/mach-ux500/platsmp.c +++ b/trunk/arch/arm/mach-ux500/platsmp.c @@ -99,7 +99,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) */ write_pen_release(cpu_logical_map(cpu)); - smp_send_reschedule(cpu); + gic_raise_softirq(cpumask_of(cpu), 1); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { diff --git a/trunk/arch/arm/mach-versatile/pci.c b/trunk/arch/arm/mach-versatile/pci.c index d2268be8c34c..a6e23f464528 100644 --- a/trunk/arch/arm/mach-versatile/pci.c +++ b/trunk/arch/arm/mach-versatile/pci.c @@ -190,7 +190,7 @@ static struct resource pre_mem = { .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH, }; -static int __init pci_versatile_setup_resources(struct pci_sys_data *sys) +static int __init pci_versatile_setup_resources(struct list_head *resources) { int ret = 0; @@ -218,9 +218,9 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys) * the mem resource for this bus * the prefetch mem resource for this bus */ - pci_add_resource_offset(&sys->resources, &io_mem, sys->io_offset); - pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset); - pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset); + pci_add_resource_offset(resources, &io_mem, sys->io_offset); + pci_add_resource_offset(resources, &non_mem, sys->mem_offset); + pci_add_resource_offset(resources, &pre_mem, sys->mem_offset); goto out; @@ -249,7 +249,7 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys) if (nr == 0) { sys->mem_offset = 0; - ret = pci_versatile_setup_resources(sys); + ret = pci_versatile_setup_resources(&sys->resources); if (ret < 0) { printk("pci_versatile_setup: resources... oops?\n"); goto out; diff --git a/trunk/arch/arm/mach-w90x900/dev.c b/trunk/arch/arm/mach-w90x900/dev.c index 48f5b9fdfb7f..db82568a998a 100644 --- a/trunk/arch/arm/mach-w90x900/dev.c +++ b/trunk/arch/arm/mach-w90x900/dev.c @@ -27,7 +27,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index 7c8a7d8467bf..7edef9121632 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -723,7 +723,7 @@ config CPU_HIGH_VECTOR bool "Select the High exception vector" help Say Y here to select high exception vector(0xFFFF0000~). - The exception vector can vary depending on the platform + The exception vector can be vary depending on the platform design in nommu mode. If your platform needs to select high exception vector, say Y. Otherwise or if you are unsure, say N, and the low exception diff --git a/trunk/arch/arm/mm/abort-ev6.S b/trunk/arch/arm/mm/abort-ev6.S index 80741992a9fc..ff1f7cc11f87 100644 --- a/trunk/arch/arm/mm/abort-ev6.S +++ b/trunk/arch/arm/mm/abort-ev6.S @@ -26,23 +26,18 @@ ENTRY(v6_early_abort) mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR /* - * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR. + * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR (erratum 326103). + * The test below covers all the write situations, including Java bytecodes */ -#ifdef CONFIG_ARM_ERRATA_326103 - ldr ip, =0x4107b36 - mrc p15, 0, r3, c0, c0, 0 @ get processor id - teq ip, r3, lsr #4 @ r0 ARM1136? - bne do_DataAbort + bic r1, r1, #1 << 11 @ clear bit 11 of FSR tst r5, #PSR_J_BIT @ Java? - tsteq r5, #PSR_T_BIT @ Thumb? bne do_DataAbort - bic r1, r1, #1 << 11 @ clear bit 11 of FSR - ldr r3, [r4] @ read aborted ARM instruction + do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3 + ldreq r3, [r4] @ read aborted ARM instruction #ifdef CONFIG_CPU_ENDIAN_BE8 - rev r3, r3 + reveq r3, r3 #endif do_ldrd_abort tmp=ip, insn=r3 tst r3, #1 << 20 @ L = 0 -> write orreq r1, r1, #1 << 11 @ yes. -#endif b do_DataAbort diff --git a/trunk/arch/arm/mm/cache-l2x0.c b/trunk/arch/arm/mm/cache-l2x0.c index 2a8e380501e8..a53fd2aaa2f4 100644 --- a/trunk/arch/arm/mm/cache-l2x0.c +++ b/trunk/arch/arm/mm/cache-l2x0.c @@ -32,7 +32,6 @@ static void __iomem *l2x0_base; static DEFINE_RAW_SPINLOCK(l2x0_lock); static u32 l2x0_way_mask; /* Bitmask of active ways */ static u32 l2x0_size; -static unsigned long sync_reg_offset = L2X0_CACHE_SYNC; struct l2x0_regs l2x0_saved_regs; @@ -62,7 +61,12 @@ static inline void cache_sync(void) { void __iomem *base = l2x0_base; - writel_relaxed(0, base + sync_reg_offset); +#ifdef CONFIG_PL310_ERRATA_753970 + /* write to an unmmapped register */ + writel_relaxed(0, base + L2X0_DUMMY_REG); +#else + writel_relaxed(0, base + L2X0_CACHE_SYNC); +#endif cache_wait(base + L2X0_CACHE_SYNC, 1); } @@ -81,13 +85,10 @@ static inline void l2x0_inv_line(unsigned long addr) } #if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915) -static inline void debug_writel(unsigned long val) -{ - if (outer_cache.set_debug) - outer_cache.set_debug(val); -} -static void pl310_set_debug(unsigned long val) +#define debug_writel(val) outer_cache.set_debug(val) + +static void l2x0_set_debug(unsigned long val) { writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL); } @@ -97,7 +98,7 @@ static inline void debug_writel(unsigned long val) { } -#define pl310_set_debug NULL +#define l2x0_set_debug NULL #endif #ifdef CONFIG_PL310_ERRATA_588369 @@ -330,11 +331,6 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) else ways = 8; type = "L310"; -#ifdef CONFIG_PL310_ERRATA_753970 - /* Unmapped register. */ - sync_reg_offset = L2X0_DUMMY_REG; -#endif - outer_cache.set_debug = pl310_set_debug; break; case L2X0_CACHE_ID_PART_L210: ways = (aux >> 13) & 0xf; @@ -383,6 +379,7 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) outer_cache.flush_all = l2x0_flush_all; outer_cache.inv_all = l2x0_inv_all; outer_cache.disable = l2x0_disable; + outer_cache.set_debug = l2x0_set_debug; printk(KERN_INFO "%s cache controller enabled\n", type); printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n", diff --git a/trunk/arch/arm/mm/fault.c b/trunk/arch/arm/mm/fault.c index f07467533365..9055b5a84ec5 100644 --- a/trunk/arch/arm/mm/fault.c +++ b/trunk/arch/arm/mm/fault.c @@ -320,7 +320,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) */ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr); - if (!(fault & VM_FAULT_ERROR) && flags & FAULT_FLAG_ALLOW_RETRY) { + if (flags & FAULT_FLAG_ALLOW_RETRY) { if (fault & VM_FAULT_MAJOR) { tsk->maj_flt++; perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, diff --git a/trunk/arch/arm/mm/init.c b/trunk/arch/arm/mm/init.c index 8f5813bbffb5..595079fa9d1d 100644 --- a/trunk/arch/arm/mm/init.c +++ b/trunk/arch/arm/mm/init.c @@ -293,11 +293,11 @@ EXPORT_SYMBOL(pfn_valid); #endif #ifndef CONFIG_SPARSEMEM -static void __init arm_memory_present(void) +static void arm_memory_present(void) { } #else -static void __init arm_memory_present(void) +static void arm_memory_present(void) { struct memblock_region *reg; diff --git a/trunk/arch/arm/mm/mmu.c b/trunk/arch/arm/mm/mmu.c index 2c7cf2f9c837..b86f8933ff91 100644 --- a/trunk/arch/arm/mm/mmu.c +++ b/trunk/arch/arm/mm/mmu.c @@ -618,8 +618,8 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr, } } -static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, - unsigned long end, unsigned long phys, const struct mem_type *type) +static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end, + unsigned long phys, const struct mem_type *type) { pud_t *pud = pud_offset(pgd, addr); unsigned long next; diff --git a/trunk/arch/arm/mm/nommu.c b/trunk/arch/arm/mm/nommu.c index d51225f90ae2..6486d2f253cd 100644 --- a/trunk/arch/arm/mm/nommu.c +++ b/trunk/arch/arm/mm/nommu.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "mm.h" @@ -40,7 +39,6 @@ void __init sanity_check_meminfo(void) */ void __init paging_init(struct machine_desc *mdesc) { - early_trap_init((void *)CONFIG_VECTORS_BASE); bootmem_init(); } diff --git a/trunk/arch/arm/mm/proc-v7.S b/trunk/arch/arm/mm/proc-v7.S index c2e2b66f72b5..f1c8486f7501 100644 --- a/trunk/arch/arm/mm/proc-v7.S +++ b/trunk/arch/arm/mm/proc-v7.S @@ -254,18 +254,6 @@ __v7_setup: ldr r6, =NMRR @ NMRR mcr p15, 0, r5, c10, c2, 0 @ write PRRR mcr p15, 0, r6, c10, c2, 1 @ write NMRR -#endif -#ifndef CONFIG_ARM_THUMBEE - mrc p15, 0, r0, c0, c1, 0 @ read ID_PFR0 for ThumbEE - and r0, r0, #(0xf << 12) @ ThumbEE enabled field - teq r0, #(1 << 12) @ check if ThumbEE is present - bne 1f - mov r5, #0 - mcr p14, 6, r5, c1, c0, 0 @ Initialize TEEHBR to 0 - mrc p14, 6, r0, c0, c0, 0 @ load TEECR - orr r0, r0, #1 @ set the 1st bit in order to - mcr p14, 6, r0, c0, c0, 0 @ stop userspace TEEHBR access -1: #endif adr r5, v7_crval ldmia r5, {r5, r6} diff --git a/trunk/arch/arm/plat-mxc/3ds_debugboard.c b/trunk/arch/arm/plat-mxc/3ds_debugboard.c index 5cac2c540f4f..d1e31fa1b0c3 100644 --- a/trunk/arch/arm/plat-mxc/3ds_debugboard.c +++ b/trunk/arch/arm/plat-mxc/3ds_debugboard.c @@ -80,7 +80,7 @@ static struct smsc911x_platform_config smsc911x_config = { static struct platform_device smsc_lan9217_device = { .name = "smsc911x", - .id = -1, + .id = 0, .dev = { .platform_data = &smsc911x_config, }, diff --git a/trunk/arch/arm/plat-omap/Kconfig b/trunk/arch/arm/plat-omap/Kconfig index ad95c7a5d009..ce1e9b96ba1a 100644 --- a/trunk/arch/arm/plat-omap/Kconfig +++ b/trunk/arch/arm/plat-omap/Kconfig @@ -17,7 +17,6 @@ config ARCH_OMAP1 select IRQ_DOMAIN select HAVE_IDE select NEED_MACH_MEMORY_H - select NEED_MACH_IO_H if PCCARD help "Systems based on omap7xx, omap15xx or omap16xx" diff --git a/trunk/arch/arm/plat-omap/clock.c b/trunk/arch/arm/plat-omap/clock.c index 62ec5c452792..56b6f8b7053e 100644 --- a/trunk/arch/arm/plat-omap/clock.c +++ b/trunk/arch/arm/plat-omap/clock.c @@ -398,6 +398,32 @@ struct clk dummy_ck = { .ops = &clkops_null, }; +#ifdef CONFIG_CPU_FREQ +void clk_init_cpufreq_table(struct cpufreq_frequency_table **table) +{ + unsigned long flags; + + if (!arch_clock || !arch_clock->clk_init_cpufreq_table) + return; + + spin_lock_irqsave(&clockfw_lock, flags); + arch_clock->clk_init_cpufreq_table(table); + spin_unlock_irqrestore(&clockfw_lock, flags); +} + +void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) +{ + unsigned long flags; + + if (!arch_clock || !arch_clock->clk_exit_cpufreq_table) + return; + + spin_lock_irqsave(&clockfw_lock, flags); + arch_clock->clk_exit_cpufreq_table(table); + spin_unlock_irqrestore(&clockfw_lock, flags); +} +#endif + /* * */ @@ -415,8 +441,6 @@ static int __init clk_disable_unused(void) return 0; pr_info("clock: disabling unused clocks to save power\n"); - - spin_lock_irqsave(&clockfw_lock, flags); list_for_each_entry(ck, &clocks, node) { if (ck->ops == &clkops_null) continue; @@ -424,9 +448,10 @@ static int __init clk_disable_unused(void) if (ck->usecount > 0 || !ck->enable_reg) continue; + spin_lock_irqsave(&clockfw_lock, flags); arch_clock->clk_disable_unused(ck); + spin_unlock_irqrestore(&clockfw_lock, flags); } - spin_unlock_irqrestore(&clockfw_lock, flags); return 0; } diff --git a/trunk/arch/arm/plat-omap/dma.c b/trunk/arch/arm/plat-omap/dma.c index c58d896cd5c3..ecdb3da0dea9 100644 --- a/trunk/arch/arm/plat-omap/dma.c +++ b/trunk/arch/arm/plat-omap/dma.c @@ -916,13 +916,6 @@ void omap_start_dma(int lch) l |= OMAP_DMA_CCR_BUFFERING_DISABLE; l |= OMAP_DMA_CCR_EN; - /* - * As dma_write() uses IO accessors which are weakly ordered, there - * is no guarantee that data in coherent DMA memory will be visible - * to the DMA device. Add a memory barrier here to ensure that any - * such data is visible prior to enabling DMA. - */ - mb(); p->dma_write(l, CCR, lch); dma_chan[lch].flags |= OMAP_DMA_ACTIVE; @@ -972,13 +965,6 @@ void omap_stop_dma(int lch) p->dma_write(l, CCR, lch); } - /* - * Ensure that data transferred by DMA is visible to any access - * after DMA has been disabled. This is important for coherent - * DMA regions. - */ - mb(); - if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { int next_lch, cur_lch = lch; char dma_chan_link_map[dma_lch_count]; diff --git a/trunk/arch/arm/plat-omap/include/plat/clock.h b/trunk/arch/arm/plat-omap/include/plat/clock.h index d0ef57c1d71b..240a7b9fd946 100644 --- a/trunk/arch/arm/plat-omap/include/plat/clock.h +++ b/trunk/arch/arm/plat-omap/include/plat/clock.h @@ -272,6 +272,8 @@ struct clk { #endif }; +struct cpufreq_frequency_table; + struct clk_functions { int (*clk_enable)(struct clk *clk); void (*clk_disable)(struct clk *clk); @@ -281,6 +283,10 @@ struct clk_functions { void (*clk_allow_idle)(struct clk *clk); void (*clk_deny_idle)(struct clk *clk); void (*clk_disable_unused)(struct clk *clk); +#ifdef CONFIG_CPU_FREQ + void (*clk_init_cpufreq_table)(struct cpufreq_frequency_table **); + void (*clk_exit_cpufreq_table)(struct cpufreq_frequency_table **); +#endif }; extern int mpurate; @@ -295,6 +301,10 @@ extern void recalculate_root_clocks(void); extern unsigned long followparent_recalc(struct clk *clk); extern void clk_enable_init_clocks(void); unsigned long omap_fixed_divisor_recalc(struct clk *clk); +#ifdef CONFIG_CPU_FREQ +extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table); +extern void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table); +#endif extern struct clk *omap_clk_get_by_name(const char *name); extern int omap_clk_enable_autoidle_all(void); extern int omap_clk_disable_autoidle_all(void); diff --git a/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h b/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h index 3f26db4ee8e6..9e8e63d52aab 100644 --- a/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -47,17 +47,17 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2; * with the original PRCM protocol defined for OMAP2420 */ #define SYSC_TYPE1_MIDLEMODE_SHIFT 12 -#define SYSC_TYPE1_MIDLEMODE_MASK (0x3 << SYSC_TYPE1_MIDLEMODE_SHIFT) +#define SYSC_TYPE1_MIDLEMODE_MASK (0x3 << SYSC_MIDLEMODE_SHIFT) #define SYSC_TYPE1_CLOCKACTIVITY_SHIFT 8 -#define SYSC_TYPE1_CLOCKACTIVITY_MASK (0x3 << SYSC_TYPE1_CLOCKACTIVITY_SHIFT) +#define SYSC_TYPE1_CLOCKACTIVITY_MASK (0x3 << SYSC_CLOCKACTIVITY_SHIFT) #define SYSC_TYPE1_SIDLEMODE_SHIFT 3 -#define SYSC_TYPE1_SIDLEMODE_MASK (0x3 << SYSC_TYPE1_SIDLEMODE_SHIFT) +#define SYSC_TYPE1_SIDLEMODE_MASK (0x3 << SYSC_SIDLEMODE_SHIFT) #define SYSC_TYPE1_ENAWAKEUP_SHIFT 2 -#define SYSC_TYPE1_ENAWAKEUP_MASK (1 << SYSC_TYPE1_ENAWAKEUP_SHIFT) +#define SYSC_TYPE1_ENAWAKEUP_MASK (1 << SYSC_ENAWAKEUP_SHIFT) #define SYSC_TYPE1_SOFTRESET_SHIFT 1 -#define SYSC_TYPE1_SOFTRESET_MASK (1 << SYSC_TYPE1_SOFTRESET_SHIFT) +#define SYSC_TYPE1_SOFTRESET_MASK (1 << SYSC_SOFTRESET_SHIFT) #define SYSC_TYPE1_AUTOIDLE_SHIFT 0 -#define SYSC_TYPE1_AUTOIDLE_MASK (1 << SYSC_TYPE1_AUTOIDLE_SHIFT) +#define SYSC_TYPE1_AUTOIDLE_MASK (1 << SYSC_AUTOIDLE_SHIFT) /* * OCP SYSCONFIG bit shifts/masks TYPE2. These are for IPs compliant @@ -305,7 +305,6 @@ struct omap_hwmod_sysc_fields { * @rev_offs: IP block revision register offset (from module base addr) * @sysc_offs: OCP_SYSCONFIG register offset (from module base addr) * @syss_offs: OCP_SYSSTATUS register offset (from module base addr) - * @srst_udelay: Delay needed after doing a softreset in usecs * @idlemodes: One or more of {SIDLE,MSTANDBY}_{OFF,FORCE,SMART} * @sysc_flags: SYS{C,S}_HAS* flags indicating SYSCONFIG bits supported * @clockact: the default value of the module CLOCKACTIVITY bits @@ -331,10 +330,9 @@ struct omap_hwmod_class_sysconfig { u16 sysc_offs; u16 syss_offs; u16 sysc_flags; - struct omap_hwmod_sysc_fields *sysc_fields; - u8 srst_udelay; u8 idlemodes; u8 clockact; + struct omap_hwmod_sysc_fields *sysc_fields; }; /** diff --git a/trunk/arch/arm/plat-omap/sram.c b/trunk/arch/arm/plat-omap/sram.c index f9a8c5341ee9..eec98afa0f83 100644 --- a/trunk/arch/arm/plat-omap/sram.c +++ b/trunk/arch/arm/plat-omap/sram.c @@ -348,6 +348,7 @@ u32 omap3_configure_core_dpll(u32 m2, u32 unlock_dll, u32 f, u32 inc, sdrc_actim_ctrl_b_1, sdrc_mr_1); } +#ifdef CONFIG_PM void omap3_sram_restore_context(void) { omap_sram_ceil = omap_sram_base + omap_sram_size; @@ -357,18 +358,17 @@ void omap3_sram_restore_context(void) omap3_sram_configure_core_dpll_sz); omap_push_sram_idle(); } +#endif /* CONFIG_PM */ + +#endif /* CONFIG_ARCH_OMAP3 */ static inline int omap34xx_sram_init(void) { +#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) omap3_sram_restore_context(); +#endif return 0; } -#else -static inline int omap34xx_sram_init(void) -{ - return 0; -} -#endif /* CONFIG_ARCH_OMAP3 */ static inline int am33xx_sram_init(void) { diff --git a/trunk/arch/arm/plat-s3c24xx/cpu.c b/trunk/arch/arm/plat-s3c24xx/cpu.c index 290942d9adda..0db73ae646bc 100644 --- a/trunk/arch/arm/plat-s3c24xx/cpu.c +++ b/trunk/arch/arm/plat-s3c24xx/cpu.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/arm/plat-samsung/Kconfig b/trunk/arch/arm/plat-samsung/Kconfig index a0ffc77da809..71553f410016 100644 --- a/trunk/arch/arm/plat-samsung/Kconfig +++ b/trunk/arch/arm/plat-samsung/Kconfig @@ -302,7 +302,6 @@ comment "Power management" config SAMSUNG_PM_DEBUG bool "S3C2410 PM Suspend debug" depends on PM - select DEBUG_LL help Say Y here if you want verbose debugging from the PM Suspend and Resume code. See diff --git a/trunk/arch/arm/plat-samsung/include/plat/sdhci.h b/trunk/arch/arm/plat-samsung/include/plat/sdhci.h index e834c5ef437c..317e246ffc56 100644 --- a/trunk/arch/arm/plat-samsung/include/plat/sdhci.h +++ b/trunk/arch/arm/plat-samsung/include/plat/sdhci.h @@ -18,8 +18,6 @@ #ifndef __PLAT_S3C_SDHCI_H #define __PLAT_S3C_SDHCI_H __FILE__ -#include - struct platform_device; struct mmc_host; struct mmc_card; @@ -358,30 +356,4 @@ static inline void exynos4_default_sdhci3(void) { } #endif /* CONFIG_EXYNOS4_SETUP_SDHCI */ -static inline void s3c_sdhci_setname(int id, char *name) -{ - switch (id) { -#ifdef CONFIG_S3C_DEV_HSMMC - case 0: - s3c_device_hsmmc0.name = name; - break; -#endif -#ifdef CONFIG_S3C_DEV_HSMMC1 - case 1: - s3c_device_hsmmc1.name = name; - break; -#endif -#ifdef CONFIG_S3C_DEV_HSMMC2 - case 2: - s3c_device_hsmmc2.name = name; - break; -#endif -#ifdef CONFIG_S3C_DEV_HSMMC3 - case 3: - s3c_device_hsmmc3.name = name; - break; -#endif - } -} - #endif /* __PLAT_S3C_SDHCI_H */ diff --git a/trunk/arch/arm/vfp/vfpmodule.c b/trunk/arch/arm/vfp/vfpmodule.c index bc683b8219b5..858748eaa144 100644 --- a/trunk/arch/arm/vfp/vfpmodule.c +++ b/trunk/arch/arm/vfp/vfpmodule.c @@ -17,8 +17,6 @@ #include #include #include -#include -#include #include #include @@ -530,103 +528,6 @@ void vfp_flush_hwstate(struct thread_info *thread) put_cpu(); } -/* - * Save the current VFP state into the provided structures and prepare - * for entry into a new function (signal handler). - */ -int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp, - struct user_vfp_exc __user *ufp_exc) -{ - struct thread_info *thread = current_thread_info(); - struct vfp_hard_struct *hwstate = &thread->vfpstate.hard; - int err = 0; - - /* Ensure that the saved hwstate is up-to-date. */ - vfp_sync_hwstate(thread); - - /* - * Copy the floating point registers. There can be unused - * registers see asm/hwcap.h for details. - */ - err |= __copy_to_user(&ufp->fpregs, &hwstate->fpregs, - sizeof(hwstate->fpregs)); - /* - * Copy the status and control register. - */ - __put_user_error(hwstate->fpscr, &ufp->fpscr, err); - - /* - * Copy the exception registers. - */ - __put_user_error(hwstate->fpexc, &ufp_exc->fpexc, err); - __put_user_error(hwstate->fpinst, &ufp_exc->fpinst, err); - __put_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err); - - if (err) - return -EFAULT; - - /* Ensure that VFP is disabled. */ - vfp_flush_hwstate(thread); - - /* - * As per the PCS, clear the length and stride bits for function - * entry. - */ - hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK); - - /* - * Disable VFP in the hwstate so that we can detect if it gets - * used. - */ - hwstate->fpexc &= ~FPEXC_EN; - return 0; -} - -/* Sanitise and restore the current VFP state from the provided structures. */ -int vfp_restore_user_hwstate(struct user_vfp __user *ufp, - struct user_vfp_exc __user *ufp_exc) -{ - struct thread_info *thread = current_thread_info(); - struct vfp_hard_struct *hwstate = &thread->vfpstate.hard; - unsigned long fpexc; - int err = 0; - - /* - * If VFP has been used, then disable it to avoid corrupting - * the new thread state. - */ - if (hwstate->fpexc & FPEXC_EN) - vfp_flush_hwstate(thread); - - /* - * Copy the floating point registers. There can be unused - * registers see asm/hwcap.h for details. - */ - err |= __copy_from_user(&hwstate->fpregs, &ufp->fpregs, - sizeof(hwstate->fpregs)); - /* - * Copy the status and control register. - */ - __get_user_error(hwstate->fpscr, &ufp->fpscr, err); - - /* - * Sanitise and restore the exception registers. - */ - __get_user_error(fpexc, &ufp_exc->fpexc, err); - - /* Ensure the VFP is enabled. */ - fpexc |= FPEXC_EN; - - /* Ensure FPINST2 is invalid and the exception flag is cleared. */ - fpexc &= ~(FPEXC_EX | FPEXC_FP2V); - hwstate->fpexc = fpexc; - - __get_user_error(hwstate->fpinst, &ufp_exc->fpinst, err); - __get_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err); - - return err ? -EFAULT : 0; -} - /* * VFP hardware can lose all context when a CPU goes offline. * As we will be running in SMP mode with CPU hotplug, we will save the diff --git a/trunk/arch/avr32/boot/images/Makefile b/trunk/arch/avr32/boot/images/Makefile index 2a3b53978a3b..1848bf0d7f62 100644 --- a/trunk/arch/avr32/boot/images/Makefile +++ b/trunk/arch/avr32/boot/images/Makefile @@ -6,6 +6,8 @@ # for more details. # +MKIMAGE := $(srctree)/scripts/mkuboot.sh + extra-y := vmlinux.bin vmlinux.gz OBJCOPYFLAGS_vmlinux.bin := -O binary -R .note.gnu.build-id @@ -15,9 +17,10 @@ $(obj)/vmlinux.bin: vmlinux FORCE $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE $(call if_changed,gzip) -UIMAGE_LOADADDR = $(CONFIG_LOAD_ADDRESS) -UIMAGE_ENTRYADDR = $(CONFIG_ENTRY_ADDRESS) -UIMAGE_COMPRESSION = gzip +quiet_cmd_uimage = UIMAGE $@ + cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A avr32 -O linux -T kernel \ + -C gzip -a $(CONFIG_LOAD_ADDRESS) -e $(CONFIG_ENTRY_ADDRESS) \ + -n 'Linux-$(KERNELRELEASE)' -d $< $@ targets += uImage uImage.srec $(obj)/uImage: $(obj)/vmlinux.gz diff --git a/trunk/arch/avr32/include/asm/barrier.h b/trunk/arch/avr32/include/asm/barrier.h index 0961275373db..808001c9cf8c 100644 --- a/trunk/arch/avr32/include/asm/barrier.h +++ b/trunk/arch/avr32/include/asm/barrier.h @@ -8,8 +8,6 @@ #ifndef __ASM_AVR32_BARRIER_H #define __ASM_AVR32_BARRIER_H -#define nop() asm volatile("nop") - #define mb() asm volatile("" : : : "memory") #define rmb() mb() #define wmb() asm volatile("sync 0" : : : "memory") diff --git a/trunk/arch/avr32/include/asm/special_insns.h b/trunk/arch/avr32/include/asm/special_insns.h new file mode 100644 index 000000000000..f922218dfaa5 --- /dev/null +++ b/trunk/arch/avr32/include/asm/special_insns.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2004-2006 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_AVR32_SPECIAL_INSNS_H +#define __ASM_AVR32_SPECIAL_INSNS_H + +#define nop() asm volatile("nop") + +#endif /* __ASM_AVR32_SPECIAL_INSNS_H */ diff --git a/trunk/arch/avr32/mach-at32ap/include/mach/board.h b/trunk/arch/avr32/mach-at32ap/include/mach/board.h index 70742ec997f8..71733866cb4f 100644 --- a/trunk/arch/avr32/mach-at32ap/include/mach/board.h +++ b/trunk/arch/avr32/mach-at32ap/include/mach/board.h @@ -7,7 +7,7 @@ #include #include #include -#include +#include #define GPIO_PIN_NONE (-1) diff --git a/trunk/arch/blackfin/Kconfig b/trunk/arch/blackfin/Kconfig index 373a6902d8fa..c1269a1085e1 100644 --- a/trunk/arch/blackfin/Kconfig +++ b/trunk/arch/blackfin/Kconfig @@ -823,7 +823,7 @@ config CACHELINE_ALIGNED_L1 bool "Locate cacheline_aligned data to L1 Data Memory" default y if !BF54x default n if BF54x - depends on !SMP && !BF531 && !CRC32 + depends on !SMP && !BF531 help If enabled, cacheline_aligned data is linked into L1 data memory. (less latency) diff --git a/trunk/arch/blackfin/boot/Makefile b/trunk/arch/blackfin/boot/Makefile index f7d27d50d02c..0a49279e3428 100644 --- a/trunk/arch/blackfin/boot/Makefile +++ b/trunk/arch/blackfin/boot/Makefile @@ -6,17 +6,20 @@ # for more details. # +MKIMAGE := $(srctree)/scripts/mkuboot.sh + targets := vmImage vmImage.bin vmImage.bz2 vmImage.gz vmImage.lzma vmImage.lzo vmImage.xip extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.xip -ifeq ($(CONFIG_RAMKERNEL),y) -UIMAGE_LOADADDR = $(CONFIG_BOOT_LOAD) -else # CONFIG_ROMKERNEL must be set -UIMAGE_LOADADDR = $(CONFIG_ROM_BASE) -endif -UIMAGE_ENTRYADDR = $(shell $(NM) vmlinux | awk '$$NF == "__start" {print $$1}') -UIMAGE_NAME = '$(CPU_REV)-$(KERNELRELEASE)' -UIMAGE_OPTS-$(CONFIG_ROMKERNEL) += -x +UIMAGE_OPTS-y := +UIMAGE_OPTS-$(CONFIG_RAMKERNEL) += -a $(CONFIG_BOOT_LOAD) +UIMAGE_OPTS-$(CONFIG_ROMKERNEL) += -a $(CONFIG_ROM_BASE) -x + +quiet_cmd_uimage = UIMAGE $@ + cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(ARCH) -O linux -T kernel \ + -C $(2) -n '$(CPU_REV)-$(KERNELRELEASE)' \ + -e $(shell $(NM) vmlinux | awk '$$NF == "__start" {print $$1}') \ + $(UIMAGE_OPTS-y) -d $< $@ $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) diff --git a/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig b/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig index 90b175323644..9ccc18a6b4df 100644 --- a/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig +++ b/trunk/arch/blackfin/configs/BF527-EZKIT_defconfig @@ -147,7 +147,6 @@ CONFIG_USB_OTG_BLACKLIST_HUB=y CONFIG_USB_MON=y CONFIG_USB_MUSB_HDRC=y CONFIG_USB_MUSB_BLACKFIN=y -CONFIG_MUSB_PIO_ONLY=y CONFIG_USB_STORAGE=y CONFIG_USB_GADGET=y CONFIG_RTC_CLASS=y diff --git a/trunk/arch/blackfin/include/asm/cmpxchg.h b/trunk/arch/blackfin/include/asm/cmpxchg.h index c05868cc61c1..ba2484f4cb2a 100644 --- a/trunk/arch/blackfin/include/asm/cmpxchg.h +++ b/trunk/arch/blackfin/include/asm/cmpxchg.h @@ -122,8 +122,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, (unsigned long)(n), sizeof(*(ptr)))) #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) -#define cmpxchg(ptr, o, n) cmpxchg_local((ptr), (o), (n)) -#define cmpxchg64(ptr, o, n) cmpxchg64_local((ptr), (o), (n)) +#include #endif /* !CONFIG_SMP */ diff --git a/trunk/arch/blackfin/include/asm/gpio.h b/trunk/arch/blackfin/include/asm/gpio.h index 12d3571b5232..5a25856381ff 100644 --- a/trunk/arch/blackfin/include/asm/gpio.h +++ b/trunk/arch/blackfin/include/asm/gpio.h @@ -244,24 +244,14 @@ static inline int gpio_set_debounce(unsigned gpio, unsigned debounce) return -EINVAL; } -static inline int __gpio_get_value(unsigned gpio) -{ - return bfin_gpio_get_value(gpio); -} - -static inline void __gpio_set_value(unsigned gpio, int value) -{ - return bfin_gpio_set_value(gpio, value); -} - static inline int gpio_get_value(unsigned gpio) { - return __gpio_get_value(gpio); + return bfin_gpio_get_value(gpio); } static inline void gpio_set_value(unsigned gpio, int value) { - return __gpio_set_value(gpio, value); + return bfin_gpio_set_value(gpio, value); } static inline int gpio_to_irq(unsigned gpio) diff --git a/trunk/arch/blackfin/kernel/setup.c b/trunk/arch/blackfin/kernel/setup.c index 2ad747e909fb..2aa019368504 100644 --- a/trunk/arch/blackfin/kernel/setup.c +++ b/trunk/arch/blackfin/kernel/setup.c @@ -550,7 +550,6 @@ static __init void memory_setup(void) { #ifdef CONFIG_MTD_UCLINUX unsigned long mtd_phys = 0; - unsigned long n; #endif unsigned long max_mem; @@ -594,9 +593,9 @@ static __init void memory_setup(void) mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 8))); # if defined(CONFIG_EXT2_FS) || defined(CONFIG_EXT3_FS) - n = ext2_image_size((void *)(mtd_phys + 0x400)); - if (n) - mtd_size = PAGE_ALIGN(n * 1024); + if (*((unsigned short *)(mtd_phys + 0x438)) == EXT2_SUPER_MAGIC) + mtd_size = + PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x404)) << 10); # endif # if defined(CONFIG_CRAMFS) diff --git a/trunk/arch/blackfin/mach-bf538/boards/ezkit.c b/trunk/arch/blackfin/mach-bf538/boards/ezkit.c index 85038f54354d..1633a6f306c0 100644 --- a/trunk/arch/blackfin/mach-bf538/boards/ezkit.c +++ b/trunk/arch/blackfin/mach-bf538/boards/ezkit.c @@ -38,7 +38,7 @@ static struct platform_device rtc_device = { .name = "rtc-bfin", .id = -1, }; -#endif /* CONFIG_RTC_DRV_BFIN */ +#endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) #ifdef CONFIG_SERIAL_BFIN_UART0 @@ -100,7 +100,7 @@ static struct platform_device bfin_uart0_device = { .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ }, }; -#endif /* CONFIG_SERIAL_BFIN_UART0 */ +#endif #ifdef CONFIG_SERIAL_BFIN_UART1 static struct resource bfin_uart1_resources[] = { { @@ -148,7 +148,7 @@ static struct platform_device bfin_uart1_device = { .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ }, }; -#endif /* CONFIG_SERIAL_BFIN_UART1 */ +#endif #ifdef CONFIG_SERIAL_BFIN_UART2 static struct resource bfin_uart2_resources[] = { { @@ -196,8 +196,8 @@ static struct platform_device bfin_uart2_device = { .platform_data = &bfin_uart2_peripherals, /* Passed to driver */ }, }; -#endif /* CONFIG_SERIAL_BFIN_UART2 */ -#endif /* CONFIG_SERIAL_BFIN */ +#endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -224,7 +224,7 @@ static struct platform_device bfin_sir0_device = { .num_resources = ARRAY_SIZE(bfin_sir0_resources), .resource = bfin_sir0_resources, }; -#endif /* CONFIG_BFIN_SIR0 */ +#endif #ifdef CONFIG_BFIN_SIR1 static struct resource bfin_sir1_resources[] = { { @@ -249,7 +249,7 @@ static struct platform_device bfin_sir1_device = { .num_resources = ARRAY_SIZE(bfin_sir1_resources), .resource = bfin_sir1_resources, }; -#endif /* CONFIG_BFIN_SIR1 */ +#endif #ifdef CONFIG_BFIN_SIR2 static struct resource bfin_sir2_resources[] = { { @@ -274,8 +274,8 @@ static struct platform_device bfin_sir2_device = { .num_resources = ARRAY_SIZE(bfin_sir2_resources), .resource = bfin_sir2_resources, }; -#endif /* CONFIG_BFIN_SIR2 */ -#endif /* CONFIG_BFIN_SIR */ +#endif +#endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) #ifdef CONFIG_SERIAL_BFIN_SPORT0_UART @@ -311,7 +311,7 @@ static struct platform_device bfin_sport0_uart_device = { .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ }, }; -#endif /* CONFIG_SERIAL_BFIN_SPORT0_UART */ +#endif #ifdef CONFIG_SERIAL_BFIN_SPORT1_UART static struct resource bfin_sport1_uart_resources[] = { { @@ -345,7 +345,7 @@ static struct platform_device bfin_sport1_uart_device = { .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ }, }; -#endif /* CONFIG_SERIAL_BFIN_SPORT1_UART */ +#endif #ifdef CONFIG_SERIAL_BFIN_SPORT2_UART static struct resource bfin_sport2_uart_resources[] = { { @@ -379,7 +379,7 @@ static struct platform_device bfin_sport2_uart_device = { .platform_data = &bfin_sport2_peripherals, /* Passed to driver */ }, }; -#endif /* CONFIG_SERIAL_BFIN_SPORT2_UART */ +#endif #ifdef CONFIG_SERIAL_BFIN_SPORT3_UART static struct resource bfin_sport3_uart_resources[] = { { @@ -413,8 +413,8 @@ static struct platform_device bfin_sport3_uart_device = { .platform_data = &bfin_sport3_peripherals, /* Passed to driver */ }, }; -#endif /* CONFIG_SERIAL_BFIN_SPORT3_UART */ -#endif /* CONFIG_SERIAL_BFIN_SPORT */ +#endif +#endif #if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE) static unsigned short bfin_can_peripherals[] = { @@ -452,7 +452,7 @@ static struct platform_device bfin_can_device = { .platform_data = &bfin_can_peripherals, /* Passed to driver */ }, }; -#endif /* CONFIG_CAN_BFIN */ +#endif /* * USB-LAN EzExtender board @@ -488,7 +488,7 @@ static struct platform_device smc91x_device = { .platform_data = &smc91x_info, }, }; -#endif /* CONFIG_SMC91X */ +#endif #if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE) /* all SPI peripherals info goes here */ @@ -518,8 +518,7 @@ static struct flash_platform_data bfin_spi_flash_data = { static struct bfin5xx_spi_chip spi_flash_chip_info = { .enable_dma = 0, /* use dma transfer with this chip*/ }; -#endif /* CONFIG_MTD_M25P80 */ -#endif /* CONFIG_SPI_BFIN5XX */ +#endif #if defined(CONFIG_TOUCHSCREEN_AD7879) || defined(CONFIG_TOUCHSCREEN_AD7879_MODULE) #include @@ -536,7 +535,7 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = { .gpio_export = 1, /* Export GPIO to gpiolib */ .gpio_base = -1, /* Dynamic allocation */ }; -#endif /* CONFIG_TOUCHSCREEN_AD7879 */ +#endif #if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) #include @@ -565,7 +564,7 @@ static struct platform_device bfin_lq035q1_device = { .platform_data = &bfin_lq035q1_data, }, }; -#endif /* CONFIG_FB_BFIN_LQ035Q1 */ +#endif static struct spi_board_info bf538_spi_board_info[] __initdata = { #if defined(CONFIG_MTD_M25P80) \ @@ -580,7 +579,7 @@ static struct spi_board_info bf538_spi_board_info[] __initdata = { .controller_data = &spi_flash_chip_info, .mode = SPI_MODE_3, }, -#endif /* CONFIG_MTD_M25P80 */ +#endif #if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE) { .modalias = "ad7879", @@ -591,7 +590,7 @@ static struct spi_board_info bf538_spi_board_info[] __initdata = { .chip_select = 1, .mode = SPI_CPHA | SPI_CPOL, }, -#endif /* CONFIG_TOUCHSCREEN_AD7879_SPI */ +#endif #if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) { .modalias = "bfin-lq035q1-spi", @@ -600,7 +599,7 @@ static struct spi_board_info bf538_spi_board_info[] __initdata = { .chip_select = 2, .mode = SPI_CPHA | SPI_CPOL, }, -#endif /* CONFIG_FB_BFIN_LQ035Q1 */ +#endif #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) { .modalias = "spidev", @@ -608,7 +607,7 @@ static struct spi_board_info bf538_spi_board_info[] __initdata = { .bus_num = 0, .chip_select = 1, }, -#endif /* CONFIG_SPI_SPIDEV */ +#endif }; /* SPI (0) */ @@ -717,6 +716,8 @@ static struct platform_device bf538_spi_master2 = { }, }; +#endif /* spi master and devices */ + #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) static struct resource bfin_twi0_resource[] = { [0] = { @@ -758,8 +759,8 @@ static struct platform_device i2c_bfin_twi1_device = { .num_resources = ARRAY_SIZE(bfin_twi1_resource), .resource = bfin_twi1_resource, }; -#endif /* CONFIG_BF542 */ -#endif /* CONFIG_I2C_BLACKFIN_TWI */ +#endif +#endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) #include diff --git a/trunk/arch/c6x/include/asm/irq.h b/trunk/arch/c6x/include/asm/irq.h index ab4577f93d96..f13b78d5e1ca 100644 --- a/trunk/arch/c6x/include/asm/irq.h +++ b/trunk/arch/c6x/include/asm/irq.h @@ -42,6 +42,10 @@ /* This number is used when no interrupt has been assigned */ #define NO_IRQ 0 +struct irq_data; +extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d); +extern irq_hw_number_t virq_to_hw(unsigned int virq); + extern void __init init_pic_c64xplus(void); extern void init_IRQ(void); diff --git a/trunk/arch/c6x/kernel/irq.c b/trunk/arch/c6x/kernel/irq.c index c90fb5e82ad7..65b8ddf54b44 100644 --- a/trunk/arch/c6x/kernel/irq.c +++ b/trunk/arch/c6x/kernel/irq.c @@ -130,3 +130,16 @@ int arch_show_interrupts(struct seq_file *p, int prec) seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count); return 0; } + +irq_hw_number_t irqd_to_hwirq(struct irq_data *d) +{ + return d->hwirq; +} +EXPORT_SYMBOL_GPL(irqd_to_hwirq); + +irq_hw_number_t virq_to_hw(unsigned int virq) +{ + struct irq_data *irq_data = irq_get_irq_data(virq); + return WARN_ON(!irq_data) ? 0 : irq_data->hwirq; +} +EXPORT_SYMBOL_GPL(virq_to_hw); diff --git a/trunk/arch/c6x/kernel/signal.c b/trunk/arch/c6x/kernel/signal.c index 3b5a05099989..304f675826e9 100644 --- a/trunk/arch/c6x/kernel/signal.c +++ b/trunk/arch/c6x/kernel/signal.c @@ -85,7 +85,10 @@ asmlinkage int do_rt_sigreturn(struct pt_regs *regs) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) goto badframe; @@ -276,8 +279,15 @@ static int handle_signal(int sig, /* Set up the stack frame */ ret = setup_rt_frame(sig, ka, info, oldset, regs); - if (ret == 0) - block_sigmask(ka, sig); + if (ret == 0) { + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked, ¤t->blocked, + &ka->sa.sa_mask); + if (!(ka->sa.sa_flags & SA_NODEFER)) + sigaddset(¤t->blocked, sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + } return ret; } diff --git a/trunk/arch/frv/mb93090-mb00/pci-dma.c b/trunk/arch/frv/mb93090-mb00/pci-dma.c index 4f8d8bcdc7de..41098a3803a2 100644 --- a/trunk/arch/frv/mb93090-mb00/pci-dma.c +++ b/trunk/arch/frv/mb93090-mb00/pci-dma.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/hexagon/include/asm/dma-mapping.h b/trunk/arch/hexagon/include/asm/dma-mapping.h index 233ed3d2d25e..448b224ba4ef 100644 --- a/trunk/arch/hexagon/include/asm/dma-mapping.h +++ b/trunk/arch/hexagon/include/asm/dma-mapping.h @@ -71,35 +71,29 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) return (dma_addr == bad_dma_address); } -#define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) - -static inline void *dma_alloc_attrs(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag, - struct dma_attrs *attrs) +static inline void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) { void *ret; struct dma_map_ops *ops = get_dma_ops(dev); BUG_ON(!dma_ops); - ret = ops->alloc(dev, size, dma_handle, flag, attrs); + ret = ops->alloc_coherent(dev, size, dma_handle, flag); debug_dma_alloc_coherent(dev, size, *dma_handle, ret); return ret; } -#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) - -static inline void dma_free_attrs(struct device *dev, size_t size, - void *cpu_addr, dma_addr_t dma_handle, - struct dma_attrs *attrs) +static inline void dma_free_coherent(struct device *dev, size_t size, + void *cpu_addr, dma_addr_t dma_handle) { struct dma_map_ops *dma_ops = get_dma_ops(dev); BUG_ON(!dma_ops); - dma_ops->free(dev, size, cpu_addr, dma_handle, attrs); + dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); } diff --git a/trunk/arch/hexagon/kernel/dma.c b/trunk/arch/hexagon/kernel/dma.c index 0f2367cc5493..e711ace62fdf 100644 --- a/trunk/arch/hexagon/kernel/dma.c +++ b/trunk/arch/hexagon/kernel/dma.c @@ -22,7 +22,6 @@ #include #include #include -#include struct dma_map_ops *dma_ops; EXPORT_SYMBOL(dma_ops); @@ -55,8 +54,7 @@ static struct gen_pool *coherent_pool; /* Allocates from a pool of uncached memory that was reserved at boot time */ void *hexagon_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_addr, gfp_t flag, - struct dma_attrs *attrs) + dma_addr_t *dma_addr, gfp_t flag) { void *ret; @@ -83,7 +81,7 @@ void *hexagon_dma_alloc_coherent(struct device *dev, size_t size, } static void hexagon_free_coherent(struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_addr, struct dma_attrs *attrs) + dma_addr_t dma_addr) { gen_pool_free(coherent_pool, (unsigned long) vaddr, size); } @@ -204,8 +202,8 @@ static void hexagon_sync_single_for_device(struct device *dev, } struct dma_map_ops hexagon_dma_ops = { - .alloc = hexagon_dma_alloc_coherent, - .free = hexagon_free_coherent, + .alloc_coherent = hexagon_dma_alloc_coherent, + .free_coherent = hexagon_free_coherent, .map_sg = hexagon_map_sg, .map_page = hexagon_map_page, .sync_single_for_cpu = hexagon_sync_single_for_cpu, diff --git a/trunk/arch/hexagon/kernel/process.c b/trunk/arch/hexagon/kernel/process.c index ff02821bfb7e..18c4f0b0f4ba 100644 --- a/trunk/arch/hexagon/kernel/process.c +++ b/trunk/arch/hexagon/kernel/process.c @@ -1,7 +1,7 @@ /* * Process creation support for Hexagon * - * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved. + * Copyright (c) 2010-2011, Code Aurora Forum. 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 version 2 and @@ -88,7 +88,7 @@ void (*idle_sleep)(void) = default_idle; void cpu_idle(void) { while (1) { - tick_nohz_idle_enter(); + tick_nohz_stop_sched_tick(1); local_irq_disable(); while (!need_resched()) { idle_sleep(); @@ -97,7 +97,7 @@ void cpu_idle(void) local_irq_disable(); } local_irq_enable(); - tick_nohz_idle_exit(); + tick_nohz_restart_sched_tick(); schedule(); } } diff --git a/trunk/arch/hexagon/kernel/ptrace.c b/trunk/arch/hexagon/kernel/ptrace.c index 96c3b2c4dbad..32342de1a79c 100644 --- a/trunk/arch/hexagon/kernel/ptrace.c +++ b/trunk/arch/hexagon/kernel/ptrace.c @@ -28,7 +28,6 @@ #include #include #include -#include #include diff --git a/trunk/arch/hexagon/kernel/smp.c b/trunk/arch/hexagon/kernel/smp.c index 1298141874a3..15d1fd22bbc5 100644 --- a/trunk/arch/hexagon/kernel/smp.c +++ b/trunk/arch/hexagon/kernel/smp.c @@ -1,7 +1,7 @@ /* * SMP support for Hexagon * - * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved. + * Copyright (c) 2010-2011, Code Aurora Forum. 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 version 2 and @@ -28,7 +28,6 @@ #include #include #include -#include #include /* timer_interrupt */ #include @@ -36,7 +35,7 @@ #define BASE_IPI_IRQ 26 /* - * cpu_possible_mask needs to be filled out prior to setup_per_cpu_areas + * cpu_possible_map needs to be filled out prior to setup_per_cpu_areas * (which is prior to any of our smp_prepare_cpu crap), in order to set * up the... per_cpu areas. */ @@ -178,12 +177,7 @@ void __cpuinit start_secondary(void) printk(KERN_INFO "%s cpu %d\n", __func__, current_thread_info()->cpu); - notify_cpu_starting(cpu); - - ipi_call_lock(); set_cpu_online(cpu, true); - ipi_call_unlock(); - local_irq_enable(); cpu_idle(); @@ -214,7 +208,7 @@ int __cpuinit __cpu_up(unsigned int cpu) stack_start = ((void *) thread) + THREAD_SIZE; __vmstart(start_secondary, stack_start); - while (!cpu_online(cpu)) + while (!cpu_isset(cpu, cpu_online_map)) barrier(); return 0; @@ -235,7 +229,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) /* Right now, let's just fake it. */ for (i = 0; i < max_cpus; i++) - set_cpu_present(i, true); + cpu_set(i, cpu_present_map); /* Also need to register the interrupts for IPI */ if (max_cpus > 1) @@ -275,5 +269,5 @@ void smp_start_cpus(void) int i; for (i = 0; i < NR_CPUS; i++) - set_cpu_possible(i, true); + cpu_set(i, cpu_possible_map); } diff --git a/trunk/arch/hexagon/kernel/time.c b/trunk/arch/hexagon/kernel/time.c index 5d9b33b67935..6bee15c9c113 100644 --- a/trunk/arch/hexagon/kernel/time.c +++ b/trunk/arch/hexagon/kernel/time.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/hexagon/kernel/vdso.c b/trunk/arch/hexagon/kernel/vdso.c index 5d39f42f7085..f212a453b527 100644 --- a/trunk/arch/hexagon/kernel/vdso.c +++ b/trunk/arch/hexagon/kernel/vdso.c @@ -21,7 +21,6 @@ #include #include #include -#include #include diff --git a/trunk/arch/ia64/hp/common/sba_iommu.c b/trunk/arch/ia64/hp/common/sba_iommu.c index bcda5b2d121a..f6ea3a3b4a84 100644 --- a/trunk/arch/ia64/hp/common/sba_iommu.c +++ b/trunk/arch/ia64/hp/common/sba_iommu.c @@ -1129,8 +1129,7 @@ void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, * See Documentation/DMA-API-HOWTO.txt */ static void * -sba_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, - gfp_t flags, struct dma_attrs *attrs) +sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags) { struct ioc *ioc; void *addr; @@ -1192,8 +1191,8 @@ sba_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, * * See Documentation/DMA-API-HOWTO.txt */ -static void sba_free_coherent(struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_handle, struct dma_attrs *attrs) +static void sba_free_coherent (struct device *dev, size_t size, void *vaddr, + dma_addr_t dma_handle) { sba_unmap_single_attrs(dev, dma_handle, size, 0, NULL); free_pages((unsigned long) vaddr, get_order(size)); @@ -2213,8 +2212,8 @@ sba_page_override(char *str) __setup("sbapagesize=",sba_page_override); struct dma_map_ops sba_dma_ops = { - .alloc = sba_alloc_coherent, - .free = sba_free_coherent, + .alloc_coherent = sba_alloc_coherent, + .free_coherent = sba_free_coherent, .map_page = sba_map_page, .unmap_page = sba_unmap_page, .map_sg = sba_map_sg_attrs, diff --git a/trunk/arch/ia64/include/asm/cmpxchg.h b/trunk/arch/ia64/include/asm/cmpxchg.h index 4f37dbbb8640..507c66c77600 100644 --- a/trunk/arch/ia64/include/asm/cmpxchg.h +++ b/trunk/arch/ia64/include/asm/cmpxchg.h @@ -1,147 +1 @@ -#ifndef _ASM_IA64_CMPXCHG_H -#define _ASM_IA64_CMPXCHG_H - -/* - * Compare/Exchange, forked from asm/intrinsics.h - * which was: - * - * Copyright (C) 2002-2003 Hewlett-Packard Co - * David Mosberger-Tang - */ - -#ifndef __ASSEMBLY__ - -#include -/* include compiler specific intrinsics */ -#include -#ifdef __INTEL_COMPILER -# include -#else -# include -#endif - -/* - * This function doesn't exist, so you'll get a linker error if - * something tries to do an invalid xchg(). - */ -extern void ia64_xchg_called_with_bad_pointer(void); - -#define __xchg(x, ptr, size) \ -({ \ - unsigned long __xchg_result; \ - \ - switch (size) { \ - case 1: \ - __xchg_result = ia64_xchg1((__u8 *)ptr, x); \ - break; \ - \ - case 2: \ - __xchg_result = ia64_xchg2((__u16 *)ptr, x); \ - break; \ - \ - case 4: \ - __xchg_result = ia64_xchg4((__u32 *)ptr, x); \ - break; \ - \ - case 8: \ - __xchg_result = ia64_xchg8((__u64 *)ptr, x); \ - break; \ - default: \ - ia64_xchg_called_with_bad_pointer(); \ - } \ - __xchg_result; \ -}) - -#define xchg(ptr, x) \ -((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr)))) - -/* - * Atomic compare and exchange. Compare OLD with MEM, if identical, - * store NEW in MEM. Return the initial value in MEM. Success is - * indicated by comparing RETURN with OLD. - */ - -#define __HAVE_ARCH_CMPXCHG 1 - -/* - * This function doesn't exist, so you'll get a linker error - * if something tries to do an invalid cmpxchg(). - */ -extern long ia64_cmpxchg_called_with_bad_pointer(void); - -#define ia64_cmpxchg(sem, ptr, old, new, size) \ -({ \ - __u64 _o_, _r_; \ - \ - switch (size) { \ - case 1: \ - _o_ = (__u8) (long) (old); \ - break; \ - case 2: \ - _o_ = (__u16) (long) (old); \ - break; \ - case 4: \ - _o_ = (__u32) (long) (old); \ - break; \ - case 8: \ - _o_ = (__u64) (long) (old); \ - break; \ - default: \ - break; \ - } \ - switch (size) { \ - case 1: \ - _r_ = ia64_cmpxchg1_##sem((__u8 *) ptr, new, _o_); \ - break; \ - \ - case 2: \ - _r_ = ia64_cmpxchg2_##sem((__u16 *) ptr, new, _o_); \ - break; \ - \ - case 4: \ - _r_ = ia64_cmpxchg4_##sem((__u32 *) ptr, new, _o_); \ - break; \ - \ - case 8: \ - _r_ = ia64_cmpxchg8_##sem((__u64 *) ptr, new, _o_); \ - break; \ - \ - default: \ - _r_ = ia64_cmpxchg_called_with_bad_pointer(); \ - break; \ - } \ - (__typeof__(old)) _r_; \ -}) - -#define cmpxchg_acq(ptr, o, n) \ - ia64_cmpxchg(acq, (ptr), (o), (n), sizeof(*(ptr))) -#define cmpxchg_rel(ptr, o, n) \ - ia64_cmpxchg(rel, (ptr), (o), (n), sizeof(*(ptr))) - -/* for compatibility with other platforms: */ -#define cmpxchg(ptr, o, n) cmpxchg_acq((ptr), (o), (n)) -#define cmpxchg64(ptr, o, n) cmpxchg_acq((ptr), (o), (n)) - -#define cmpxchg_local cmpxchg -#define cmpxchg64_local cmpxchg64 - -#ifdef CONFIG_IA64_DEBUG_CMPXCHG -# define CMPXCHG_BUGCHECK_DECL int _cmpxchg_bugcheck_count = 128; -# define CMPXCHG_BUGCHECK(v) \ -do { \ - if (_cmpxchg_bugcheck_count-- <= 0) { \ - void *ip; \ - extern int printk(const char *fmt, ...); \ - ip = (void *) ia64_getreg(_IA64_REG_IP); \ - printk("CMPXCHG_BUGCHECK: stuck at %p on word %p\n", ip, (v));\ - break; \ - } \ -} while (0) -#else /* !CONFIG_IA64_DEBUG_CMPXCHG */ -# define CMPXCHG_BUGCHECK_DECL -# define CMPXCHG_BUGCHECK(v) -#endif /* !CONFIG_IA64_DEBUG_CMPXCHG */ - -#endif /* !__ASSEMBLY__ */ - -#endif /* _ASM_IA64_CMPXCHG_H */ +/* Future home of xchg() and cmpxchg() */ diff --git a/trunk/arch/ia64/include/asm/dma-mapping.h b/trunk/arch/ia64/include/asm/dma-mapping.h index 4f5e8148440d..4336d080b241 100644 --- a/trunk/arch/ia64/include/asm/dma-mapping.h +++ b/trunk/arch/ia64/include/asm/dma-mapping.h @@ -23,29 +23,23 @@ extern void machvec_dma_sync_single(struct device *, dma_addr_t, size_t, extern void machvec_dma_sync_sg(struct device *, struct scatterlist *, int, enum dma_data_direction); -#define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) - -static inline void *dma_alloc_attrs(struct device *dev, size_t size, - dma_addr_t *daddr, gfp_t gfp, - struct dma_attrs *attrs) +static inline void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *daddr, gfp_t gfp) { struct dma_map_ops *ops = platform_dma_get_ops(dev); void *caddr; - caddr = ops->alloc(dev, size, daddr, gfp, attrs); + caddr = ops->alloc_coherent(dev, size, daddr, gfp); debug_dma_alloc_coherent(dev, size, *daddr, caddr); return caddr; } -#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) - -static inline void dma_free_attrs(struct device *dev, size_t size, - void *caddr, dma_addr_t daddr, - struct dma_attrs *attrs) +static inline void dma_free_coherent(struct device *dev, size_t size, + void *caddr, dma_addr_t daddr) { struct dma_map_ops *ops = platform_dma_get_ops(dev); debug_dma_free_coherent(dev, size, caddr, daddr); - ops->free(dev, size, caddr, daddr, attrs); + ops->free_coherent(dev, size, caddr, daddr); } #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) diff --git a/trunk/arch/ia64/include/asm/futex.h b/trunk/arch/ia64/include/asm/futex.h index d2bf1fd5e44f..0ab82cc2dc8f 100644 --- a/trunk/arch/ia64/include/asm/futex.h +++ b/trunk/arch/ia64/include/asm/futex.h @@ -106,16 +106,15 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, return -EFAULT; { - register unsigned long r8 __asm ("r8"); + register unsigned long r8 __asm ("r8") = 0; unsigned long prev; __asm__ __volatile__( " mf;; \n" - " mov %0=r0 \n" - " mov ar.ccv=%4;; \n" - "[1:] cmpxchg4.acq %1=[%2],%3,ar.ccv \n" + " mov ar.ccv=%3;; \n" + "[1:] cmpxchg4.acq %0=[%1],%2,ar.ccv \n" " .xdata4 \"__ex_table\", 1b-., 2f-. \n" "[2:]" - : "=r" (r8), "=r" (prev) + : "=r" (prev) : "r" (uaddr), "r" (newval), "rO" ((long) (unsigned) oldval) : "memory"); diff --git a/trunk/arch/ia64/include/asm/intrinsics.h b/trunk/arch/ia64/include/asm/intrinsics.h index d129e367e764..e4076b511829 100644 --- a/trunk/arch/ia64/include/asm/intrinsics.h +++ b/trunk/arch/ia64/include/asm/intrinsics.h @@ -18,7 +18,6 @@ #else # include #endif -#include #define ia64_native_get_psr_i() (ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I) @@ -82,6 +81,119 @@ extern unsigned long __bad_increment_for_ia64_fetch_and_add (void); #define ia64_fetch_and_add(i,v) (ia64_fetchadd(i, v, rel) + (i)) /* return new value */ +/* + * This function doesn't exist, so you'll get a linker error if + * something tries to do an invalid xchg(). + */ +extern void ia64_xchg_called_with_bad_pointer (void); + +#define __xchg(x,ptr,size) \ +({ \ + unsigned long __xchg_result; \ + \ + switch (size) { \ + case 1: \ + __xchg_result = ia64_xchg1((__u8 *)ptr, x); \ + break; \ + \ + case 2: \ + __xchg_result = ia64_xchg2((__u16 *)ptr, x); \ + break; \ + \ + case 4: \ + __xchg_result = ia64_xchg4((__u32 *)ptr, x); \ + break; \ + \ + case 8: \ + __xchg_result = ia64_xchg8((__u64 *)ptr, x); \ + break; \ + default: \ + ia64_xchg_called_with_bad_pointer(); \ + } \ + __xchg_result; \ +}) + +#define xchg(ptr,x) \ + ((__typeof__(*(ptr))) __xchg ((unsigned long) (x), (ptr), sizeof(*(ptr)))) + +/* + * Atomic compare and exchange. Compare OLD with MEM, if identical, + * store NEW in MEM. Return the initial value in MEM. Success is + * indicated by comparing RETURN with OLD. + */ + +#define __HAVE_ARCH_CMPXCHG 1 + +/* + * This function doesn't exist, so you'll get a linker error + * if something tries to do an invalid cmpxchg(). + */ +extern long ia64_cmpxchg_called_with_bad_pointer (void); + +#define ia64_cmpxchg(sem,ptr,old,new,size) \ +({ \ + __u64 _o_, _r_; \ + \ + switch (size) { \ + case 1: _o_ = (__u8 ) (long) (old); break; \ + case 2: _o_ = (__u16) (long) (old); break; \ + case 4: _o_ = (__u32) (long) (old); break; \ + case 8: _o_ = (__u64) (long) (old); break; \ + default: break; \ + } \ + switch (size) { \ + case 1: \ + _r_ = ia64_cmpxchg1_##sem((__u8 *) ptr, new, _o_); \ + break; \ + \ + case 2: \ + _r_ = ia64_cmpxchg2_##sem((__u16 *) ptr, new, _o_); \ + break; \ + \ + case 4: \ + _r_ = ia64_cmpxchg4_##sem((__u32 *) ptr, new, _o_); \ + break; \ + \ + case 8: \ + _r_ = ia64_cmpxchg8_##sem((__u64 *) ptr, new, _o_); \ + break; \ + \ + default: \ + _r_ = ia64_cmpxchg_called_with_bad_pointer(); \ + break; \ + } \ + (__typeof__(old)) _r_; \ +}) + +#define cmpxchg_acq(ptr, o, n) \ + ia64_cmpxchg(acq, (ptr), (o), (n), sizeof(*(ptr))) +#define cmpxchg_rel(ptr, o, n) \ + ia64_cmpxchg(rel, (ptr), (o), (n), sizeof(*(ptr))) + +/* for compatibility with other platforms: */ +#define cmpxchg(ptr, o, n) cmpxchg_acq((ptr), (o), (n)) +#define cmpxchg64(ptr, o, n) cmpxchg_acq((ptr), (o), (n)) + +#define cmpxchg_local cmpxchg +#define cmpxchg64_local cmpxchg64 + +#ifdef CONFIG_IA64_DEBUG_CMPXCHG +# define CMPXCHG_BUGCHECK_DECL int _cmpxchg_bugcheck_count = 128; +# define CMPXCHG_BUGCHECK(v) \ + do { \ + if (_cmpxchg_bugcheck_count-- <= 0) { \ + void *ip; \ + extern int printk(const char *fmt, ...); \ + ip = (void *) ia64_getreg(_IA64_REG_IP); \ + printk("CMPXCHG_BUGCHECK: stuck at %p on word %p\n", ip, (v)); \ + break; \ + } \ + } while (0) +#else /* !CONFIG_IA64_DEBUG_CMPXCHG */ +# define CMPXCHG_BUGCHECK_DECL +# define CMPXCHG_BUGCHECK(v) +#endif /* !CONFIG_IA64_DEBUG_CMPXCHG */ + #endif #ifdef __KERNEL__ diff --git a/trunk/arch/ia64/kernel/acpi.c b/trunk/arch/ia64/kernel/acpi.c index 6f38b6120d96..ac795d311f44 100644 --- a/trunk/arch/ia64/kernel/acpi.c +++ b/trunk/arch/ia64/kernel/acpi.c @@ -839,7 +839,7 @@ static __init int setup_additional_cpus(char *s) early_param("additional_cpus", setup_additional_cpus); /* - * cpu_possible_mask should be static, it cannot change as CPUs + * cpu_possible_map should be static, it cannot change as CPUs * are onlined, or offlined. The reason is per-cpu data-structures * are allocated by some modules at init time, and dont expect to * do this dynamically on cpu arrival/departure. diff --git a/trunk/arch/ia64/kernel/pci-swiotlb.c b/trunk/arch/ia64/kernel/pci-swiotlb.c index 939260aeac98..d9485d952ed0 100644 --- a/trunk/arch/ia64/kernel/pci-swiotlb.c +++ b/trunk/arch/ia64/kernel/pci-swiotlb.c @@ -15,24 +15,16 @@ int swiotlb __read_mostly; EXPORT_SYMBOL(swiotlb); static void *ia64_swiotlb_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp, - struct dma_attrs *attrs) + dma_addr_t *dma_handle, gfp_t gfp) { if (dev->coherent_dma_mask != DMA_BIT_MASK(64)) gfp |= GFP_DMA; return swiotlb_alloc_coherent(dev, size, dma_handle, gfp); } -static void ia64_swiotlb_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_addr, - struct dma_attrs *attrs) -{ - swiotlb_free_coherent(dev, size, vaddr, dma_addr); -} - struct dma_map_ops swiotlb_dma_ops = { - .alloc = ia64_swiotlb_alloc_coherent, - .free = ia64_swiotlb_free_coherent, + .alloc_coherent = ia64_swiotlb_alloc_coherent, + .free_coherent = swiotlb_free_coherent, .map_page = swiotlb_map_page, .unmap_page = swiotlb_unmap_page, .map_sg = swiotlb_map_sg_attrs, diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index f00ba025375d..9d0fd7d5bb82 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -604,6 +604,12 @@ pfm_unprotect_ctx_ctxsw(pfm_context_t *x, unsigned long f) spin_unlock(&(x)->ctx_lock); } +static inline unsigned int +pfm_do_munmap(struct mm_struct *mm, unsigned long addr, size_t len, int acct) +{ + return do_munmap(mm, addr, len); +} + static inline unsigned long pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, unsigned long exec) { @@ -1452,9 +1458,8 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu) * a PROTECT_CTX() section. */ static int -pfm_remove_smpl_mapping(void *vaddr, unsigned long size) +pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long size) { - struct task_struct *task = current; int r; /* sanity checks */ @@ -1468,8 +1473,13 @@ pfm_remove_smpl_mapping(void *vaddr, unsigned long size) /* * does the actual unmapping */ - r = vm_munmap((unsigned long)vaddr, size); + down_write(&task->mm->mmap_sem); + DPRINT(("down_write done smpl_vaddr=%p size=%lu\n", vaddr, size)); + + r = pfm_do_munmap(task->mm, (unsigned long)vaddr, size, 0); + + up_write(&task->mm->mmap_sem); if (r !=0) { printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task_pid_nr(task), vaddr, size); } @@ -1935,7 +1945,7 @@ pfm_flush(struct file *filp, fl_owner_t id) * because some VM function reenables interrupts. * */ - if (smpl_buf_vaddr) pfm_remove_smpl_mapping(smpl_buf_vaddr, smpl_buf_size); + if (smpl_buf_vaddr) pfm_remove_smpl_mapping(current, smpl_buf_vaddr, smpl_buf_size); return 0; } diff --git a/trunk/arch/ia64/sn/pci/pci_dma.c b/trunk/arch/ia64/sn/pci/pci_dma.c index 3290d6e00c31..a9d310de57da 100644 --- a/trunk/arch/ia64/sn/pci/pci_dma.c +++ b/trunk/arch/ia64/sn/pci/pci_dma.c @@ -76,8 +76,7 @@ EXPORT_SYMBOL(sn_dma_set_mask); * more information. */ static void *sn_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t * dma_handle, gfp_t flags, - struct dma_attrs *attrs) + dma_addr_t * dma_handle, gfp_t flags) { void *cpuaddr; unsigned long phys_addr; @@ -138,7 +137,7 @@ static void *sn_dma_alloc_coherent(struct device *dev, size_t size, * any associated IOMMU mappings. */ static void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, - dma_addr_t dma_handle, struct dma_attrs *attrs) + dma_addr_t dma_handle) { struct pci_dev *pdev = to_pci_dev(dev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); @@ -467,8 +466,8 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size) } static struct dma_map_ops sn_dma_ops = { - .alloc = sn_dma_alloc_coherent, - .free = sn_dma_free_coherent, + .alloc_coherent = sn_dma_alloc_coherent, + .free_coherent = sn_dma_free_coherent, .map_page = sn_dma_map_page, .unmap_page = sn_dma_unmap_page, .map_sg = sn_dma_map_sg, diff --git a/trunk/arch/m68k/configs/m5275evb_defconfig b/trunk/arch/m68k/configs/m5275evb_defconfig index a1230e82bb1e..33c32aeca12b 100644 --- a/trunk/arch/m68k/configs/m5275evb_defconfig +++ b/trunk/arch/m68k/configs/m5275evb_defconfig @@ -49,6 +49,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_FEC=y +CONFIG_FEC2=y # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_PPP=y diff --git a/trunk/arch/m68k/include/asm/atomic.h b/trunk/arch/m68k/include/asm/atomic.h index f4e32de263a7..336e6173794f 100644 --- a/trunk/arch/m68k/include/asm/atomic.h +++ b/trunk/arch/m68k/include/asm/atomic.h @@ -3,7 +3,6 @@ #include #include -#include /* * Atomic operations that C can't guarantee us. Useful for diff --git a/trunk/arch/m68k/mac/config.c b/trunk/arch/m68k/mac/config.c index d9f62e0f46c0..96fa6ed7e799 100644 --- a/trunk/arch/m68k/mac/config.c +++ b/trunk/arch/m68k/mac/config.c @@ -980,9 +980,6 @@ int __init mac_platform_init(void) { u8 *swim_base; - if (!MACH_IS_MAC) - return -ENODEV; - /* * Serial devices */ diff --git a/trunk/arch/m68k/platform/527x/config.c b/trunk/arch/m68k/platform/527x/config.c index f91a53294c35..7ed848c3b848 100644 --- a/trunk/arch/m68k/platform/527x/config.c +++ b/trunk/arch/m68k/platform/527x/config.c @@ -74,7 +74,9 @@ static void __init m527x_fec_init(void) writew(par | 0xf00, MCF_IPSBAR + 0x100082); v = readb(MCF_IPSBAR + 0x100078); writeb(v | 0xc0, MCF_IPSBAR + 0x100078); +#endif +#ifdef CONFIG_FEC2 /* Set multi-function pins to ethernet mode for fec1 */ par = readw(MCF_IPSBAR + 0x100082); writew(par | 0xa0, MCF_IPSBAR + 0x100082); diff --git a/trunk/arch/m68k/platform/68EZ328/Makefile b/trunk/arch/m68k/platform/68EZ328/Makefile index b44d799b1115..ee97735a242c 100644 --- a/trunk/arch/m68k/platform/68EZ328/Makefile +++ b/trunk/arch/m68k/platform/68EZ328/Makefile @@ -3,3 +3,9 @@ # obj-y := config.o + +extra-y := bootlogo.rh + +$(obj)/bootlogo.rh: $(src)/bootlogo.h + perl $(src)/../68328/bootlogo.pl < $(src)/bootlogo.h \ + > $(obj)/bootlogo.rh diff --git a/trunk/arch/m68k/platform/68VZ328/bootlogo.h b/trunk/arch/m68k/platform/68EZ328/bootlogo.h similarity index 99% rename from trunk/arch/m68k/platform/68VZ328/bootlogo.h rename to trunk/arch/m68k/platform/68EZ328/bootlogo.h index b38e2b255142..e842bdae5839 100644 --- a/trunk/arch/m68k/platform/68VZ328/bootlogo.h +++ b/trunk/arch/m68k/platform/68EZ328/bootlogo.h @@ -1,6 +1,6 @@ #define splash_width 640 #define splash_height 480 -unsigned char __attribute__ ((aligned(16))) bootlogo_bits[] = { +static unsigned char splash_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/trunk/arch/m68k/platform/68VZ328/Makefile b/trunk/arch/m68k/platform/68VZ328/Makefile index a49d75e65489..447ffa0fd7c7 100644 --- a/trunk/arch/m68k/platform/68VZ328/Makefile +++ b/trunk/arch/m68k/platform/68VZ328/Makefile @@ -3,9 +3,14 @@ # obj-y := config.o -extra-$(DRAGEN2):= screen.h +logo-$(UCDIMM) := bootlogo.rh +logo-$(DRAGEN2) := screen.h +extra-y := $(logo-y) + +$(obj)/bootlogo.rh: $(src)/../68EZ328/bootlogo.h + perl $(src)/bootlogo.pl < $(src)/../68328/bootlogo.h > $(obj)/bootlogo.rh $(obj)/screen.h: $(src)/screen.xbm $(src)/xbm2lcd.pl perl $(src)/xbm2lcd.pl < $(src)/screen.xbm > $(obj)/screen.h -clean-files := $(obj)/screen.h +clean-files := $(obj)/screen.h $(obj)/bootlogo.rh diff --git a/trunk/arch/m68k/platform/coldfire/device.c b/trunk/arch/m68k/platform/coldfire/device.c index 7af97362b95c..fa50c48292ff 100644 --- a/trunk/arch/m68k/platform/coldfire/device.c +++ b/trunk/arch/m68k/platform/coldfire/device.c @@ -114,7 +114,7 @@ static struct resource mcf_fec1_resources[] = { static struct platform_device mcf_fec1 = { .name = "fec", - .id = 1, + .id = 0, .num_resources = ARRAY_SIZE(mcf_fec1_resources), .resource = mcf_fec1_resources, }; diff --git a/trunk/arch/m68k/q40/config.c b/trunk/arch/m68k/q40/config.c index 8a1ce327c963..512adb64f7dd 100644 --- a/trunk/arch/m68k/q40/config.c +++ b/trunk/arch/m68k/q40/config.c @@ -334,9 +334,6 @@ static __init int q40_add_kbd_device(void) { struct platform_device *pdev; - if (!MACH_IS_Q40) - return -ENODEV; - pdev = platform_device_register_simple("q40kbd", -1, NULL, 0); if (IS_ERR(pdev)) return PTR_ERR(pdev); diff --git a/trunk/arch/microblaze/boot/Makefile b/trunk/arch/microblaze/boot/Makefile index fa83ea497db7..34940c828def 100644 --- a/trunk/arch/microblaze/boot/Makefile +++ b/trunk/arch/microblaze/boot/Makefile @@ -2,6 +2,8 @@ # arch/microblaze/boot/Makefile # +MKIMAGE := $(srctree)/scripts/mkuboot.sh + obj-y += linked_dtb.o targets := linux.bin linux.bin.gz simpleImage.% @@ -33,9 +35,11 @@ quiet_cmd_strip = STRIP $@ cmd_strip = $(STRIP) -K microblaze_start -K _end -K __log_buf \ -K _fdt_start vmlinux -o $@ -UIMAGE_IN = $@ -UIMAGE_OUT = $@.ub -UIMAGE_LOADADDR = $(CONFIG_KERNEL_BASE_ADDR) +quiet_cmd_uimage = UIMAGE $@.ub + cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A microblaze -O linux -T kernel \ + -C none -n 'Linux-$(KERNELRELEASE)' \ + -a $(CONFIG_KERNEL_BASE_ADDR) -e $(CONFIG_KERNEL_BASE_ADDR) \ + -d $@ $@.ub $(obj)/simpleImage.%: vmlinux FORCE $(call if_changed,cp,.unstrip) diff --git a/trunk/arch/microblaze/include/asm/cmpxchg.h b/trunk/arch/microblaze/include/asm/cmpxchg.h index 538afc0ab9f3..0094859abd9b 100644 --- a/trunk/arch/microblaze/include/asm/cmpxchg.h +++ b/trunk/arch/microblaze/include/asm/cmpxchg.h @@ -1,8 +1,6 @@ #ifndef _ASM_MICROBLAZE_CMPXCHG_H #define _ASM_MICROBLAZE_CMPXCHG_H -#include - void __bad_xchg(volatile void *ptr, int size); static inline unsigned long __xchg(unsigned long x, volatile void *ptr, diff --git a/trunk/arch/microblaze/include/asm/dma-mapping.h b/trunk/arch/microblaze/include/asm/dma-mapping.h index 01d228286cb0..3a3e5b886854 100644 --- a/trunk/arch/microblaze/include/asm/dma-mapping.h +++ b/trunk/arch/microblaze/include/asm/dma-mapping.h @@ -123,34 +123,28 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_alloc_coherent(d, s, h, f) dma_alloc_attrs(d, s, h, f, NULL) - -static inline void *dma_alloc_attrs(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag, - struct dma_attrs *attrs) +static inline void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) { struct dma_map_ops *ops = get_dma_ops(dev); void *memory; BUG_ON(!ops); - memory = ops->alloc(dev, size, dma_handle, flag, attrs); + memory = ops->alloc_coherent(dev, size, dma_handle, flag); debug_dma_alloc_coherent(dev, size, *dma_handle, memory); return memory; } -#define dma_free_coherent(d,s,c,h) dma_free_attrs(d, s, c, h, NULL) - -static inline void dma_free_attrs(struct device *dev, size_t size, - void *cpu_addr, dma_addr_t dma_handle, - struct dma_attrs *attrs) +static inline void dma_free_coherent(struct device *dev, size_t size, + void *cpu_addr, dma_addr_t dma_handle) { struct dma_map_ops *ops = get_dma_ops(dev); BUG_ON(!ops); debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); - ops->free(dev, size, cpu_addr, dma_handle, attrs); + ops->free_coherent(dev, size, cpu_addr, dma_handle); } static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, diff --git a/trunk/arch/microblaze/include/asm/futex.h b/trunk/arch/microblaze/include/asm/futex.h index ff8cde159d9a..b0526d2716fa 100644 --- a/trunk/arch/microblaze/include/asm/futex.h +++ b/trunk/arch/microblaze/include/asm/futex.h @@ -24,7 +24,7 @@ .word 1b,4b,2b,4b; \ .previous;" \ : "=&r" (oldval), "=&r" (ret) \ - : "r" (uaddr), "i" (-EFAULT), "r" (oparg) \ + : "b" (uaddr), "i" (-EFAULT), "r" (oparg) \ ); \ }) diff --git a/trunk/arch/microblaze/include/asm/processor.h b/trunk/arch/microblaze/include/asm/processor.h index bffb54527299..510a8e1c16ba 100644 --- a/trunk/arch/microblaze/include/asm/processor.h +++ b/trunk/arch/microblaze/include/asm/processor.h @@ -31,8 +31,6 @@ extern const struct seq_operations cpuinfo_op; /* Do necessary setup to start up a newly executed thread. */ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp); -extern void ret_from_fork(void); - # endif /* __ASSEMBLY__ */ # ifndef CONFIG_MMU @@ -145,6 +143,8 @@ static inline void exit_thread(void) unsigned long get_wchan(struct task_struct *p); +extern void ret_from_fork(void); + /* The size allocated for kernel stacks. This _must_ be a power of two! */ # define KERNEL_STACK_SIZE 0x2000 diff --git a/trunk/arch/microblaze/kernel/dma.c b/trunk/arch/microblaze/kernel/dma.c index a2bfa2ca5730..65a4af4cbbbe 100644 --- a/trunk/arch/microblaze/kernel/dma.c +++ b/trunk/arch/microblaze/kernel/dma.c @@ -33,8 +33,7 @@ static unsigned long get_dma_direct_offset(struct device *dev) #define NOT_COHERENT_CACHE static void *dma_direct_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag, - struct dma_attrs *attrs) + dma_addr_t *dma_handle, gfp_t flag) { #ifdef NOT_COHERENT_CACHE return consistent_alloc(flag, size, dma_handle); @@ -58,8 +57,7 @@ static void *dma_direct_alloc_coherent(struct device *dev, size_t size, } static void dma_direct_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, - struct dma_attrs *attrs) + void *vaddr, dma_addr_t dma_handle) { #ifdef NOT_COHERENT_CACHE consistent_free(size, vaddr); @@ -178,8 +176,8 @@ dma_direct_sync_sg_for_device(struct device *dev, } struct dma_map_ops dma_direct_ops = { - .alloc = dma_direct_alloc_coherent, - .free = dma_direct_free_coherent, + .alloc_coherent = dma_direct_alloc_coherent, + .free_coherent = dma_direct_free_coherent, .map_sg = dma_direct_map_sg, .unmap_sg = dma_direct_unmap_sg, .dma_supported = dma_direct_dma_supported, diff --git a/trunk/arch/microblaze/kernel/early_printk.c b/trunk/arch/microblaze/kernel/early_printk.c index aba1f9a97d5d..ec485876d0d0 100644 --- a/trunk/arch/microblaze/kernel/early_printk.c +++ b/trunk/arch/microblaze/kernel/early_printk.c @@ -176,7 +176,6 @@ void __init remap_early_printk(void) base_addr = (u32) ioremap(base_addr, PAGE_SIZE); printk(KERN_CONT "0x%x\n", base_addr); -#ifdef CONFIG_MMU /* * Early console is on the top of skipped TLB entries * decrease tlb_skip size ensure that hardcoded TLB entry will be @@ -190,7 +189,6 @@ void __init remap_early_printk(void) * cmp rX, orig_base_addr */ tlb_skip -= 1; -#endif } void __init disable_early_printk(void) diff --git a/trunk/arch/microblaze/kernel/setup.c b/trunk/arch/microblaze/kernel/setup.c index 16d8dfd9094b..71af974aa24a 100644 --- a/trunk/arch/microblaze/kernel/setup.c +++ b/trunk/arch/microblaze/kernel/setup.c @@ -206,7 +206,6 @@ static int microblaze_debugfs_init(void) } arch_initcall(microblaze_debugfs_init); -# ifdef CONFIG_MMU static int __init debugfs_tlb(void) { struct dentry *d; @@ -219,7 +218,6 @@ static int __init debugfs_tlb(void) return -ENOMEM; } device_initcall(debugfs_tlb); -# endif #endif static int dflt_bus_notify(struct notifier_block *nb, diff --git a/trunk/arch/microblaze/kernel/unwind.c b/trunk/arch/microblaze/kernel/unwind.c index 6be4ae3c3351..9781a528cfc9 100644 --- a/trunk/arch/microblaze/kernel/unwind.c +++ b/trunk/arch/microblaze/kernel/unwind.c @@ -24,7 +24,6 @@ #include #include #include -#include struct stack_trace; diff --git a/trunk/arch/microblaze/lib/uaccess_old.S b/trunk/arch/microblaze/lib/uaccess_old.S index f085995ee848..f037266cdaf3 100644 --- a/trunk/arch/microblaze/lib/uaccess_old.S +++ b/trunk/arch/microblaze/lib/uaccess_old.S @@ -122,22 +122,22 @@ __strnlen_user: 15: swi r24, r5, 0x0018 + offset; \ 16: swi r25, r5, 0x001C + offset; \ .section __ex_table,"a"; \ - .word 1b, 33f; \ - .word 2b, 33f; \ - .word 3b, 33f; \ - .word 4b, 33f; \ - .word 5b, 33f; \ - .word 6b, 33f; \ - .word 7b, 33f; \ - .word 8b, 33f; \ - .word 9b, 33f; \ - .word 10b, 33f; \ - .word 11b, 33f; \ - .word 12b, 33f; \ - .word 13b, 33f; \ - .word 14b, 33f; \ - .word 15b, 33f; \ - .word 16b, 33f; \ + .word 1b, 0f; \ + .word 2b, 0f; \ + .word 3b, 0f; \ + .word 4b, 0f; \ + .word 5b, 0f; \ + .word 6b, 0f; \ + .word 7b, 0f; \ + .word 8b, 0f; \ + .word 9b, 0f; \ + .word 10b, 0f; \ + .word 11b, 0f; \ + .word 12b, 0f; \ + .word 13b, 0f; \ + .word 14b, 0f; \ + .word 15b, 0f; \ + .word 16b, 0f; \ .text #define COPY_80(offset) \ @@ -190,17 +190,14 @@ w2: sw r4, r5, r3 .align 4 /* Alignment is important to keep icache happy */ page: /* Create room on stack and save registers for storign values */ - addik r1, r1, -40 - swi r5, r1, 0 - swi r6, r1, 4 - swi r7, r1, 8 - swi r19, r1, 12 - swi r20, r1, 16 - swi r21, r1, 20 - swi r22, r1, 24 - swi r23, r1, 28 - swi r24, r1, 32 - swi r25, r1, 36 + addik r1, r1, -32 + swi r19, r1, 4 + swi r20, r1, 8 + swi r21, r1, 12 + swi r22, r1, 16 + swi r23, r1, 20 + swi r24, r1, 24 + swi r25, r1, 28 loop: /* r4, r19, r20, r21, r22, r23, r24, r25 are used for storing values */ /* Loop unrolling to get performance boost */ COPY_80(0x000); @@ -208,44 +205,21 @@ loop: /* r4, r19, r20, r21, r22, r23, r24, r25 are used for storing values */ COPY_80(0x100); COPY_80(0x180); /* copy loop */ - addik r6, r6, 0x200 - addik r7, r7, -0x200 - bneid r7, loop - addik r5, r5, 0x200 - + addik r6, r6, 0x200 + addik r7, r7, -0x200 + bneid r7, loop + addik r5, r5, 0x200 /* Restore register content */ - lwi r5, r1, 0 - lwi r6, r1, 4 - lwi r7, r1, 8 - lwi r19, r1, 12 - lwi r20, r1, 16 - lwi r21, r1, 20 - lwi r22, r1, 24 - lwi r23, r1, 28 - lwi r24, r1, 32 - lwi r25, r1, 36 - addik r1, r1, 40 + lwi r19, r1, 4 + lwi r20, r1, 8 + lwi r21, r1, 12 + lwi r22, r1, 16 + lwi r23, r1, 20 + lwi r24, r1, 24 + lwi r25, r1, 28 + addik r1, r1, 32 /* return back */ - addik r3, r0, 0 - rtsd r15, 8 - nop - -/* Fault case - return temp count */ -33: addik r3, r7, 0 - /* Restore register content */ - lwi r5, r1, 0 - lwi r6, r1, 4 - lwi r7, r1, 8 - lwi r19, r1, 12 - lwi r20, r1, 16 - lwi r21, r1, 20 - lwi r22, r1, 24 - lwi r23, r1, 28 - lwi r24, r1, 32 - lwi r25, r1, 36 - addik r1, r1, 40 - /* return back */ rtsd r15, 8 nop diff --git a/trunk/arch/mips/ath79/dev-wmac.c b/trunk/arch/mips/ath79/dev-wmac.c index 9c717bf98ffe..e21507052066 100644 --- a/trunk/arch/mips/ath79/dev-wmac.c +++ b/trunk/arch/mips/ath79/dev-wmac.c @@ -58,8 +58,8 @@ static void __init ar913x_wmac_setup(void) static int ar933x_wmac_reset(void) { - ath79_device_reset_set(AR933X_RESET_WMAC); ath79_device_reset_clear(AR933X_RESET_WMAC); + ath79_device_reset_set(AR933X_RESET_WMAC); return 0; } diff --git a/trunk/arch/mips/cavium-octeon/dma-octeon.c b/trunk/arch/mips/cavium-octeon/dma-octeon.c index 41dd00884975..b6bb92c16a47 100644 --- a/trunk/arch/mips/cavium-octeon/dma-octeon.c +++ b/trunk/arch/mips/cavium-octeon/dma-octeon.c @@ -157,7 +157,7 @@ static void octeon_dma_sync_sg_for_device(struct device *dev, } static void *octeon_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs) + dma_addr_t *dma_handle, gfp_t gfp) { void *ret; @@ -192,7 +192,7 @@ static void *octeon_dma_alloc_coherent(struct device *dev, size_t size, } static void octeon_dma_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs) + void *vaddr, dma_addr_t dma_handle) { int order = get_order(size); @@ -240,8 +240,8 @@ EXPORT_SYMBOL(dma_to_phys); static struct octeon_dma_map_ops octeon_linear_dma_map_ops = { .dma_map_ops = { - .alloc = octeon_dma_alloc_coherent, - .free = octeon_dma_free_coherent, + .alloc_coherent = octeon_dma_alloc_coherent, + .free_coherent = octeon_dma_free_coherent, .map_page = octeon_dma_map_page, .unmap_page = swiotlb_unmap_page, .map_sg = octeon_dma_map_sg, @@ -325,8 +325,8 @@ void __init plat_swiotlb_setup(void) #ifdef CONFIG_PCI static struct octeon_dma_map_ops _octeon_pci_dma_map_ops = { .dma_map_ops = { - .alloc = octeon_dma_alloc_coherent, - .free = octeon_dma_free_coherent, + .alloc_coherent = octeon_dma_alloc_coherent, + .free_coherent = octeon_dma_free_coherent, .map_page = octeon_dma_map_page, .unmap_page = swiotlb_unmap_page, .map_sg = octeon_dma_map_sg, diff --git a/trunk/arch/mips/cavium-octeon/flash_setup.c b/trunk/arch/mips/cavium-octeon/flash_setup.c index e44a55bc7f0d..0a430e06f5e5 100644 --- a/trunk/arch/mips/cavium-octeon/flash_setup.c +++ b/trunk/arch/mips/cavium-octeon/flash_setup.c @@ -60,7 +60,7 @@ static int __init flash_init(void) if (mymtd) { mymtd->owner = THIS_MODULE; mtd_device_parse_register(mymtd, part_probe_types, - NULL, NULL, 0); + 0, NULL, 0); } else { pr_err("Failed to register MTD device for flash\n"); } diff --git a/trunk/arch/mips/cavium-octeon/smp.c b/trunk/arch/mips/cavium-octeon/smp.c index 97e7ce9b50ed..c3e2b85c3b02 100644 --- a/trunk/arch/mips/cavium-octeon/smp.c +++ b/trunk/arch/mips/cavium-octeon/smp.c @@ -78,7 +78,7 @@ static inline void octeon_send_ipi_mask(const struct cpumask *mask, } /** - * Detect available CPUs, populate cpu_possible_mask + * Detect available CPUs, populate cpu_possible_map */ static void octeon_smp_hotplug_setup(void) { @@ -268,7 +268,7 @@ static int octeon_cpu_disable(void) spin_lock(&smp_reserve_lock); - set_cpu_online(cpu, false); + cpu_clear(cpu, cpu_online_map); cpu_clear(cpu, cpu_callin_map); local_irq_disable(); fixup_irqs(); diff --git a/trunk/arch/mips/include/asm/dma-mapping.h b/trunk/arch/mips/include/asm/dma-mapping.h index be39a12901c6..7aa37ddfca4b 100644 --- a/trunk/arch/mips/include/asm/dma-mapping.h +++ b/trunk/arch/mips/include/asm/dma-mapping.h @@ -57,31 +57,25 @@ dma_set_mask(struct device *dev, u64 mask) extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction); -#define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) - -static inline void *dma_alloc_attrs(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp, - struct dma_attrs *attrs) +static inline void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp) { void *ret; struct dma_map_ops *ops = get_dma_ops(dev); - ret = ops->alloc(dev, size, dma_handle, gfp, attrs); + ret = ops->alloc_coherent(dev, size, dma_handle, gfp); debug_dma_alloc_coherent(dev, size, *dma_handle, ret); return ret; } -#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) - -static inline void dma_free_attrs(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, - struct dma_attrs *attrs) +static inline void dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) { struct dma_map_ops *ops = get_dma_ops(dev); - ops->free(dev, size, vaddr, dma_handle, attrs); + ops->free_coherent(dev, size, vaddr, dma_handle); debug_dma_free_coherent(dev, size, vaddr, dma_handle); } diff --git a/trunk/arch/mips/include/asm/mach-jz4740/irq.h b/trunk/arch/mips/include/asm/mach-jz4740/irq.h index 5ad1a9c113c6..a865c983c70a 100644 --- a/trunk/arch/mips/include/asm/mach-jz4740/irq.h +++ b/trunk/arch/mips/include/asm/mach-jz4740/irq.h @@ -45,7 +45,7 @@ #define JZ4740_IRQ_LCD JZ4740_IRQ(30) /* 2nd-level interrupts */ -#define JZ4740_IRQ_DMA(x) (JZ4740_IRQ(32) + (x)) +#define JZ4740_IRQ_DMA(x) (JZ4740_IRQ(32) + (X)) #define JZ4740_IRQ_INTC_GPIO(x) (JZ4740_IRQ_GPIO0 - (x)) #define JZ4740_IRQ_GPIO(x) (JZ4740_IRQ(48) + (x)) diff --git a/trunk/arch/mips/include/asm/mmu_context.h b/trunk/arch/mips/include/asm/mmu_context.h index 9b02cfba7449..73c0d45798de 100644 --- a/trunk/arch/mips/include/asm/mmu_context.h +++ b/trunk/arch/mips/include/asm/mmu_context.h @@ -37,6 +37,12 @@ extern void tlbmiss_handler_setup_pgd(unsigned long pgd); write_c0_xcontext((unsigned long) smp_processor_id() << 51); \ } while (0) + +static inline unsigned long get_current_pgd(void) +{ + return PHYS_TO_XKSEG_CACHED((read_c0_context() >> 11) & ~0xfffUL); +} + #else /* CONFIG_MIPS_PGD_C0_CONTEXT: using pgd_current*/ /* diff --git a/trunk/arch/mips/kernel/mips-mt-fpaff.c b/trunk/arch/mips/kernel/mips-mt-fpaff.c index 33f63bab478a..802e6160f37e 100644 --- a/trunk/arch/mips/kernel/mips-mt-fpaff.c +++ b/trunk/arch/mips/kernel/mips-mt-fpaff.c @@ -173,7 +173,7 @@ asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len, if (retval) goto out_unlock; - cpumask_and(&mask, &p->thread.user_cpus_allowed, cpu_possible_mask); + cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map); out_unlock: read_unlock(&tasklist_lock); diff --git a/trunk/arch/mips/kernel/proc.c b/trunk/arch/mips/kernel/proc.c index f8b2c592514d..e309665b6c81 100644 --- a/trunk/arch/mips/kernel/proc.c +++ b/trunk/arch/mips/kernel/proc.c @@ -25,7 +25,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) int i; #ifdef CONFIG_SMP - if (!cpu_online(n)) + if (!cpu_isset(n, cpu_online_map)) return 0; #endif diff --git a/trunk/arch/mips/kernel/signal.c b/trunk/arch/mips/kernel/signal.c index d5a338a1739c..185ca00c4c84 100644 --- a/trunk/arch/mips/kernel/signal.c +++ b/trunk/arch/mips/kernel/signal.c @@ -257,8 +257,11 @@ asmlinkage int sys_sigsuspend(nabi_no_regargs struct pt_regs regs) return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); current->saved_sigmask = current->blocked; - set_current_blocked(&newset); + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); current->state = TASK_INTERRUPTIBLE; schedule(); @@ -283,8 +286,11 @@ asmlinkage int sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); current->saved_sigmask = current->blocked; - set_current_blocked(&newset); + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); current->state = TASK_INTERRUPTIBLE; schedule(); @@ -356,7 +362,10 @@ asmlinkage void sys_sigreturn(nabi_no_regargs struct pt_regs regs) goto badframe; sigdelsetmask(&blocked, ~_BLOCKABLE); - set_current_blocked(&blocked); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = blocked; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); sig = restore_sigcontext(®s, &frame->sf_sc); if (sig < 0) @@ -392,7 +401,10 @@ asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); sig = restore_sigcontext(®s, &frame->rs_uc.uc_mcontext); if (sig < 0) @@ -568,7 +580,12 @@ static int handle_signal(unsigned long sig, siginfo_t *info, if (ret) return ret; - block_sigmask(ka, sig); + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); + if (!(ka->sa.sa_flags & SA_NODEFER)) + sigaddset(¤t->blocked, sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); return ret; } diff --git a/trunk/arch/mips/kernel/signal32.c b/trunk/arch/mips/kernel/signal32.c index ac3b8d89aae5..06b5da392e24 100644 --- a/trunk/arch/mips/kernel/signal32.c +++ b/trunk/arch/mips/kernel/signal32.c @@ -290,8 +290,11 @@ asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs) return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); current->saved_sigmask = current->blocked; - set_current_blocked(&newset); + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); current->state = TASK_INTERRUPTIBLE; schedule(); @@ -315,8 +318,11 @@ asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); current->saved_sigmask = current->blocked; - set_current_blocked(&newset); + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); current->state = TASK_INTERRUPTIBLE; schedule(); @@ -482,7 +488,10 @@ asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs) goto badframe; sigdelsetmask(&blocked, ~_BLOCKABLE); - set_current_blocked(&blocked); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = blocked; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); sig = restore_sigcontext32(®s, &frame->sf_sc); if (sig < 0) @@ -520,7 +529,10 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); sig = restore_sigcontext32(®s, &frame->rs_uc.uc_mcontext); if (sig < 0) diff --git a/trunk/arch/mips/kernel/signal_n32.c b/trunk/arch/mips/kernel/signal_n32.c index 86eb4b04631c..ae29e894ab8d 100644 --- a/trunk/arch/mips/kernel/signal_n32.c +++ b/trunk/arch/mips/kernel/signal_n32.c @@ -93,8 +93,11 @@ asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) sigset_from_compat(&newset, &uset); sigdelsetmask(&newset, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); current->saved_sigmask = current->blocked; - set_current_blocked(&newset); + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); current->state = TASK_INTERRUPTIBLE; schedule(); @@ -118,7 +121,10 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); sig = restore_sigcontext(®s, &frame->rs_uc.uc_mcontext); if (sig < 0) diff --git a/trunk/arch/mips/kernel/smp-bmips.c b/trunk/arch/mips/kernel/smp-bmips.c index 3046e2986006..ca673569fd24 100644 --- a/trunk/arch/mips/kernel/smp-bmips.c +++ b/trunk/arch/mips/kernel/smp-bmips.c @@ -317,7 +317,7 @@ static int bmips_cpu_disable(void) pr_info("SMP: CPU%d is offline\n", cpu); - set_cpu_online(cpu, false); + cpu_clear(cpu, cpu_online_map); cpu_clear(cpu, cpu_callin_map); local_flush_tlb_all(); diff --git a/trunk/arch/mips/kernel/smp.c b/trunk/arch/mips/kernel/smp.c index ba9376bf52a1..9c1cce9de35f 100644 --- a/trunk/arch/mips/kernel/smp.c +++ b/trunk/arch/mips/kernel/smp.c @@ -148,7 +148,7 @@ static void stop_this_cpu(void *dummy) /* * Remove this CPU: */ - set_cpu_online(smp_processor_id(), false); + cpu_clear(smp_processor_id(), cpu_online_map); for (;;) { if (cpu_wait) (*cpu_wait)(); /* Wait if available. */ @@ -174,7 +174,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) mp_ops->prepare_cpus(max_cpus); set_cpu_sibling_map(0); #ifndef CONFIG_HOTPLUG_CPU - init_cpu_present(cpu_possible_mask); + init_cpu_present(&cpu_possible_map); #endif } @@ -248,7 +248,7 @@ int __cpuinit __cpu_up(unsigned int cpu) while (!cpu_isset(cpu, cpu_callin_map)) udelay(100); - set_cpu_online(cpu, true); + cpu_set(cpu, cpu_online_map); return 0; } @@ -320,12 +320,13 @@ void flush_tlb_mm(struct mm_struct *mm) if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { smp_on_other_tlbs(flush_tlb_mm_ipi, mm); } else { + cpumask_t mask = cpu_online_map; unsigned int cpu; - for_each_online_cpu(cpu) { - if (cpu != smp_processor_id() && cpu_context(cpu, mm)) + cpu_clear(smp_processor_id(), mask); + for_each_cpu_mask(cpu, mask) + if (cpu_context(cpu, mm)) cpu_context(cpu, mm) = 0; - } } local_flush_tlb_mm(mm); @@ -359,12 +360,13 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned l smp_on_other_tlbs(flush_tlb_range_ipi, &fd); } else { + cpumask_t mask = cpu_online_map; unsigned int cpu; - for_each_online_cpu(cpu) { - if (cpu != smp_processor_id() && cpu_context(cpu, mm)) + cpu_clear(smp_processor_id(), mask); + for_each_cpu_mask(cpu, mask) + if (cpu_context(cpu, mm)) cpu_context(cpu, mm) = 0; - } } local_flush_tlb_range(vma, start, end); preempt_enable(); @@ -405,12 +407,13 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) smp_on_other_tlbs(flush_tlb_page_ipi, &fd); } else { + cpumask_t mask = cpu_online_map; unsigned int cpu; - for_each_online_cpu(cpu) { - if (cpu != smp_processor_id() && cpu_context(cpu, vma->vm_mm)) + cpu_clear(smp_processor_id(), mask); + for_each_cpu_mask(cpu, mask) + if (cpu_context(cpu, vma->vm_mm)) cpu_context(cpu, vma->vm_mm) = 0; - } } local_flush_tlb_page(vma, page); preempt_enable(); diff --git a/trunk/arch/mips/kernel/smtc.c b/trunk/arch/mips/kernel/smtc.c index f5dd38f1d015..c4f75bbc0bd6 100644 --- a/trunk/arch/mips/kernel/smtc.c +++ b/trunk/arch/mips/kernel/smtc.c @@ -291,7 +291,7 @@ static void smtc_configure_tlb(void) * possibly leave some TCs/VPEs as "slave" processors. * * Use c0_MVPConf0 to find out how many TCs are available, setting up - * cpu_possible_mask and the logical/physical mappings. + * cpu_possible_map and the logical/physical mappings. */ int __init smtc_build_cpu_map(int start_cpu_slot) diff --git a/trunk/arch/mips/mm/c-octeon.c b/trunk/arch/mips/mm/c-octeon.c index 47037ec5589b..1f9ca07f53c8 100644 --- a/trunk/arch/mips/mm/c-octeon.c +++ b/trunk/arch/mips/mm/c-octeon.c @@ -80,9 +80,9 @@ static void octeon_flush_icache_all_cores(struct vm_area_struct *vma) if (vma) mask = *mm_cpumask(vma->vm_mm); else - mask = *cpu_online_mask; - cpumask_clear_cpu(cpu, &mask); - for_each_cpu(cpu, &mask) + mask = cpu_online_map; + cpu_clear(cpu, mask); + for_each_cpu_mask(cpu, mask) octeon_send_ipi_single(cpu, SMP_ICACHE_FLUSH); preempt_enable(); diff --git a/trunk/arch/mips/mm/dma-default.c b/trunk/arch/mips/mm/dma-default.c index 3fab2046c8a4..46084912e588 100644 --- a/trunk/arch/mips/mm/dma-default.c +++ b/trunk/arch/mips/mm/dma-default.c @@ -98,7 +98,7 @@ void *dma_alloc_noncoherent(struct device *dev, size_t size, EXPORT_SYMBOL(dma_alloc_noncoherent); static void *mips_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t * dma_handle, gfp_t gfp, struct dma_attrs *attrs) + dma_addr_t * dma_handle, gfp_t gfp) { void *ret; @@ -132,7 +132,7 @@ void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr, EXPORT_SYMBOL(dma_free_noncoherent); static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_handle, struct dma_attrs *attrs) + dma_addr_t dma_handle) { unsigned long addr = (unsigned long) vaddr; int order = get_order(size); @@ -323,8 +323,8 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size, EXPORT_SYMBOL(dma_cache_sync); static struct dma_map_ops mips_default_dma_map_ops = { - .alloc = mips_dma_alloc_coherent, - .free = mips_dma_free_coherent, + .alloc_coherent = mips_dma_alloc_coherent, + .free_coherent = mips_dma_free_coherent, .map_page = mips_dma_map_page, .unmap_page = mips_dma_unmap_page, .map_sg = mips_dma_map_sg, diff --git a/trunk/arch/mips/netlogic/common/smp.c b/trunk/arch/mips/netlogic/common/smp.c index fab316de57e9..db17f49886c2 100644 --- a/trunk/arch/mips/netlogic/common/smp.c +++ b/trunk/arch/mips/netlogic/common/smp.c @@ -165,7 +165,7 @@ void __init nlm_smp_setup(void) cpu_set(boot_cpu, phys_cpu_present_map); __cpu_number_map[boot_cpu] = 0; __cpu_logical_map[0] = boot_cpu; - set_cpu_possible(0, true); + cpu_set(0, cpu_possible_map); num_cpus = 1; for (i = 0; i < NR_CPUS; i++) { @@ -177,14 +177,14 @@ void __init nlm_smp_setup(void) cpu_set(i, phys_cpu_present_map); __cpu_number_map[i] = num_cpus; __cpu_logical_map[num_cpus] = i; - set_cpu_possible(num_cpus, true); + cpu_set(num_cpus, cpu_possible_map); ++num_cpus; } } pr_info("Phys CPU present map: %lx, possible map %lx\n", (unsigned long)phys_cpu_present_map.bits[0], - (unsigned long)cpumask_bits(cpu_possible_mask)[0]); + (unsigned long)cpu_possible_map.bits[0]); pr_info("Detected %i Slave CPU(s)\n", num_cpus); nlm_set_nmi_handler(nlm_boot_secondary_cpus); diff --git a/trunk/arch/mips/pmc-sierra/yosemite/smp.c b/trunk/arch/mips/pmc-sierra/yosemite/smp.c index b71fae231049..2608752898c0 100644 --- a/trunk/arch/mips/pmc-sierra/yosemite/smp.c +++ b/trunk/arch/mips/pmc-sierra/yosemite/smp.c @@ -146,7 +146,7 @@ static void __cpuinit yos_boot_secondary(int cpu, struct task_struct *idle) } /* - * Detect available CPUs, populate cpu_possible_mask before smp_init + * Detect available CPUs, populate cpu_possible_map before smp_init * * We don't want to start the secondary CPU yet nor do we have a nice probing * feature in PMON so we just assume presence of the secondary core. @@ -155,10 +155,10 @@ static void __init yos_smp_setup(void) { int i; - init_cpu_possible(cpu_none_mask); + cpus_clear(cpu_possible_map); for (i = 0; i < 2; i++) { - set_cpu_possible(i, true); + cpu_set(i, cpu_possible_map); __cpu_number_map[i] = i; __cpu_logical_map[i] = i; } @@ -169,7 +169,7 @@ static void __init yos_prepare_cpus(unsigned int max_cpus) /* * Be paranoid. Enable the IPI only if we're really about to go SMP. */ - if (num_possible_cpus()) + if (cpus_weight(cpu_possible_map)) set_c0_status(STATUSF_IP5); } diff --git a/trunk/arch/mips/sgi-ip27/ip27-smp.c b/trunk/arch/mips/sgi-ip27/ip27-smp.c index 735b43bf8f82..c6851df9ab74 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-smp.c +++ b/trunk/arch/mips/sgi-ip27/ip27-smp.c @@ -76,7 +76,7 @@ static int do_cpumask(cnodeid_t cnode, nasid_t nasid, int highest) /* Only let it join in if it's marked enabled */ if ((acpu->cpu_info.flags & KLINFO_ENABLE) && (tot_cpus_found != NR_CPUS)) { - set_cpu_possible(cpuid, true); + cpu_set(cpuid, cpu_possible_map); alloc_cpupda(cpuid, tot_cpus_found); cpus_found++; tot_cpus_found++; diff --git a/trunk/arch/mips/sibyte/bcm1480/smp.c b/trunk/arch/mips/sibyte/bcm1480/smp.c index de88e22694a0..d667875be564 100644 --- a/trunk/arch/mips/sibyte/bcm1480/smp.c +++ b/trunk/arch/mips/sibyte/bcm1480/smp.c @@ -138,7 +138,7 @@ static void __cpuinit bcm1480_boot_secondary(int cpu, struct task_struct *idle) /* * Use CFE to find out how many CPUs are available, setting up - * cpu_possible_mask and the logical/physical mappings. + * cpu_possible_map and the logical/physical mappings. * XXXKW will the boot CPU ever not be physical 0? * * Common setup before any secondaries are started @@ -147,13 +147,14 @@ static void __init bcm1480_smp_setup(void) { int i, num; - init_cpu_possible(cpumask_of(0)); + cpus_clear(cpu_possible_map); + cpu_set(0, cpu_possible_map); __cpu_number_map[0] = 0; __cpu_logical_map[0] = 0; for (i = 1, num = 0; i < NR_CPUS; i++) { if (cfe_cpu_stop(i) == 0) { - set_cpu_possible(i, true); + cpu_set(i, cpu_possible_map); __cpu_number_map[i] = ++num; __cpu_logical_map[num] = i; } diff --git a/trunk/arch/mips/sibyte/sb1250/smp.c b/trunk/arch/mips/sibyte/sb1250/smp.c index 285cfef4ebc0..38e7f6bd7922 100644 --- a/trunk/arch/mips/sibyte/sb1250/smp.c +++ b/trunk/arch/mips/sibyte/sb1250/smp.c @@ -126,7 +126,7 @@ static void __cpuinit sb1250_boot_secondary(int cpu, struct task_struct *idle) /* * Use CFE to find out how many CPUs are available, setting up - * cpu_possible_mask and the logical/physical mappings. + * cpu_possible_map and the logical/physical mappings. * XXXKW will the boot CPU ever not be physical 0? * * Common setup before any secondaries are started @@ -135,13 +135,14 @@ static void __init sb1250_smp_setup(void) { int i, num; - init_cpu_possible(cpumask_of(0)); + cpus_clear(cpu_possible_map); + cpu_set(0, cpu_possible_map); __cpu_number_map[0] = 0; __cpu_logical_map[0] = 0; for (i = 1, num = 0; i < NR_CPUS; i++) { if (cfe_cpu_stop(i) == 0) { - set_cpu_possible(i, true); + cpu_set(i, cpu_possible_map); __cpu_number_map[i] = ++num; __cpu_logical_map[num] = i; } diff --git a/trunk/arch/parisc/include/asm/atomic.h b/trunk/arch/parisc/include/asm/atomic.h index 6c6defc24619..3ae56073cc3d 100644 --- a/trunk/arch/parisc/include/asm/atomic.h +++ b/trunk/arch/parisc/include/asm/atomic.h @@ -6,7 +6,6 @@ #define _ASM_PARISC_ATOMIC_H_ #include -#include /* * Atomic operations that C can't guarantee us. Useful for @@ -49,6 +48,112 @@ extern arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned; # define _atomic_spin_unlock_irqrestore(l,f) do { local_irq_restore(f); } while (0) #endif +/* This should get optimized out since it's never called. +** Or get a link error if xchg is used "wrong". +*/ +extern void __xchg_called_with_bad_pointer(void); + + +/* __xchg32/64 defined in arch/parisc/lib/bitops.c */ +extern unsigned long __xchg8(char, char *); +extern unsigned long __xchg32(int, int *); +#ifdef CONFIG_64BIT +extern unsigned long __xchg64(unsigned long, unsigned long *); +#endif + +/* optimizer better get rid of switch since size is a constant */ +static __inline__ unsigned long +__xchg(unsigned long x, __volatile__ void * ptr, int size) +{ + switch(size) { +#ifdef CONFIG_64BIT + case 8: return __xchg64(x,(unsigned long *) ptr); +#endif + case 4: return __xchg32((int) x, (int *) ptr); + case 1: return __xchg8((char) x, (char *) ptr); + } + __xchg_called_with_bad_pointer(); + return x; +} + + +/* +** REVISIT - Abandoned use of LDCW in xchg() for now: +** o need to test sizeof(*ptr) to avoid clearing adjacent bytes +** o and while we are at it, could CONFIG_64BIT code use LDCD too? +** +** if (__builtin_constant_p(x) && (x == NULL)) +** if (((unsigned long)p & 0xf) == 0) +** return __ldcw(p); +*/ +#define xchg(ptr,x) \ + ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) + + +#define __HAVE_ARCH_CMPXCHG 1 + +/* bug catcher for when unsupported size is used - won't link */ +extern void __cmpxchg_called_with_bad_pointer(void); + +/* __cmpxchg_u32/u64 defined in arch/parisc/lib/bitops.c */ +extern unsigned long __cmpxchg_u32(volatile unsigned int *m, unsigned int old, unsigned int new_); +extern unsigned long __cmpxchg_u64(volatile unsigned long *ptr, unsigned long old, unsigned long new_); + +/* don't worry...optimizer will get rid of most of this */ +static __inline__ unsigned long +__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size) +{ + switch(size) { +#ifdef CONFIG_64BIT + case 8: return __cmpxchg_u64((unsigned long *)ptr, old, new_); +#endif + case 4: return __cmpxchg_u32((unsigned int *)ptr, (unsigned int) old, (unsigned int) new_); + } + __cmpxchg_called_with_bad_pointer(); + return old; +} + +#define cmpxchg(ptr,o,n) \ + ({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, sizeof(*(ptr))); \ + }) + +#include + +static inline unsigned long __cmpxchg_local(volatile void *ptr, + unsigned long old, + unsigned long new_, int size) +{ + switch (size) { +#ifdef CONFIG_64BIT + case 8: return __cmpxchg_u64((unsigned long *)ptr, old, new_); +#endif + case 4: return __cmpxchg_u32(ptr, old, new_); + default: + return __cmpxchg_local_generic(ptr, old, new_, size); + } +} + +/* + * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make + * them available. + */ +#define cmpxchg_local(ptr, o, n) \ + ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \ + (unsigned long)(n), sizeof(*(ptr)))) +#ifdef CONFIG_64BIT +#define cmpxchg64_local(ptr, o, n) \ + ({ \ + BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ + cmpxchg_local((ptr), (o), (n)); \ + }) +#else +#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) +#endif + /* * Note that we need not lock read accesses - aligned word writes/reads * are atomic, so a reader never sees inconsistent values. diff --git a/trunk/arch/parisc/include/asm/cmpxchg.h b/trunk/arch/parisc/include/asm/cmpxchg.h deleted file mode 100644 index dbd13354ec41..000000000000 --- a/trunk/arch/parisc/include/asm/cmpxchg.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * forked from parisc asm/atomic.h which was: - * Copyright (C) 2000 Philipp Rumpf - * Copyright (C) 2006 Kyle McMartin - */ - -#ifndef _ASM_PARISC_CMPXCHG_H_ -#define _ASM_PARISC_CMPXCHG_H_ - -/* This should get optimized out since it's never called. -** Or get a link error if xchg is used "wrong". -*/ -extern void __xchg_called_with_bad_pointer(void); - -/* __xchg32/64 defined in arch/parisc/lib/bitops.c */ -extern unsigned long __xchg8(char, char *); -extern unsigned long __xchg32(int, int *); -#ifdef CONFIG_64BIT -extern unsigned long __xchg64(unsigned long, unsigned long *); -#endif - -/* optimizer better get rid of switch since size is a constant */ -static inline unsigned long -__xchg(unsigned long x, __volatile__ void *ptr, int size) -{ - switch (size) { -#ifdef CONFIG_64BIT - case 8: return __xchg64(x, (unsigned long *) ptr); -#endif - case 4: return __xchg32((int) x, (int *) ptr); - case 1: return __xchg8((char) x, (char *) ptr); - } - __xchg_called_with_bad_pointer(); - return x; -} - -/* -** REVISIT - Abandoned use of LDCW in xchg() for now: -** o need to test sizeof(*ptr) to avoid clearing adjacent bytes -** o and while we are at it, could CONFIG_64BIT code use LDCD too? -** -** if (__builtin_constant_p(x) && (x == NULL)) -** if (((unsigned long)p & 0xf) == 0) -** return __ldcw(p); -*/ -#define xchg(ptr, x) \ - ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))) - -#define __HAVE_ARCH_CMPXCHG 1 - -/* bug catcher for when unsupported size is used - won't link */ -extern void __cmpxchg_called_with_bad_pointer(void); - -/* __cmpxchg_u32/u64 defined in arch/parisc/lib/bitops.c */ -extern unsigned long __cmpxchg_u32(volatile unsigned int *m, unsigned int old, - unsigned int new_); -extern unsigned long __cmpxchg_u64(volatile unsigned long *ptr, - unsigned long old, unsigned long new_); - -/* don't worry...optimizer will get rid of most of this */ -static inline unsigned long -__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size) -{ - switch (size) { -#ifdef CONFIG_64BIT - case 8: return __cmpxchg_u64((unsigned long *)ptr, old, new_); -#endif - case 4: return __cmpxchg_u32((unsigned int *)ptr, - (unsigned int)old, (unsigned int)new_); - } - __cmpxchg_called_with_bad_pointer(); - return old; -} - -#define cmpxchg(ptr, o, n) \ -({ \ - __typeof__(*(ptr)) _o_ = (o); \ - __typeof__(*(ptr)) _n_ = (n); \ - (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ - (unsigned long)_n_, sizeof(*(ptr))); \ -}) - -#include - -static inline unsigned long __cmpxchg_local(volatile void *ptr, - unsigned long old, - unsigned long new_, int size) -{ - switch (size) { -#ifdef CONFIG_64BIT - case 8: return __cmpxchg_u64((unsigned long *)ptr, old, new_); -#endif - case 4: return __cmpxchg_u32(ptr, old, new_); - default: - return __cmpxchg_local_generic(ptr, old, new_, size); - } -} - -/* - * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make - * them available. - */ -#define cmpxchg_local(ptr, o, n) \ - ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \ - (unsigned long)(n), sizeof(*(ptr)))) -#ifdef CONFIG_64BIT -#define cmpxchg64_local(ptr, o, n) \ -({ \ - BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ - cmpxchg_local((ptr), (o), (n)); \ -}) -#else -#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) -#endif - -#endif /* _ASM_PARISC_CMPXCHG_H_ */ diff --git a/trunk/arch/parisc/include/asm/futex.h b/trunk/arch/parisc/include/asm/futex.h index 49df14805a9b..2388bdb32832 100644 --- a/trunk/arch/parisc/include/asm/futex.h +++ b/trunk/arch/parisc/include/asm/futex.h @@ -8,29 +8,6 @@ #include #include -/* The following has to match the LWS code in syscall.S. We have - sixteen four-word locks. */ - -static inline void -_futex_spin_lock_irqsave(u32 __user *uaddr, unsigned long int *flags) -{ - extern u32 lws_lock_start[]; - long index = ((long)uaddr & 0xf0) >> 2; - arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; - local_irq_save(*flags); - arch_spin_lock(s); -} - -static inline void -_futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags) -{ - extern u32 lws_lock_start[]; - long index = ((long)uaddr & 0xf0) >> 2; - arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index]; - arch_spin_unlock(s); - local_irq_restore(*flags); -} - static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) { @@ -49,7 +26,7 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) pagefault_disable(); - _futex_spin_lock_irqsave(uaddr, &flags); + _atomic_spin_lock_irqsave(uaddr, flags); switch (op) { case FUTEX_OP_SET: @@ -94,7 +71,7 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) ret = -ENOSYS; } - _futex_spin_unlock_irqrestore(uaddr, &flags); + _atomic_spin_unlock_irqrestore(uaddr, flags); pagefault_enable(); @@ -136,7 +113,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, * address. This should scale to a couple of CPUs. */ - _futex_spin_lock_irqsave(uaddr, &flags); + _atomic_spin_lock_irqsave(uaddr, flags); ret = get_user(val, uaddr); @@ -145,7 +122,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, *uval = val; - _futex_spin_unlock_irqrestore(uaddr, &flags); + _atomic_spin_unlock_irqrestore(uaddr, flags); return ret; } diff --git a/trunk/arch/parisc/kernel/pdc_cons.c b/trunk/arch/parisc/kernel/pdc_cons.c index 0b3393381a81..4f004596a6e7 100644 --- a/trunk/arch/parisc/kernel/pdc_cons.c +++ b/trunk/arch/parisc/kernel/pdc_cons.c @@ -104,7 +104,7 @@ static int pdc_console_tty_open(struct tty_struct *tty, struct file *filp) static void pdc_console_tty_close(struct tty_struct *tty, struct file *filp) { - if (tty->count == 1) { + if (!tty->count) { del_timer_sync(&pdc_console_timer); tty_port_tty_set(&tty_port, NULL); } diff --git a/trunk/arch/parisc/kernel/smp.c b/trunk/arch/parisc/kernel/smp.c index 0bb1d63907f8..5006e8ea3051 100644 --- a/trunk/arch/parisc/kernel/smp.c +++ b/trunk/arch/parisc/kernel/smp.c @@ -290,7 +290,8 @@ smp_cpu_init(int cpunum) mb(); /* Well, support 2.4 linux scheme as well. */ - if (cpu_online(cpunum)) { + if (cpu_isset(cpunum, cpu_online_map)) + { extern void machine_halt(void); /* arch/parisc.../process.c */ printk(KERN_CRIT "CPU#%d already initialized!\n", cpunum); diff --git a/trunk/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi b/trunk/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi deleted file mode 100644 index 1cf0b77b1efe..000000000000 --- a/trunk/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi +++ /dev/null @@ -1,43 +0,0 @@ -/* - * PQ3 MPIC Message (Group B) device tree stub [ controller @ offset 0x42400 ] - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -message@42400 { - compatible = "fsl,mpic-v3.1-msgr"; - reg = <0x42400 0x200>; - interrupts = < - 0xb4 2 0 0 - 0xb5 2 0 0 - 0xb6 2 0 0 - 0xb7 2 0 0>; -}; diff --git a/trunk/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi b/trunk/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi index 71c30eb10056..fdedf7b1fe0f 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi @@ -53,16 +53,6 @@ timer@41100 { 3 0 3 0>; }; -message@41400 { - compatible = "fsl,mpic-v3.1-msgr"; - reg = <0x41400 0x200>; - interrupts = < - 0xb0 2 0 0 - 0xb1 2 0 0 - 0xb2 2 0 0 - 0xb3 2 0 0>; -}; - msi@41600 { compatible = "fsl,mpic-msi"; reg = <0x41600 0x80>; diff --git a/trunk/arch/powerpc/boot/dts/p1020mbg-pc.dtsi b/trunk/arch/powerpc/boot/dts/p1020mbg-pc.dtsi deleted file mode 100644 index a24699cfea9c..000000000000 --- a/trunk/arch/powerpc/boot/dts/p1020mbg-pc.dtsi +++ /dev/null @@ -1,151 +0,0 @@ -/* - * P1020 MBG-PC Device Tree Source stub (no addresses or top-level ranges) - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -&lbc { - nor@0,0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "cfi-flash"; - reg = <0x0 0x0 0x4000000>; - bank-width = <2>; - device-width = <1>; - - partition@0 { - /* 128KB for DTB Image */ - reg = <0x0 0x00020000>; - label = "NOR DTB Image"; - }; - - partition@20000 { - /* 3.875 MB for Linux Kernel Image */ - reg = <0x00020000 0x003e0000>; - label = "NOR Linux Kernel Image"; - }; - - partition@400000 { - /* 58MB for Root file System */ - reg = <0x00400000 0x03a00000>; - label = "NOR Root File System"; - }; - - partition@3e00000 { - /* This location must not be altered */ - /* 1M for Vitesse 7385 Switch firmware */ - reg = <0x3e00000 0x00100000>; - label = "NOR Vitesse-7385 Firmware"; - read-only; - }; - - partition@3f00000 { - /* This location must not be altered */ - /* 512KB for u-boot Bootloader Image */ - /* 512KB for u-boot Environment Variables */ - reg = <0x03f00000 0x00100000>; - label = "NOR U-Boot Image"; - read-only; - }; - }; - - L2switch@2,0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "vitesse-7385"; - reg = <0x2 0x0 0x20000>; - }; -}; - -&soc { - i2c@3000 { - rtc@68 { - compatible = "dallas,ds1339"; - reg = <0x68>; - }; - }; - - mdio@24000 { - phy0: ethernet-phy@0 { - interrupts = <3 1 0 0>; - reg = <0x0>; - }; - phy1: ethernet-phy@1 { - interrupts = <2 1 0 0>; - reg = <0x1>; - }; - }; - - mdio@25000 { - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - - mdio@26000 { - tbi2: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - - enet0: ethernet@b0000 { - fixed-link = <1 1 1000 0 0>; - phy-connection-type = "rgmii-id"; - }; - - enet1: ethernet@b1000 { - phy-handle = <&phy0>; - tbi-handle = <&tbi1>; - phy-connection-type = "sgmii"; - }; - - enet2: ethernet@b2000 { - phy-handle = <&phy1>; - phy-connection-type = "rgmii-id"; - }; - - usb@22000 { - phy_type = "ulpi"; - }; - - /* USB2 is shared with localbus, so it must be disabled - by default. We can't put 'status = "disabled";' here - since U-Boot doesn't clear the status property when - it enables USB2. OTOH, U-Boot does create a new node - when there isn't any. So, just comment it out. - */ - usb@23000 { - status = "disabled"; - phy_type = "ulpi"; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/p1020mbg-pc_32b.dts b/trunk/arch/powerpc/boot/dts/p1020mbg-pc_32b.dts deleted file mode 100644 index ab8f076eae90..000000000000 --- a/trunk/arch/powerpc/boot/dts/p1020mbg-pc_32b.dts +++ /dev/null @@ -1,89 +0,0 @@ -/* - * P1020 MBG-PC Device Tree Source (32-bit address map) - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/include/ "fsl/p1020si-pre.dtsi" -/ { - model = "fsl,P1020MBG-PC"; - compatible = "fsl,P1020MBG-PC"; - - memory { - device_type = "memory"; - }; - - lbc: localbus@ffe05000 { - reg = <0x0 0xffe05000 0x0 0x1000>; - - /* NOR and L2 switch */ - ranges = <0x0 0x0 0x0 0xec000000 0x04000000 - 0x1 0x0 0x0 0xffa00000 0x00040000 - 0x2 0x0 0x0 0xffb00000 0x00020000>; - }; - - soc: soc@ffe00000 { - ranges = <0x0 0x0 0xffe00000 0x100000>; - }; - - pci0: pcie@ffe09000 { - reg = <0x0 0xffe09000 0x0 0x1000>; - ranges = <0x2000000 0x0 0xe0000000 0x0 0xa0000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0x0 0xffc10000 0x0 0x10000>; - pcie@0 { - ranges = <0x2000000 0x0 0xe0000000 - 0x2000000 0x0 0xe0000000 - 0x0 0x20000000 - - 0x1000000 0x0 0x0 - 0x1000000 0x0 0x0 - 0x0 0x100000>; - }; - }; - - pci1: pcie@ffe0a000 { - reg = <0x0 0xffe0a000 0x0 0x1000>; - ranges = <0x2000000 0x0 0xe0000000 0x0 0x80000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0x0 0xffc00000 0x0 0x10000>; - pcie@0 { - ranges = <0x2000000 0x0 0xe0000000 - 0x2000000 0x0 0xe0000000 - 0x0 0x20000000 - - 0x1000000 0x0 0x0 - 0x1000000 0x0 0x0 - 0x0 0x100000>; - }; - }; -}; - -/include/ "p1020mbg-pc.dtsi" -/include/ "fsl/p1020si-post.dtsi" diff --git a/trunk/arch/powerpc/boot/dts/p1020mbg-pc_36b.dts b/trunk/arch/powerpc/boot/dts/p1020mbg-pc_36b.dts deleted file mode 100644 index 9e9f401419b1..000000000000 --- a/trunk/arch/powerpc/boot/dts/p1020mbg-pc_36b.dts +++ /dev/null @@ -1,89 +0,0 @@ -/* - * P1020 MBG-PC Device Tree Source (36-bit address map) - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/include/ "fsl/p1020si-pre.dtsi" -/ { - model = "fsl,P1020MBG-PC"; - compatible = "fsl,P1020MBG-PC"; - - memory { - device_type = "memory"; - }; - - lbc: localbus@fffe05000 { - reg = <0xf 0xffe05000 0x0 0x1000>; - - /* NOR and L2 switch */ - ranges = <0x0 0x0 0xf 0xec000000 0x04000000 - 0x1 0x0 0xf 0xffa00000 0x00040000 - 0x2 0x0 0xf 0xffb00000 0x00020000>; - }; - - soc: soc@fffe00000 { - ranges = <0x0 0xf 0xffe00000 0x100000>; - }; - - pci0: pcie@fffe09000 { - reg = <0xf 0xffe09000 0x0 0x1000>; - ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>; - pcie@0 { - ranges = <0x2000000 0x0 0xe0000000 - 0x2000000 0x0 0xe0000000 - 0x0 0x20000000 - - 0x1000000 0x0 0x0 - 0x1000000 0x0 0x0 - 0x0 0x100000>; - }; - }; - - pci1: pcie@fffe0a000 { - reg = <0xf 0xffe0a000 0 0x1000>; - ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>; - pcie@0 { - ranges = <0x2000000 0x0 0xe0000000 - 0x2000000 0x0 0xe0000000 - 0x0 0x20000000 - - 0x1000000 0x0 0x0 - 0x1000000 0x0 0x0 - 0x0 0x100000>; - }; - }; -}; - -/include/ "p1020mbg-pc.dtsi" -/include/ "fsl/p1020si-post.dtsi" diff --git a/trunk/arch/powerpc/boot/dts/p1020utm-pc.dtsi b/trunk/arch/powerpc/boot/dts/p1020utm-pc.dtsi deleted file mode 100644 index 7ea85eabcc5c..000000000000 --- a/trunk/arch/powerpc/boot/dts/p1020utm-pc.dtsi +++ /dev/null @@ -1,140 +0,0 @@ -/* - * P1020 UTM-PC Device Tree Source stub (no addresses or top-level ranges) - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -&lbc { - nor@0,0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "cfi-flash"; - reg = <0x0 0x0 0x2000000>; - bank-width = <2>; - device-width = <1>; - - partition@0 { - /* 256KB for DTB Image */ - reg = <0x0 0x00040000>; - label = "NOR DTB Image"; - }; - - partition@40000 { - /* 3.75 MB for Linux Kernel Image */ - reg = <0x00040000 0x003c0000>; - label = "NOR Linux Kernel Image"; - }; - - partition@400000 { - /* 27MB for Root file System */ - reg = <0x00400000 0x01b00000>; - label = "NOR Root File System"; - }; - - partition@1f00000 { - /* This location must not be altered */ - /* 512KB for u-boot Bootloader Image */ - /* 512KB for u-boot Environment Variables */ - reg = <0x01f00000 0x00100000>; - label = "NOR U-Boot Image"; - read-only; - }; - }; -}; - -&soc { - i2c@3000 { - rtc@68 { - compatible = "dallas,ds1339"; - reg = <0x68>; - }; - }; - - mdio@24000 { - phy0: ethernet-phy@0 { - interrupts = <3 1 0 0>; - reg = <0x0>; - }; - phy1: ethernet-phy@1 { - interrupts = <2 1 0 0>; - reg = <0x1>; - }; - phy2: ethernet-phy@2 { - interrupts = <1 1 0 0>; - reg = <0x2>; - }; - }; - - mdio@25000 { - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - - mdio@26000 { - tbi2: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - - enet0: ethernet@b0000 { - phy-handle = <&phy2>; - phy-connection-type = "rgmii-id"; - }; - - enet1: ethernet@b1000 { - phy-handle = <&phy0>; - tbi-handle = <&tbi1>; - phy-connection-type = "sgmii"; - }; - - enet2: ethernet@b2000 { - phy-handle = <&phy1>; - phy-connection-type = "rgmii-id"; - }; - - usb@22000 { - phy_type = "ulpi"; - }; - - /* USB2 is shared with localbus, so it must be disabled - by default. We can't put 'status = "disabled";' here - since U-Boot doesn't clear the status property when - it enables USB2. OTOH, U-Boot does create a new node - when there isn't any. So, just comment it out. - */ - usb@23000 { - status = "disabled"; - phy_type = "ulpi"; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/p1020utm-pc_32b.dts b/trunk/arch/powerpc/boot/dts/p1020utm-pc_32b.dts deleted file mode 100644 index 4bfdd8971cdb..000000000000 --- a/trunk/arch/powerpc/boot/dts/p1020utm-pc_32b.dts +++ /dev/null @@ -1,89 +0,0 @@ -/* - * P1020 UTM-PC Device Tree Source (32-bit address map) - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/include/ "fsl/p1020si-pre.dtsi" -/ { - model = "fsl,P1020UTM-PC"; - compatible = "fsl,P1020UTM-PC"; - - memory { - device_type = "memory"; - }; - - lbc: localbus@ffe05000 { - reg = <0x0 0xffe05000 0x0 0x1000>; - - /* NOR */ - ranges = <0x0 0x0 0x0 0xec000000 0x02000000 - 0x1 0x0 0x0 0xffa00000 0x00040000 - 0x2 0x0 0x0 0xffb00000 0x00020000>; - }; - - soc: soc@ffe00000 { - ranges = <0x0 0x0 0xffe00000 0x100000>; - }; - - pci0: pcie@ffe09000 { - reg = <0x0 0xffe09000 0x0 0x1000>; - ranges = <0x2000000 0x0 0xe0000000 0x0 0xa0000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0x0 0xffc10000 0x0 0x10000>; - pcie@0 { - ranges = <0x2000000 0x0 0xe0000000 - 0x2000000 0x0 0xe0000000 - 0x0 0x20000000 - - 0x1000000 0x0 0x0 - 0x1000000 0x0 0x0 - 0x0 0x100000>; - }; - }; - - pci1: pcie@ffe0a000 { - reg = <0x0 0xffe0a000 0x0 0x1000>; - ranges = <0x2000000 0x0 0xe0000000 0x0 0x80000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0x0 0xffc00000 0x0 0x10000>; - pcie@0 { - ranges = <0x2000000 0x0 0xe0000000 - 0x2000000 0x0 0xe0000000 - 0x0 0x20000000 - - 0x1000000 0x0 0x0 - 0x1000000 0x0 0x0 - 0x0 0x100000>; - }; - }; -}; - -/include/ "p1020utm-pc.dtsi" -/include/ "fsl/p1020si-post.dtsi" diff --git a/trunk/arch/powerpc/boot/dts/p1020utm-pc_36b.dts b/trunk/arch/powerpc/boot/dts/p1020utm-pc_36b.dts deleted file mode 100644 index abec53557501..000000000000 --- a/trunk/arch/powerpc/boot/dts/p1020utm-pc_36b.dts +++ /dev/null @@ -1,89 +0,0 @@ -/* - * P1020 UTM-PC Device Tree Source (36-bit address map) - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/include/ "fsl/p1020si-pre.dtsi" -/ { - model = "fsl,P1020UTM-PC"; - compatible = "fsl,P1020UTM-PC"; - - memory { - device_type = "memory"; - }; - - lbc: localbus@fffe05000 { - reg = <0xf 0xffe05000 0x0 0x1000>; - - /* NOR */ - ranges = <0x0 0x0 0xf 0xec000000 0x02000000 - 0x1 0x0 0xf 0xffa00000 0x00040000 - 0x2 0x0 0xf 0xffb00000 0x00020000>; - }; - - soc: soc@fffe00000 { - ranges = <0x0 0xf 0xffe00000 0x100000>; - }; - - pci0: pcie@fffe09000 { - reg = <0xf 0xffe09000 0x0 0x1000>; - ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>; - pcie@0 { - ranges = <0x2000000 0x0 0xe0000000 - 0x2000000 0x0 0xe0000000 - 0x0 0x20000000 - - 0x1000000 0x0 0x0 - 0x1000000 0x0 0x0 - 0x0 0x100000>; - }; - }; - - pci1: pcie@fffe0a000 { - reg = <0xf 0xffe0a000 0 0x1000>; - ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>; - pcie@0 { - ranges = <0x2000000 0x0 0xe0000000 - 0x2000000 0x0 0xe0000000 - 0x0 0x20000000 - - 0x1000000 0x0 0x0 - 0x1000000 0x0 0x0 - 0x0 0x100000>; - }; - }; -}; - -/include/ "p1020utm-pc.dtsi" -/include/ "fsl/p1020si-post.dtsi" diff --git a/trunk/arch/powerpc/boot/dts/p2041rdb.dts b/trunk/arch/powerpc/boot/dts/p2041rdb.dts index 285213976a7f..4f957db01230 100644 --- a/trunk/arch/powerpc/boot/dts/p2041rdb.dts +++ b/trunk/arch/powerpc/boot/dts/p2041rdb.dts @@ -135,6 +135,7 @@ reg = <0xf 0xfe200000 0 0x1000>; ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>; + fsl,msi = <&msi0>; pcie@0 { ranges = <0x02000000 0 0xe0000000 0x02000000 0 0xe0000000 @@ -150,6 +151,7 @@ reg = <0xf 0xfe201000 0 0x1000>; ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>; + fsl,msi = <&msi1>; pcie@0 { ranges = <0x02000000 0 0xe0000000 0x02000000 0 0xe0000000 @@ -165,6 +167,7 @@ reg = <0xf 0xfe202000 0 0x1000>; ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>; + fsl,msi = <&msi2>; pcie@0 { ranges = <0x02000000 0 0xe0000000 0x02000000 0 0xe0000000 diff --git a/trunk/arch/powerpc/boot/dts/p3041ds.dts b/trunk/arch/powerpc/boot/dts/p3041ds.dts index 22a215e94162..f469145abaeb 100644 --- a/trunk/arch/powerpc/boot/dts/p3041ds.dts +++ b/trunk/arch/powerpc/boot/dts/p3041ds.dts @@ -173,6 +173,7 @@ reg = <0xf 0xfe200000 0 0x1000>; ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>; + fsl,msi = <&msi0>; pcie@0 { ranges = <0x02000000 0 0xe0000000 0x02000000 0 0xe0000000 @@ -188,6 +189,7 @@ reg = <0xf 0xfe201000 0 0x1000>; ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>; + fsl,msi = <&msi1>; pcie@0 { ranges = <0x02000000 0 0xe0000000 0x02000000 0 0xe0000000 @@ -203,6 +205,7 @@ reg = <0xf 0xfe202000 0 0x1000>; ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>; + fsl,msi = <&msi2>; pcie@0 { ranges = <0x02000000 0 0xe0000000 0x02000000 0 0xe0000000 @@ -218,6 +221,7 @@ reg = <0xf 0xfe203000 0 0x1000>; ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>; + fsl,msi = <&msi2>; pcie@0 { ranges = <0x02000000 0 0xe0000000 0x02000000 0 0xe0000000 diff --git a/trunk/arch/powerpc/boot/dts/p3060qds.dts b/trunk/arch/powerpc/boot/dts/p3060qds.dts index 9ae875c8a211..529042e4b9a2 100644 --- a/trunk/arch/powerpc/boot/dts/p3060qds.dts +++ b/trunk/arch/powerpc/boot/dts/p3060qds.dts @@ -212,6 +212,7 @@ reg = <0xf 0xfe200000 0 0x1000>; ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>; + fsl,msi = <&msi0>; pcie@0 { ranges = <0x02000000 0 0xe0000000 0x02000000 0 0xe0000000 @@ -227,6 +228,7 @@ reg = <0xf 0xfe201000 0 0x1000>; ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>; + fsl,msi = <&msi1>; pcie@0 { ranges = <0x02000000 0 0xe0000000 0x02000000 0 0xe0000000 diff --git a/trunk/arch/powerpc/boot/dts/p4080ds.dts b/trunk/arch/powerpc/boot/dts/p4080ds.dts index 3e204609d02e..6d60e54e50a0 100644 --- a/trunk/arch/powerpc/boot/dts/p4080ds.dts +++ b/trunk/arch/powerpc/boot/dts/p4080ds.dts @@ -141,6 +141,7 @@ reg = <0xf 0xfe200000 0 0x1000>; ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>; + fsl,msi = <&msi0>; pcie@0 { ranges = <0x02000000 0 0xe0000000 0x02000000 0 0xe0000000 @@ -156,6 +157,7 @@ reg = <0xf 0xfe201000 0 0x1000>; ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>; + fsl,msi = <&msi1>; pcie@0 { ranges = <0x02000000 0 0xe0000000 0x02000000 0 0xe0000000 @@ -171,6 +173,7 @@ reg = <0xf 0xfe202000 0 0x1000>; ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>; + fsl,msi = <&msi2>; pcie@0 { ranges = <0x02000000 0 0xe0000000 0x02000000 0 0xe0000000 diff --git a/trunk/arch/powerpc/boot/dts/p5020ds.dts b/trunk/arch/powerpc/boot/dts/p5020ds.dts index 27c07ed6adc1..1c250684c902 100644 --- a/trunk/arch/powerpc/boot/dts/p5020ds.dts +++ b/trunk/arch/powerpc/boot/dts/p5020ds.dts @@ -173,6 +173,7 @@ reg = <0xf 0xfe200000 0 0x1000>; ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>; + fsl,msi = <&msi0>; pcie@0 { ranges = <0x02000000 0 0xe0000000 0x02000000 0 0xe0000000 @@ -188,6 +189,7 @@ reg = <0xf 0xfe201000 0 0x1000>; ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>; + fsl,msi = <&msi1>; pcie@0 { ranges = <0x02000000 0 0xe0000000 0x02000000 0 0xe0000000 @@ -203,6 +205,7 @@ reg = <0xf 0xfe202000 0 0x1000>; ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>; + fsl,msi = <&msi2>; pcie@0 { ranges = <0x02000000 0 0xe0000000 0x02000000 0 0xe0000000 @@ -218,6 +221,7 @@ reg = <0xf 0xfe203000 0 0x1000>; ranges = <0x02000000 0 0xe0000000 0xc 0x60000000 0 0x20000000 0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>; + fsl,msi = <&msi2>; pcie@0 { ranges = <0x02000000 0 0xe0000000 0x02000000 0 0xe0000000 diff --git a/trunk/arch/powerpc/configs/corenet32_smp_defconfig b/trunk/arch/powerpc/configs/corenet32_smp_defconfig index 91db656294e8..f8aef205d222 100644 --- a/trunk/arch/powerpc/configs/corenet32_smp_defconfig +++ b/trunk/arch/powerpc/configs/corenet32_smp_defconfig @@ -116,7 +116,6 @@ CONFIG_SERIAL_8250_RSA=y CONFIG_HW_RANDOM=y CONFIG_NVRAM=y CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y CONFIG_SPI=y CONFIG_SPI_GPIO=y diff --git a/trunk/arch/powerpc/configs/corenet64_smp_defconfig b/trunk/arch/powerpc/configs/corenet64_smp_defconfig index 6798343580f0..82b13bfcf3c0 100644 --- a/trunk/arch/powerpc/configs/corenet64_smp_defconfig +++ b/trunk/arch/powerpc/configs/corenet64_smp_defconfig @@ -71,8 +71,6 @@ CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_DETECT_IRQ=y CONFIG_SERIAL_8250_RSA=y CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MPC=y # CONFIG_HWMON is not set CONFIG_VIDEO_OUTPUT_CONTROL=y # CONFIG_HID_SUPPORT is not set diff --git a/trunk/arch/powerpc/configs/mpc85xx_defconfig b/trunk/arch/powerpc/configs/mpc85xx_defconfig index d6b6df5e8743..cc87a8441566 100644 --- a/trunk/arch/powerpc/configs/mpc85xx_defconfig +++ b/trunk/arch/powerpc/configs/mpc85xx_defconfig @@ -117,7 +117,6 @@ CONFIG_SERIAL_8250_RSA=y CONFIG_SERIAL_QE=m CONFIG_NVRAM=y CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y CONFIG_I2C_CPM=m CONFIG_I2C_MPC=y CONFIG_SPI=y diff --git a/trunk/arch/powerpc/configs/mpc85xx_smp_defconfig b/trunk/arch/powerpc/configs/mpc85xx_smp_defconfig index 5b0e2926becd..48d6682f2434 100644 --- a/trunk/arch/powerpc/configs/mpc85xx_smp_defconfig +++ b/trunk/arch/powerpc/configs/mpc85xx_smp_defconfig @@ -119,7 +119,6 @@ CONFIG_SERIAL_8250_RSA=y CONFIG_SERIAL_QE=m CONFIG_NVRAM=y CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y CONFIG_I2C_CPM=m CONFIG_I2C_MPC=y CONFIG_SPI=y diff --git a/trunk/arch/powerpc/include/asm/dma-mapping.h b/trunk/arch/powerpc/include/asm/dma-mapping.h index 62678e365ca0..dd70fac57ec8 100644 --- a/trunk/arch/powerpc/include/asm/dma-mapping.h +++ b/trunk/arch/powerpc/include/asm/dma-mapping.h @@ -22,11 +22,9 @@ /* Some dma direct funcs must be visible for use in other dma_ops */ extern void *dma_direct_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag, - struct dma_attrs *attrs); + dma_addr_t *dma_handle, gfp_t flag); extern void dma_direct_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, - struct dma_attrs *attrs); + void *vaddr, dma_addr_t dma_handle); #ifdef CONFIG_NOT_COHERENT_CACHE @@ -132,29 +130,23 @@ static inline int dma_supported(struct device *dev, u64 mask) extern int dma_set_mask(struct device *dev, u64 dma_mask); -#define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) - -static inline void *dma_alloc_attrs(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag, - struct dma_attrs *attrs) +static inline void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) { struct dma_map_ops *dma_ops = get_dma_ops(dev); void *cpu_addr; BUG_ON(!dma_ops); - cpu_addr = dma_ops->alloc(dev, size, dma_handle, flag, attrs); + cpu_addr = dma_ops->alloc_coherent(dev, size, dma_handle, flag); debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr); return cpu_addr; } -#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) - -static inline void dma_free_attrs(struct device *dev, size_t size, - void *cpu_addr, dma_addr_t dma_handle, - struct dma_attrs *attrs) +static inline void dma_free_coherent(struct device *dev, size_t size, + void *cpu_addr, dma_addr_t dma_handle) { struct dma_map_ops *dma_ops = get_dma_ops(dev); @@ -162,7 +154,7 @@ static inline void dma_free_attrs(struct device *dev, size_t size, debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); - dma_ops->free(dev, size, cpu_addr, dma_handle, attrs); + dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); } static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) diff --git a/trunk/arch/powerpc/include/asm/epapr_hcalls.h b/trunk/arch/powerpc/include/asm/epapr_hcalls.h index 976835d8f22e..f3b0c2cc9fea 100644 --- a/trunk/arch/powerpc/include/asm/epapr_hcalls.h +++ b/trunk/arch/powerpc/include/asm/epapr_hcalls.h @@ -134,15 +134,10 @@ * whether they will be clobbered. * * Note that r11 can be used as an output parameter. - * - * The "memory" clobber is only necessary for hcalls where the Hypervisor - * will read or write guest memory. However, we add it to all hcalls because - * the impact is minimal, and we want to ensure that it's present for the - * hcalls that need it. */ /* List of common clobbered registers. Do not use this macro. */ -#define EV_HCALL_CLOBBERS "r0", "r12", "xer", "ctr", "lr", "cc", "memory" +#define EV_HCALL_CLOBBERS "r0", "r12", "xer", "ctr", "lr", "cc" #define EV_HCALL_CLOBBERS8 EV_HCALL_CLOBBERS #define EV_HCALL_CLOBBERS7 EV_HCALL_CLOBBERS8, "r10" diff --git a/trunk/arch/powerpc/include/asm/fsl_guts.h b/trunk/arch/powerpc/include/asm/fsl_guts.h index aa4c488589ce..ce04530d2000 100644 --- a/trunk/arch/powerpc/include/asm/fsl_guts.h +++ b/trunk/arch/powerpc/include/asm/fsl_guts.h @@ -16,6 +16,15 @@ #define __ASM_POWERPC_FSL_GUTS_H__ #ifdef __KERNEL__ +/* + * These #ifdefs are safe because it's not possible to build a kernel that + * runs on e500 and e600 cores. + */ + +#if !defined(CONFIG_PPC_85xx) && !defined(CONFIG_PPC_86xx) +#error Only 85xx and 86xx SOCs are supported +#endif + /** * Global Utility Registers. * @@ -27,7 +36,11 @@ * different names. In these cases, one name is chosen to avoid extraneous * #ifdefs. */ -struct ccsr_guts { +#ifdef CONFIG_PPC_85xx +struct ccsr_guts_85xx { +#else +struct ccsr_guts_86xx { +#endif __be32 porpllsr; /* 0x.0000 - POR PLL Ratio Status Register */ __be32 porbmsr; /* 0x.0004 - POR Boot Mode Status Register */ __be32 porimpscr; /* 0x.0008 - POR I/O Impedance Status and Control Register */ @@ -64,8 +77,11 @@ struct ccsr_guts { u8 res0a8[0xb0 - 0xa8]; __be32 rstcr; /* 0x.00b0 - Reset Control Register */ u8 res0b4[0xc0 - 0xb4]; - __be32 iovselsr; /* 0x.00c0 - I/O voltage select status register - Called 'elbcvselcr' on 86xx SOCs */ +#ifdef CONFIG_PPC_85xx + __be32 iovselsr; /* 0x.00c0 - I/O voltage select status register */ +#else + __be32 elbcvselcr; /* 0x.00c0 - eLBC Voltage Select Ctrl Reg */ +#endif u8 res0c4[0x224 - 0xc4]; __be32 iodelay1; /* 0x.0224 - IO delay control register 1 */ __be32 iodelay2; /* 0x.0228 - IO delay control register 2 */ @@ -120,7 +136,7 @@ struct ccsr_guts { * ch: The channel on the DMA controller (0, 1, 2, or 3) * device: The device to set as the source (CCSR_GUTS_DMACR_DEV_xx) */ -static inline void guts_set_dmacr(struct ccsr_guts __iomem *guts, +static inline void guts_set_dmacr(struct ccsr_guts_86xx __iomem *guts, unsigned int co, unsigned int ch, unsigned int device) { unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch)); @@ -156,7 +172,7 @@ static inline void guts_set_dmacr(struct ccsr_guts __iomem *guts, * ch: The channel on the DMA controller (0, 1, 2, or 3) * value: the new value for the bit (0 or 1) */ -static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts, +static inline void guts_set_pmuxcr_dma(struct ccsr_guts_86xx __iomem *guts, unsigned int co, unsigned int ch, unsigned int value) { if ((ch == 0) || (ch == 3)) { diff --git a/trunk/arch/powerpc/include/asm/irq.h b/trunk/arch/powerpc/include/asm/irq.h index 0e40843a1c6e..cf417e510736 100644 --- a/trunk/arch/powerpc/include/asm/irq.h +++ b/trunk/arch/powerpc/include/asm/irq.h @@ -18,6 +18,10 @@ #include +/* Define a way to iterate across irqs. */ +#define for_each_irq(i) \ + for ((i) = 0; (i) < NR_IRQS; ++(i)) + extern atomic_t ppc_n_lost_interrupts; /* This number is used when no interrupt has been assigned */ @@ -29,6 +33,8 @@ extern atomic_t ppc_n_lost_interrupts; /* Same thing, used by the generic IRQ code */ #define NR_IRQS_LEGACY NUM_ISA_INTERRUPTS +struct irq_data; +extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d); extern irq_hw_number_t virq_to_hw(unsigned int virq); /** diff --git a/trunk/arch/powerpc/include/asm/mpic.h b/trunk/arch/powerpc/include/asm/mpic.h index c9f698a994be..c65b9294376e 100644 --- a/trunk/arch/powerpc/include/asm/mpic.h +++ b/trunk/arch/powerpc/include/asm/mpic.h @@ -275,6 +275,9 @@ struct mpic unsigned int isu_mask; /* Number of sources */ unsigned int num_sources; + /* default senses array */ + unsigned char *senses; + unsigned int senses_count; /* vector numbers used for internal sources (ipi/timers) */ unsigned int ipi_vecs[4]; @@ -412,6 +415,21 @@ extern struct mpic *mpic_alloc(struct device_node *node, extern void mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, phys_addr_t phys_addr); +/* Set default sense codes + * + * @mpic: controller + * @senses: array of sense codes + * @count: size of above array + * + * Optionally provide an array (indexed on hardware interrupt numbers + * for this MPIC) of default sense codes for the chip. Those are linux + * sense codes IRQ_TYPE_* + * + * The driver gets ownership of the pointer, don't dispose of it or + * anything like that. __init only. + */ +extern void mpic_set_default_senses(struct mpic *mpic, u8 *senses, int count); + /* Initialize the controller. After this has been called, none of the above * should be called again for this mpic diff --git a/trunk/arch/powerpc/include/asm/mpic_msgr.h b/trunk/arch/powerpc/include/asm/mpic_msgr.h index 326d33ca55cd..3ec37dc9003e 100644 --- a/trunk/arch/powerpc/include/asm/mpic_msgr.h +++ b/trunk/arch/powerpc/include/asm/mpic_msgr.h @@ -13,7 +13,6 @@ #include #include -#include struct mpic_msgr { u32 __iomem *base; diff --git a/trunk/arch/powerpc/include/asm/reg_booke.h b/trunk/arch/powerpc/include/asm/reg_booke.h index 8a97aa7289d3..b86faa9107da 100644 --- a/trunk/arch/powerpc/include/asm/reg_booke.h +++ b/trunk/arch/powerpc/include/asm/reg_booke.h @@ -15,6 +15,11 @@ #ifndef __ASM_POWERPC_REG_BOOKE_H__ #define __ASM_POWERPC_REG_BOOKE_H__ +#ifdef CONFIG_BOOKE_WDT +extern u32 booke_wdt_enabled; +extern u32 booke_wdt_period; +#endif /* CONFIG_BOOKE_WDT */ + /* Machine State Register (MSR) Fields */ #define MSR_GS (1<<28) /* Guest state */ #define MSR_UCLE (1<<26) /* User-mode cache lock enable */ diff --git a/trunk/arch/powerpc/kernel/dma-iommu.c b/trunk/arch/powerpc/kernel/dma-iommu.c index bcfdcd22c766..3f6464b4d970 100644 --- a/trunk/arch/powerpc/kernel/dma-iommu.c +++ b/trunk/arch/powerpc/kernel/dma-iommu.c @@ -17,8 +17,7 @@ * to the dma address (mapping) of the first page. */ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag, - struct dma_attrs *attrs) + dma_addr_t *dma_handle, gfp_t flag) { return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size, dma_handle, dev->coherent_dma_mask, flag, @@ -26,8 +25,7 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, } static void dma_iommu_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, - struct dma_attrs *attrs) + void *vaddr, dma_addr_t dma_handle) { iommu_free_coherent(get_iommu_table_base(dev), size, vaddr, dma_handle); } @@ -107,8 +105,8 @@ static u64 dma_iommu_get_required_mask(struct device *dev) } struct dma_map_ops dma_iommu_ops = { - .alloc = dma_iommu_alloc_coherent, - .free = dma_iommu_free_coherent, + .alloc_coherent = dma_iommu_alloc_coherent, + .free_coherent = dma_iommu_free_coherent, .map_sg = dma_iommu_map_sg, .unmap_sg = dma_iommu_unmap_sg, .dma_supported = dma_iommu_dma_supported, diff --git a/trunk/arch/powerpc/kernel/dma-swiotlb.c b/trunk/arch/powerpc/kernel/dma-swiotlb.c index 4ab88dafb235..1ebc9189aada 100644 --- a/trunk/arch/powerpc/kernel/dma-swiotlb.c +++ b/trunk/arch/powerpc/kernel/dma-swiotlb.c @@ -47,8 +47,8 @@ static u64 swiotlb_powerpc_get_required(struct device *dev) * for everything else. */ struct dma_map_ops swiotlb_dma_ops = { - .alloc = dma_direct_alloc_coherent, - .free = dma_direct_free_coherent, + .alloc_coherent = dma_direct_alloc_coherent, + .free_coherent = dma_direct_free_coherent, .map_sg = swiotlb_map_sg_attrs, .unmap_sg = swiotlb_unmap_sg_attrs, .dma_supported = swiotlb_dma_supported, diff --git a/trunk/arch/powerpc/kernel/dma.c b/trunk/arch/powerpc/kernel/dma.c index b1ec983dcec8..7d0233c12ee3 100644 --- a/trunk/arch/powerpc/kernel/dma.c +++ b/trunk/arch/powerpc/kernel/dma.c @@ -26,8 +26,7 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag, - struct dma_attrs *attrs) + dma_addr_t *dma_handle, gfp_t flag) { void *ret; #ifdef CONFIG_NOT_COHERENT_CACHE @@ -55,8 +54,7 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size, } void dma_direct_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, - struct dma_attrs *attrs) + void *vaddr, dma_addr_t dma_handle) { #ifdef CONFIG_NOT_COHERENT_CACHE __dma_free_coherent(size, vaddr); @@ -152,8 +150,8 @@ static inline void dma_direct_sync_single(struct device *dev, #endif struct dma_map_ops dma_direct_ops = { - .alloc = dma_direct_alloc_coherent, - .free = dma_direct_free_coherent, + .alloc_coherent = dma_direct_alloc_coherent, + .free_coherent = dma_direct_free_coherent, .map_sg = dma_direct_map_sg, .unmap_sg = dma_direct_unmap_sg, .dma_supported = dma_direct_dma_supported, diff --git a/trunk/arch/powerpc/kernel/entry_32.S b/trunk/arch/powerpc/kernel/entry_32.S index ba3aeb4bc06a..3e57a00b8cba 100644 --- a/trunk/arch/powerpc/kernel/entry_32.S +++ b/trunk/arch/powerpc/kernel/entry_32.S @@ -206,43 +206,40 @@ reenable_mmu: /* re-enable mmu so we can */ andi. r10,r10,MSR_EE /* Did EE change? */ beq 1f + /* Save handler and return address into the 2 unused words + * of the STACK_FRAME_OVERHEAD (sneak sneak sneak). Everything + * else can be recovered from the pt_regs except r3 which for + * normal interrupts has been set to pt_regs and for syscalls + * is an argument, so we temporarily use ORIG_GPR3 to save it + */ + stw r9,8(r1) + stw r11,12(r1) + stw r3,ORIG_GPR3(r1) /* * The trace_hardirqs_off will use CALLER_ADDR0 and CALLER_ADDR1. * If from user mode there is only one stack frame on the stack, and * accessing CALLER_ADDR1 will cause oops. So we need create a dummy * stack frame to make trace_hardirqs_off happy. - * - * This is handy because we also need to save a bunch of GPRs, - * r3 can be different from GPR3(r1) at this point, r9 and r11 - * contains the old MSR and handler address respectively, - * r4 & r5 can contain page fault arguments that need to be passed - * along as well. r12, CCR, CTR, XER etc... are left clobbered as - * they aren't useful past this point (aren't syscall arguments), - * the rest is restored from the exception frame. */ - stwu r1,-32(r1) - stw r9,8(r1) - stw r11,12(r1) - stw r3,16(r1) - stw r4,20(r1) - stw r5,24(r1) andi. r12,r12,MSR_PR - b 11f + beq 11f + stwu r1,-16(r1) bl trace_hardirqs_off + addi r1,r1,16 b 12f + 11: bl trace_hardirqs_off 12: - lwz r5,24(r1) - lwz r4,20(r1) - lwz r3,16(r1) - lwz r11,12(r1) - lwz r9,8(r1) - addi r1,r1,32 lwz r0,GPR0(r1) + lwz r3,ORIG_GPR3(r1) + lwz r4,GPR4(r1) + lwz r5,GPR5(r1) lwz r6,GPR6(r1) lwz r7,GPR7(r1) lwz r8,GPR8(r1) + lwz r9,8(r1) + lwz r11,12(r1) 1: mtctr r11 mtlr r9 bctr /* jump to handler */ diff --git a/trunk/arch/powerpc/kernel/fadump.c b/trunk/arch/powerpc/kernel/fadump.c index 18bdf74fa164..cfe7a38708c3 100644 --- a/trunk/arch/powerpc/kernel/fadump.c +++ b/trunk/arch/powerpc/kernel/fadump.c @@ -40,8 +40,6 @@ #include #include #include -#include -#include static struct fw_dump fw_dump; static struct fadump_mem_struct fdm; diff --git a/trunk/arch/powerpc/kernel/ibmebus.c b/trunk/arch/powerpc/kernel/ibmebus.c index b01d14eeca8d..79bb282e6501 100644 --- a/trunk/arch/powerpc/kernel/ibmebus.c +++ b/trunk/arch/powerpc/kernel/ibmebus.c @@ -65,8 +65,7 @@ static struct of_device_id __initdata ibmebus_matches[] = { static void *ibmebus_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, - gfp_t flag, - struct dma_attrs *attrs) + gfp_t flag) { void *mem; @@ -78,8 +77,7 @@ static void *ibmebus_alloc_coherent(struct device *dev, static void ibmebus_free_coherent(struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_handle, - struct dma_attrs *attrs) + dma_addr_t dma_handle) { kfree(vaddr); } @@ -138,8 +136,8 @@ static u64 ibmebus_dma_get_required_mask(struct device *dev) } static struct dma_map_ops ibmebus_dma_ops = { - .alloc = ibmebus_alloc_coherent, - .free = ibmebus_free_coherent, + .alloc_coherent = ibmebus_alloc_coherent, + .free_coherent = ibmebus_free_coherent, .map_sg = ibmebus_map_sg, .unmap_sg = ibmebus_unmap_sg, .dma_supported = ibmebus_dma_supported, diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index 43eb74fcedde..243dbabfe74d 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -330,10 +330,14 @@ void migrate_irqs(void) alloc_cpumask_var(&mask, GFP_KERNEL); - for_each_irq_desc(irq, desc) { + for_each_irq(irq) { struct irq_data *data; struct irq_chip *chip; + desc = irq_to_desc(irq); + if (!desc) + continue; + data = irq_desc_get_irq_data(desc); if (irqd_is_per_cpu(data)) continue; @@ -556,6 +560,12 @@ void do_softirq(void) local_irq_restore(flags); } +irq_hw_number_t irqd_to_hwirq(struct irq_data *d) +{ + return d->hwirq; +} +EXPORT_SYMBOL_GPL(irqd_to_hwirq); + irq_hw_number_t virq_to_hw(unsigned int virq) { struct irq_data *irq_data = irq_get_irq_data(virq); diff --git a/trunk/arch/powerpc/kernel/kgdb.c b/trunk/arch/powerpc/kernel/kgdb.c index 782bd0a3c2f0..76a6e40a6f7c 100644 --- a/trunk/arch/powerpc/kernel/kgdb.c +++ b/trunk/arch/powerpc/kernel/kgdb.c @@ -24,7 +24,6 @@ #include #include #include -#include /* * This table contains the mapping between PowerPC hardware trap types, and diff --git a/trunk/arch/powerpc/kernel/machine_kexec.c b/trunk/arch/powerpc/kernel/machine_kexec.c index 5df777794403..c957b1202bdc 100644 --- a/trunk/arch/powerpc/kernel/machine_kexec.c +++ b/trunk/arch/powerpc/kernel/machine_kexec.c @@ -23,11 +23,14 @@ void machine_kexec_mask_interrupts(void) { unsigned int i; - struct irq_desc *desc; - for_each_irq_desc(i, desc) { + for_each_irq(i) { + struct irq_desc *desc = irq_to_desc(i); struct irq_chip *chip; + if (!desc) + continue; + chip = irq_desc_get_chip(desc); if (!chip) continue; diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index 4937c9690090..f88698c0f332 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -1235,7 +1235,7 @@ void __ppc64_runlatch_on(void) ctrl |= CTRL_RUNLATCH; mtspr(SPRN_CTRLT, ctrl); - ti->local_flags |= _TLF_RUNLATCH; + ti->local_flags |= TLF_RUNLATCH; } /* Called with hard IRQs off */ @@ -1244,7 +1244,7 @@ void __ppc64_runlatch_off(void) struct thread_info *ti = current_thread_info(); unsigned long ctrl; - ti->local_flags &= ~_TLF_RUNLATCH; + ti->local_flags &= ~TLF_RUNLATCH; ctrl = mfspr(SPRN_CTRLF); ctrl &= ~CTRL_RUNLATCH; diff --git a/trunk/arch/powerpc/kernel/setup_32.c b/trunk/arch/powerpc/kernel/setup_32.c index ec8a53fa9e8f..9825f29d1faf 100644 --- a/trunk/arch/powerpc/kernel/setup_32.c +++ b/trunk/arch/powerpc/kernel/setup_32.c @@ -150,9 +150,6 @@ notrace void __init machine_init(u64 dt_ptr) } #ifdef CONFIG_BOOKE_WDT -extern u32 booke_wdt_enabled; -extern u32 booke_wdt_period; - /* Checks wdt=x and wdt_period=xx command-line option */ notrace int __init early_parse_wdt(char *p) { diff --git a/trunk/arch/powerpc/kernel/vio.c b/trunk/arch/powerpc/kernel/vio.c index a3a99901c8ec..b2f7c8480bf6 100644 --- a/trunk/arch/powerpc/kernel/vio.c +++ b/trunk/arch/powerpc/kernel/vio.c @@ -482,8 +482,7 @@ static void vio_cmo_balance(struct work_struct *work) } static void *vio_dma_iommu_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag, - struct dma_attrs *attrs) + dma_addr_t *dma_handle, gfp_t flag) { struct vio_dev *viodev = to_vio_dev(dev); void *ret; @@ -493,7 +492,7 @@ static void *vio_dma_iommu_alloc_coherent(struct device *dev, size_t size, return NULL; } - ret = dma_iommu_ops.alloc(dev, size, dma_handle, flag, attrs); + ret = dma_iommu_ops.alloc_coherent(dev, size, dma_handle, flag); if (unlikely(ret == NULL)) { vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE)); atomic_inc(&viodev->cmo.allocs_failed); @@ -503,12 +502,11 @@ static void *vio_dma_iommu_alloc_coherent(struct device *dev, size_t size, } static void vio_dma_iommu_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, - struct dma_attrs *attrs) + void *vaddr, dma_addr_t dma_handle) { struct vio_dev *viodev = to_vio_dev(dev); - dma_iommu_ops.free(dev, size, vaddr, dma_handle, attrs); + dma_iommu_ops.free_coherent(dev, size, vaddr, dma_handle); vio_cmo_dealloc(viodev, roundup(size, PAGE_SIZE)); } @@ -609,8 +607,8 @@ static u64 vio_dma_get_required_mask(struct device *dev) } struct dma_map_ops vio_dma_mapping_ops = { - .alloc = vio_dma_iommu_alloc_coherent, - .free = vio_dma_iommu_free_coherent, + .alloc_coherent = vio_dma_iommu_alloc_coherent, + .free_coherent = vio_dma_iommu_free_coherent, .map_sg = vio_dma_iommu_map_sg, .unmap_sg = vio_dma_iommu_unmap_sg, .map_page = vio_dma_iommu_map_page, diff --git a/trunk/arch/powerpc/kvm/book3s_emulate.c b/trunk/arch/powerpc/kvm/book3s_emulate.c index 135663a3e4fc..f1950d131827 100644 --- a/trunk/arch/powerpc/kvm/book3s_emulate.c +++ b/trunk/arch/powerpc/kvm/book3s_emulate.c @@ -21,7 +21,6 @@ #include #include #include -#include #define OP_19_XOP_RFID 18 #define OP_19_XOP_RFI 50 diff --git a/trunk/arch/powerpc/kvm/book3s_hv_builtin.c b/trunk/arch/powerpc/kvm/book3s_hv_builtin.c index e1b60f56f2a1..bed1279aa6a8 100644 --- a/trunk/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/trunk/arch/powerpc/kvm/book3s_hv_builtin.c @@ -173,9 +173,9 @@ static void __init kvm_linear_init_one(ulong size, int count, int type) static struct kvmppc_linear_info *kvm_alloc_linear(int type) { - struct kvmppc_linear_info *ri, *ret; + struct kvmppc_linear_info *ri; - ret = NULL; + ri = NULL; spin_lock(&linear_lock); list_for_each_entry(ri, &free_linears, list) { if (ri->type != type) @@ -183,12 +183,11 @@ static struct kvmppc_linear_info *kvm_alloc_linear(int type) list_del(&ri->list); atomic_inc(&ri->use_count); - memset(ri->base_virt, 0, ri->npages << PAGE_SHIFT); - ret = ri; break; } spin_unlock(&linear_lock); - return ret; + memset(ri->base_virt, 0, ri->npages << PAGE_SHIFT); + return ri; } static void kvm_release_linear(struct kvmppc_linear_info *ri) diff --git a/trunk/arch/powerpc/kvm/book3s_hv_interrupts.S b/trunk/arch/powerpc/kvm/book3s_hv_interrupts.S index d3fb4df02c41..3f7b674dd4bf 100644 --- a/trunk/arch/powerpc/kvm/book3s_hv_interrupts.S +++ b/trunk/arch/powerpc/kvm/book3s_hv_interrupts.S @@ -46,10 +46,8 @@ _GLOBAL(__kvmppc_vcore_entry) /* Save host state to the stack */ stdu r1, -SWITCH_FRAME_SIZE(r1) - /* Save non-volatile registers (r14 - r31) and CR */ + /* Save non-volatile registers (r14 - r31) */ SAVE_NVGPRS(r1) - mfcr r3 - std r3, _CCR(r1) /* Save host DSCR */ BEGIN_FTR_SECTION @@ -159,10 +157,8 @@ kvmppc_handler_highmem: * R13 = PACA */ - /* Restore non-volatile host registers (r14 - r31) and CR */ + /* Restore non-volatile host registers (r14 - r31) */ REST_NVGPRS(r1) - ld r4, _CCR(r1) - mtcr r4 addi r1, r1, SWITCH_FRAME_SIZE ld r0, PPC_LR_STKOFF(r1) diff --git a/trunk/arch/powerpc/kvm/book3s_interrupts.S b/trunk/arch/powerpc/kvm/book3s_interrupts.S index 3e35383bdb21..0a8515a5c042 100644 --- a/trunk/arch/powerpc/kvm/book3s_interrupts.S +++ b/trunk/arch/powerpc/kvm/book3s_interrupts.S @@ -84,10 +84,6 @@ kvm_start_entry: /* Save non-volatile registers (r14 - r31) */ SAVE_NVGPRS(r1) - /* Save CR */ - mfcr r14 - stw r14, _CCR(r1) - /* Save LR */ PPC_STL r0, _LINK(r1) @@ -169,9 +165,6 @@ kvm_exit_loop: PPC_LL r4, _LINK(r1) mtlr r4 - lwz r14, _CCR(r1) - mtcr r14 - /* Restore non-volatile host registers (r14 - r31) */ REST_NVGPRS(r1) diff --git a/trunk/arch/powerpc/kvm/book3s_paired_singles.c b/trunk/arch/powerpc/kvm/book3s_paired_singles.c index a59a25a13218..e70ef2d86431 100644 --- a/trunk/arch/powerpc/kvm/book3s_paired_singles.c +++ b/trunk/arch/powerpc/kvm/book3s_paired_singles.c @@ -24,7 +24,6 @@ #include #include #include -#include #include /* #define DEBUG */ diff --git a/trunk/arch/powerpc/kvm/book3s_pr.c b/trunk/arch/powerpc/kvm/book3s_pr.c index 7759053d391b..7340e1090b77 100644 --- a/trunk/arch/powerpc/kvm/book3s_pr.c +++ b/trunk/arch/powerpc/kvm/book3s_pr.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -777,7 +776,6 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, } } - preempt_disable(); if (!(r & RESUME_HOST)) { /* To avoid clobbering exit_reason, only check for signals if * we aren't already exiting to userspace for some other @@ -799,6 +797,8 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, run->exit_reason = KVM_EXIT_INTR; r = -EINTR; } else { + preempt_disable(); + /* In case an interrupt came in that was triggered * from userspace (like DEC), we need to check what * to inject now! */ @@ -880,8 +880,7 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) switch (reg->id) { case KVM_REG_PPC_HIOR: - r = copy_to_user((u64 __user *)(long)reg->addr, - &to_book3s(vcpu)->hior, sizeof(u64)); + r = put_user(to_book3s(vcpu)->hior, (u64 __user *)reg->addr); break; default: break; @@ -896,8 +895,7 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) switch (reg->id) { case KVM_REG_PPC_HIOR: - r = copy_from_user(&to_book3s(vcpu)->hior, - (u64 __user *)(long)reg->addr, sizeof(u64)); + r = get_user(to_book3s(vcpu)->hior, (u64 __user *)reg->addr); if (!r) to_book3s(vcpu)->hior_explicit = true; break; diff --git a/trunk/arch/powerpc/kvm/booke_interrupts.S b/trunk/arch/powerpc/kvm/booke_interrupts.S index c8c4b878795a..10d8ef602e5c 100644 --- a/trunk/arch/powerpc/kvm/booke_interrupts.S +++ b/trunk/arch/powerpc/kvm/booke_interrupts.S @@ -34,8 +34,7 @@ /* r2 is special: it holds 'current', and it made nonvolatile in the * kernel with the -ffixed-r2 gcc option. */ #define HOST_R2 12 -#define HOST_CR 16 -#define HOST_NV_GPRS 20 +#define HOST_NV_GPRS 16 #define HOST_NV_GPR(n) (HOST_NV_GPRS + ((n - 14) * 4)) #define HOST_MIN_STACK_SIZE (HOST_NV_GPR(31) + 4) #define HOST_STACK_SIZE (((HOST_MIN_STACK_SIZE + 15) / 16) * 16) /* Align. */ @@ -297,10 +296,8 @@ heavyweight_exit: /* Return to kvm_vcpu_run(). */ lwz r4, HOST_STACK_LR(r1) - lwz r5, HOST_CR(r1) addi r1, r1, HOST_STACK_SIZE mtlr r4 - mtcr r5 /* r3 still contains the return code from kvmppc_handle_exit(). */ blr @@ -317,8 +314,6 @@ _GLOBAL(__kvmppc_vcpu_run) stw r3, HOST_RUN(r1) mflr r3 stw r3, HOST_STACK_LR(r1) - mfcr r5 - stw r5, HOST_CR(r1) /* Save host non-volatile register state to stack. */ stw r14, HOST_NV_GPR(r14)(r1) diff --git a/trunk/arch/powerpc/net/bpf_jit.h b/trunk/arch/powerpc/net/bpf_jit.h index 5c3cf2d04e41..af1ab5e9a691 100644 --- a/trunk/arch/powerpc/net/bpf_jit.h +++ b/trunk/arch/powerpc/net/bpf_jit.h @@ -48,13 +48,7 @@ /* * Assembly helpers from arch/powerpc/net/bpf_jit.S: */ -#define DECLARE_LOAD_FUNC(func) \ - extern u8 func[], func##_negative_offset[], func##_positive_offset[] - -DECLARE_LOAD_FUNC(sk_load_word); -DECLARE_LOAD_FUNC(sk_load_half); -DECLARE_LOAD_FUNC(sk_load_byte); -DECLARE_LOAD_FUNC(sk_load_byte_msh); +extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[]; #define FUNCTION_DESCR_SIZE 24 diff --git a/trunk/arch/powerpc/net/bpf_jit_64.S b/trunk/arch/powerpc/net/bpf_jit_64.S index 55ba3855a97f..ff4506e85cce 100644 --- a/trunk/arch/powerpc/net/bpf_jit_64.S +++ b/trunk/arch/powerpc/net/bpf_jit_64.S @@ -31,13 +31,14 @@ * then branch directly to slow_path_XXX if required. (In fact, could * load a spare GPR with the address of slow_path_generic and pass size * as an argument, making the call site a mtlr, li and bllr.) + * + * Technically, the "is addr < 0" check is unnecessary & slowing down + * the ABS path, as it's statically checked on generation. */ .globl sk_load_word sk_load_word: cmpdi r_addr, 0 - blt bpf_slow_path_word_neg - .globl sk_load_word_positive_offset -sk_load_word_positive_offset: + blt bpf_error /* Are we accessing past headlen? */ subi r_scratch1, r_HL, 4 cmpd r_scratch1, r_addr @@ -50,9 +51,7 @@ sk_load_word_positive_offset: .globl sk_load_half sk_load_half: cmpdi r_addr, 0 - blt bpf_slow_path_half_neg - .globl sk_load_half_positive_offset -sk_load_half_positive_offset: + blt bpf_error subi r_scratch1, r_HL, 2 cmpd r_scratch1, r_addr blt bpf_slow_path_half @@ -62,9 +61,7 @@ sk_load_half_positive_offset: .globl sk_load_byte sk_load_byte: cmpdi r_addr, 0 - blt bpf_slow_path_byte_neg - .globl sk_load_byte_positive_offset -sk_load_byte_positive_offset: + blt bpf_error cmpd r_HL, r_addr ble bpf_slow_path_byte lbzx r_A, r_D, r_addr @@ -72,20 +69,22 @@ sk_load_byte_positive_offset: /* * BPF_S_LDX_B_MSH: ldxb 4*([offset]&0xf) - * r_addr is the offset value + * r_addr is the offset value, already known positive */ .globl sk_load_byte_msh sk_load_byte_msh: - cmpdi r_addr, 0 - blt bpf_slow_path_byte_msh_neg - .globl sk_load_byte_msh_positive_offset -sk_load_byte_msh_positive_offset: cmpd r_HL, r_addr ble bpf_slow_path_byte_msh lbzx r_X, r_D, r_addr rlwinm r_X, r_X, 2, 32-4-2, 31-2 blr +bpf_error: + /* Entered with cr0 = lt */ + li r3, 0 + /* Generated code will 'blt epilogue', returning 0. */ + blr + /* Call out to skb_copy_bits: * We'll need to back up our volatile regs first; we have * local variable space at r1+(BPF_PPC_STACK_BASIC). @@ -137,84 +136,3 @@ bpf_slow_path_byte_msh: lbz r_X, BPF_PPC_STACK_BASIC+(2*8)(r1) rlwinm r_X, r_X, 2, 32-4-2, 31-2 blr - -/* Call out to bpf_internal_load_pointer_neg_helper: - * We'll need to back up our volatile regs first; we have - * local variable space at r1+(BPF_PPC_STACK_BASIC). - * Allocate a new stack frame here to remain ABI-compliant in - * stashing LR. - */ -#define sk_negative_common(SIZE) \ - mflr r0; \ - std r0, 16(r1); \ - /* R3 goes in parameter space of caller's frame */ \ - std r_skb, (BPF_PPC_STACKFRAME+48)(r1); \ - std r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \ - std r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \ - stdu r1, -BPF_PPC_SLOWPATH_FRAME(r1); \ - /* R3 = r_skb, as passed */ \ - mr r4, r_addr; \ - li r5, SIZE; \ - bl bpf_internal_load_pointer_neg_helper; \ - /* R3 != 0 on success */ \ - addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \ - ld r0, 16(r1); \ - ld r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \ - ld r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \ - mtlr r0; \ - cmpldi r3, 0; \ - beq bpf_error_slow; /* cr0 = EQ */ \ - mr r_addr, r3; \ - ld r_skb, (BPF_PPC_STACKFRAME+48)(r1); \ - /* Great success! */ - -bpf_slow_path_word_neg: - lis r_scratch1,-32 /* SKF_LL_OFF */ - cmpd r_addr, r_scratch1 /* addr < SKF_* */ - blt bpf_error /* cr0 = LT */ - .globl sk_load_word_negative_offset -sk_load_word_negative_offset: - sk_negative_common(4) - lwz r_A, 0(r_addr) - blr - -bpf_slow_path_half_neg: - lis r_scratch1,-32 /* SKF_LL_OFF */ - cmpd r_addr, r_scratch1 /* addr < SKF_* */ - blt bpf_error /* cr0 = LT */ - .globl sk_load_half_negative_offset -sk_load_half_negative_offset: - sk_negative_common(2) - lhz r_A, 0(r_addr) - blr - -bpf_slow_path_byte_neg: - lis r_scratch1,-32 /* SKF_LL_OFF */ - cmpd r_addr, r_scratch1 /* addr < SKF_* */ - blt bpf_error /* cr0 = LT */ - .globl sk_load_byte_negative_offset -sk_load_byte_negative_offset: - sk_negative_common(1) - lbz r_A, 0(r_addr) - blr - -bpf_slow_path_byte_msh_neg: - lis r_scratch1,-32 /* SKF_LL_OFF */ - cmpd r_addr, r_scratch1 /* addr < SKF_* */ - blt bpf_error /* cr0 = LT */ - .globl sk_load_byte_msh_negative_offset -sk_load_byte_msh_negative_offset: - sk_negative_common(1) - lbz r_X, 0(r_addr) - rlwinm r_X, r_X, 2, 32-4-2, 31-2 - blr - -bpf_error_slow: - /* fabricate a cr0 = lt */ - li r_scratch1, -1 - cmpdi r_scratch1, 0 -bpf_error: - /* Entered with cr0 = lt */ - li r3, 0 - /* Generated code will 'blt epilogue', returning 0. */ - blr diff --git a/trunk/arch/powerpc/net/bpf_jit_comp.c b/trunk/arch/powerpc/net/bpf_jit_comp.c index 2dc8b1484845..73619d3aeb6c 100644 --- a/trunk/arch/powerpc/net/bpf_jit_comp.c +++ b/trunk/arch/powerpc/net/bpf_jit_comp.c @@ -127,9 +127,6 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) PPC_BLR(); } -#define CHOOSE_LOAD_FUNC(K, func) \ - ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset) - /* Assemble the body code between the prologue & epilogue. */ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, struct codegen_context *ctx, @@ -394,16 +391,21 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, /*** Absolute loads from packet header/data ***/ case BPF_S_LD_W_ABS: - func = CHOOSE_LOAD_FUNC(K, sk_load_word); + func = sk_load_word; goto common_load; case BPF_S_LD_H_ABS: - func = CHOOSE_LOAD_FUNC(K, sk_load_half); + func = sk_load_half; goto common_load; case BPF_S_LD_B_ABS: - func = CHOOSE_LOAD_FUNC(K, sk_load_byte); + func = sk_load_byte; common_load: - /* Load from [K]. */ + /* + * Load from [K]. Reference with the (negative) + * SKF_NET_OFF/SKF_LL_OFF offsets is unsupported. + */ ctx->seen |= SEEN_DATAREF; + if ((int)K < 0) + return -ENOTSUPP; PPC_LI64(r_scratch1, func); PPC_MTLR(r_scratch1); PPC_LI32(r_addr, K); @@ -427,7 +429,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, common_load_ind: /* * Load from [X + K]. Negative offsets are tested for - * in the helper functions. + * in the helper functions, and result in a 'ret 0'. */ ctx->seen |= SEEN_DATAREF | SEEN_XREG; PPC_LI64(r_scratch1, func); @@ -441,7 +443,13 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, break; case BPF_S_LDX_B_MSH: - func = CHOOSE_LOAD_FUNC(K, sk_load_byte_msh); + /* + * x86 version drops packet (RET 0) when K<0, whereas + * interpreter does allow K<0 (__load_pointer, special + * ancillary data). common_load returns ENOTSUPP if K<0, + * so we fall back to interpreter & filter works. + */ + func = sk_load_byte_msh; goto common_load; break; diff --git a/trunk/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/trunk/arch/powerpc/platforms/52xx/mpc52xx_pci.c index e2d401ad8fbb..bfb11e01133e 100644 --- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_pci.c +++ b/trunk/arch/powerpc/platforms/52xx/mpc52xx_pci.c @@ -93,7 +93,7 @@ struct mpc52xx_pci { }; /* MPC5200 device tree match tables */ -const struct of_device_id mpc52xx_pci_ids[] __initconst = { +const struct of_device_id mpc52xx_pci_ids[] __initdata = { { .type = "pci", .compatible = "fsl,mpc5200-pci", }, { .type = "pci", .compatible = "mpc5200-pci", }, {} diff --git a/trunk/arch/powerpc/platforms/85xx/common.c b/trunk/arch/powerpc/platforms/85xx/common.c index 67dac22b4363..9fef5302adc1 100644 --- a/trunk/arch/powerpc/platforms/85xx/common.c +++ b/trunk/arch/powerpc/platforms/85xx/common.c @@ -21,12 +21,6 @@ static struct of_device_id __initdata mpc85xx_common_ids[] = { { .compatible = "fsl,qe", }, { .compatible = "fsl,cpm2", }, { .compatible = "fsl,srio", }, - /* So that the DMA channel nodes can be probed individually: */ - { .compatible = "fsl,eloplus-dma", }, - /* For the PMC driver */ - { .compatible = "fsl,mpc8548-guts", }, - /* Probably unnecessary? */ - { .compatible = "gpio-leds", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c index d208ebccb91c..3754ddc00af7 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -270,7 +270,7 @@ static void __init mpc85xx_mds_qe_init(void) if (machine_is(p1021_mds)) { - struct ccsr_guts __iomem *guts; + struct ccsr_guts_85xx __iomem *guts; np = of_find_node_by_name(NULL, "global-utilities"); if (np) { @@ -399,6 +399,12 @@ static int __init board_fixups(void) machine_arch_initcall(mpc8568_mds, board_fixups); machine_arch_initcall(mpc8569_mds, board_fixups); +static struct of_device_id mpc85xx_ids[] = { + { .compatible = "fsl,mpc8548-guts", }, + { .compatible = "gpio-leds", }, + {}, +}; + static int __init mpc85xx_publish_devices(void) { if (machine_is(mpc8568_mds)) @@ -406,7 +412,10 @@ static int __init mpc85xx_publish_devices(void) if (machine_is(mpc8569_mds)) simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio"); - return mpc85xx_common_publish_devices(); + mpc85xx_common_publish_devices(); + of_platform_bus_probe(NULL, mpc85xx_ids, NULL); + + return 0; } machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices); diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_rdb.c index 313fce4f5574..9848f9e39853 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_rdb.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_rdb.c @@ -127,7 +127,7 @@ static void __init mpc85xx_rdb_setup_arch(void) #if defined(CONFIG_UCC_GETH) || defined(CONFIG_SERIAL_QE) if (machine_is(p1025_rdb)) { - struct ccsr_guts __iomem *guts; + struct ccsr_guts_85xx __iomem *guts; np = of_find_node_by_name(NULL, "global-utilities"); if (np) { diff --git a/trunk/arch/powerpc/platforms/85xx/p1022_ds.c b/trunk/arch/powerpc/platforms/85xx/p1022_ds.c index f700c81a1321..0fe88e39945e 100644 --- a/trunk/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/trunk/arch/powerpc/platforms/85xx/p1022_ds.c @@ -150,7 +150,7 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port) { struct device_node *guts_node; struct device_node *indirect_node = NULL; - struct ccsr_guts __iomem *guts; + struct ccsr_guts_85xx __iomem *guts; u8 __iomem *lbc_lcs0_ba = NULL; u8 __iomem *lbc_lcs1_ba = NULL; u8 b; @@ -269,7 +269,7 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port) void p1022ds_set_pixel_clock(unsigned int pixclock) { struct device_node *guts_np = NULL; - struct ccsr_guts __iomem *guts; + struct ccsr_guts_85xx __iomem *guts; unsigned long freq; u64 temp; u32 pxclk; @@ -460,7 +460,18 @@ static void __init p1022_ds_setup_arch(void) pr_info("Freescale P1022 DS reference board\n"); } -machine_device_initcall(p1022_ds, mpc85xx_common_publish_devices); +static struct of_device_id __initdata p1022_ds_ids[] = { + /* So that the DMA channel nodes can be probed individually: */ + { .compatible = "fsl,eloplus-dma", }, + {}, +}; + +static int __init p1022_ds_publish_devices(void) +{ + mpc85xx_common_publish_devices(); + return of_platform_bus_probe(NULL, p1022_ds_ids, NULL); +} +machine_device_initcall(p1022_ds, p1022_ds_publish_devices); machine_arch_initcall(p1022_ds, swiotlb_setup_bus_notifier); diff --git a/trunk/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/trunk/arch/powerpc/platforms/86xx/mpc8610_hpcd.c index 62cd3c555bfb..bbc615206c67 100644 --- a/trunk/arch/powerpc/platforms/86xx/mpc8610_hpcd.c +++ b/trunk/arch/powerpc/platforms/86xx/mpc8610_hpcd.c @@ -225,7 +225,7 @@ void mpc8610hpcd_set_monitor_port(enum fsl_diu_monitor_port port) void mpc8610hpcd_set_pixel_clock(unsigned int pixclock) { struct device_node *guts_np = NULL; - struct ccsr_guts __iomem *guts; + struct ccsr_guts_86xx __iomem *guts; unsigned long freq; u64 temp; u32 pxclk; diff --git a/trunk/arch/powerpc/platforms/cell/axon_msi.c b/trunk/arch/powerpc/platforms/cell/axon_msi.c index 85825b5401e5..db360fc4cf0e 100644 --- a/trunk/arch/powerpc/platforms/cell/axon_msi.c +++ b/trunk/arch/powerpc/platforms/cell/axon_msi.c @@ -114,7 +114,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc) pr_devel("axon_msi: woff %x roff %x msi %x\n", write_offset, msic->read_offset, msi); - if (msi < nr_irqs && irq_get_chip_data(msi) == msic) { + if (msi < NR_IRQS && irq_get_chip_data(msi) == msic) { generic_handle_irq(msi); msic->fifo_virt[idx] = cpu_to_le32(0xffffffff); } else { @@ -276,6 +276,9 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) if (rc) return rc; + /* We rely on being able to stash a virq in a u16 */ + BUILD_BUG_ON(NR_IRQS > 65536); + list_for_each_entry(entry, &dev->msi_list, list) { virq = irq_create_direct_mapping(msic->irq_domain); if (virq == NO_IRQ) { @@ -389,8 +392,7 @@ static int axon_msi_probe(struct platform_device *device) } memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); - /* We rely on being able to stash a virq in a u16, so limit irqs to < 65536 */ - msic->irq_domain = irq_domain_add_nomap(dn, 65536, &msic_host_ops, msic); + msic->irq_domain = irq_domain_add_nomap(dn, &msic_host_ops, msic); if (!msic->irq_domain) { printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n", dn->full_name); diff --git a/trunk/arch/powerpc/platforms/cell/beat_interrupt.c b/trunk/arch/powerpc/platforms/cell/beat_interrupt.c index 8c6dc42ecf65..e5c3a2c6090d 100644 --- a/trunk/arch/powerpc/platforms/cell/beat_interrupt.c +++ b/trunk/arch/powerpc/platforms/cell/beat_interrupt.c @@ -239,7 +239,7 @@ void __init beatic_init_IRQ(void) ppc_md.get_irq = beatic_get_irq; /* Allocate an irq host */ - beatic_host = irq_domain_add_nomap(NULL, 0, &beatic_pic_host_ops, NULL); + beatic_host = irq_domain_add_nomap(NULL, &beatic_pic_host_ops, NULL); BUG_ON(beatic_host == NULL); irq_set_default_host(beatic_host); } @@ -248,6 +248,6 @@ void beatic_deinit_IRQ(void) { int i; - for (i = 1; i < nr_irqs; i++) + for (i = 1; i < NR_IRQS; i++) beat_destruct_irq_plug(i); } diff --git a/trunk/arch/powerpc/platforms/cell/iommu.c b/trunk/arch/powerpc/platforms/cell/iommu.c index b9f509a34c01..ae9fc7bc17d6 100644 --- a/trunk/arch/powerpc/platforms/cell/iommu.c +++ b/trunk/arch/powerpc/platforms/cell/iommu.c @@ -564,8 +564,7 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev) /* A coherent allocation implies strong ordering */ static void *dma_fixed_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag, - struct dma_attrs *attrs) + dma_addr_t *dma_handle, gfp_t flag) { if (iommu_fixed_is_weak) return iommu_alloc_coherent(dev, cell_get_iommu_table(dev), @@ -573,19 +572,18 @@ static void *dma_fixed_alloc_coherent(struct device *dev, size_t size, device_to_mask(dev), flag, dev_to_node(dev)); else - return dma_direct_ops.alloc(dev, size, dma_handle, flag, - attrs); + return dma_direct_ops.alloc_coherent(dev, size, dma_handle, + flag); } static void dma_fixed_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, - struct dma_attrs *attrs) + void *vaddr, dma_addr_t dma_handle) { if (iommu_fixed_is_weak) iommu_free_coherent(cell_get_iommu_table(dev), size, vaddr, dma_handle); else - dma_direct_ops.free(dev, size, vaddr, dma_handle, attrs); + dma_direct_ops.free_coherent(dev, size, vaddr, dma_handle); } static dma_addr_t dma_fixed_map_page(struct device *dev, struct page *page, @@ -644,8 +642,8 @@ static int dma_fixed_dma_supported(struct device *dev, u64 mask) static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask); struct dma_map_ops dma_iommu_fixed_ops = { - .alloc = dma_fixed_alloc_coherent, - .free = dma_fixed_free_coherent, + .alloc_coherent = dma_fixed_alloc_coherent, + .free_coherent = dma_fixed_free_coherent, .map_sg = dma_fixed_map_sg, .unmap_sg = dma_fixed_unmap_sg, .dma_supported = dma_fixed_dma_supported, diff --git a/trunk/arch/powerpc/platforms/cell/qpace_setup.c b/trunk/arch/powerpc/platforms/cell/qpace_setup.c index 6e3409d590ac..7f9b6742f8b6 100644 --- a/trunk/arch/powerpc/platforms/cell/qpace_setup.c +++ b/trunk/arch/powerpc/platforms/cell/qpace_setup.c @@ -61,7 +61,7 @@ static void qpace_progress(char *s, unsigned short hex) printk("*** %04x : %s\n", hex, s ? s : ""); } -static const struct of_device_id qpace_bus_ids[] __initconst = { +static const struct of_device_id qpace_bus_ids[] __initdata = { { .type = "soc", }, { .compatible = "soc", }, { .type = "spider", }, diff --git a/trunk/arch/powerpc/platforms/cell/setup.c b/trunk/arch/powerpc/platforms/cell/setup.c index 4ab087671185..fa3e294fd343 100644 --- a/trunk/arch/powerpc/platforms/cell/setup.c +++ b/trunk/arch/powerpc/platforms/cell/setup.c @@ -140,7 +140,7 @@ static int __devinit cell_setup_phb(struct pci_controller *phb) return 0; } -static const struct of_device_id cell_bus_ids[] __initconst = { +static const struct of_device_id cell_bus_ids[] __initdata = { { .type = "soc", }, { .compatible = "soc", }, { .type = "spider", }, diff --git a/trunk/arch/powerpc/platforms/powermac/low_i2c.c b/trunk/arch/powerpc/platforms/powermac/low_i2c.c index 03685a329d7d..996c5ff7824b 100644 --- a/trunk/arch/powerpc/platforms/powermac/low_i2c.c +++ b/trunk/arch/powerpc/platforms/powermac/low_i2c.c @@ -366,20 +366,11 @@ static void kw_i2c_timeout(unsigned long data) unsigned long flags; spin_lock_irqsave(&host->lock, flags); - - /* - * If the timer is pending, that means we raced with the - * irq, in which case we just return - */ - if (timer_pending(&host->timeout_timer)) - goto skip; - kw_i2c_handle_interrupt(host, kw_read_reg(reg_isr)); if (host->state != state_idle) { host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT; add_timer(&host->timeout_timer); } - skip: spin_unlock_irqrestore(&host->lock, flags); } diff --git a/trunk/arch/powerpc/platforms/powermac/pic.c b/trunk/arch/powerpc/platforms/powermac/pic.c index c4e630576ff2..66ad93de1d55 100644 --- a/trunk/arch/powerpc/platforms/powermac/pic.c +++ b/trunk/arch/powerpc/platforms/powermac/pic.c @@ -57,9 +57,9 @@ static int max_real_irqs; static DEFINE_RAW_SPINLOCK(pmac_pic_lock); -/* The max irq number this driver deals with is 128; see max_irqs */ -static DECLARE_BITMAP(ppc_lost_interrupts, 128); -static DECLARE_BITMAP(ppc_cached_irq_mask, 128); +#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) +static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; +static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; static int pmac_irq_cascade = -1; static struct irq_domain *pmac_pic_host; diff --git a/trunk/arch/powerpc/platforms/powermac/smp.c b/trunk/arch/powerpc/platforms/powermac/smp.c index b4ddaa3fbb29..a81e5a88fbdf 100644 --- a/trunk/arch/powerpc/platforms/powermac/smp.c +++ b/trunk/arch/powerpc/platforms/powermac/smp.c @@ -192,7 +192,7 @@ static int psurge_secondary_ipi_init(void) { int rc = -ENOMEM; - psurge_host = irq_domain_add_nomap(NULL, 0, &psurge_host_ops, NULL); + psurge_host = irq_domain_add_nomap(NULL, &psurge_host_ops, NULL); if (psurge_host) psurge_secondary_virq = irq_create_direct_mapping(psurge_host); diff --git a/trunk/arch/powerpc/platforms/ps3/interrupt.c b/trunk/arch/powerpc/platforms/ps3/interrupt.c index 5f3b23220b8e..2a4ff86cc21f 100644 --- a/trunk/arch/powerpc/platforms/ps3/interrupt.c +++ b/trunk/arch/powerpc/platforms/ps3/interrupt.c @@ -753,8 +753,9 @@ void __init ps3_init_IRQ(void) unsigned cpu; struct irq_domain *host; - host = irq_domain_add_nomap(NULL, PS3_PLUG_MAX + 1, &ps3_host_ops, NULL); + host = irq_domain_add_nomap(NULL, &ps3_host_ops, NULL); irq_set_default_host(host); + irq_set_virq_count(PS3_PLUG_MAX + 1); for_each_possible_cpu(cpu) { struct ps3_private *pd = &per_cpu(ps3_private, cpu); diff --git a/trunk/arch/powerpc/platforms/ps3/system-bus.c b/trunk/arch/powerpc/platforms/ps3/system-bus.c index 5606fe36faf2..880eb9ce22c5 100644 --- a/trunk/arch/powerpc/platforms/ps3/system-bus.c +++ b/trunk/arch/powerpc/platforms/ps3/system-bus.c @@ -515,8 +515,7 @@ core_initcall(ps3_system_bus_init); * to the dma address (mapping) of the first page. */ static void * ps3_alloc_coherent(struct device *_dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag, - struct dma_attrs *attrs) + dma_addr_t *dma_handle, gfp_t flag) { int result; struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); @@ -553,7 +552,7 @@ static void * ps3_alloc_coherent(struct device *_dev, size_t size, } static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr, - dma_addr_t dma_handle, struct dma_attrs *attrs) + dma_addr_t dma_handle) { struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); @@ -702,8 +701,8 @@ static u64 ps3_dma_get_required_mask(struct device *_dev) } static struct dma_map_ops ps3_sb_dma_ops = { - .alloc = ps3_alloc_coherent, - .free = ps3_free_coherent, + .alloc_coherent = ps3_alloc_coherent, + .free_coherent = ps3_free_coherent, .map_sg = ps3_sb_map_sg, .unmap_sg = ps3_sb_unmap_sg, .dma_supported = ps3_dma_supported, @@ -713,8 +712,8 @@ static struct dma_map_ops ps3_sb_dma_ops = { }; static struct dma_map_ops ps3_ioc0_dma_ops = { - .alloc = ps3_alloc_coherent, - .free = ps3_free_coherent, + .alloc_coherent = ps3_alloc_coherent, + .free_coherent = ps3_free_coherent, .map_sg = ps3_ioc0_map_sg, .unmap_sg = ps3_ioc0_unmap_sg, .dma_supported = ps3_dma_supported, diff --git a/trunk/arch/powerpc/platforms/pseries/Kconfig b/trunk/arch/powerpc/platforms/pseries/Kconfig index 178a5f300bc9..aadbe4f6d537 100644 --- a/trunk/arch/powerpc/platforms/pseries/Kconfig +++ b/trunk/arch/powerpc/platforms/pseries/Kconfig @@ -30,9 +30,9 @@ config PPC_SPLPAR two or more partitions. config EEH - bool + bool "PCI Extended Error Handling (EEH)" if EXPERT depends on PPC_PSERIES && PCI - default y + default y if !EXPERT config PSERIES_MSI bool diff --git a/trunk/arch/powerpc/platforms/pseries/eeh.c b/trunk/arch/powerpc/platforms/pseries/eeh.c index a75e37dc41aa..309d38ef7322 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh.c @@ -1076,7 +1076,7 @@ static void eeh_add_device_late(struct pci_dev *dev) pr_debug("EEH: Adding device %s\n", pci_name(dev)); dn = pci_device_to_OF_node(dev); - edev = of_node_to_eeh_dev(dn); + edev = pci_dev_to_eeh_dev(dev); if (edev->pdev == dev) { pr_debug("EEH: Already referenced !\n"); return; diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_event.c b/trunk/arch/powerpc/platforms/pseries/eeh_event.c index 4cb375c0f8d1..4a4752565856 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_event.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_event.c @@ -59,7 +59,8 @@ static int eeh_event_handler(void * dummy) struct eeh_event *event; struct eeh_dev *edev; - set_task_comm(current, "eehd"); + daemonize("eehd"); + set_current_state(TASK_INTERRUPTIBLE); spin_lock_irqsave(&eeh_eventlist_lock, flags); event = NULL; @@ -82,7 +83,6 @@ static int eeh_event_handler(void * dummy) printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n", eeh_pci_name(edev->pdev)); - set_current_state(TASK_INTERRUPTIBLE); /* Don't add to load average */ edev = handle_eeh_events(event); eeh_clear_slot(eeh_dev_to_of_node(edev), EEH_MODE_RECOVERING); diff --git a/trunk/arch/powerpc/sysdev/cpm2_pic.c b/trunk/arch/powerpc/sysdev/cpm2_pic.c index 10386b676d87..d3be961e2ae7 100644 --- a/trunk/arch/powerpc/sysdev/cpm2_pic.c +++ b/trunk/arch/powerpc/sysdev/cpm2_pic.c @@ -51,7 +51,8 @@ static intctl_cpm2_t __iomem *cpm2_intctl; static struct irq_domain *cpm2_pic_host; -static unsigned long ppc_cached_irq_mask[2]; /* 2 32-bit registers */ +#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) +static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; static const u_char irq_to_siureg[] = { 1, 1, 1, 1, 1, 1, 1, 1, diff --git a/trunk/arch/powerpc/sysdev/mpc8xx_pic.c b/trunk/arch/powerpc/sysdev/mpc8xx_pic.c index b724622c3a0b..d5f5416be310 100644 --- a/trunk/arch/powerpc/sysdev/mpc8xx_pic.c +++ b/trunk/arch/powerpc/sysdev/mpc8xx_pic.c @@ -18,45 +18,69 @@ extern int cpm_get_irq(struct pt_regs *regs); static struct irq_domain *mpc8xx_pic_host; -static unsigned long mpc8xx_cached_irq_mask; +#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) +static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; static sysconf8xx_t __iomem *siu_reg; -static inline unsigned long mpc8xx_irqd_to_bit(struct irq_data *d) -{ - return 0x80000000 >> irqd_to_hwirq(d); -} +int cpm_get_irq(struct pt_regs *regs); static void mpc8xx_unmask_irq(struct irq_data *d) { - mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d); - out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask); + int bit, word; + unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); + + bit = irq_nr & 0x1f; + word = irq_nr >> 5; + + ppc_cached_irq_mask[word] |= (1 << (31-bit)); + out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); } static void mpc8xx_mask_irq(struct irq_data *d) { - mpc8xx_cached_irq_mask &= ~mpc8xx_irqd_to_bit(d); - out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask); + int bit, word; + unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); + + bit = irq_nr & 0x1f; + word = irq_nr >> 5; + + ppc_cached_irq_mask[word] &= ~(1 << (31-bit)); + out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); } static void mpc8xx_ack(struct irq_data *d) { - out_be32(&siu_reg->sc_sipend, mpc8xx_irqd_to_bit(d)); + int bit; + unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); + + bit = irq_nr & 0x1f; + out_be32(&siu_reg->sc_sipend, 1 << (31-bit)); } static void mpc8xx_end_irq(struct irq_data *d) { - mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d); - out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask); + int bit, word; + unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); + + bit = irq_nr & 0x1f; + word = irq_nr >> 5; + + ppc_cached_irq_mask[word] |= (1 << (31-bit)); + out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); } static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type) { - /* only external IRQ senses are programmable */ - if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !(irqd_to_hwirq(d) & 1)) { + if (flow_type & IRQ_TYPE_EDGE_FALLING) { + irq_hw_number_t hw = (unsigned int)irqd_to_hwirq(d); unsigned int siel = in_be32(&siu_reg->sc_siel); - siel |= mpc8xx_irqd_to_bit(d); - out_be32(&siu_reg->sc_siel, siel); - __irq_set_handler_locked(d->irq, handle_edge_irq); + + /* only external IRQ senses are programmable */ + if ((hw & 1) == 0) { + siel |= (0x80000000 >> hw); + out_be32(&siu_reg->sc_siel, siel); + __irq_set_handler_locked(d->irq, handle_edge_irq); + } } return 0; } @@ -108,9 +132,6 @@ static int mpc8xx_pic_host_xlate(struct irq_domain *h, struct device_node *ct, IRQ_TYPE_EDGE_FALLING, }; - if (intspec[0] > 0x1f) - return 0; - *out_hwirq = intspec[0]; if (intsize > 1 && intspec[1] < 4) *out_flags = map_pic_senses[intspec[1]]; diff --git a/trunk/arch/powerpc/sysdev/mpic.c b/trunk/arch/powerpc/sysdev/mpic.c index 395af1347749..9ac71ebd2c40 100644 --- a/trunk/arch/powerpc/sysdev/mpic.c +++ b/trunk/arch/powerpc/sysdev/mpic.c @@ -604,14 +604,18 @@ static struct mpic *mpic_find(unsigned int irq) } /* Determine if the linux irq is an IPI */ -static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int src) +static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int irq) { + unsigned int src = virq_to_hw(irq); + return (src >= mpic->ipi_vecs[0] && src <= mpic->ipi_vecs[3]); } /* Determine if the linux irq is a timer */ -static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int src) +static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int irq) { + unsigned int src = virq_to_hw(irq); + return (src >= mpic->timer_vecs[0] && src <= mpic->timer_vecs[7]); } @@ -872,45 +876,21 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type) if (src >= mpic->num_sources) return -EINVAL; - vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); - - /* We don't support "none" type */ if (flow_type == IRQ_TYPE_NONE) - flow_type = IRQ_TYPE_DEFAULT; - - /* Default: read HW settings */ - if (flow_type == IRQ_TYPE_DEFAULT) { - switch(vold & (MPIC_INFO(VECPRI_POLARITY_MASK) | - MPIC_INFO(VECPRI_SENSE_MASK))) { - case MPIC_INFO(VECPRI_SENSE_EDGE) | - MPIC_INFO(VECPRI_POLARITY_POSITIVE): - flow_type = IRQ_TYPE_EDGE_RISING; - break; - case MPIC_INFO(VECPRI_SENSE_EDGE) | - MPIC_INFO(VECPRI_POLARITY_NEGATIVE): - flow_type = IRQ_TYPE_EDGE_FALLING; - break; - case MPIC_INFO(VECPRI_SENSE_LEVEL) | - MPIC_INFO(VECPRI_POLARITY_POSITIVE): - flow_type = IRQ_TYPE_LEVEL_HIGH; - break; - case MPIC_INFO(VECPRI_SENSE_LEVEL) | - MPIC_INFO(VECPRI_POLARITY_NEGATIVE): - flow_type = IRQ_TYPE_LEVEL_LOW; - break; - } - } + if (mpic->senses && src < mpic->senses_count) + flow_type = mpic->senses[src]; + if (flow_type == IRQ_TYPE_NONE) + flow_type = IRQ_TYPE_LEVEL_LOW; - /* Apply to irq desc */ irqd_set_trigger_type(d, flow_type); - /* Apply to HW */ if (mpic_is_ht_interrupt(mpic, src)) vecpri = MPIC_VECPRI_POLARITY_POSITIVE | MPIC_VECPRI_SENSE_EDGE; else vecpri = mpic_type_to_vecpri(mpic, flow_type); + vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) | MPIC_INFO(VECPRI_SENSE_MASK)); vnew |= vecpri; @@ -1046,7 +1026,7 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq, irq_set_chip_and_handler(virq, chip, handle_fasteoi_irq); /* Set default irq type */ - irq_set_irq_type(virq, IRQ_TYPE_DEFAULT); + irq_set_irq_type(virq, IRQ_TYPE_NONE); /* If the MPIC was reset, then all vectors have already been * initialized. Otherwise, a per source lazy initialization @@ -1437,6 +1417,12 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, mpic->num_sources = isu_first + mpic->isu_size; } +void __init mpic_set_default_senses(struct mpic *mpic, u8 *senses, int count) +{ + mpic->senses = senses; + mpic->senses_count = count; +} + void __init mpic_init(struct mpic *mpic) { int i, cpu; @@ -1569,12 +1555,12 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri) return; raw_spin_lock_irqsave(&mpic_lock, flags); - if (mpic_is_ipi(mpic, src)) { + if (mpic_is_ipi(mpic, irq)) { reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) & ~MPIC_VECPRI_PRIORITY_MASK; mpic_ipi_write(src - mpic->ipi_vecs[0], reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); - } else if (mpic_is_tm(mpic, src)) { + } else if (mpic_is_tm(mpic, irq)) { reg = mpic_tm_read(src - mpic->timer_vecs[0]) & ~MPIC_VECPRI_PRIORITY_MASK; mpic_tm_write(src - mpic->timer_vecs[0], diff --git a/trunk/arch/powerpc/sysdev/mpic_msgr.c b/trunk/arch/powerpc/sysdev/mpic_msgr.c index 483d8fa72e8b..6e7fa386e76a 100644 --- a/trunk/arch/powerpc/sysdev/mpic_msgr.c +++ b/trunk/arch/powerpc/sysdev/mpic_msgr.c @@ -27,7 +27,6 @@ static struct mpic_msgr **mpic_msgrs; static unsigned int mpic_msgr_count; -static DEFINE_RAW_SPINLOCK(msgrs_lock); static inline void _mpic_msgr_mer_write(struct mpic_msgr *msgr, u32 value) { @@ -57,11 +56,12 @@ struct mpic_msgr *mpic_msgr_get(unsigned int reg_num) if (reg_num >= mpic_msgr_count) return ERR_PTR(-ENODEV); - raw_spin_lock_irqsave(&msgrs_lock, flags); - msgr = mpic_msgrs[reg_num]; - if (msgr->in_use == MSGR_FREE) + raw_spin_lock_irqsave(&msgr->lock, flags); + if (mpic_msgrs[reg_num]->in_use == MSGR_FREE) { + msgr = mpic_msgrs[reg_num]; msgr->in_use = MSGR_INUSE; - raw_spin_unlock_irqrestore(&msgrs_lock, flags); + } + raw_spin_unlock_irqrestore(&msgr->lock, flags); return msgr; } @@ -228,7 +228,7 @@ static __devinit int mpic_msgr_probe(struct platform_device *dev) reg_number = block_number * MPIC_MSGR_REGISTERS_PER_BLOCK + i; msgr->base = msgr_block_addr + i * MPIC_MSGR_STRIDE; - msgr->mer = (u32 *)((u8 *)msgr->base + MPIC_MSGR_MER_OFFSET); + msgr->mer = msgr->base + MPIC_MSGR_MER_OFFSET; msgr->in_use = MSGR_FREE; msgr->num = i; raw_spin_lock_init(&msgr->lock); diff --git a/trunk/arch/powerpc/sysdev/qe_lib/qe.c b/trunk/arch/powerpc/sysdev/qe_lib/qe.c index 818e763f8265..ceb09cbd2329 100644 --- a/trunk/arch/powerpc/sysdev/qe_lib/qe.c +++ b/trunk/arch/powerpc/sysdev/qe_lib/qe.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2010 Freescale Semicondutor, Inc. All rights reserved. + * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. * * Authors: Shlomi Gridish * Li Yang @@ -266,19 +266,7 @@ EXPORT_SYMBOL(qe_clock_source); static void qe_snums_init(void) { int i; - static const u8 snum_init_76[] = { - 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D, - 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89, - 0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9, - 0xD8, 0xD9, 0xE8, 0xE9, 0x44, 0x45, 0x4C, 0x4D, - 0x54, 0x55, 0x5C, 0x5D, 0x64, 0x65, 0x6C, 0x6D, - 0x74, 0x75, 0x7C, 0x7D, 0x84, 0x85, 0x8C, 0x8D, - 0x94, 0x95, 0x9C, 0x9D, 0xA4, 0xA5, 0xAC, 0xAD, - 0xB4, 0xB5, 0xBC, 0xBD, 0xC4, 0xC5, 0xCC, 0xCD, - 0xD4, 0xD5, 0xDC, 0xDD, 0xE4, 0xE5, 0xEC, 0xED, - 0xF4, 0xF5, 0xFC, 0xFD, - }; - static const u8 snum_init_46[] = { + static const u8 snum_init[] = { 0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D, 0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89, 0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9, @@ -286,15 +274,9 @@ static void qe_snums_init(void) 0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59, 0x68, 0x69, 0x78, 0x79, 0x80, 0x81, }; - static const u8 *snum_init; qe_num_of_snum = qe_get_num_of_snums(); - if (qe_num_of_snum == 76) - snum_init = snum_init_76; - else - snum_init = snum_init_46; - for (i = 0; i < qe_num_of_snum; i++) { snums[i].num = snum_init[i]; snums[i].state = QE_SNUM_STATE_FREE; diff --git a/trunk/arch/powerpc/sysdev/scom.c b/trunk/arch/powerpc/sysdev/scom.c index 702256a1ca11..49a3ece1c6b3 100644 --- a/trunk/arch/powerpc/sysdev/scom.c +++ b/trunk/arch/powerpc/sysdev/scom.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/powerpc/sysdev/xics/xics-common.c b/trunk/arch/powerpc/sysdev/xics/xics-common.c index cd1d18db92c6..ea5e204e3450 100644 --- a/trunk/arch/powerpc/sysdev/xics/xics-common.c +++ b/trunk/arch/powerpc/sysdev/xics/xics-common.c @@ -188,7 +188,6 @@ void xics_migrate_irqs_away(void) { int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id(); unsigned int irq, virq; - struct irq_desc *desc; /* If we used to be the default server, move to the new "boot_cpuid" */ if (hw_cpu == xics_default_server) @@ -203,7 +202,8 @@ void xics_migrate_irqs_away(void) /* Allow IPIs again... */ icp_ops->set_priority(DEFAULT_PRIORITY); - for_each_irq_desc(virq, desc) { + for_each_irq(virq) { + struct irq_desc *desc; struct irq_chip *chip; long server; unsigned long flags; @@ -212,8 +212,9 @@ void xics_migrate_irqs_away(void) /* We can't set affinity on ISA interrupts */ if (virq < NUM_ISA_INTERRUPTS) continue; + desc = irq_to_desc(virq); /* We only need to migrate enabled IRQS */ - if (!desc->action) + if (!desc || !desc->action) continue; if (desc->irq_data.domain != xics_host) continue; diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index 9015060919a0..2b7c0fbe578e 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -90,6 +90,7 @@ config S390 select HAVE_KERNEL_XZ select HAVE_ARCH_MUTEX_CPU_RELAX select HAVE_ARCH_JUMP_LABEL if !MARCH_G5 + select HAVE_RCU_TABLE_FREE if SMP select ARCH_SAVE_PAGE_KEYS if HIBERNATION select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP diff --git a/trunk/arch/s390/defconfig b/trunk/arch/s390/defconfig index 1957a9dd256d..6cf8e26b3137 100644 --- a/trunk/arch/s390/defconfig +++ b/trunk/arch/s390/defconfig @@ -1,12 +1,8 @@ CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y -CONFIG_TASKSTATS=y -CONFIG_TASK_DELAY_ACCT=y -CONFIG_TASK_XACCT=y -CONFIG_TASK_IO_ACCOUNTING=y CONFIG_AUDIT=y +CONFIG_RCU_TRACE=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_CGROUPS=y @@ -18,22 +14,16 @@ CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y CONFIG_CGROUP_SCHED=y CONFIG_RT_GROUP_SCHED=y CONFIG_BLK_CGROUP=y -CONFIG_NAMESPACES=y CONFIG_BLK_DEV_INITRD=y -CONFIG_RD_BZIP2=y -CONFIG_RD_LZMA=y -CONFIG_RD_XZ=y -CONFIG_RD_LZO=y -CONFIG_EXPERT=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # CONFIG_COMPAT_BRK is not set +CONFIG_SLAB=y CONFIG_PROFILING=y CONFIG_OPROFILE=y CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y -CONFIG_PARTITION_ADVANCED=y -CONFIG_IBM_PARTITION=y CONFIG_DEFAULT_DEADLINE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -44,15 +34,18 @@ CONFIG_KSM=y CONFIG_BINFMT_MISC=m CONFIG_CMM=m CONFIG_HZ_100=y -CONFIG_CRASH_DUMP=y +CONFIG_KEXEC=y +CONFIG_PM=y CONFIG_HIBERNATION=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_NET_KEY=y +CONFIG_AFIUCV=m CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_INET_LRO is not set CONFIG_IPV6=y +CONFIG_NET_SCTPPROBE=m CONFIG_L2TP=m CONFIG_L2TP_DEBUGFS=m CONFIG_VLAN_8021Q=y @@ -91,14 +84,15 @@ CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_ZFCP=y +CONFIG_ZFCP_DIF=y CONFIG_NETDEVICES=y -CONFIG_BONDING=m CONFIG_DUMMY=m +CONFIG_BONDING=m CONFIG_EQUALIZER=m CONFIG_TUN=m +CONFIG_NET_ETHERNET=y CONFIG_VIRTIO_NET=y CONFIG_RAW_DRIVER=m -CONFIG_VIRTIO_BALLOON=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set @@ -109,21 +103,27 @@ CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y # CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_PARTITION_ADVANCED=y +CONFIG_IBM_PARTITION=y +CONFIG_DLM=m CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y CONFIG_TIMER_STATS=y CONFIG_PROVE_LOCKING=y CONFIG_PROVE_RCU=y CONFIG_LOCK_STAT=y CONFIG_DEBUG_LOCKDEP=y +CONFIG_DEBUG_SPINLOCK_SLEEP=y CONFIG_DEBUG_LIST=y CONFIG_DEBUG_NOTIFIERS=y -CONFIG_RCU_TRACE=y +# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_KPROBES_SANITY_TEST=y CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y CONFIG_CPU_NOTIFIER_ERROR_INJECT=m CONFIG_LATENCYTOP=y +CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_DEBUG_PAGEALLOC=y -CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_FTRACE is not set # CONFIG_STRICT_DEVMEM is not set CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m @@ -173,3 +173,4 @@ CONFIG_CRYPTO_SHA512_S390=m CONFIG_CRYPTO_DES_S390=m CONFIG_CRYPTO_AES_S390=m CONFIG_CRC7=m +CONFIG_VIRTIO_BALLOON=y diff --git a/trunk/arch/s390/include/asm/cpu_mf.h b/trunk/arch/s390/include/asm/cpu_mf.h index a3afecdae145..e49db5d5d06f 100644 --- a/trunk/arch/s390/include/asm/cpu_mf.h +++ b/trunk/arch/s390/include/asm/cpu_mf.h @@ -12,8 +12,6 @@ #ifndef _ASM_S390_CPU_MF_H #define _ASM_S390_CPU_MF_H -#include - #define CPU_MF_INT_SF_IAE (1 << 31) /* invalid entry address */ #define CPU_MF_INT_SF_ISE (1 << 30) /* incorrect SDBT entry */ #define CPU_MF_INT_SF_PRA (1 << 29) /* program request alert */ diff --git a/trunk/arch/s390/include/asm/facility.h b/trunk/arch/s390/include/asm/facility.h index 2ee66a65f2d4..1e5b27edc0c9 100644 --- a/trunk/arch/s390/include/asm/facility.h +++ b/trunk/arch/s390/include/asm/facility.h @@ -38,11 +38,12 @@ static inline void stfle(u64 *stfle_fac_list, int size) unsigned long nr; preempt_disable(); + S390_lowcore.stfl_fac_list = 0; asm volatile( " .insn s,0xb2b10000,0(0)\n" /* stfl */ "0:\n" EX_TABLE(0b, 0b) - : "+m" (S390_lowcore.stfl_fac_list)); + : "=m" (S390_lowcore.stfl_fac_list)); nr = 4; /* bytes stored by stfl */ memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4); if (S390_lowcore.stfl_fac_list & 0x01000000) { diff --git a/trunk/arch/s390/include/asm/mmu.h b/trunk/arch/s390/include/asm/mmu.h index 6340178748bf..1c7d6ce328bf 100644 --- a/trunk/arch/s390/include/asm/mmu.h +++ b/trunk/arch/s390/include/asm/mmu.h @@ -1,8 +1,6 @@ #ifndef __MMU_H #define __MMU_H -#include - typedef struct { atomic_t attach_count; unsigned int flush_mm; diff --git a/trunk/arch/s390/include/asm/pgalloc.h b/trunk/arch/s390/include/asm/pgalloc.h index 78e3041919de..8eef9b5b3cf4 100644 --- a/trunk/arch/s390/include/asm/pgalloc.h +++ b/trunk/arch/s390/include/asm/pgalloc.h @@ -22,7 +22,10 @@ void crst_table_free(struct mm_struct *, unsigned long *); unsigned long *page_table_alloc(struct mm_struct *, unsigned long); void page_table_free(struct mm_struct *, unsigned long *); +#ifdef CONFIG_HAVE_RCU_TABLE_FREE void page_table_free_rcu(struct mmu_gather *, unsigned long *); +void __tlb_remove_table(void *_table); +#endif static inline void clear_table(unsigned long *s, unsigned long val, size_t n) { diff --git a/trunk/arch/s390/include/asm/swab.h b/trunk/arch/s390/include/asm/swab.h index a3e4ebb32090..6bdee21c077e 100644 --- a/trunk/arch/s390/include/asm/swab.h +++ b/trunk/arch/s390/include/asm/swab.h @@ -77,7 +77,7 @@ static inline __u16 __arch_swab16p(const __u16 *x) asm volatile( #ifndef __s390x__ - " icm %0,2,%O1+1(%R1)\n" + " icm %0,2,%O+1(%R1)\n" " ic %0,%1\n" : "=&d" (result) : "Q" (*x) : "cc"); #else /* __s390x__ */ diff --git a/trunk/arch/s390/include/asm/tlb.h b/trunk/arch/s390/include/asm/tlb.h index 775a5eea8f9e..c687a2c83462 100644 --- a/trunk/arch/s390/include/asm/tlb.h +++ b/trunk/arch/s390/include/asm/tlb.h @@ -30,10 +30,14 @@ struct mmu_gather { struct mm_struct *mm; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE struct mmu_table_batch *batch; +#endif unsigned int fullmm; + unsigned int need_flush; }; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE struct mmu_table_batch { struct rcu_head rcu; unsigned int nr; @@ -45,6 +49,7 @@ struct mmu_table_batch { extern void tlb_table_flush(struct mmu_gather *tlb); extern void tlb_remove_table(struct mmu_gather *tlb, void *table); +#endif static inline void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, @@ -52,20 +57,29 @@ static inline void tlb_gather_mmu(struct mmu_gather *tlb, { tlb->mm = mm; tlb->fullmm = full_mm_flush; + tlb->need_flush = 0; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE tlb->batch = NULL; +#endif if (tlb->fullmm) __tlb_flush_mm(mm); } static inline void tlb_flush_mmu(struct mmu_gather *tlb) { + if (!tlb->need_flush) + return; + tlb->need_flush = 0; + __tlb_flush_mm(tlb->mm); +#ifdef CONFIG_HAVE_RCU_TABLE_FREE tlb_table_flush(tlb); +#endif } static inline void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) { - tlb_table_flush(tlb); + tlb_flush_mmu(tlb); } /* @@ -91,8 +105,10 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page) static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, unsigned long address) { +#ifdef CONFIG_HAVE_RCU_TABLE_FREE if (!tlb->fullmm) return page_table_free_rcu(tlb, (unsigned long *) pte); +#endif page_table_free(tlb->mm, (unsigned long *) pte); } @@ -109,8 +125,10 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, #ifdef __s390x__ if (tlb->mm->context.asce_limit <= (1UL << 31)) return; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE if (!tlb->fullmm) return tlb_remove_table(tlb, pmd); +#endif crst_table_free(tlb->mm, (unsigned long *) pmd); #endif } @@ -128,8 +146,10 @@ static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud, #ifdef __s390x__ if (tlb->mm->context.asce_limit <= (1UL << 42)) return; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE if (!tlb->fullmm) return tlb_remove_table(tlb, pud); +#endif crst_table_free(tlb->mm, (unsigned long *) pud); #endif } diff --git a/trunk/arch/s390/kernel/head.S b/trunk/arch/s390/kernel/head.S index adccd908ebc7..c27a0727f930 100644 --- a/trunk/arch/s390/kernel/head.S +++ b/trunk/arch/s390/kernel/head.S @@ -474,9 +474,9 @@ ENTRY(startup_kdump) stck __LC_LAST_UPDATE_CLOCK spt 5f-.LPG0(%r13) mvc __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13) - xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST #ifndef CONFIG_MARCH_G5 # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10} + xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST .insn s,0xb2b10000,__LC_STFL_FAC_LIST # store facility list tm __LC_STFL_FAC_LIST,0x01 # stfle available ? jz 0f diff --git a/trunk/arch/s390/kernel/irq.c b/trunk/arch/s390/kernel/irq.c index 8a22c27219dd..1c2cdd59ccd0 100644 --- a/trunk/arch/s390/kernel/irq.c +++ b/trunk/arch/s390/kernel/irq.c @@ -118,10 +118,9 @@ asmlinkage void do_softirq(void) "a" (__do_softirq) : "0", "1", "2", "3", "4", "5", "14", "cc", "memory" ); - } else { + } else /* We are already on the async stack. */ __do_softirq(); - } } local_irq_restore(flags); @@ -193,12 +192,11 @@ int unregister_external_interrupt(u16 code, ext_int_handler_t handler) int index = ext_hash(code); spin_lock_irqsave(&ext_int_hash_lock, flags); - list_for_each_entry_rcu(p, &ext_int_hash[index], entry) { + list_for_each_entry_rcu(p, &ext_int_hash[index], entry) if (p->code == code && p->handler == handler) { list_del_rcu(&p->entry); kfree_rcu(p, rcu); } - } spin_unlock_irqrestore(&ext_int_hash_lock, flags); return 0; } @@ -213,10 +211,9 @@ void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code, old_regs = set_irq_regs(regs); irq_enter(); - if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) { + if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) /* Serve timer interrupts first. */ clock_comparator_work(); - } kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++; if (ext_code.code != 0x1004) __get_cpu_var(s390_idle).nohz_delay = 1; diff --git a/trunk/arch/s390/kernel/lgr.c b/trunk/arch/s390/kernel/lgr.c index 87f080b17af1..ac39e7a731fc 100644 --- a/trunk/arch/s390/kernel/lgr.c +++ b/trunk/arch/s390/kernel/lgr.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/s390/kernel/perf_cpum_cf.c b/trunk/arch/s390/kernel/perf_cpum_cf.c index cb019f429e88..8481ecf2ad71 100644 --- a/trunk/arch/s390/kernel/perf_cpum_cf.c +++ b/trunk/arch/s390/kernel/perf_cpum_cf.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include @@ -178,7 +178,7 @@ static void cpumf_pmu_enable(struct pmu *pmu) err = lcctl(cpuhw->state); if (err) { pr_err("Enabling the performance measuring unit " - "failed with rc=%x\n", err); + "failed with rc=%lx\n", err); return; } @@ -203,7 +203,7 @@ static void cpumf_pmu_disable(struct pmu *pmu) err = lcctl(inactive); if (err) { pr_err("Disabling the performance measuring unit " - "failed with rc=%x\n", err); + "failed with rc=%lx\n", err); return; } diff --git a/trunk/arch/s390/kernel/perf_event.c b/trunk/arch/s390/kernel/perf_event.c index f58f37f66824..609f985198cf 100644 --- a/trunk/arch/s390/kernel/perf_event.c +++ b/trunk/arch/s390/kernel/perf_event.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/s390/kernel/setup.c b/trunk/arch/s390/kernel/setup.c index 06264ae8ccd9..1581ea2e027a 100644 --- a/trunk/arch/s390/kernel/setup.c +++ b/trunk/arch/s390/kernel/setup.c @@ -50,7 +50,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 1f77227669e8..a8bf9994b086 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -32,8 +32,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/trunk/arch/s390/mm/maccess.c b/trunk/arch/s390/mm/maccess.c index e1335dc2b1b7..7bb15fcca75e 100644 --- a/trunk/arch/s390/mm/maccess.c +++ b/trunk/arch/s390/mm/maccess.c @@ -61,14 +61,21 @@ long probe_kernel_write(void *dst, const void *src, size_t size) return copied < 0 ? -EFAULT : 0; } -static int __memcpy_real(void *dest, void *src, size_t count) +/* + * Copy memory in real mode (kernel to kernel) + */ +int memcpy_real(void *dest, void *src, size_t count) { register unsigned long _dest asm("2") = (unsigned long) dest; register unsigned long _len1 asm("3") = (unsigned long) count; register unsigned long _src asm("4") = (unsigned long) src; register unsigned long _len2 asm("5") = (unsigned long) count; + unsigned long flags; int rc = -EFAULT; + if (!count) + return 0; + flags = __arch_local_irq_stnsm(0xf8UL); asm volatile ( "0: mvcle %1,%2,0x0\n" "1: jo 0b\n" @@ -79,23 +86,7 @@ static int __memcpy_real(void *dest, void *src, size_t count) "+d" (_len2), "=m" (*((long *) dest)) : "m" (*((long *) src)) : "cc", "memory"); - return rc; -} - -/* - * Copy memory in real mode (kernel to kernel) - */ -int memcpy_real(void *dest, void *src, size_t count) -{ - unsigned long flags; - int rc; - - if (!count) - return 0; - local_irq_save(flags); - __arch_local_irq_stnsm(0xfbUL); - rc = __memcpy_real(dest, src, count); - local_irq_restore(flags); + arch_local_irq_restore(flags); return rc; } diff --git a/trunk/arch/s390/mm/pgtable.c b/trunk/arch/s390/mm/pgtable.c index 6e765bf00670..373adf69b01c 100644 --- a/trunk/arch/s390/mm/pgtable.c +++ b/trunk/arch/s390/mm/pgtable.c @@ -678,6 +678,8 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) } } +#ifdef CONFIG_HAVE_RCU_TABLE_FREE + static void __page_table_free_rcu(void *table, unsigned bit) { struct page *page; @@ -731,66 +733,7 @@ void __tlb_remove_table(void *_table) free_pages((unsigned long) table, ALLOC_ORDER); } -static void tlb_remove_table_smp_sync(void *arg) -{ - /* Simply deliver the interrupt */ -} - -static void tlb_remove_table_one(void *table) -{ - /* - * This isn't an RCU grace period and hence the page-tables cannot be - * assumed to be actually RCU-freed. - * - * It is however sufficient for software page-table walkers that rely - * on IRQ disabling. See the comment near struct mmu_table_batch. - */ - smp_call_function(tlb_remove_table_smp_sync, NULL, 1); - __tlb_remove_table(table); -} - -static void tlb_remove_table_rcu(struct rcu_head *head) -{ - struct mmu_table_batch *batch; - int i; - - batch = container_of(head, struct mmu_table_batch, rcu); - - for (i = 0; i < batch->nr; i++) - __tlb_remove_table(batch->tables[i]); - - free_page((unsigned long)batch); -} - -void tlb_table_flush(struct mmu_gather *tlb) -{ - struct mmu_table_batch **batch = &tlb->batch; - - if (*batch) { - __tlb_flush_mm(tlb->mm); - call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu); - *batch = NULL; - } -} - -void tlb_remove_table(struct mmu_gather *tlb, void *table) -{ - struct mmu_table_batch **batch = &tlb->batch; - - if (*batch == NULL) { - *batch = (struct mmu_table_batch *) - __get_free_page(GFP_NOWAIT | __GFP_NOWARN); - if (*batch == NULL) { - __tlb_flush_mm(tlb->mm); - tlb_remove_table_one(table); - return; - } - (*batch)->nr = 0; - } - (*batch)->tables[(*batch)->nr++] = table; - if ((*batch)->nr == MAX_TABLE_BATCH) - tlb_table_flush(tlb); -} +#endif /* * switch on pgstes for its userspace process (for kvm) diff --git a/trunk/arch/sh/Kconfig.debug b/trunk/arch/sh/Kconfig.debug index 5f2bb4242c0f..c1d5a820b1aa 100644 --- a/trunk/arch/sh/Kconfig.debug +++ b/trunk/arch/sh/Kconfig.debug @@ -61,7 +61,6 @@ config DUMP_CODE config DWARF_UNWINDER bool "Enable the DWARF unwinder for stacktraces" select FRAME_POINTER - depends on SUPERH32 default n help Enabling this option will make stacktraces more accurate, at diff --git a/trunk/arch/sh/boards/board-sh7785lcr.c b/trunk/arch/sh/boards/board-sh7785lcr.c index d0d6221d7c2e..d879848f3cdd 100644 --- a/trunk/arch/sh/boards/board-sh7785lcr.c +++ b/trunk/arch/sh/boards/board-sh7785lcr.c @@ -28,7 +28,6 @@ #include #include #include -#include /* * NOTE: This board has 2 physical memory maps. diff --git a/trunk/arch/sh/boards/mach-hp6xx/pm.c b/trunk/arch/sh/boards/mach-hp6xx/pm.c index 8b50cf763c06..adc9b4bba828 100644 --- a/trunk/arch/sh/boards/mach-hp6xx/pm.c +++ b/trunk/arch/sh/boards/mach-hp6xx/pm.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/sh/boot/Makefile b/trunk/arch/sh/boot/Makefile index 58592dfa5cb6..e4ea31a62c55 100644 --- a/trunk/arch/sh/boot/Makefile +++ b/trunk/arch/sh/boot/Makefile @@ -8,6 +8,8 @@ # Copyright (C) 1999 Stuart Menefy # +MKIMAGE := $(srctree)/scripts/mkuboot.sh + # # Assign safe dummy values if these variables are not defined, # in order to suppress error message. @@ -59,8 +61,10 @@ KERNEL_ENTRY := $(shell /bin/bash -c 'printf "0x%08x" \ $(KERNEL_MEMORY) + \ $(CONFIG_ZERO_PAGE_OFFSET) + $(CONFIG_ENTRY_OFFSET)]') -UIMAGE_LOADADDR = $(KERNEL_LOAD) -UIMAGE_ENTRYADDR = $(KERNEL_ENTRY) +quiet_cmd_uimage = UIMAGE $@ + cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sh -O linux -T kernel \ + -C $(2) -a $(KERNEL_LOAD) -e $(KERNEL_ENTRY) \ + -n 'Linux-$(KERNELRELEASE)' -d $< $@ $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) diff --git a/trunk/arch/sh/drivers/dma/dma-sysfs.c b/trunk/arch/sh/drivers/dma/dma-sysfs.c index 67ee95603813..b1cb2715ad6e 100644 --- a/trunk/arch/sh/drivers/dma/dma-sysfs.c +++ b/trunk/arch/sh/drivers/dma/dma-sysfs.c @@ -54,7 +54,7 @@ static int __init dma_subsys_init(void) if (unlikely(ret)) return ret; - return device_create_file(dma_subsys.dev_root, &dev_attr_devices); + return device_create_file(dma_subsys.dev_root, &dev_attr_devices.attr); } postcore_initcall(dma_subsys_init); diff --git a/trunk/arch/sh/include/asm/atomic.h b/trunk/arch/sh/include/asm/atomic.h index f4c1c20bcdf6..37f2f4a55231 100644 --- a/trunk/arch/sh/include/asm/atomic.h +++ b/trunk/arch/sh/include/asm/atomic.h @@ -11,7 +11,7 @@ #include #include -#define ATOMIC_INIT(i) { (i) } +#define ATOMIC_INIT(i) ( (atomic_t) { (i) } ) #define atomic_read(v) (*(volatile int *)&(v)->counter) #define atomic_set(v,i) ((v)->counter = (i)) diff --git a/trunk/arch/sh/include/asm/dma-mapping.h b/trunk/arch/sh/include/asm/dma-mapping.h index 8bd965e00a15..1a73c3e759a7 100644 --- a/trunk/arch/sh/include/asm/dma-mapping.h +++ b/trunk/arch/sh/include/asm/dma-mapping.h @@ -52,31 +52,25 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) return dma_addr == 0; } -#define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) - -static inline void *dma_alloc_attrs(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp, - struct dma_attrs *attrs) +static inline void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp) { struct dma_map_ops *ops = get_dma_ops(dev); void *memory; if (dma_alloc_from_coherent(dev, size, dma_handle, &memory)) return memory; - if (!ops->alloc) + if (!ops->alloc_coherent) return NULL; - memory = ops->alloc(dev, size, dma_handle, gfp, attrs); + memory = ops->alloc_coherent(dev, size, dma_handle, gfp); debug_dma_alloc_coherent(dev, size, *dma_handle, memory); return memory; } -#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) - -static inline void dma_free_attrs(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, - struct dma_attrs *attrs) +static inline void dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) { struct dma_map_ops *ops = get_dma_ops(dev); @@ -84,16 +78,14 @@ static inline void dma_free_attrs(struct device *dev, size_t size, return; debug_dma_free_coherent(dev, size, vaddr, dma_handle); - if (ops->free) - ops->free(dev, size, vaddr, dma_handle, attrs); + if (ops->free_coherent) + ops->free_coherent(dev, size, vaddr, dma_handle); } /* arch/sh/mm/consistent.c */ extern void *dma_generic_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_addr, gfp_t flag, - struct dma_attrs *attrs); + dma_addr_t *dma_addr, gfp_t flag); extern void dma_generic_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, - struct dma_attrs *attrs); + void *vaddr, dma_addr_t dma_handle); #endif /* __ASM_SH_DMA_MAPPING_H */ diff --git a/trunk/arch/sh/kernel/cpu/fpu.c b/trunk/arch/sh/kernel/cpu/fpu.c index f8f7af51c128..7f1b70cace35 100644 --- a/trunk/arch/sh/kernel/cpu/fpu.c +++ b/trunk/arch/sh/kernel/cpu/fpu.c @@ -2,7 +2,6 @@ #include #include #include -#include int init_fpu(struct task_struct *tsk) { diff --git a/trunk/arch/sh/kernel/cpu/sh2a/fpu.c b/trunk/arch/sh/kernel/cpu/sh2a/fpu.c index 98bbaa447c93..488d24e0cdf0 100644 --- a/trunk/arch/sh/kernel/cpu/sh2a/fpu.c +++ b/trunk/arch/sh/kernel/cpu/sh2a/fpu.c @@ -14,7 +14,6 @@ #include #include #include -#include /* The PR (precision) bit in the FP Status Register must be clear when * an frchg instruction is executed, otherwise the instruction is undefined. diff --git a/trunk/arch/sh/kernel/cpu/sh4/fpu.c b/trunk/arch/sh/kernel/cpu/sh4/fpu.c index 69ab4d3c8d41..e74cd6c0f10d 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/fpu.c +++ b/trunk/arch/sh/kernel/cpu/sh4/fpu.c @@ -16,7 +16,6 @@ #include #include #include -#include /* The PR (precision) bit in the FP Status Register must be clear when * an frchg instruction is executed, otherwise the instruction is undefined. diff --git a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7757.c index 04ab5aeaf920..5853989586ed 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7757.c @@ -113,7 +113,7 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), /* MSTP32 clocks */ - CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP004]), + CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP004]), CLKDEV_CON_ID("riic0", &mstp_clks[MSTP000]), CLKDEV_CON_ID("riic1", &mstp_clks[MSTP000]), CLKDEV_CON_ID("riic2", &mstp_clks[MSTP000]), diff --git a/trunk/arch/sh/kernel/cpu/shmobile/cpuidle.c b/trunk/arch/sh/kernel/cpu/shmobile/cpuidle.c index 1ddc876d3b26..6d62eb40e750 100644 --- a/trunk/arch/sh/kernel/cpu/shmobile/cpuidle.c +++ b/trunk/arch/sh/kernel/cpu/shmobile/cpuidle.c @@ -29,6 +29,7 @@ static int cpuidle_sleep_enter(struct cpuidle_device *dev, int index) { unsigned long allowed_mode = SUSP_SH_SLEEP; + ktime_t before, after; int requested_state = index; int allowed_state; int k; @@ -46,16 +47,19 @@ static int cpuidle_sleep_enter(struct cpuidle_device *dev, */ k = min_t(int, allowed_state, requested_state); + before = ktime_get(); sh_mobile_call_standby(cpuidle_mode[k]); + after = ktime_get(); + + dev->last_residency = (int)ktime_to_ns(ktime_sub(after, before)) >> 10; return k; } static struct cpuidle_device cpuidle_dev; static struct cpuidle_driver cpuidle_driver = { - .name = "sh_idle", - .owner = THIS_MODULE, - .en_core_tk_irqen = 1, + .name = "sh_idle", + .owner = THIS_MODULE, }; void sh_mobile_setup_cpuidle(void) diff --git a/trunk/arch/sh/kernel/cpu/shmobile/pm.c b/trunk/arch/sh/kernel/cpu/shmobile/pm.c index 08d27fac8d08..a6f95ae4aae7 100644 --- a/trunk/arch/sh/kernel/cpu/shmobile/pm.c +++ b/trunk/arch/sh/kernel/cpu/shmobile/pm.c @@ -16,7 +16,6 @@ #include #include #include -#include /* * Notifier lists for pre/post sleep notification diff --git a/trunk/arch/sh/kernel/dma-nommu.c b/trunk/arch/sh/kernel/dma-nommu.c index 5b0bfcda6d0b..3c55b87f8b63 100644 --- a/trunk/arch/sh/kernel/dma-nommu.c +++ b/trunk/arch/sh/kernel/dma-nommu.c @@ -63,8 +63,8 @@ static void nommu_sync_sg(struct device *dev, struct scatterlist *sg, #endif struct dma_map_ops nommu_dma_ops = { - .alloc = dma_generic_alloc_coherent, - .free = dma_generic_free_coherent, + .alloc_coherent = dma_generic_alloc_coherent, + .free_coherent = dma_generic_free_coherent, .map_page = nommu_map_page, .map_sg = nommu_map_sg, #ifdef CONFIG_DMA_NONCOHERENT diff --git a/trunk/arch/sh/kernel/idle.c b/trunk/arch/sh/kernel/idle.c index ee226e20c20c..64852ecc6881 100644 --- a/trunk/arch/sh/kernel/idle.c +++ b/trunk/arch/sh/kernel/idle.c @@ -17,8 +17,8 @@ #include #include #include -#include #include +#include #include #include diff --git a/trunk/arch/sh/kernel/kgdb.c b/trunk/arch/sh/kernel/kgdb.c index b117781bfea2..efb6d398dec3 100644 --- a/trunk/arch/sh/kernel/kgdb.c +++ b/trunk/arch/sh/kernel/kgdb.c @@ -14,7 +14,6 @@ #include #include #include -#include /* Macros for single step instruction identification */ #define OPCODE_BT(op) (((op) & 0xff00) == 0x8900) diff --git a/trunk/arch/sh/kernel/process_32.c b/trunk/arch/sh/kernel/process_32.c index 94273aaf78c1..f72e3a951588 100644 --- a/trunk/arch/sh/kernel/process_32.c +++ b/trunk/arch/sh/kernel/process_32.c @@ -26,7 +26,6 @@ #include #include #include -#include void show_regs(struct pt_regs * regs) { diff --git a/trunk/arch/sh/kernel/smp.c b/trunk/arch/sh/kernel/smp.c index eaebdf6a5c77..a17a14d32340 100644 --- a/trunk/arch/sh/kernel/smp.c +++ b/trunk/arch/sh/kernel/smp.c @@ -27,7 +27,6 @@ #include #include #include -#include int __cpu_number_map[NR_CPUS]; /* Map physical to logical */ int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */ diff --git a/trunk/arch/sh/kernel/vsyscall/vsyscall-sigreturn.S b/trunk/arch/sh/kernel/vsyscall/vsyscall-sigreturn.S index 23af17584054..555a64f124ca 100644 --- a/trunk/arch/sh/kernel/vsyscall/vsyscall-sigreturn.S +++ b/trunk/arch/sh/kernel/vsyscall/vsyscall-sigreturn.S @@ -34,41 +34,6 @@ __kernel_rt_sigreturn: 1: .short __NR_rt_sigreturn .LEND_rt_sigreturn: .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn - .previous .section .eh_frame,"a",@progbits -.LCIE1: - .ualong .LCIE1_end - .LCIE1_start -.LCIE1_start: - .ualong 0 /* CIE ID */ - .byte 0x1 /* Version number */ - .string "zRS" /* NUL-terminated augmentation string */ - .uleb128 0x1 /* Code alignment factor */ - .sleb128 -4 /* Data alignment factor */ - .byte 0x11 /* Return address register column */ - .uleb128 0x1 /* Augmentation length and data */ - .byte 0x1b /* DW_EH_PE_pcrel | DW_EH_PE_sdata4. */ - .byte 0xc, 0xf, 0x0 /* DW_CFA_def_cfa: r15 ofs 0 */ - - .align 2 -.LCIE1_end: - - .ualong .LFDE0_end-.LFDE0_start /* Length FDE0 */ -.LFDE0_start: - .ualong .LFDE0_start-.LCIE1 /* CIE pointer */ - .ualong .LSTART_sigreturn-. /* PC-relative start address */ - .ualong .LEND_sigreturn-.LSTART_sigreturn - .uleb128 0 /* Augmentation */ - .align 2 -.LFDE0_end: - - .ualong .LFDE1_end-.LFDE1_start /* Length FDE1 */ -.LFDE1_start: - .ualong .LFDE1_start-.LCIE1 /* CIE pointer */ - .ualong .LSTART_rt_sigreturn-. /* PC-relative start address */ - .ualong .LEND_rt_sigreturn-.LSTART_rt_sigreturn - .uleb128 0 /* Augmentation */ - .align 2 -.LFDE1_end: - .previous diff --git a/trunk/arch/sh/kernel/vsyscall/vsyscall-trapa.S b/trunk/arch/sh/kernel/vsyscall/vsyscall-trapa.S index 0eb74d00690a..3e70f851cdc6 100644 --- a/trunk/arch/sh/kernel/vsyscall/vsyscall-trapa.S +++ b/trunk/arch/sh/kernel/vsyscall/vsyscall-trapa.S @@ -3,34 +3,37 @@ .type __kernel_vsyscall,@function __kernel_vsyscall: .LSTART_vsyscall: - trapa #0x10 - nop + /* XXX: We'll have to do something here once we opt to use the vDSO + * page for something other than the signal trampoline.. as well as + * fill out .eh_frame -- PFM. */ .LEND_vsyscall: .size __kernel_vsyscall,.-.LSTART_vsyscall - .previous .section .eh_frame,"a",@progbits + .previous .LCIE: .ualong .LCIE_end - .LCIE_start .LCIE_start: .ualong 0 /* CIE ID */ .byte 0x1 /* Version number */ - .string "zR" /* NUL-terminated augmentation string */ + .string "zRS" /* NUL-terminated augmentation string */ .uleb128 0x1 /* Code alignment factor */ .sleb128 -4 /* Data alignment factor */ .byte 0x11 /* Return address register column */ - .uleb128 0x1 /* Augmentation length and data */ - .byte 0x1b /* DW_EH_PE_pcrel | DW_EH_PE_sdata4. */ - .byte 0xc,0xf,0x0 /* DW_CFA_def_cfa: r15 ofs 0 */ + /* Augmentation length and data (none) */ + .byte 0xc /* DW_CFA_def_cfa */ + .uleb128 0xf /* r15 */ + .uleb128 0x0 /* offset 0 */ + .align 2 .LCIE_end: .ualong .LFDE_end-.LFDE_start /* Length FDE */ .LFDE_start: - .ualong .LFDE_start-.LCIE /* CIE pointer */ - .ualong .LSTART_vsyscall-. /* PC-relative start address */ + .ualong .LCIE /* CIE pointer */ + .ualong .LSTART_vsyscall-. /* start address */ .ualong .LEND_vsyscall-.LSTART_vsyscall - .uleb128 0 /* Augmentation */ + .uleb128 0 .align 2 .LFDE_end: .previous diff --git a/trunk/arch/sh/mm/cache-sh4.c b/trunk/arch/sh/mm/cache-sh4.c index 0e529285b28d..112fea12522a 100644 --- a/trunk/arch/sh/mm/cache-sh4.c +++ b/trunk/arch/sh/mm/cache-sh4.c @@ -18,7 +18,6 @@ #include #include #include -#include #include /* diff --git a/trunk/arch/sh/mm/consistent.c b/trunk/arch/sh/mm/consistent.c index b81d9dbf9fef..f251b5f27652 100644 --- a/trunk/arch/sh/mm/consistent.c +++ b/trunk/arch/sh/mm/consistent.c @@ -33,8 +33,7 @@ static int __init dma_init(void) fs_initcall(dma_init); void *dma_generic_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp, - struct dma_attrs *attrs) + dma_addr_t *dma_handle, gfp_t gfp) { void *ret, *ret_nocache; int order = get_order(size); @@ -65,8 +64,7 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size, } void dma_generic_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, - struct dma_attrs *attrs) + void *vaddr, dma_addr_t dma_handle) { int order = get_order(size); unsigned long pfn = dma_handle >> PAGE_SHIFT; diff --git a/trunk/arch/sh/mm/fault_32.c b/trunk/arch/sh/mm/fault_32.c index e99b104d967a..324eef93c900 100644 --- a/trunk/arch/sh/mm/fault_32.c +++ b/trunk/arch/sh/mm/fault_32.c @@ -86,7 +86,7 @@ static noinline int vmalloc_fault(unsigned long address) pte_t *pte_k; /* Make sure we are in vmalloc/module/P3 area: */ - if (!(address >= P3SEG && address < P3_ADDR_MAX)) + if (!(address >= VMALLOC_START && address < P3_ADDR_MAX)) return -1; /* diff --git a/trunk/arch/sh/mm/flush-sh4.c b/trunk/arch/sh/mm/flush-sh4.c index 0b85dd9dd3a7..75a17f5bfa14 100644 --- a/trunk/arch/sh/mm/flush-sh4.c +++ b/trunk/arch/sh/mm/flush-sh4.c @@ -1,6 +1,5 @@ #include #include -#include #include #include diff --git a/trunk/arch/sh/mm/sram.c b/trunk/arch/sh/mm/sram.c index 2d8fa718d55e..bc156ec4545e 100644 --- a/trunk/arch/sh/mm/sram.c +++ b/trunk/arch/sh/mm/sram.c @@ -9,7 +9,6 @@ */ #include #include -#include #include /* diff --git a/trunk/arch/sparc/boot/Makefile b/trunk/arch/sparc/boot/Makefile index d56d199c1aa8..9205416b1e67 100644 --- a/trunk/arch/sparc/boot/Makefile +++ b/trunk/arch/sparc/boot/Makefile @@ -5,6 +5,7 @@ ROOT_IMG := /usr/src/root.img ELFTOAOUT := elftoaout +MKIMAGE := $(srctree)/scripts/mkuboot.sh hostprogs-y := piggyback btfixupprep targets := tftpboot.img btfix.o btfix.S image zImage vmlinux.aout @@ -91,9 +92,11 @@ $(obj)/image.bin: $(obj)/image FORCE $(obj)/image.gz: $(obj)/image.bin $(call if_changed,gzip) -UIMAGE_LOADADDR = $(CONFIG_UBOOT_LOAD_ADDR) -UIMAGE_ENTRYADDR = $(CONFIG_UBOOT_ENTRY_ADDR) -UIMAGE_COMPRESSION = gzip +quiet_cmd_uimage = UIMAGE $@ + cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sparc -O linux -T kernel \ + -C gzip -a $(CONFIG_UBOOT_LOAD_ADDR) \ + -e $(CONFIG_UBOOT_ENTRY_ADDR) -n 'Linux-$(KERNELRELEASE)' \ + -d $< $@ quiet_cmd_uimage.o = UIMAGE.O $@ cmd_uimage.o = $(LD) -Tdata $(CONFIG_UBOOT_FLASH_ADDR) \ diff --git a/trunk/arch/sparc/include/asm/dma-mapping.h b/trunk/arch/sparc/include/asm/dma-mapping.h index 48a7c65731d2..8c0e4f7bb204 100644 --- a/trunk/arch/sparc/include/asm/dma-mapping.h +++ b/trunk/arch/sparc/include/asm/dma-mapping.h @@ -26,30 +26,24 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev) #include -#define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) - -static inline void *dma_alloc_attrs(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag, - struct dma_attrs *attrs) +static inline void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) { struct dma_map_ops *ops = get_dma_ops(dev); void *cpu_addr; - cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs); + cpu_addr = ops->alloc_coherent(dev, size, dma_handle, flag); debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr); return cpu_addr; } -#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) - -static inline void dma_free_attrs(struct device *dev, size_t size, - void *cpu_addr, dma_addr_t dma_handle, - struct dma_attrs *attrs) +static inline void dma_free_coherent(struct device *dev, size_t size, + void *cpu_addr, dma_addr_t dma_handle) { struct dma_map_ops *ops = get_dma_ops(dev); debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); - ops->free(dev, size, cpu_addr, dma_handle, attrs); + ops->free_coherent(dev, size, cpu_addr, dma_handle); } static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) diff --git a/trunk/arch/sparc/include/asm/pgtable_64.h b/trunk/arch/sparc/include/asm/pgtable_64.h index 76e4a52aa85e..6fa2f7980e6b 100644 --- a/trunk/arch/sparc/include/asm/pgtable_64.h +++ b/trunk/arch/sparc/include/asm/pgtable_64.h @@ -12,6 +12,8 @@ * the SpitFire page tables. */ +#include + #include #include #include @@ -20,8 +22,6 @@ #include #include -#include - /* The kernel image occupies 0x4000000 to 0x6000000 (4MB --> 96MB). * The page copy blockops can use 0x6000000 to 0x8000000. * The TSB is mapped in the 0x8000000 to 0xa000000 range. diff --git a/trunk/arch/sparc/include/asm/ptrace.h b/trunk/arch/sparc/include/asm/ptrace.h index fd9c3f21cbf0..ef8c7c068f53 100644 --- a/trunk/arch/sparc/include/asm/ptrace.h +++ b/trunk/arch/sparc/include/asm/ptrace.h @@ -165,7 +165,6 @@ struct sparc_stackf { #ifdef __KERNEL__ #include -#include static inline int pt_regs_trap_type(struct pt_regs *regs) { @@ -241,7 +240,6 @@ extern unsigned long profile_pc(struct pt_regs *); #ifndef __ASSEMBLY__ #ifdef __KERNEL__ -#include static inline bool pt_regs_is_syscall(struct pt_regs *regs) { diff --git a/trunk/arch/sparc/kernel/ds.c b/trunk/arch/sparc/kernel/ds.c index b93c2c9ccb1d..fea13c7b1aee 100644 --- a/trunk/arch/sparc/kernel/ds.c +++ b/trunk/arch/sparc/kernel/ds.c @@ -1264,4 +1264,4 @@ static int __init ds_init(void) return vio_register_driver(&ds_driver); } -fs_initcall(ds_init); +subsys_initcall(ds_init); diff --git a/trunk/arch/sparc/kernel/iommu.c b/trunk/arch/sparc/kernel/iommu.c index 070ed141aac7..4643d68713fa 100644 --- a/trunk/arch/sparc/kernel/iommu.c +++ b/trunk/arch/sparc/kernel/iommu.c @@ -280,8 +280,7 @@ static inline void iommu_free_ctx(struct iommu *iommu, int ctx) } static void *dma_4u_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_addrp, gfp_t gfp, - struct dma_attrs *attrs) + dma_addr_t *dma_addrp, gfp_t gfp) { unsigned long flags, order, first_page; struct iommu *iommu; @@ -331,8 +330,7 @@ static void *dma_4u_alloc_coherent(struct device *dev, size_t size, } static void dma_4u_free_coherent(struct device *dev, size_t size, - void *cpu, dma_addr_t dvma, - struct dma_attrs *attrs) + void *cpu, dma_addr_t dvma) { struct iommu *iommu; unsigned long flags, order, npages; @@ -827,8 +825,8 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev, } static struct dma_map_ops sun4u_dma_ops = { - .alloc = dma_4u_alloc_coherent, - .free = dma_4u_free_coherent, + .alloc_coherent = dma_4u_alloc_coherent, + .free_coherent = dma_4u_free_coherent, .map_page = dma_4u_map_page, .unmap_page = dma_4u_unmap_page, .map_sg = dma_4u_map_sg, diff --git a/trunk/arch/sparc/kernel/ioport.c b/trunk/arch/sparc/kernel/ioport.c index 21bd73943f7f..d0479e2163fa 100644 --- a/trunk/arch/sparc/kernel/ioport.c +++ b/trunk/arch/sparc/kernel/ioport.c @@ -261,8 +261,7 @@ EXPORT_SYMBOL(sbus_set_sbus64); * CPU may access them without any explicit flushing. */ static void *sbus_alloc_coherent(struct device *dev, size_t len, - dma_addr_t *dma_addrp, gfp_t gfp, - struct dma_attrs *attrs) + dma_addr_t *dma_addrp, gfp_t gfp) { struct platform_device *op = to_platform_device(dev); unsigned long len_total = PAGE_ALIGN(len); @@ -316,7 +315,7 @@ static void *sbus_alloc_coherent(struct device *dev, size_t len, } static void sbus_free_coherent(struct device *dev, size_t n, void *p, - dma_addr_t ba, struct dma_attrs *attrs) + dma_addr_t ba) { struct resource *res; struct page *pgv; @@ -408,8 +407,8 @@ static void sbus_sync_sg_for_device(struct device *dev, struct scatterlist *sg, } struct dma_map_ops sbus_dma_ops = { - .alloc = sbus_alloc_coherent, - .free = sbus_free_coherent, + .alloc_coherent = sbus_alloc_coherent, + .free_coherent = sbus_free_coherent, .map_page = sbus_map_page, .unmap_page = sbus_unmap_page, .map_sg = sbus_map_sg, @@ -437,8 +436,7 @@ arch_initcall(sparc_register_ioport); * hwdev should be valid struct pci_dev pointer for PCI devices. */ static void *pci32_alloc_coherent(struct device *dev, size_t len, - dma_addr_t *pba, gfp_t gfp, - struct dma_attrs *attrs) + dma_addr_t *pba, gfp_t gfp) { unsigned long len_total = PAGE_ALIGN(len); void *va; @@ -491,7 +489,7 @@ static void *pci32_alloc_coherent(struct device *dev, size_t len, * past this call are illegal. */ static void pci32_free_coherent(struct device *dev, size_t n, void *p, - dma_addr_t ba, struct dma_attrs *attrs) + dma_addr_t ba) { struct resource *res; @@ -647,8 +645,8 @@ static void pci32_sync_sg_for_device(struct device *device, struct scatterlist * } struct dma_map_ops pci32_dma_ops = { - .alloc = pci32_alloc_coherent, - .free = pci32_free_coherent, + .alloc_coherent = pci32_alloc_coherent, + .free_coherent = pci32_free_coherent, .map_page = pci32_map_page, .unmap_page = pci32_unmap_page, .map_sg = pci32_map_sg, diff --git a/trunk/arch/sparc/kernel/jump_label.c b/trunk/arch/sparc/kernel/jump_label.c index 48565c11e82a..971fd435a281 100644 --- a/trunk/arch/sparc/kernel/jump_label.c +++ b/trunk/arch/sparc/kernel/jump_label.c @@ -6,8 +6,6 @@ #include #include -#include - #ifdef HAVE_JUMP_LABEL void arch_jump_label_transform(struct jump_entry *entry, diff --git a/trunk/arch/sparc/kernel/kgdb_64.c b/trunk/arch/sparc/kernel/kgdb_64.c index c8759550799f..768290a6c028 100644 --- a/trunk/arch/sparc/kernel/kgdb_64.c +++ b/trunk/arch/sparc/kernel/kgdb_64.c @@ -7,7 +7,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/sparc/kernel/leon_kernel.c b/trunk/arch/sparc/kernel/leon_kernel.c index 35e43673c453..a19c8a063683 100644 --- a/trunk/arch/sparc/kernel/leon_kernel.c +++ b/trunk/arch/sparc/kernel/leon_kernel.c @@ -104,11 +104,11 @@ static int irq_choose_cpu(const struct cpumask *affinity) { cpumask_t mask; - cpumask_and(&mask, cpu_online_mask, affinity); - if (cpumask_equal(&mask, cpu_online_mask) || cpumask_empty(&mask)) + cpus_and(mask, cpu_online_map, *affinity); + if (cpus_equal(mask, cpu_online_map) || cpus_empty(mask)) return boot_cpu_id; else - return cpumask_first(&mask); + return first_cpu(mask); } #else #define irq_choose_cpu(affinity) boot_cpu_id diff --git a/trunk/arch/sparc/kernel/leon_pci.c b/trunk/arch/sparc/kernel/leon_pci.c index 19f56058742b..aba6b958b2a5 100644 --- a/trunk/arch/sparc/kernel/leon_pci.c +++ b/trunk/arch/sparc/kernel/leon_pci.c @@ -45,6 +45,7 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) void __devinit pcibios_fixup_bus(struct pci_bus *pbus) { + struct leon_pci_info *info = pbus->sysdata; struct pci_dev *dev; int i, has_io, has_mem; u16 cmd; @@ -110,6 +111,18 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) return pci_enable_resources(dev, mask); } +struct device_node *pci_device_to_OF_node(struct pci_dev *pdev) +{ + /* + * Currently the OpenBoot nodes are not connected with the PCI device, + * this is because the LEON PROM does not create PCI nodes. Eventually + * this will change and the same approach as pcic.c can be used to + * match PROM nodes with pci devices. + */ + return NULL; +} +EXPORT_SYMBOL(pci_device_to_OF_node); + void __devinit pcibios_update_irq(struct pci_dev *dev, int irq) { #ifdef CONFIG_PCI_DEBUG diff --git a/trunk/arch/sparc/kernel/leon_smp.c b/trunk/arch/sparc/kernel/leon_smp.c index 160cac9c4036..1210fde18740 100644 --- a/trunk/arch/sparc/kernel/leon_smp.c +++ b/trunk/arch/sparc/kernel/leon_smp.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -79,8 +78,6 @@ void __cpuinit leon_callin(void) local_flush_tlb_all(); leon_configure_cache_smp(); - notify_cpu_starting(cpuid); - /* Get our local ticker going. */ smp_setup_percpu_timer(); diff --git a/trunk/arch/sparc/kernel/pci_sun4v.c b/trunk/arch/sparc/kernel/pci_sun4v.c index 7661e84a05a0..af5755d20fbe 100644 --- a/trunk/arch/sparc/kernel/pci_sun4v.c +++ b/trunk/arch/sparc/kernel/pci_sun4v.c @@ -128,8 +128,7 @@ static inline long iommu_batch_end(void) } static void *dma_4v_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_addrp, gfp_t gfp, - struct dma_attrs *attrs) + dma_addr_t *dma_addrp, gfp_t gfp) { unsigned long flags, order, first_page, npages, n; struct iommu *iommu; @@ -199,7 +198,7 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size, } static void dma_4v_free_coherent(struct device *dev, size_t size, void *cpu, - dma_addr_t dvma, struct dma_attrs *attrs) + dma_addr_t dvma) { struct pci_pbm_info *pbm; struct iommu *iommu; @@ -528,8 +527,8 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, } static struct dma_map_ops sun4v_dma_ops = { - .alloc = dma_4v_alloc_coherent, - .free = dma_4v_free_coherent, + .alloc_coherent = dma_4v_alloc_coherent, + .free_coherent = dma_4v_free_coherent, .map_page = dma_4v_map_page, .unmap_page = dma_4v_unmap_page, .map_sg = dma_4v_map_sg, diff --git a/trunk/arch/sparc/kernel/rtrap_64.S b/trunk/arch/sparc/kernel/rtrap_64.S index 9171fc238def..77f1b95e0806 100644 --- a/trunk/arch/sparc/kernel/rtrap_64.S +++ b/trunk/arch/sparc/kernel/rtrap_64.S @@ -20,6 +20,11 @@ .text .align 32 +__handle_softirq: + call do_softirq + nop + ba,a,pt %xcc, __handle_softirq_continue + nop __handle_preemption: call schedule wrpr %g0, RTRAP_PSTATE, %pstate @@ -84,7 +89,9 @@ rtrap: cmp %l1, 0 /* mm/ultra.S:xcall_report_regs KNOWS about this load. */ + bne,pn %icc, __handle_softirq ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 +__handle_softirq_continue: rtrap_xcall: sethi %hi(0xf << 20), %l4 and %l1, %l4, %l4 diff --git a/trunk/arch/sparc/kernel/sun4d_smp.c b/trunk/arch/sparc/kernel/sun4d_smp.c index 540b2fec09f0..133387980b56 100644 --- a/trunk/arch/sparc/kernel/sun4d_smp.c +++ b/trunk/arch/sparc/kernel/sun4d_smp.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include "kernel.h" diff --git a/trunk/arch/sparc/kernel/sun4m_smp.c b/trunk/arch/sparc/kernel/sun4m_smp.c index 02db9a0412ce..594768686525 100644 --- a/trunk/arch/sparc/kernel/sun4m_smp.c +++ b/trunk/arch/sparc/kernel/sun4m_smp.c @@ -10,7 +10,6 @@ #include #include -#include #include #include "irq.h" diff --git a/trunk/arch/sparc/kernel/sys_sparc_64.c b/trunk/arch/sparc/kernel/sys_sparc_64.c index 3ee51f189a55..232df9949530 100644 --- a/trunk/arch/sparc/kernel/sys_sparc_64.c +++ b/trunk/arch/sparc/kernel/sys_sparc_64.c @@ -566,10 +566,15 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, SYSCALL_DEFINE2(64_munmap, unsigned long, addr, size_t, len) { + long ret; + if (invalid_64bit_range(addr, len)) return -EINVAL; - return vm_munmap(addr, len); + down_write(¤t->mm->mmap_sem); + ret = do_munmap(current->mm, addr, len); + up_write(¤t->mm->mmap_sem); + return ret; } extern unsigned long do_mremap(unsigned long addr, diff --git a/trunk/arch/sparc/mm/fault_32.c b/trunk/arch/sparc/mm/fault_32.c index df3155a17991..7705c6731e28 100644 --- a/trunk/arch/sparc/mm/fault_32.c +++ b/trunk/arch/sparc/mm/fault_32.c @@ -225,8 +225,6 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, unsigned long g2; int from_user = !(regs->psr & PSR_PS); int fault, code; - unsigned int flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | - (write ? FAULT_FLAG_WRITE : 0)); if(text_fault) address = regs->pc; @@ -253,7 +251,6 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); -retry: down_read(&mm->mmap_sem); /* @@ -292,11 +289,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, * make sure we exit gracefully rather than endlessly redo * the fault. */ - fault = handle_mm_fault(mm, vma, address, flags); - - if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) - return; - + fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0); if (unlikely(fault & VM_FAULT_ERROR)) { if (fault & VM_FAULT_OOM) goto out_of_memory; @@ -304,29 +297,13 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, goto do_sigbus; BUG(); } - - if (flags & FAULT_FLAG_ALLOW_RETRY) { - if (fault & VM_FAULT_MAJOR) { - current->maj_flt++; - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, - 1, regs, address); - } else { - current->min_flt++; - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, - 1, regs, address); - } - if (fault & VM_FAULT_RETRY) { - flags &= ~FAULT_FLAG_ALLOW_RETRY; - - /* No need to up_read(&mm->mmap_sem) as we would - * have already released it in __lock_page_or_retry - * in mm/filemap.c. - */ - - goto retry; - } + if (fault & VM_FAULT_MAJOR) { + current->maj_flt++; + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address); + } else { + current->min_flt++; + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address); } - up_read(&mm->mmap_sem); return; diff --git a/trunk/arch/sparc/mm/fault_64.c b/trunk/arch/sparc/mm/fault_64.c index 1fe0429b6314..504c0622f729 100644 --- a/trunk/arch/sparc/mm/fault_64.c +++ b/trunk/arch/sparc/mm/fault_64.c @@ -279,7 +279,6 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) unsigned int insn = 0; int si_code, fault_code, fault; unsigned long address, mm_rss; - unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; fault_code = get_thread_fault_code(); @@ -334,8 +333,6 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) insn = get_fault_insn(regs, insn); goto handle_kernel_fault; } - -retry: down_read(&mm->mmap_sem); } @@ -426,12 +423,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) goto bad_area; } - flags |= ((fault_code & FAULT_CODE_WRITE) ? FAULT_FLAG_WRITE : 0); - fault = handle_mm_fault(mm, vma, address, flags); - - if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) - return; - + fault = handle_mm_fault(mm, vma, address, (fault_code & FAULT_CODE_WRITE) ? FAULT_FLAG_WRITE : 0); if (unlikely(fault & VM_FAULT_ERROR)) { if (fault & VM_FAULT_OOM) goto out_of_memory; @@ -439,27 +431,12 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) goto do_sigbus; BUG(); } - - if (flags & FAULT_FLAG_ALLOW_RETRY) { - if (fault & VM_FAULT_MAJOR) { - current->maj_flt++; - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, - 1, regs, address); - } else { - current->min_flt++; - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, - 1, regs, address); - } - if (fault & VM_FAULT_RETRY) { - flags &= ~FAULT_FLAG_ALLOW_RETRY; - - /* No need to up_read(&mm->mmap_sem) as we would - * have already released it in __lock_page_or_retry - * in mm/filemap.c. - */ - - goto retry; - } + if (fault & VM_FAULT_MAJOR) { + current->maj_flt++; + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address); + } else { + current->min_flt++; + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address); } up_read(&mm->mmap_sem); diff --git a/trunk/arch/tile/Kconfig b/trunk/arch/tile/Kconfig index 96033e2d6845..11270ca22c0a 100644 --- a/trunk/arch/tile/Kconfig +++ b/trunk/arch/tile/Kconfig @@ -12,7 +12,7 @@ config TILE select GENERIC_PENDING_IRQ if SMP select GENERIC_IRQ_SHOW select SYS_HYPERVISOR - select ARCH_HAVE_NMI_SAFE_CMPXCHG + select ARCH_HAVE_NMI_SAFE_CMPXCHG if !M386 # FIXME: investigate whether we need/want these options. # select HAVE_IOREMAP_PROT @@ -69,9 +69,6 @@ config ARCH_PHYS_ADDR_T_64BIT config ARCH_DMA_ADDR_T_64BIT def_bool y -config NEED_DMA_MAP_STATE - def_bool y - config LOCKDEP_SUPPORT def_bool y @@ -121,7 +118,7 @@ config 64BIT config ARCH_DEFCONFIG string - default "arch/tile/configs/tilepro_defconfig" if !TILEGX + default "arch/tile/configs/tile_defconfig" if !TILEGX default "arch/tile/configs/tilegx_defconfig" if TILEGX source "init/Kconfig" @@ -243,7 +240,6 @@ endchoice config PAGE_OFFSET hex - depends on !64BIT default 0xF0000000 if VMSPLIT_3_75G default 0xE0000000 if VMSPLIT_3_5G default 0xB0000000 if VMSPLIT_2_75G diff --git a/trunk/arch/tile/Makefile b/trunk/arch/tile/Makefile index 9520bc5a4b7f..17acce70569b 100644 --- a/trunk/arch/tile/Makefile +++ b/trunk/arch/tile/Makefile @@ -30,8 +30,7 @@ ifneq ($(CONFIG_DEBUG_EXTRA_FLAGS),"") KBUILD_CFLAGS += $(CONFIG_DEBUG_EXTRA_FLAGS) endif -LIBGCC_PATH := \ - $(shell $(CC) $(KBUILD_CFLAGS) $(KCFLAGS) -print-libgcc-file-name) +LIBGCC_PATH := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) # Provide the path to use for "make defconfig". KBUILD_DEFCONFIG := $(ARCH)_defconfig @@ -54,6 +53,8 @@ libs-y += $(LIBGCC_PATH) # See arch/tile/Kbuild for content of core part of the kernel core-y += arch/tile/ +core-$(CONFIG_KVM) += arch/tile/kvm/ + ifdef TILERA_ROOT INSTALL_PATH ?= $(TILERA_ROOT)/tile/boot endif diff --git a/trunk/arch/tile/include/arch/spr_def.h b/trunk/arch/tile/include/arch/spr_def.h index d6ba449b5363..f548efeb2de3 100644 --- a/trunk/arch/tile/include/arch/spr_def.h +++ b/trunk/arch/tile/include/arch/spr_def.h @@ -60,8 +60,8 @@ _concat4(SPR_IPI_EVENT_, CONFIG_KERNEL_PL,,) #define SPR_IPI_EVENT_RESET_K \ _concat4(SPR_IPI_EVENT_RESET_, CONFIG_KERNEL_PL,,) -#define SPR_IPI_EVENT_SET_K \ - _concat4(SPR_IPI_EVENT_SET_, CONFIG_KERNEL_PL,,) +#define SPR_IPI_MASK_SET_K \ + _concat4(SPR_IPI_MASK_SET_, CONFIG_KERNEL_PL,,) #define INT_IPI_K \ _concat4(INT_IPI_, CONFIG_KERNEL_PL,,) diff --git a/trunk/arch/tile/include/asm/atomic.h b/trunk/arch/tile/include/asm/atomic.h index f2461429a4a4..bb696da5d7cd 100644 --- a/trunk/arch/tile/include/asm/atomic.h +++ b/trunk/arch/tile/include/asm/atomic.h @@ -17,8 +17,6 @@ #ifndef _ASM_TILE_ATOMIC_H #define _ASM_TILE_ATOMIC_H -#include - #ifndef __ASSEMBLY__ #include @@ -123,6 +121,54 @@ static inline int atomic_read(const atomic_t *v) */ #define atomic_add_negative(i, v) (atomic_add_return((i), (v)) < 0) +/* Nonexistent functions intended to cause link errors. */ +extern unsigned long __xchg_called_with_bad_pointer(void); +extern unsigned long __cmpxchg_called_with_bad_pointer(void); + +#define xchg(ptr, x) \ + ({ \ + typeof(*(ptr)) __x; \ + switch (sizeof(*(ptr))) { \ + case 4: \ + __x = (typeof(__x))(typeof(__x-__x))atomic_xchg( \ + (atomic_t *)(ptr), \ + (u32)(typeof((x)-(x)))(x)); \ + break; \ + case 8: \ + __x = (typeof(__x))(typeof(__x-__x))atomic64_xchg( \ + (atomic64_t *)(ptr), \ + (u64)(typeof((x)-(x)))(x)); \ + break; \ + default: \ + __xchg_called_with_bad_pointer(); \ + } \ + __x; \ + }) + +#define cmpxchg(ptr, o, n) \ + ({ \ + typeof(*(ptr)) __x; \ + switch (sizeof(*(ptr))) { \ + case 4: \ + __x = (typeof(__x))(typeof(__x-__x))atomic_cmpxchg( \ + (atomic_t *)(ptr), \ + (u32)(typeof((o)-(o)))(o), \ + (u32)(typeof((n)-(n)))(n)); \ + break; \ + case 8: \ + __x = (typeof(__x))(typeof(__x-__x))atomic64_cmpxchg( \ + (atomic64_t *)(ptr), \ + (u64)(typeof((o)-(o)))(o), \ + (u64)(typeof((n)-(n)))(n)); \ + break; \ + default: \ + __cmpxchg_called_with_bad_pointer(); \ + } \ + __x; \ + }) + +#define tas(ptr) (xchg((ptr), 1)) + #endif /* __ASSEMBLY__ */ #ifndef __tilegx__ diff --git a/trunk/arch/tile/include/asm/atomic_32.h b/trunk/arch/tile/include/asm/atomic_32.h index 54d1da826f93..466dc4a39a4f 100644 --- a/trunk/arch/tile/include/asm/atomic_32.h +++ b/trunk/arch/tile/include/asm/atomic_32.h @@ -200,7 +200,7 @@ static inline u64 atomic64_add_return(u64 i, atomic64_t *v) * @u: ...unless v is equal to u. * * Atomically adds @a to @v, so long as @v was not already @u. - * Returns non-zero if @v was not @u, and zero otherwise. + * Returns the old value of @v. */ static inline u64 atomic64_add_unless(atomic64_t *v, u64 a, u64 u) { diff --git a/trunk/arch/tile/include/asm/bitops_64.h b/trunk/arch/tile/include/asm/bitops_64.h index 60b87ee54fb8..58d021a9834f 100644 --- a/trunk/arch/tile/include/asm/bitops_64.h +++ b/trunk/arch/tile/include/asm/bitops_64.h @@ -38,10 +38,10 @@ static inline void clear_bit(unsigned nr, volatile unsigned long *addr) static inline void change_bit(unsigned nr, volatile unsigned long *addr) { - unsigned long mask = (1UL << (nr % BITS_PER_LONG)); - unsigned long guess, oldval; + unsigned long old, mask = (1UL << (nr % BITS_PER_LONG)); + long guess, oldval; addr += nr / BITS_PER_LONG; - oldval = *addr; + old = *addr; do { guess = oldval; oldval = atomic64_cmpxchg((atomic64_t *)addr, @@ -85,7 +85,7 @@ static inline int test_and_change_bit(unsigned nr, volatile unsigned long *addr) { unsigned long mask = (1UL << (nr % BITS_PER_LONG)); - unsigned long guess, oldval; + long guess, oldval = *addr; addr += nr / BITS_PER_LONG; oldval = *addr; do { diff --git a/trunk/arch/tile/include/asm/cmpxchg.h b/trunk/arch/tile/include/asm/cmpxchg.h deleted file mode 100644 index 276f067e3640..000000000000 --- a/trunk/arch/tile/include/asm/cmpxchg.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * cmpxchg.h -- forked from asm/atomic.h with this copyright: - * - * Copyright 2010 Tilera Corporation. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, version 2. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for - * more details. - * - */ - -#ifndef _ASM_TILE_CMPXCHG_H -#define _ASM_TILE_CMPXCHG_H - -#ifndef __ASSEMBLY__ - -/* Nonexistent functions intended to cause link errors. */ -extern unsigned long __xchg_called_with_bad_pointer(void); -extern unsigned long __cmpxchg_called_with_bad_pointer(void); - -#define xchg(ptr, x) \ - ({ \ - typeof(*(ptr)) __x; \ - switch (sizeof(*(ptr))) { \ - case 4: \ - __x = (typeof(__x))(typeof(__x-__x))atomic_xchg( \ - (atomic_t *)(ptr), \ - (u32)(typeof((x)-(x)))(x)); \ - break; \ - case 8: \ - __x = (typeof(__x))(typeof(__x-__x))atomic64_xchg( \ - (atomic64_t *)(ptr), \ - (u64)(typeof((x)-(x)))(x)); \ - break; \ - default: \ - __xchg_called_with_bad_pointer(); \ - } \ - __x; \ - }) - -#define cmpxchg(ptr, o, n) \ - ({ \ - typeof(*(ptr)) __x; \ - switch (sizeof(*(ptr))) { \ - case 4: \ - __x = (typeof(__x))(typeof(__x-__x))atomic_cmpxchg( \ - (atomic_t *)(ptr), \ - (u32)(typeof((o)-(o)))(o), \ - (u32)(typeof((n)-(n)))(n)); \ - break; \ - case 8: \ - __x = (typeof(__x))(typeof(__x-__x))atomic64_cmpxchg( \ - (atomic64_t *)(ptr), \ - (u64)(typeof((o)-(o)))(o), \ - (u64)(typeof((n)-(n)))(n)); \ - break; \ - default: \ - __cmpxchg_called_with_bad_pointer(); \ - } \ - __x; \ - }) - -#define tas(ptr) (xchg((ptr), 1)) - -#endif /* __ASSEMBLY__ */ - -#endif /* _ASM_TILE_CMPXCHG_H */ diff --git a/trunk/arch/tile/include/asm/irq.h b/trunk/arch/tile/include/asm/irq.h index 33cff9a3058b..f80f8ceabc67 100644 --- a/trunk/arch/tile/include/asm/irq.h +++ b/trunk/arch/tile/include/asm/irq.h @@ -21,7 +21,7 @@ #define NR_IRQS 32 /* IRQ numbers used for linux IPIs. */ -#define IRQ_RESCHEDULE 0 +#define IRQ_RESCHEDULE 1 #define irq_canonicalize(irq) (irq) diff --git a/trunk/arch/tile/include/asm/pci.h b/trunk/arch/tile/include/asm/pci.h index 32e6cbe8dff3..5d5a635530bd 100644 --- a/trunk/arch/tile/include/asm/pci.h +++ b/trunk/arch/tile/include/asm/pci.h @@ -47,8 +47,8 @@ struct pci_controller { */ #define PCI_DMA_BUS_IS_PHYS 1 -int __init tile_pci_init(void); -int __init pcibios_init(void); +int __devinit tile_pci_init(void); +int __devinit pcibios_init(void); static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} diff --git a/trunk/arch/tile/include/asm/spinlock_64.h b/trunk/arch/tile/include/asm/spinlock_64.h index 5f8b6a095fd8..72be5904e020 100644 --- a/trunk/arch/tile/include/asm/spinlock_64.h +++ b/trunk/arch/tile/include/asm/spinlock_64.h @@ -137,7 +137,7 @@ static inline void arch_read_unlock(arch_rwlock_t *rw) static inline void arch_write_unlock(arch_rwlock_t *rw) { __insn_mf(); - __insn_exch4(&rw->lock, 0); /* Avoid waiting in the write buffer. */ + rw->lock = 0; } static inline int arch_read_trylock(arch_rwlock_t *rw) diff --git a/trunk/arch/tile/include/asm/stack.h b/trunk/arch/tile/include/asm/stack.h index 0e9d382a2d45..4d97a2db932e 100644 --- a/trunk/arch/tile/include/asm/stack.h +++ b/trunk/arch/tile/include/asm/stack.h @@ -25,6 +25,7 @@ struct KBacktraceIterator { BacktraceIterator it; struct task_struct *task; /* task we are backtracing */ + pte_t *pgtable; /* page table for user space access */ int end; /* iteration complete. */ int new_context; /* new context is starting */ int profile; /* profiling, so stop on async intrpt */ diff --git a/trunk/arch/tile/include/asm/traps.h b/trunk/arch/tile/include/asm/traps.h index e28c3df4176a..5f20f920f932 100644 --- a/trunk/arch/tile/include/asm/traps.h +++ b/trunk/arch/tile/include/asm/traps.h @@ -64,11 +64,7 @@ void do_breakpoint(struct pt_regs *, int fault_num); #ifdef __tilegx__ -/* kernel/single_step.c */ void gx_singlestep_handle(struct pt_regs *, int fault_num); - -/* kernel/intvec_64.S */ -void fill_ra_stack(void); #endif -#endif /* _ASM_TILE_TRAPS_H */ +#endif /* _ASM_TILE_SYSCALLS_H */ diff --git a/trunk/arch/tile/kernel/entry.S b/trunk/arch/tile/kernel/entry.S index ec91568df880..431e9ae60488 100644 --- a/trunk/arch/tile/kernel/entry.S +++ b/trunk/arch/tile/kernel/entry.S @@ -85,7 +85,6 @@ STD_ENTRY(cpu_idle_on_new_stack) /* Loop forever on a nap during SMP boot. */ STD_ENTRY(smp_nap) nap - nop /* avoid provoking the icache prefetch with a jump */ j smp_nap /* we are not architecturally guaranteed not to exit nap */ jrp lr /* clue in the backtracer */ STD_ENDPROC(smp_nap) @@ -106,6 +105,5 @@ STD_ENTRY(_cpu_idle) .global _cpu_idle_nap _cpu_idle_nap: nap - nop /* avoid provoking the icache prefetch with a jump */ jrp lr STD_ENDPROC(_cpu_idle) diff --git a/trunk/arch/tile/kernel/intvec_32.S b/trunk/arch/tile/kernel/intvec_32.S index 5d56a1ef5ba5..aecc8ed5f39b 100644 --- a/trunk/arch/tile/kernel/intvec_32.S +++ b/trunk/arch/tile/kernel/intvec_32.S @@ -799,10 +799,6 @@ handle_interrupt: * This routine takes a boolean in r30 indicating if this is an NMI. * If so, we also expect a boolean in r31 indicating whether to * re-enable the oprofile interrupts. - * - * Note that .Lresume_userspace is jumped to directly in several - * places, and we need to make sure r30 is set correctly in those - * callers as well. */ STD_ENTRY(interrupt_return) /* If we're resuming to kernel space, don't check thread flags. */ @@ -1241,10 +1237,7 @@ handle_syscall: bzt r30, 1f jal do_syscall_trace FEEDBACK_REENTER(handle_syscall) -1: { - movei r30, 0 /* not an NMI */ - j .Lresume_userspace /* jump into middle of interrupt_return */ - } +1: j .Lresume_userspace /* jump into middle of interrupt_return */ .Linvalid_syscall: /* Report an invalid syscall back to the user program */ @@ -1253,10 +1246,7 @@ handle_syscall: movei r28, -ENOSYS } sw r29, r28 - { - movei r30, 0 /* not an NMI */ - j .Lresume_userspace /* jump into middle of interrupt_return */ - } + j .Lresume_userspace /* jump into middle of interrupt_return */ STD_ENDPROC(handle_syscall) /* Return the address for oprofile to suppress in backtraces. */ @@ -1272,10 +1262,7 @@ STD_ENTRY(ret_from_fork) jal sim_notify_fork jal schedule_tail FEEDBACK_REENTER(ret_from_fork) - { - movei r30, 0 /* not an NMI */ - j .Lresume_userspace /* jump into middle of interrupt_return */ - } + j .Lresume_userspace /* jump into middle of interrupt_return */ STD_ENDPROC(ret_from_fork) /* @@ -1389,10 +1376,7 @@ handle_ill: jal send_sigtrap /* issue a SIGTRAP */ FEEDBACK_REENTER(handle_ill) - { - movei r30, 0 /* not an NMI */ - j .Lresume_userspace /* jump into middle of interrupt_return */ - } + j .Lresume_userspace /* jump into middle of interrupt_return */ .Ldispatch_normal_ill: { diff --git a/trunk/arch/tile/kernel/intvec_64.S b/trunk/arch/tile/kernel/intvec_64.S index 49d9d6621682..79c93e10ba27 100644 --- a/trunk/arch/tile/kernel/intvec_64.S +++ b/trunk/arch/tile/kernel/intvec_64.S @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -606,10 +605,6 @@ handle_interrupt: * This routine takes a boolean in r30 indicating if this is an NMI. * If so, we also expect a boolean in r31 indicating whether to * re-enable the oprofile interrupts. - * - * Note that .Lresume_userspace is jumped to directly in several - * places, and we need to make sure r30 is set correctly in those - * callers as well. */ STD_ENTRY(interrupt_return) /* If we're resuming to kernel space, don't check thread flags. */ @@ -1044,28 +1039,11 @@ handle_syscall: /* Do syscall trace again, if requested. */ ld r30, r31 - andi r0, r30, _TIF_SYSCALL_TRACE - { - andi r0, r30, _TIF_SINGLESTEP - beqzt r0, 1f - } + andi r30, r30, _TIF_SYSCALL_TRACE + beqzt r30, 1f jal do_syscall_trace FEEDBACK_REENTER(handle_syscall) - andi r0, r30, _TIF_SINGLESTEP - -1: beqzt r0, 2f - - /* Single stepping -- notify ptrace. */ - { - movei r0, SIGTRAP - jal ptrace_notify - } - FEEDBACK_REENTER(handle_syscall) - -2: { - movei r30, 0 /* not an NMI */ - j .Lresume_userspace /* jump into middle of interrupt_return */ - } +1: j .Lresume_userspace /* jump into middle of interrupt_return */ .Lcompat_syscall: /* @@ -1099,10 +1077,7 @@ handle_syscall: movei r28, -ENOSYS } st r29, r28 - { - movei r30, 0 /* not an NMI */ - j .Lresume_userspace /* jump into middle of interrupt_return */ - } + j .Lresume_userspace /* jump into middle of interrupt_return */ STD_ENDPROC(handle_syscall) /* Return the address for oprofile to suppress in backtraces. */ @@ -1118,10 +1093,7 @@ STD_ENTRY(ret_from_fork) jal sim_notify_fork jal schedule_tail FEEDBACK_REENTER(ret_from_fork) - { - movei r30, 0 /* not an NMI */ - j .Lresume_userspace /* jump into middle of interrupt_return */ - } + j .Lresume_userspace STD_ENDPROC(ret_from_fork) /* Various stub interrupt handlers and syscall handlers */ @@ -1184,18 +1156,6 @@ int_unalign: push_extra_callee_saves r0 j do_trap -/* Fill the return address stack with nonzero entries. */ -STD_ENTRY(fill_ra_stack) - { - move r0, lr - jal 1f - } -1: jal 2f -2: jal 3f -3: jal 4f -4: jrp r0 - STD_ENDPROC(fill_ra_stack) - /* Include .intrpt1 array of interrupt vectors */ .section ".intrpt1", "ax" @@ -1206,7 +1166,7 @@ STD_ENTRY(fill_ra_stack) #define do_hardwall_trap bad_intr #endif - int_hand INT_MEM_ERROR, MEM_ERROR, do_trap + int_hand INT_MEM_ERROR, MEM_ERROR, bad_intr int_hand INT_SINGLE_STEP_3, SINGLE_STEP_3, bad_intr #if CONFIG_KERNEL_PL == 2 int_hand INT_SINGLE_STEP_2, SINGLE_STEP_2, gx_singlestep_handle diff --git a/trunk/arch/tile/kernel/module.c b/trunk/arch/tile/kernel/module.c index 98d476920106..b90ab9925674 100644 --- a/trunk/arch/tile/kernel/module.c +++ b/trunk/arch/tile/kernel/module.c @@ -67,8 +67,6 @@ void *module_alloc(unsigned long size) area = __get_vm_area(size, VM_ALLOC, MEM_MODULE_START, MEM_MODULE_END); if (!area) goto error; - area->nr_pages = npages; - area->pages = pages; if (map_vm_area(area, prot_rwx, &pages)) { vunmap(area->addr); diff --git a/trunk/arch/tile/kernel/pci.c b/trunk/arch/tile/kernel/pci.c index b56d12bf5900..a1bb59eecc18 100644 --- a/trunk/arch/tile/kernel/pci.c +++ b/trunk/arch/tile/kernel/pci.c @@ -141,7 +141,7 @@ static int __devinit tile_init_irqs(int controller_id, * * Returns the number of controllers discovered. */ -int __init tile_pci_init(void) +int __devinit tile_pci_init(void) { int i; @@ -287,7 +287,7 @@ static void __devinit fixup_read_and_payload_sizes(void) * The controllers have been set up by the time we get here, by a call to * tile_pci_init. */ -int __init pcibios_init(void) +int __devinit pcibios_init(void) { int i; diff --git a/trunk/arch/tile/kernel/proc.c b/trunk/arch/tile/kernel/proc.c index 446a7f52cc11..7a9327046404 100644 --- a/trunk/arch/tile/kernel/proc.c +++ b/trunk/arch/tile/kernel/proc.c @@ -146,6 +146,7 @@ static ctl_table unaligned_table[] = { }, {} }; +#endif static struct ctl_path tile_path[] = { { .procname = "tile" }, @@ -154,9 +155,10 @@ static struct ctl_path tile_path[] = { static int __init proc_sys_tile_init(void) { +#ifndef __tilegx__ /* FIXME: GX: no support for unaligned access yet */ register_sysctl_paths(tile_path, unaligned_table); +#endif return 0; } arch_initcall(proc_sys_tile_init); -#endif diff --git a/trunk/arch/tile/kernel/process.c b/trunk/arch/tile/kernel/process.c index 2d5ef617bb39..30caecac94dc 100644 --- a/trunk/arch/tile/kernel/process.c +++ b/trunk/arch/tile/kernel/process.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -286,7 +285,7 @@ struct task_struct *validate_current(void) static struct task_struct corrupt = { .comm = "" }; struct task_struct *tsk = current; if (unlikely((unsigned long)tsk < PAGE_OFFSET || - (high_memory && (void *)tsk > high_memory) || + (void *)tsk > high_memory || ((unsigned long)tsk & (__alignof__(*tsk) - 1)) != 0)) { pr_err("Corrupt 'current' %p (sp %#lx)\n", tsk, stack_pointer); tsk = &corrupt; diff --git a/trunk/arch/tile/kernel/setup.c b/trunk/arch/tile/kernel/setup.c index bff23f476110..5f85d8b34dbb 100644 --- a/trunk/arch/tile/kernel/setup.c +++ b/trunk/arch/tile/kernel/setup.c @@ -103,11 +103,13 @@ unsigned long __initdata pci_reserve_end_pfn = -1U; static int __init setup_maxmem(char *str) { - unsigned long long maxmem; - if (str == NULL || (maxmem = memparse(str, NULL)) == 0) + long maxmem_mb; + if (str == NULL || strict_strtol(str, 0, &maxmem_mb) != 0 || + maxmem_mb == 0) return -EINVAL; - maxmem_pfn = (maxmem >> HPAGE_SHIFT) << (HPAGE_SHIFT - PAGE_SHIFT); + maxmem_pfn = (maxmem_mb >> (HPAGE_SHIFT - 20)) << + (HPAGE_SHIFT - PAGE_SHIFT); pr_info("Forcing RAM used to no more than %dMB\n", maxmem_pfn >> (20 - PAGE_SHIFT)); return 0; @@ -117,15 +119,14 @@ early_param("maxmem", setup_maxmem); static int __init setup_maxnodemem(char *str) { char *endp; - unsigned long long maxnodemem; - long node; + long maxnodemem_mb, node; node = str ? simple_strtoul(str, &endp, 0) : INT_MAX; - if (node >= MAX_NUMNODES || *endp != ':') + if (node >= MAX_NUMNODES || *endp != ':' || + strict_strtol(endp+1, 0, &maxnodemem_mb) != 0) return -EINVAL; - maxnodemem = memparse(endp+1, NULL); - maxnodemem_pfn[node] = (maxnodemem >> HPAGE_SHIFT) << + maxnodemem_pfn[node] = (maxnodemem_mb >> (HPAGE_SHIFT - 20)) << (HPAGE_SHIFT - PAGE_SHIFT); pr_info("Forcing RAM used on node %ld to no more than %dMB\n", node, maxnodemem_pfn[node] >> (20 - PAGE_SHIFT)); @@ -912,13 +913,6 @@ void __cpuinit setup_cpu(int boot) #ifdef CONFIG_BLK_DEV_INITRD -/* - * Note that the kernel can potentially support other compression - * techniques than gz, though we don't do so by default. If we ever - * decide to do so we can either look for other filename extensions, - * or just allow a file with this name to be compressed with an - * arbitrary compressor (somewhat counterintuitively). - */ static int __initdata set_initramfs_file; static char __initdata initramfs_file[128] = "initramfs.cpio.gz"; @@ -934,9 +928,9 @@ static int __init setup_initramfs_file(char *str) early_param("initramfs_file", setup_initramfs_file); /* - * We look for an "initramfs.cpio.gz" file in the hvfs. + * We look for an additional "initramfs.cpio.gz" file in the hvfs. * If there is one, we allocate some memory for it and it will be - * unpacked to the initramfs. + * unpacked to the initramfs after any built-in initramfs_data. */ static void __init load_hv_initrd(void) { @@ -1106,7 +1100,7 @@ EXPORT_SYMBOL(hash_for_home_map); /* * cpu_cacheable_map lists all the cpus whose caches the hypervisor can - * flush on our behalf. It is set to cpu_possible_mask OR'ed with + * flush on our behalf. It is set to cpu_possible_map OR'ed with * hash_for_home_map, and it is what should be passed to * hv_flush_remote() to flush all caches. Note that if there are * dedicated hypervisor driver tiles that have authorized use of their @@ -1192,7 +1186,7 @@ static void __init setup_cpu_maps(void) sizeof(cpu_lotar_map)); if (rc < 0) { pr_err("warning: no HV_INQ_TILES_LOTAR; using AVAIL\n"); - cpu_lotar_map = *cpu_possible_mask; + cpu_lotar_map = cpu_possible_map; } #if CHIP_HAS_CBOX_HOME_MAP() @@ -1202,9 +1196,9 @@ static void __init setup_cpu_maps(void) sizeof(hash_for_home_map)); if (rc < 0) early_panic("hv_inquire_tiles(HFH_CACHE) failed: rc %d\n", rc); - cpumask_or(&cpu_cacheable_map, cpu_possible_mask, &hash_for_home_map); + cpumask_or(&cpu_cacheable_map, &cpu_possible_map, &hash_for_home_map); #else - cpu_cacheable_map = *cpu_possible_mask; + cpu_cacheable_map = cpu_possible_map; #endif } diff --git a/trunk/arch/tile/kernel/single_step.c b/trunk/arch/tile/kernel/single_step.c index 89529c9f0605..bc1eb586e24d 100644 --- a/trunk/arch/tile/kernel/single_step.c +++ b/trunk/arch/tile/kernel/single_step.c @@ -153,25 +153,6 @@ static tile_bundle_bits rewrite_load_store_unaligned( if (((unsigned long)addr % size) == 0) return bundle; - /* - * Return SIGBUS with the unaligned address, if requested. - * Note that we return SIGBUS even for completely invalid addresses - * as long as they are in fact unaligned; this matches what the - * tilepro hardware would be doing, if it could provide us with the - * actual bad address in an SPR, which it doesn't. - */ - if (unaligned_fixup == 0) { - siginfo_t info = { - .si_signo = SIGBUS, - .si_code = BUS_ADRALN, - .si_addr = addr - }; - trace_unhandled_signal("unaligned trap", regs, - (unsigned long)addr, SIGBUS); - force_sig_info(info.si_signo, &info, current); - return (tilepro_bundle_bits) 0; - } - #ifndef __LITTLE_ENDIAN # error We assume little-endian representation with copy_xx_user size 2 here #endif @@ -211,6 +192,18 @@ static tile_bundle_bits rewrite_load_store_unaligned( return (tile_bundle_bits) 0; } + if (unaligned_fixup == 0) { + siginfo_t info = { + .si_signo = SIGBUS, + .si_code = BUS_ADRALN, + .si_addr = addr + }; + trace_unhandled_signal("unaligned trap", regs, + (unsigned long)addr, SIGBUS); + force_sig_info(info.si_signo, &info, current); + return (tile_bundle_bits) 0; + } + if (unaligned_printk || unaligned_fixup_count == 0) { pr_info("Process %d/%s: PC %#lx: Fixup of" " unaligned %s at %#lx.\n", @@ -346,10 +339,12 @@ void single_step_once(struct pt_regs *regs) } /* allocate a cache line of writable, executable memory */ - buffer = (void __user *) vm_mmap(NULL, 0, 64, + down_write(¤t->mm->mmap_sem); + buffer = (void __user *) do_mmap(NULL, 0, 64, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0); + up_write(¤t->mm->mmap_sem); if (IS_ERR((void __force *)buffer)) { kfree(state); diff --git a/trunk/arch/tile/kernel/smp.c b/trunk/arch/tile/kernel/smp.c index 91da0f721958..a44e103c5a63 100644 --- a/trunk/arch/tile/kernel/smp.c +++ b/trunk/arch/tile/kernel/smp.c @@ -103,7 +103,7 @@ static void smp_stop_cpu_interrupt(void) set_cpu_online(smp_processor_id(), 0); arch_local_irq_disable_all(); for (;;) - asm("nap; nop"); + asm("nap"); } /* This function calls the 'stop' function on all other CPUs in the system. */ @@ -113,12 +113,6 @@ void smp_send_stop(void) send_IPI_allbutself(MSG_TAG_STOP_CPU); } -/* On panic, just wait; we may get an smp_send_stop() later on. */ -void panic_smp_self_stop(void) -{ - while (1) - asm("nap; nop"); -} /* * Dispatch code called from hv_message_intr() for HV_MSG_TILE hv messages. diff --git a/trunk/arch/tile/kernel/smpboot.c b/trunk/arch/tile/kernel/smpboot.c index 172aef7d3159..b949edcec200 100644 --- a/trunk/arch/tile/kernel/smpboot.c +++ b/trunk/arch/tile/kernel/smpboot.c @@ -196,8 +196,6 @@ void __cpuinit online_secondary(void) /* This must be done before setting cpu_online_mask */ wmb(); - notify_cpu_starting(smp_processor_id()); - /* * We need to hold call_lock, so there is no inconsistency * between the time smp_call_function() determines number of diff --git a/trunk/arch/tile/kernel/stack.c b/trunk/arch/tile/kernel/stack.c index b2f44c28dda6..37ee4d037e0b 100644 --- a/trunk/arch/tile/kernel/stack.c +++ b/trunk/arch/tile/kernel/stack.c @@ -21,12 +21,10 @@ #include #include #include -#include -#include #include #include +#include #include -#include #include #include #include @@ -46,23 +44,72 @@ static int in_kernel_stack(struct KBacktraceIterator *kbt, unsigned long sp) return sp >= kstack_base && sp < kstack_base + THREAD_SIZE; } +/* Is address valid for reading? */ +static int valid_address(struct KBacktraceIterator *kbt, unsigned long address) +{ + HV_PTE *l1_pgtable = kbt->pgtable; + HV_PTE *l2_pgtable; + unsigned long pfn; + HV_PTE pte; + struct page *page; + + if (l1_pgtable == NULL) + return 0; /* can't read user space in other tasks */ + +#ifdef CONFIG_64BIT + /* Find the real l1_pgtable by looking in the l0_pgtable. */ + pte = l1_pgtable[HV_L0_INDEX(address)]; + if (!hv_pte_get_present(pte)) + return 0; + pfn = hv_pte_get_pfn(pte); + if (pte_huge(pte)) { + if (!pfn_valid(pfn)) { + pr_err("L0 huge page has bad pfn %#lx\n", pfn); + return 0; + } + return hv_pte_get_present(pte) && hv_pte_get_readable(pte); + } + page = pfn_to_page(pfn); + BUG_ON(PageHighMem(page)); /* No HIGHMEM on 64-bit. */ + l1_pgtable = (HV_PTE *)pfn_to_kaddr(pfn); +#endif + pte = l1_pgtable[HV_L1_INDEX(address)]; + if (!hv_pte_get_present(pte)) + return 0; + pfn = hv_pte_get_pfn(pte); + if (pte_huge(pte)) { + if (!pfn_valid(pfn)) { + pr_err("huge page has bad pfn %#lx\n", pfn); + return 0; + } + return hv_pte_get_present(pte) && hv_pte_get_readable(pte); + } + + page = pfn_to_page(pfn); + if (PageHighMem(page)) { + pr_err("L2 page table not in LOWMEM (%#llx)\n", + HV_PFN_TO_CPA(pfn)); + return 0; + } + l2_pgtable = (HV_PTE *)pfn_to_kaddr(pfn); + pte = l2_pgtable[HV_L2_INDEX(address)]; + return hv_pte_get_present(pte) && hv_pte_get_readable(pte); +} + /* Callback for backtracer; basically a glorified memcpy */ static bool read_memory_func(void *result, unsigned long address, unsigned int size, void *vkbt) { int retval; struct KBacktraceIterator *kbt = (struct KBacktraceIterator *)vkbt; - - if (address == 0) - return 0; if (__kernel_text_address(address)) { /* OK to read kernel code. */ } else if (address >= PAGE_OFFSET) { /* We only tolerate kernel-space reads of this task's stack */ if (!in_kernel_stack(kbt, address)) return 0; - } else if (!kbt->is_current) { - return 0; /* can't read from other user address spaces */ + } else if (!valid_address(kbt, address)) { + return 0; /* invalid user-space address */ } pagefault_disable(); retval = __copy_from_user_inatomic(result, @@ -80,8 +127,6 @@ static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt) unsigned long sp = kbt->it.sp; struct pt_regs *p; - if (sp % sizeof(long) != 0) - return NULL; if (!in_kernel_stack(kbt, sp)) return NULL; if (!in_kernel_stack(kbt, sp + C_ABI_SAVE_AREA_SIZE + PTREGS_SIZE-1)) @@ -124,27 +169,27 @@ static int is_sigreturn(unsigned long pc) } /* Return a pt_regs pointer for a valid signal handler frame */ -static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt, - struct rt_sigframe* kframe) +static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt) { BacktraceIterator *b = &kbt->it; - if (b->pc == VDSO_BASE && b->sp < PAGE_OFFSET && - b->sp % sizeof(long) == 0) { - int retval; - pagefault_disable(); - retval = __copy_from_user_inatomic( - kframe, (void __user __force *)b->sp, - sizeof(*kframe)); - pagefault_enable(); - if (retval != 0 || - (unsigned int)(kframe->info.si_signo) >= _NSIG) + if (b->pc == VDSO_BASE) { + struct rt_sigframe *frame; + unsigned long sigframe_top = + b->sp + sizeof(struct rt_sigframe) - 1; + if (!valid_address(kbt, b->sp) || + !valid_address(kbt, sigframe_top)) { + if (kbt->verbose) + pr_err(" (odd signal: sp %#lx?)\n", + (unsigned long)(b->sp)); return NULL; + } + frame = (struct rt_sigframe *)b->sp; if (kbt->verbose) { pr_err(" \n", - kframe->info.si_signo); + frame->info.si_signo); } - return (struct pt_regs *)&kframe->uc.uc_mcontext; + return (struct pt_regs *)&frame->uc.uc_mcontext; } return NULL; } @@ -157,11 +202,10 @@ static int KBacktraceIterator_is_sigreturn(struct KBacktraceIterator *kbt) static int KBacktraceIterator_restart(struct KBacktraceIterator *kbt) { struct pt_regs *p; - struct rt_sigframe kframe; p = valid_fault_handler(kbt); if (p == NULL) - p = valid_sigframe(kbt, &kframe); + p = valid_sigframe(kbt); if (p == NULL) return 0; backtrace_init(&kbt->it, read_memory_func, kbt, @@ -221,19 +265,41 @@ void KBacktraceIterator_init(struct KBacktraceIterator *kbt, /* * Set up callback information. We grab the kernel stack base - * so we will allow reads of that address range. + * so we will allow reads of that address range, and if we're + * asking about the current process we grab the page table + * so we can check user accesses before trying to read them. + * We flush the TLB to avoid any weird skew issues. */ - is_current = (t == NULL || t == current); + is_current = (t == NULL); kbt->is_current = is_current; if (is_current) t = validate_current(); kbt->task = t; + kbt->pgtable = NULL; kbt->verbose = 0; /* override in caller if desired */ kbt->profile = 0; /* override in caller if desired */ kbt->end = KBT_ONGOING; - kbt->new_context = 1; - if (is_current) + kbt->new_context = 0; + if (is_current) { + HV_PhysAddr pgdir_pa = hv_inquire_context().page_table; + if (pgdir_pa == (unsigned long)swapper_pg_dir - PAGE_OFFSET) { + /* + * Not just an optimization: this also allows + * this to work at all before va/pa mappings + * are set up. + */ + kbt->pgtable = swapper_pg_dir; + } else { + struct page *page = pfn_to_page(PFN_DOWN(pgdir_pa)); + if (!PageHighMem(page)) + kbt->pgtable = __va(pgdir_pa); + else + pr_err("page table not in LOWMEM" + " (%#llx)\n", pgdir_pa); + } + local_flush_tlb_all(); validate_stack(regs); + } if (regs == NULL) { if (is_current || t->state == TASK_RUNNING) { @@ -279,78 +345,6 @@ void KBacktraceIterator_next(struct KBacktraceIterator *kbt) } EXPORT_SYMBOL(KBacktraceIterator_next); -static void describe_addr(struct KBacktraceIterator *kbt, - unsigned long address, - int have_mmap_sem, char *buf, size_t bufsize) -{ - struct vm_area_struct *vma; - size_t namelen, remaining; - unsigned long size, offset, adjust; - char *p, *modname; - const char *name; - int rc; - - /* - * Look one byte back for every caller frame (i.e. those that - * aren't a new context) so we look up symbol data for the - * call itself, not the following instruction, which may be on - * a different line (or in a different function). - */ - adjust = !kbt->new_context; - address -= adjust; - - if (address >= PAGE_OFFSET) { - /* Handle kernel symbols. */ - BUG_ON(bufsize < KSYM_NAME_LEN); - name = kallsyms_lookup(address, &size, &offset, - &modname, buf); - if (name == NULL) { - buf[0] = '\0'; - return; - } - namelen = strlen(buf); - remaining = (bufsize - 1) - namelen; - p = buf + namelen; - rc = snprintf(p, remaining, "+%#lx/%#lx ", - offset + adjust, size); - if (modname && rc < remaining) - snprintf(p + rc, remaining - rc, "[%s] ", modname); - buf[bufsize-1] = '\0'; - return; - } - - /* If we don't have the mmap_sem, we can't show any more info. */ - buf[0] = '\0'; - if (!have_mmap_sem) - return; - - /* Find vma info. */ - vma = find_vma(kbt->task->mm, address); - if (vma == NULL || address < vma->vm_start) { - snprintf(buf, bufsize, "[unmapped address] "); - return; - } - - if (vma->vm_file) { - char *s; - p = d_path(&vma->vm_file->f_path, buf, bufsize); - if (IS_ERR(p)) - p = "?"; - s = strrchr(p, '/'); - if (s) - p = s+1; - } else { - p = "anon"; - } - - /* Generate a string description of the vma info. */ - namelen = strlen(p); - remaining = (bufsize - 1) - namelen; - memmove(buf, p, namelen); - snprintf(buf + namelen, remaining, "[%lx+%lx] ", - vma->vm_start, vma->vm_end - vma->vm_start); -} - /* * This method wraps the backtracer's more generic support. * It is only invoked from the architecture-specific code; show_stack() @@ -359,7 +353,6 @@ static void describe_addr(struct KBacktraceIterator *kbt, void tile_show_stack(struct KBacktraceIterator *kbt, int headers) { int i; - int have_mmap_sem = 0; if (headers) { /* @@ -376,16 +369,31 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers) kbt->verbose = 1; i = 0; for (; !KBacktraceIterator_end(kbt); KBacktraceIterator_next(kbt)) { - char namebuf[KSYM_NAME_LEN+100]; + char *modname; + const char *name; unsigned long address = kbt->it.pc; + unsigned long offset, size; + char namebuf[KSYM_NAME_LEN+100]; - /* Try to acquire the mmap_sem as we pass into userspace. */ - if (address < PAGE_OFFSET && !have_mmap_sem && kbt->task->mm) - have_mmap_sem = - down_read_trylock(&kbt->task->mm->mmap_sem); - - describe_addr(kbt, address, have_mmap_sem, - namebuf, sizeof(namebuf)); + if (address >= PAGE_OFFSET) + name = kallsyms_lookup(address, &size, &offset, + &modname, namebuf); + else + name = NULL; + + if (!name) + namebuf[0] = '\0'; + else { + size_t namelen = strlen(namebuf); + size_t remaining = (sizeof(namebuf) - 1) - namelen; + char *p = namebuf + namelen; + int rc = snprintf(p, remaining, "+%#lx/%#lx ", + offset, size); + if (modname && rc < remaining) + snprintf(p + rc, remaining - rc, + "[%s] ", modname); + namebuf[sizeof(namebuf)-1] = '\0'; + } pr_err(" frame %d: 0x%lx %s(sp 0x%lx)\n", i++, address, namebuf, (unsigned long)(kbt->it.sp)); @@ -400,8 +408,6 @@ void tile_show_stack(struct KBacktraceIterator *kbt, int headers) pr_err("Stack dump stopped; next frame identical to this one\n"); if (headers) pr_err("Stack dump complete\n"); - if (have_mmap_sem) - up_read(&kbt->task->mm->mmap_sem); } EXPORT_SYMBOL(tile_show_stack); diff --git a/trunk/arch/tile/kernel/traps.c b/trunk/arch/tile/kernel/traps.c index 73cff814ac57..2bb6602a1ee7 100644 --- a/trunk/arch/tile/kernel/traps.c +++ b/trunk/arch/tile/kernel/traps.c @@ -200,7 +200,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, { siginfo_t info = { 0 }; int signo, code; - unsigned long address = 0; + unsigned long address; bundle_bits instr; /* Re-enable interrupts. */ @@ -223,10 +223,6 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, } switch (fault_num) { - case INT_MEM_ERROR: - signo = SIGBUS; - code = BUS_OBJERR; - break; case INT_ILL: if (copy_from_user(&instr, (void __user *)regs->pc, sizeof(instr))) { @@ -293,10 +289,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, address = regs->pc; break; #ifdef __tilegx__ - case INT_ILL_TRANS: { - /* Avoid a hardware erratum with the return address stack. */ - fill_ra_stack(); - + case INT_ILL_TRANS: signo = SIGSEGV; code = SEGV_MAPERR; if (reason & SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK) @@ -304,7 +297,6 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, else address = 0; /* FIXME: GX: single-step for address */ break; - } #endif default: panic("Unexpected do_trap interrupt number %d", fault_num); @@ -316,8 +308,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, info.si_addr = (void __user *)address; if (signo == SIGILL) info.si_trapno = fault_num; - if (signo != SIGTRAP) - trace_unhandled_signal("trap", regs, address, signo); + trace_unhandled_signal("trap", regs, address, signo); force_sig_info(signo, &info, current); } diff --git a/trunk/arch/tile/lib/Makefile b/trunk/arch/tile/lib/Makefile index 985f59858234..0c26086ecbef 100644 --- a/trunk/arch/tile/lib/Makefile +++ b/trunk/arch/tile/lib/Makefile @@ -7,7 +7,6 @@ lib-y = cacheflush.o checksum.o cpumask.o delay.o uaccess.o \ strchr_$(BITS).o strlen_$(BITS).o ifeq ($(CONFIG_TILEGX),y) -CFLAGS_REMOVE_memcpy_user_64.o = -fno-omit-frame-pointer lib-y += memcpy_user_64.o else lib-y += atomic_32.o atomic_asm_32.o memcpy_tile64.o diff --git a/trunk/arch/tile/lib/cacheflush.c b/trunk/arch/tile/lib/cacheflush.c index db4fb89e12d8..8928aace7a64 100644 --- a/trunk/arch/tile/lib/cacheflush.c +++ b/trunk/arch/tile/lib/cacheflush.c @@ -39,21 +39,7 @@ void finv_buffer_remote(void *buffer, size_t size, int hfh) { char *p, *base; size_t step_size, load_count; - - /* - * On TILEPro the striping granularity is a fixed 8KB; on - * TILE-Gx it is configurable, and we rely on the fact that - * the hypervisor always configures maximum striping, so that - * bits 9 and 10 of the PA are part of the stripe function, so - * every 512 bytes we hit a striping boundary. - * - */ -#ifdef __tilegx__ - const unsigned long STRIPE_WIDTH = 512; -#else const unsigned long STRIPE_WIDTH = 8192; -#endif - #ifdef __tilegx__ /* * On TILE-Gx, we must disable the dstream prefetcher before doing @@ -88,7 +74,7 @@ void finv_buffer_remote(void *buffer, size_t size, int hfh) * memory, that one load would be sufficient, but since we may * be, we also need to back up to the last load issued to * another memory controller, which would be the point where - * we crossed a "striping" boundary (the granularity of striping + * we crossed an 8KB boundary (the granularity of striping * across memory controllers). Keep backing up and doing this * until we are before the beginning of the buffer, or have * hit all the controllers. @@ -102,22 +88,12 @@ void finv_buffer_remote(void *buffer, size_t size, int hfh) * every cache line on a full memory stripe on each * controller" that we simply do that, to simplify the logic. * - * On TILE-Gx the hash-for-home function is much more complex, - * with the upshot being we can't readily guarantee we have - * hit both entries in the 128-entry AMT that were hit by any - * load in the entire range, so we just re-load them all. - * With larger buffers, we may want to consider using a hypervisor - * trap to issue loads directly to each hash-for-home tile for - * each controller (doing it from Linux would trash the TLB). + * FIXME: See bug 9535 for some issues with this code. */ if (hfh) { step_size = L2_CACHE_BYTES; -#ifdef __tilegx__ - load_count = (size + L2_CACHE_BYTES - 1) / L2_CACHE_BYTES; -#else load_count = (STRIPE_WIDTH / L2_CACHE_BYTES) * (1 << CHIP_LOG_NUM_MSHIMS()); -#endif } else { step_size = STRIPE_WIDTH; load_count = (1 << CHIP_LOG_NUM_MSHIMS()); @@ -133,7 +109,7 @@ void finv_buffer_remote(void *buffer, size_t size, int hfh) /* Figure out how far back we need to go. */ base = p - (step_size * (load_count - 2)); - if ((unsigned long)base < (unsigned long)buffer) + if ((long)base < (long)buffer) base = buffer; /* diff --git a/trunk/arch/tile/lib/memcpy_user_64.c b/trunk/arch/tile/lib/memcpy_user_64.c index 37440caa7370..4763b3aff1cc 100644 --- a/trunk/arch/tile/lib/memcpy_user_64.c +++ b/trunk/arch/tile/lib/memcpy_user_64.c @@ -14,13 +14,7 @@ * Do memcpy(), but trap and return "n" when a load or store faults. * * Note: this idiom only works when memcpy() compiles to a leaf function. - * Here leaf function not only means it does not have calls, but also - * requires no stack operations (sp, stack frame pointer) and no - * use of callee-saved registers, else "jrp lr" will be incorrect since - * unwinding stack frame is bypassed. Since memcpy() is not complex so - * these conditions are satisfied here, but we need to be careful when - * modifying this file. This is not a clean solution but is the best - * one so far. + * If "sp" is updated during memcpy, the "jrp lr" will be incorrect. * * Also note that we are capturing "n" from the containing scope here. */ diff --git a/trunk/arch/tile/lib/spinlock_common.h b/trunk/arch/tile/lib/spinlock_common.h index 6ac37509faca..c10109809132 100644 --- a/trunk/arch/tile/lib/spinlock_common.h +++ b/trunk/arch/tile/lib/spinlock_common.h @@ -60,5 +60,5 @@ static void delay_backoff(int iterations) loops += __insn_crc32_32(stack_pointer, get_cycles_low()) & (loops - 1); - relax(loops); + relax(1 << exponent); } diff --git a/trunk/arch/tile/mm/fault.c b/trunk/arch/tile/mm/fault.c index 22e58f51ed23..cba30e9547b4 100644 --- a/trunk/arch/tile/mm/fault.c +++ b/trunk/arch/tile/mm/fault.c @@ -130,7 +130,7 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) } /* - * Handle a fault on the vmalloc area. + * Handle a fault on the vmalloc or module mapping area */ static inline int vmalloc_fault(pgd_t *pgd, unsigned long address) { @@ -203,14 +203,9 @@ static pgd_t *get_current_pgd(void) * interrupt or a critical region, and must do as little as possible. * Similarly, we can't use atomic ops here, since we may be handling a * fault caused by an atomic op access. - * - * If we find a migrating PTE while we're in an NMI context, and we're - * at a PC that has a registered exception handler, we don't wait, - * since this thread may (e.g.) have been interrupted while migrating - * its own stack, which would then cause us to self-deadlock. */ static int handle_migrating_pte(pgd_t *pgd, int fault_num, - unsigned long address, unsigned long pc, + unsigned long address, int is_kernel_mode, int write) { pud_t *pud; @@ -232,8 +227,6 @@ static int handle_migrating_pte(pgd_t *pgd, int fault_num, pte_offset_kernel(pmd, address); pteval = *pte; if (pte_migrating(pteval)) { - if (in_nmi() && search_exception_tables(pc)) - return 0; wait_for_migration(pte); return 1; } @@ -307,7 +300,7 @@ static int handle_page_fault(struct pt_regs *regs, * rather than trying to patch up the existing PTE. */ pgd = get_current_pgd(); - if (handle_migrating_pte(pgd, fault_num, address, regs->pc, + if (handle_migrating_pte(pgd, fault_num, address, is_kernel_mode, write)) return 1; @@ -342,12 +335,9 @@ static int handle_page_fault(struct pt_regs *regs, /* * If we're trying to touch user-space addresses, we must * be either at PL0, or else with interrupts enabled in the - * kernel, so either way we can re-enable interrupts here - * unless we are doing atomic access to user space with - * interrupts disabled. + * kernel, so either way we can re-enable interrupts here. */ - if (!(regs->flags & PT_FLAGS_DISABLE_IRQ)) - local_irq_enable(); + local_irq_enable(); mm = tsk->mm; @@ -675,7 +665,7 @@ struct intvec_state do_page_fault_ics(struct pt_regs *regs, int fault_num, */ if (fault_num == INT_DTLB_ACCESS) write = 1; - if (handle_migrating_pte(pgd, fault_num, address, pc, 1, write)) + if (handle_migrating_pte(pgd, fault_num, address, 1, write)) return state; /* Return zero so that we continue on with normal fault handling. */ diff --git a/trunk/arch/tile/mm/homecache.c b/trunk/arch/tile/mm/homecache.c index 499f73770b05..1cc6ae477c98 100644 --- a/trunk/arch/tile/mm/homecache.c +++ b/trunk/arch/tile/mm/homecache.c @@ -394,7 +394,6 @@ int page_home(struct page *page) return pte_to_home(*virt_to_pte(NULL, kva)); } } -EXPORT_SYMBOL(page_home); void homecache_change_page_home(struct page *page, int order, int home) { diff --git a/trunk/arch/tile/mm/init.c b/trunk/arch/tile/mm/init.c index 6a9d20ddc34f..830c4908ea76 100644 --- a/trunk/arch/tile/mm/init.c +++ b/trunk/arch/tile/mm/init.c @@ -254,6 +254,11 @@ static pgprot_t __init init_pgprot(ulong address) return construct_pgprot(PAGE_KERNEL_RO, PAGE_HOME_IMMUTABLE); } + /* As a performance optimization, keep the boot init stack here. */ + if (address >= (ulong)&init_thread_union && + address < (ulong)&init_thread_union + THREAD_SIZE) + return construct_pgprot(PAGE_KERNEL, smp_processor_id()); + #ifndef __tilegx__ #if !ATOMIC_LOCKS_FOUND_VIA_TABLE() /* Force the atomic_locks[] array page to be hash-for-home. */ @@ -552,7 +557,6 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base) address = MEM_SV_INTRPT; pmd = get_pmd(pgtables, address); - pfn = 0; /* code starts at PA 0 */ if (ktext_small) { /* Allocate an L2 PTE for the kernel text */ int cpu = 0; @@ -575,15 +579,10 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base) } BUG_ON(address != (unsigned long)_stext); - pte = NULL; - for (; address < (unsigned long)_einittext; - pfn++, address += PAGE_SIZE) { - pte_ofs = pte_index(address); - if (pte_ofs == 0) { - if (pte) - assign_pte(pmd++, pte); - pte = alloc_pte(); - } + pfn = 0; /* code starts at PA 0 */ + pte = alloc_pte(); + for (pte_ofs = 0; address < (unsigned long)_einittext; + pfn++, pte_ofs++, address += PAGE_SIZE) { if (!ktext_local) { prot = set_remote_cache_cpu(prot, cpu); cpu = cpumask_next(cpu, &ktext_mask); @@ -592,8 +591,7 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base) } pte[pte_ofs] = pfn_pte(pfn, prot); } - if (pte) - assign_pte(pmd, pte); + assign_pte(pmd, pte); } else { pte_t pteval = pfn_pte(0, PAGE_KERNEL_EXEC); pteval = pte_mkhuge(pteval); @@ -616,9 +614,7 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base) else pteval = hv_pte_set_mode(pteval, HV_PTE_MODE_CACHE_NO_L3); - for (; address < (unsigned long)_einittext; - pfn += PFN_DOWN(HPAGE_SIZE), address += HPAGE_SIZE) - *(pte_t *)(pmd++) = pfn_pte(pfn, pteval); + *(pte_t *)pmd = pteval; } /* Set swapper_pgprot here so it is flushed to memory right away. */ diff --git a/trunk/arch/tile/mm/pgtable.c b/trunk/arch/tile/mm/pgtable.c index 2410aa899b3e..87303693a072 100644 --- a/trunk/arch/tile/mm/pgtable.c +++ b/trunk/arch/tile/mm/pgtable.c @@ -177,10 +177,14 @@ void shatter_huge_page(unsigned long addr) if (!pmd_huge_page(*pmd)) return; - spin_lock_irqsave(&init_mm.page_table_lock, flags); + /* + * Grab the pgd_lock, since we may need it to walk the pgd_list, + * and since we need some kind of lock here to avoid races. + */ + spin_lock_irqsave(&pgd_lock, flags); if (!pmd_huge_page(*pmd)) { /* Lost the race to convert the huge page. */ - spin_unlock_irqrestore(&init_mm.page_table_lock, flags); + spin_unlock_irqrestore(&pgd_lock, flags); return; } @@ -190,7 +194,6 @@ void shatter_huge_page(unsigned long addr) #ifdef __PAGETABLE_PMD_FOLDED /* Walk every pgd on the system and update the pmd there. */ - spin_lock(&pgd_lock); list_for_each(pos, &pgd_list) { pmd_t *copy_pmd; pgd = list_to_pgd(pos) + pgd_index(addr); @@ -198,7 +201,6 @@ void shatter_huge_page(unsigned long addr) copy_pmd = pmd_offset(pud, addr); __set_pmd(copy_pmd, *pmd); } - spin_unlock(&pgd_lock); #endif /* Tell every cpu to notice the change. */ @@ -206,7 +208,7 @@ void shatter_huge_page(unsigned long addr) cpu_possible_mask, NULL, 0); /* Hold the lock until the TLB flush is finished to avoid races. */ - spin_unlock_irqrestore(&init_mm.page_table_lock, flags); + spin_unlock_irqrestore(&pgd_lock, flags); } /* @@ -215,13 +217,9 @@ void shatter_huge_page(unsigned long addr) * against pageattr.c; it is the unique case in which a valid change * of kernel pagetables can't be lazily synchronized by vmalloc faults. * vmalloc faults work because attached pagetables are never freed. - * - * The lock is always taken with interrupts disabled, unlike on x86 - * and other platforms, because we need to take the lock in - * shatter_huge_page(), which may be called from an interrupt context. - * We are not at risk from the tlbflush IPI deadlock that was seen on - * x86, since we use the flush_remote() API to have the hypervisor do - * the TLB flushes regardless of irq disabling. + * The locking scheme was chosen on the basis of manfred's + * recommendations and having no core impact whatsoever. + * -- wli */ DEFINE_SPINLOCK(pgd_lock); LIST_HEAD(pgd_list); @@ -471,18 +469,10 @@ void __set_pte(pte_t *ptep, pte_t pte) void set_pte(pte_t *ptep, pte_t pte) { - if (pte_present(pte) && - (!CHIP_HAS_MMIO() || hv_pte_get_mode(pte) != HV_PTE_MODE_MMIO)) { - /* The PTE actually references physical memory. */ - unsigned long pfn = pte_pfn(pte); - if (pfn_valid(pfn)) { - /* Update the home of the PTE from the struct page. */ - pte = pte_set_home(pte, page_home(pfn_to_page(pfn))); - } else if (hv_pte_get_mode(pte) == 0) { - /* remap_pfn_range(), etc, must supply PTE mode. */ - panic("set_pte(): out-of-range PFN and mode 0\n"); - } - } + struct page *page = pfn_to_page(pte_pfn(pte)); + + /* Update the home of a PTE if necessary */ + pte = pte_set_home(pte, page_home(page)); __set_pte(ptep, pte); } diff --git a/trunk/arch/um/drivers/cow.h b/trunk/arch/um/drivers/cow.h index 6673508f3426..dc36b222100b 100644 --- a/trunk/arch/um/drivers/cow.h +++ b/trunk/arch/um/drivers/cow.h @@ -3,6 +3,41 @@ #include +#if defined(__KERNEL__) + +# include + +# if defined(__BIG_ENDIAN) +# define ntohll(x) (x) +# define htonll(x) (x) +# elif defined(__LITTLE_ENDIAN) +# define ntohll(x) be64_to_cpu(x) +# define htonll(x) cpu_to_be64(x) +# else +# error "Could not determine byte order" +# endif + +#else +/* For the definition of ntohl, htonl and __BYTE_ORDER */ +#include +#include +#if defined(__BYTE_ORDER) + +# if __BYTE_ORDER == __BIG_ENDIAN +# define ntohll(x) (x) +# define htonll(x) (x) +# elif __BYTE_ORDER == __LITTLE_ENDIAN +# define ntohll(x) bswap_64(x) +# define htonll(x) bswap_64(x) +# else +# error "Could not determine byte order: __BYTE_ORDER uncorrectly defined" +# endif + +#else /* ! defined(__BYTE_ORDER) */ +# error "Could not determine byte order: __BYTE_ORDER not defined" +#endif +#endif /* ! defined(__KERNEL__) */ + extern int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize, int alignment, int *bitmap_offset_out, unsigned long *bitmap_len_out, int *data_offset_out); diff --git a/trunk/arch/um/drivers/cow_user.c b/trunk/arch/um/drivers/cow_user.c index 0ee9cc6cc4c7..9cbb426c0b91 100644 --- a/trunk/arch/um/drivers/cow_user.c +++ b/trunk/arch/um/drivers/cow_user.c @@ -8,10 +8,11 @@ * that. */ #include +#include #include #include #include -#include +#include #include "cow.h" #include "cow_sys.h" @@ -213,8 +214,8 @@ int write_cow_header(char *cow_file, int fd, char *backing_file, "header\n"); goto out; } - header->magic = htobe32(COW_MAGIC); - header->version = htobe32(COW_VERSION); + header->magic = htonl(COW_MAGIC); + header->version = htonl(COW_VERSION); err = -EINVAL; if (strlen(backing_file) > sizeof(header->backing_file) - 1) { @@ -245,10 +246,10 @@ int write_cow_header(char *cow_file, int fd, char *backing_file, goto out_free; } - header->mtime = htobe32(modtime); - header->size = htobe64(*size); - header->sectorsize = htobe32(sectorsize); - header->alignment = htobe32(alignment); + header->mtime = htonl(modtime); + header->size = htonll(*size); + header->sectorsize = htonl(sectorsize); + header->alignment = htonl(alignment); header->cow_format = COW_BITMAP; err = cow_write_file(fd, header, sizeof(*header)); @@ -300,8 +301,8 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, magic = header->v1.magic; if (magic == COW_MAGIC) version = header->v1.version; - else if (magic == be32toh(COW_MAGIC)) - version = be32toh(header->v1.version); + else if (magic == ntohl(COW_MAGIC)) + version = ntohl(header->v1.version); /* No error printed because the non-COW case comes through here */ else goto out; @@ -326,9 +327,9 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, "header\n"); goto out; } - *mtime_out = be32toh(header->v2.mtime); - *size_out = be64toh(header->v2.size); - *sectorsize_out = be32toh(header->v2.sectorsize); + *mtime_out = ntohl(header->v2.mtime); + *size_out = ntohll(header->v2.size); + *sectorsize_out = ntohl(header->v2.sectorsize); *bitmap_offset_out = sizeof(header->v2); *align_out = *sectorsize_out; file = header->v2.backing_file; @@ -340,10 +341,10 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, "header\n"); goto out; } - *mtime_out = be32toh(header->v3.mtime); - *size_out = be64toh(header->v3.size); - *sectorsize_out = be32toh(header->v3.sectorsize); - *align_out = be32toh(header->v3.alignment); + *mtime_out = ntohl(header->v3.mtime); + *size_out = ntohll(header->v3.size); + *sectorsize_out = ntohl(header->v3.sectorsize); + *align_out = ntohl(header->v3.alignment); if (*align_out == 0) { cow_printf("read_cow_header - invalid COW header, " "align == 0\n"); @@ -365,16 +366,16 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, * this was used until Dec2005 - 64bits are needed to represent * 2038+. I.e. we can safely do this truncating cast. * - * Additionally, we must use be32toh() instead of be64toh(), since + * Additionally, we must use ntohl() instead of ntohll(), since * the program used to use the former (tested - I got mtime * mismatch "0 vs whatever"). * * Ever heard about bug-to-bug-compatibility ? ;-) */ - *mtime_out = (time32_t) be32toh(header->v3_b.mtime); + *mtime_out = (time32_t) ntohl(header->v3_b.mtime); - *size_out = be64toh(header->v3_b.size); - *sectorsize_out = be32toh(header->v3_b.sectorsize); - *align_out = be32toh(header->v3_b.alignment); + *size_out = ntohll(header->v3_b.size); + *sectorsize_out = ntohl(header->v3_b.sectorsize); + *align_out = ntohl(header->v3_b.alignment); if (*align_out == 0) { cow_printf("read_cow_header - invalid COW header, " "align == 0\n"); diff --git a/trunk/arch/um/drivers/mconsole_kern.c b/trunk/arch/um/drivers/mconsole_kern.c index 43b39d61b538..e672bd6d43e3 100644 --- a/trunk/arch/um/drivers/mconsole_kern.c +++ b/trunk/arch/um/drivers/mconsole_kern.c @@ -22,7 +22,6 @@ #include #include #include -#include #include "init.h" #include "irq_kern.h" diff --git a/trunk/arch/um/include/asm/Kbuild b/trunk/arch/um/include/asm/Kbuild index fff24352255d..8419f5cf2ac7 100644 --- a/trunk/arch/um/include/asm/Kbuild +++ b/trunk/arch/um/include/asm/Kbuild @@ -1,4 +1,3 @@ generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h -generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h -generic-y += switch_to.h +generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h diff --git a/trunk/arch/um/kernel/Makefile b/trunk/arch/um/kernel/Makefile index 65a1c3d690ea..492bc4c1b62b 100644 --- a/trunk/arch/um/kernel/Makefile +++ b/trunk/arch/um/kernel/Makefile @@ -3,10 +3,9 @@ # Licensed under the GPL # -CPPFLAGS_vmlinux.lds := -DSTART=$(LDS_START) \ - -DELF_ARCH=$(LDS_ELF_ARCH) \ - -DELF_FORMAT=$(LDS_ELF_FORMAT) \ - $(LDS_EXTRA) +CPPFLAGS_vmlinux.lds := -DSTART=$(LDS_START) \ + -DELF_ARCH=$(LDS_ELF_ARCH) \ + -DELF_FORMAT=$(LDS_ELF_FORMAT) extra-y := vmlinux.lds clean-files := diff --git a/trunk/arch/um/kernel/process.c b/trunk/arch/um/kernel/process.c index 2b73dedb44ca..f386d04a84a5 100644 --- a/trunk/arch/um/kernel/process.c +++ b/trunk/arch/um/kernel/process.c @@ -88,8 +88,11 @@ static inline void set_current(struct task_struct *task) extern void arch_switch_to(struct task_struct *to); -void *__switch_to(struct task_struct *from, struct task_struct *to) +void *_switch_to(void *prev, void *next, void *last) { + struct task_struct *from = prev; + struct task_struct *to = next; + to->thread.prev_sched = from; set_current(to); @@ -108,6 +111,7 @@ void *__switch_to(struct task_struct *from, struct task_struct *to) } while (current->thread.saved_task); return current->thread.prev_sched; + } void interrupt_end(void) diff --git a/trunk/arch/um/kernel/skas/mmu.c b/trunk/arch/um/kernel/skas/mmu.c index 0a49ef0c2bf4..4947b319f53a 100644 --- a/trunk/arch/um/kernel/skas/mmu.c +++ b/trunk/arch/um/kernel/skas/mmu.c @@ -103,6 +103,7 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm) void uml_setup_stubs(struct mm_struct *mm) { + struct page **pages; int err, ret; if (!skas_needs_stub) diff --git a/trunk/arch/um/kernel/skas/process.c b/trunk/arch/um/kernel/skas/process.c index 0a9e57e7446b..2e9852c0d487 100644 --- a/trunk/arch/um/kernel/skas/process.c +++ b/trunk/arch/um/kernel/skas/process.c @@ -41,7 +41,7 @@ static int __init start_kernel_proc(void *unused) cpu_tasks[0].pid = pid; cpu_tasks[0].task = current; #ifdef CONFIG_SMP - init_cpu_online(get_cpu_mask(0)); + cpu_online_map = cpumask_of_cpu(0); #endif start_kernel(); return 0; diff --git a/trunk/arch/um/kernel/smp.c b/trunk/arch/um/kernel/smp.c index 6f588e160fb0..155206a66908 100644 --- a/trunk/arch/um/kernel/smp.c +++ b/trunk/arch/um/kernel/smp.c @@ -76,7 +76,7 @@ static int idle_proc(void *cpup) cpu_relax(); notify_cpu_starting(cpu); - set_cpu_online(cpu, true); + cpu_set(cpu, cpu_online_map); default_idle(); return 0; } @@ -110,7 +110,8 @@ void smp_prepare_cpus(unsigned int maxcpus) for (i = 0; i < ncpus; ++i) set_cpu_possible(i, true); - set_cpu_online(me, true); + cpu_clear(me, cpu_online_map); + cpu_set(me, cpu_online_map); cpu_set(me, cpu_callin_map); err = os_pipe(cpu_data[me].ipi_pipe, 1, 1); @@ -137,13 +138,13 @@ void smp_prepare_cpus(unsigned int maxcpus) void smp_prepare_boot_cpu(void) { - set_cpu_online(smp_processor_id(), true); + cpu_set(smp_processor_id(), cpu_online_map); } int __cpu_up(unsigned int cpu) { cpu_set(cpu, smp_commenced_mask); - while (!cpu_online(cpu)) + while (!cpu_isset(cpu, cpu_online_map)) mb(); return 0; } diff --git a/trunk/arch/unicore32/boot/Makefile b/trunk/arch/unicore32/boot/Makefile index ec7fb70b412b..79e5f88845d9 100644 --- a/trunk/arch/unicore32/boot/Makefile +++ b/trunk/arch/unicore32/boot/Makefile @@ -11,6 +11,8 @@ # Copyright (C) 2001~2010 GUAN Xue-tao # +MKIMAGE := $(srctree)/scripts/mkuboot.sh + targets := Image zImage uImage $(obj)/Image: vmlinux FORCE @@ -24,8 +26,14 @@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE $(call if_changed,objcopy) @echo ' Kernel: $@ is ready' -UIMAGE_ARCH = unicore -UIMAGE_LOADADDR = 0x0 +quiet_cmd_uimage = UIMAGE $@ + cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A unicore -O linux -T kernel \ + -C none -a $(LOADADDR) -e $(STARTADDR) \ + -n 'Linux-$(KERNELRELEASE)' -d $< $@ + +$(obj)/uImage: LOADADDR=0x0 + +$(obj)/uImage: STARTADDR=$(LOADADDR) $(obj)/uImage: $(obj)/zImage FORCE $(call if_changed,uimage) diff --git a/trunk/arch/unicore32/include/asm/dma-mapping.h b/trunk/arch/unicore32/include/asm/dma-mapping.h index 366460a81796..9258e592f414 100644 --- a/trunk/arch/unicore32/include/asm/dma-mapping.h +++ b/trunk/arch/unicore32/include/asm/dma-mapping.h @@ -82,26 +82,20 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) return 0; } -#define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) - -static inline void *dma_alloc_attrs(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag, - struct dma_attrs *attrs) +static inline void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) { struct dma_map_ops *dma_ops = get_dma_ops(dev); - return dma_ops->alloc(dev, size, dma_handle, flag, attrs); + return dma_ops->alloc_coherent(dev, size, dma_handle, flag); } -#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) - -static inline void dma_free_attrs(struct device *dev, size_t size, - void *cpu_addr, dma_addr_t dma_handle, - struct dma_attrs *attrs) +static inline void dma_free_coherent(struct device *dev, size_t size, + void *cpu_addr, dma_addr_t dma_handle) { struct dma_map_ops *dma_ops = get_dma_ops(dev); - dma_ops->free(dev, size, cpu_addr, dma_handle, attrs); + dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); } #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) diff --git a/trunk/arch/unicore32/mm/dma-swiotlb.c b/trunk/arch/unicore32/mm/dma-swiotlb.c index 16c08b2143a7..bfa9fbb2bbb1 100644 --- a/trunk/arch/unicore32/mm/dma-swiotlb.c +++ b/trunk/arch/unicore32/mm/dma-swiotlb.c @@ -17,23 +17,9 @@ #include -static void *unicore_swiotlb_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flags, - struct dma_attrs *attrs) -{ - return swiotlb_alloc_coherent(dev, size, dma_handle, flags); -} - -static void unicore_swiotlb_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_addr, - struct dma_attrs *attrs) -{ - swiotlb_free_coherent(dev, size, vaddr, dma_addr); -} - struct dma_map_ops swiotlb_dma_map_ops = { - .alloc = unicore_swiotlb_alloc_coherent, - .free = unicore_swiotlb_free_coherent, + .alloc_coherent = swiotlb_alloc_coherent, + .free_coherent = swiotlb_free_coherent, .map_sg = swiotlb_map_sg_attrs, .unmap_sg = swiotlb_unmap_sg_attrs, .dma_supported = swiotlb_dma_supported, diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index c9866b0b77d8..1d14cc6b79ad 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -81,7 +81,7 @@ config X86 select CLKEVT_I8253 select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_IOMAP - select DCACHE_WORD_ACCESS + select DCACHE_WORD_ACCESS if !DEBUG_PAGEALLOC config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS) diff --git a/trunk/arch/x86/Makefile b/trunk/arch/x86/Makefile index 41a7237606a3..968dbe24a255 100644 --- a/trunk/arch/x86/Makefile +++ b/trunk/arch/x86/Makefile @@ -129,7 +129,6 @@ KBUILD_CFLAGS += -Wno-sign-compare KBUILD_CFLAGS += -fno-asynchronous-unwind-tables # prevent gcc from generating any FP code by mistake KBUILD_CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) -KBUILD_CFLAGS += $(call cc-option,-mno-avx,) KBUILD_CFLAGS += $(mflags-y) KBUILD_AFLAGS += $(mflags-y) diff --git a/trunk/arch/x86/Makefile.um b/trunk/arch/x86/Makefile.um index 36b62bc52638..4be406abeefd 100644 --- a/trunk/arch/x86/Makefile.um +++ b/trunk/arch/x86/Makefile.um @@ -14,9 +14,6 @@ LINK-y += $(call cc-option,-m32) export LDFLAGS -LDS_EXTRA := -Ui386 -export LDS_EXTRA - # First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y. include $(srctree)/arch/x86/Makefile_32.cpu diff --git a/trunk/arch/x86/boot/compressed/head_32.S b/trunk/arch/x86/boot/compressed/head_32.S index c85e3ac99bba..a0559930a180 100644 --- a/trunk/arch/x86/boot/compressed/head_32.S +++ b/trunk/arch/x86/boot/compressed/head_32.S @@ -33,9 +33,6 @@ __HEAD ENTRY(startup_32) #ifdef CONFIG_EFI_STUB - jmp preferred_addr - - .balign 0x10 /* * We don't need the return address, so set up the stack so * efi_main() can find its arugments. @@ -44,17 +41,12 @@ ENTRY(startup_32) call efi_main cmpl $0, %eax + je preferred_addr movl %eax, %esi - jne 2f + call 1f 1: - /* EFI init failed, so hang. */ - hlt - jmp 1b -2: - call 3f -3: popl %eax - subl $3b, %eax + subl $1b, %eax subl BP_pref_address(%esi), %eax add BP_code32_start(%esi), %eax leal preferred_addr(%eax), %eax diff --git a/trunk/arch/x86/boot/compressed/head_64.S b/trunk/arch/x86/boot/compressed/head_64.S index 87e03a13d8e3..558d76ce23bc 100644 --- a/trunk/arch/x86/boot/compressed/head_64.S +++ b/trunk/arch/x86/boot/compressed/head_64.S @@ -200,28 +200,18 @@ ENTRY(startup_64) * entire text+data+bss and hopefully all of memory. */ #ifdef CONFIG_EFI_STUB - /* - * The entry point for the PE/COFF executable is 0x210, so only - * legacy boot loaders will execute this jmp. - */ - jmp preferred_addr - - .org 0x210 + pushq %rsi mov %rcx, %rdi mov %rdx, %rsi call efi_main - movq %rax,%rsi + popq %rsi cmpq $0,%rax - jne 2f + je preferred_addr + movq %rax,%rsi + call 1f 1: - /* EFI init failed, so hang. */ - hlt - jmp 1b -2: - call 3f -3: popq %rax - subq $3b, %rax + subq $1b, %rax subq BP_pref_address(%rsi), %rax add BP_code32_start(%esi), %eax leaq preferred_addr(%rax), %rax diff --git a/trunk/arch/x86/boot/compressed/relocs.c b/trunk/arch/x86/boot/compressed/relocs.c index fb7117a4ade1..d3c0b0277666 100644 --- a/trunk/arch/x86/boot/compressed/relocs.c +++ b/trunk/arch/x86/boot/compressed/relocs.c @@ -403,11 +403,13 @@ static void print_absolute_symbols(void) for (i = 0; i < ehdr.e_shnum; i++) { struct section *sec = &secs[i]; char *sym_strtab; + Elf32_Sym *sh_symtab; int j; if (sec->shdr.sh_type != SHT_SYMTAB) { continue; } + sh_symtab = sec->symtab; sym_strtab = sec->link->strtab; for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) { Elf32_Sym *sym; diff --git a/trunk/arch/x86/boot/tools/build.c b/trunk/arch/x86/boot/tools/build.c index 24443a332083..ed549767a231 100644 --- a/trunk/arch/x86/boot/tools/build.c +++ b/trunk/arch/x86/boot/tools/build.c @@ -205,13 +205,8 @@ int main(int argc, char ** argv) put_unaligned_le32(file_sz, &buf[pe_header + 0x50]); #ifdef CONFIG_X86_32 - /* - * Address of entry point. - * - * The EFI stub entry point is +16 bytes from the start of - * the .text section. - */ - put_unaligned_le32(i + 16, &buf[pe_header + 0x28]); + /* Address of entry point */ + put_unaligned_le32(i, &buf[pe_header + 0x28]); /* .text size */ put_unaligned_le32(file_sz, &buf[pe_header + 0xb0]); @@ -222,11 +217,9 @@ int main(int argc, char ** argv) /* * Address of entry point. startup_32 is at the beginning and * the 64-bit entry point (startup_64) is always 512 bytes - * after. The EFI stub entry point is 16 bytes after that, as - * the first instruction allows legacy loaders to jump over - * the EFI stub initialisation + * after. */ - put_unaligned_le32(i + 528, &buf[pe_header + 0x28]); + put_unaligned_le32(i + 512, &buf[pe_header + 0x28]); /* .text size */ put_unaligned_le32(file_sz, &buf[pe_header + 0xc0]); diff --git a/trunk/arch/x86/ia32/ia32_aout.c b/trunk/arch/x86/ia32/ia32_aout.c index 07b3a68d2d29..d511d951a052 100644 --- a/trunk/arch/x86/ia32/ia32_aout.c +++ b/trunk/arch/x86/ia32/ia32_aout.c @@ -119,7 +119,9 @@ static void set_brk(unsigned long start, unsigned long end) end = PAGE_ALIGN(end); if (end <= start) return; - vm_brk(start, end - start); + down_write(¤t->mm->mmap_sem); + do_brk(start, end - start); + up_write(¤t->mm->mmap_sem); } #ifdef CORE_DUMP @@ -294,7 +296,8 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) /* OK, This is the point of no return */ set_personality(PER_LINUX); - set_personality_ia32(false); + set_thread_flag(TIF_IA32); + current->mm->context.ia32_compat = 1; setup_new_exec(bprm); @@ -329,7 +332,9 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) pos = 32; map_size = ex.a_text+ex.a_data; - error = vm_brk(text_addr & PAGE_MASK, map_size); + down_write(¤t->mm->mmap_sem); + error = do_brk(text_addr & PAGE_MASK, map_size); + up_write(¤t->mm->mmap_sem); if (error != (text_addr & PAGE_MASK)) { send_sig(SIGKILL, current, 0); @@ -368,7 +373,9 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) 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); + down_write(¤t->mm->mmap_sem); + do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); + up_write(¤t->mm->mmap_sem); bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex), ex.a_text+ex.a_data, &pos); @@ -378,22 +385,26 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) goto beyond_if; } - error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, + down_write(¤t->mm->mmap_sem); + error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE | MAP_32BIT, fd_offset); + up_write(¤t->mm->mmap_sem); if (error != N_TXTADDR(ex)) { send_sig(SIGKILL, current, 0); return error; } - error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, + down_write(¤t->mm->mmap_sem); + error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE | MAP_32BIT, fd_offset + ex.a_text); + up_write(¤t->mm->mmap_sem); if (error != N_DATADDR(ex)) { send_sig(SIGKILL, current, 0); return error; @@ -465,7 +476,9 @@ static int load_aout_library(struct file *file) error_time = jiffies; } #endif - vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); + down_write(¤t->mm->mmap_sem); + do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); + up_write(¤t->mm->mmap_sem); file->f_op->read(file, (char __user *)start_addr, ex.a_text + ex.a_data, &pos); @@ -477,10 +490,12 @@ static int load_aout_library(struct file *file) goto out; } /* Now use mmap to map the library into memory. */ - error = vm_mmap(file, start_addr, ex.a_text + ex.a_data, + down_write(¤t->mm->mmap_sem); + error = do_mmap(file, start_addr, ex.a_text + ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_32BIT, N_TXTOFF(ex)); + up_write(¤t->mm->mmap_sem); retval = error; if (error != start_addr) goto out; @@ -488,7 +503,9 @@ static int load_aout_library(struct file *file) len = PAGE_ALIGN(ex.a_text + ex.a_data); bss = ex.a_text + ex.a_data + ex.a_bss; if (bss > len) { - error = vm_brk(start_addr + len, bss - len); + down_write(¤t->mm->mmap_sem); + error = do_brk(start_addr + len, bss - len); + up_write(¤t->mm->mmap_sem); retval = error; if (error != start_addr + len) goto out; diff --git a/trunk/arch/x86/ia32/sys_ia32.c b/trunk/arch/x86/ia32/sys_ia32.c index edca9c0a79cc..aec2202a596c 100644 --- a/trunk/arch/x86/ia32/sys_ia32.c +++ b/trunk/arch/x86/ia32/sys_ia32.c @@ -287,6 +287,11 @@ asmlinkage long sys32_sigaction(int sig, struct old_sigaction32 __user *act, return ret; } +asmlinkage long sys32_alarm(unsigned int seconds) +{ + return alarm_setitimer(seconds); +} + asmlinkage long sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options) { @@ -295,6 +300,11 @@ asmlinkage long sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, /* 32-bit timeval and related flotsam. */ +asmlinkage long sys32_sysfs(int option, u32 arg1, u32 arg2) +{ + return sys_sysfs(option, arg1, arg2); +} + asmlinkage long sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval) { @@ -365,6 +375,19 @@ asmlinkage long sys32_pwrite(unsigned int fd, const char __user *ubuf, } +asmlinkage long sys32_personality(unsigned long personality) +{ + int ret; + + if (personality(current->personality) == PER_LINUX32 && + personality == PER_LINUX) + personality = PER_LINUX32; + ret = sys_personality(personality); + if (ret == PER_LINUX32) + ret = PER_LINUX; + return ret; +} + asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count) { diff --git a/trunk/arch/x86/include/asm/cmpxchg.h b/trunk/arch/x86/include/asm/cmpxchg.h index 99480e55973d..b3b733262909 100644 --- a/trunk/arch/x86/include/asm/cmpxchg.h +++ b/trunk/arch/x86/include/asm/cmpxchg.h @@ -43,7 +43,7 @@ extern void __add_wrong_size(void) switch (sizeof(*(ptr))) { \ case __X86_CASE_B: \ asm volatile (lock #op "b %b0, %1\n" \ - : "+q" (__ret), "+m" (*(ptr)) \ + : "+r" (__ret), "+m" (*(ptr)) \ : : "memory", "cc"); \ break; \ case __X86_CASE_W: \ @@ -173,7 +173,7 @@ extern void __add_wrong_size(void) switch (sizeof(*(ptr))) { \ case __X86_CASE_B: \ asm volatile (lock "addb %b1, %0\n" \ - : "+m" (*(ptr)) : "qi" (inc) \ + : "+m" (*(ptr)) : "ri" (inc) \ : "memory", "cc"); \ break; \ case __X86_CASE_W: \ diff --git a/trunk/arch/x86/include/asm/dma-mapping.h b/trunk/arch/x86/include/asm/dma-mapping.h index 4b4331d71935..ed3065fd6314 100644 --- a/trunk/arch/x86/include/asm/dma-mapping.h +++ b/trunk/arch/x86/include/asm/dma-mapping.h @@ -59,8 +59,7 @@ extern int dma_supported(struct device *hwdev, u64 mask); extern int dma_set_mask(struct device *dev, u64 mask); extern void *dma_generic_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_addr, gfp_t flag, - struct dma_attrs *attrs); + dma_addr_t *dma_addr, gfp_t flag); static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) { @@ -112,11 +111,9 @@ static inline gfp_t dma_alloc_coherent_gfp_flags(struct device *dev, gfp_t gfp) return gfp; } -#define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) - static inline void * -dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle, - gfp_t gfp, struct dma_attrs *attrs) +dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, + gfp_t gfp) { struct dma_map_ops *ops = get_dma_ops(dev); void *memory; @@ -132,21 +129,18 @@ dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle, if (!is_device_dma_capable(dev)) return NULL; - if (!ops->alloc) + if (!ops->alloc_coherent) return NULL; - memory = ops->alloc(dev, size, dma_handle, - dma_alloc_coherent_gfp_flags(dev, gfp), attrs); + memory = ops->alloc_coherent(dev, size, dma_handle, + dma_alloc_coherent_gfp_flags(dev, gfp)); debug_dma_alloc_coherent(dev, size, *dma_handle, memory); return memory; } -#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) - -static inline void dma_free_attrs(struct device *dev, size_t size, - void *vaddr, dma_addr_t bus, - struct dma_attrs *attrs) +static inline void dma_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t bus) { struct dma_map_ops *ops = get_dma_ops(dev); @@ -156,8 +150,8 @@ static inline void dma_free_attrs(struct device *dev, size_t size, return; debug_dma_free_coherent(dev, size, vaddr, bus); - if (ops->free) - ops->free(dev, size, vaddr, bus, attrs); + if (ops->free_coherent) + ops->free_coherent(dev, size, vaddr, bus); } #endif diff --git a/trunk/arch/x86/include/asm/posix_types.h b/trunk/arch/x86/include/asm/posix_types.h index 7ef7c3020e5c..3427b7798dbc 100644 --- a/trunk/arch/x86/include/asm/posix_types.h +++ b/trunk/arch/x86/include/asm/posix_types.h @@ -7,9 +7,9 @@ #else # ifdef __i386__ # include "posix_types_32.h" -# elif defined(__ILP32__) -# include "posix_types_x32.h" -# else +# elif defined(__LP64__) # include "posix_types_64.h" +# else +# include "posix_types_x32.h" # endif #endif diff --git a/trunk/arch/x86/include/asm/processor.h b/trunk/arch/x86/include/asm/processor.h index 4fa7dcceb6c0..7284c9a6a0b5 100644 --- a/trunk/arch/x86/include/asm/processor.h +++ b/trunk/arch/x86/include/asm/processor.h @@ -974,6 +974,16 @@ extern bool cpu_has_amd_erratum(const int *); #define cpu_has_amd_erratum(x) (false) #endif /* CONFIG_CPU_SUP_AMD */ +#ifdef CONFIG_X86_32 +/* + * disable hlt during certain critical i/o operations + */ +#define HAVE_DISABLE_HLT +#endif + +void disable_hlt(void); +void enable_hlt(void); + void cpu_idle_wait(void); extern unsigned long arch_align_stack(unsigned long sp); diff --git a/trunk/arch/x86/include/asm/sigcontext.h b/trunk/arch/x86/include/asm/sigcontext.h index 5ca71c065eef..4a085383af27 100644 --- a/trunk/arch/x86/include/asm/sigcontext.h +++ b/trunk/arch/x86/include/asm/sigcontext.h @@ -257,7 +257,7 @@ struct sigcontext { __u64 oldmask; __u64 cr2; struct _fpstate __user *fpstate; /* zero when no FPU context */ -#ifdef __ILP32__ +#ifndef __LP64__ __u32 __fpstate_pad; #endif __u64 reserved1[8]; diff --git a/trunk/arch/x86/include/asm/siginfo.h b/trunk/arch/x86/include/asm/siginfo.h index 34c47b3341c0..fc1aa5535646 100644 --- a/trunk/arch/x86/include/asm/siginfo.h +++ b/trunk/arch/x86/include/asm/siginfo.h @@ -2,13 +2,7 @@ #define _ASM_X86_SIGINFO_H #ifdef __x86_64__ -# ifdef __ILP32__ /* x32 */ -typedef long long __kernel_si_clock_t __attribute__((aligned(4))); -# define __ARCH_SI_CLOCK_T __kernel_si_clock_t -# define __ARCH_SI_ATTRIBUTES __attribute__((aligned(8))) -# else /* x86-64 */ -# define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) -# endif +# define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) #endif #include diff --git a/trunk/arch/x86/include/asm/spinlock.h b/trunk/arch/x86/include/asm/spinlock.h index 76bfa2cf301d..b315a33867f2 100644 --- a/trunk/arch/x86/include/asm/spinlock.h +++ b/trunk/arch/x86/include/asm/spinlock.h @@ -20,10 +20,8 @@ #ifdef CONFIG_X86_32 # define LOCK_PTR_REG "a" -# define REG_PTR_MODE "k" #else # define LOCK_PTR_REG "D" -# define REG_PTR_MODE "q" #endif #if defined(CONFIG_X86_32) && \ diff --git a/trunk/arch/x86/include/asm/uaccess.h b/trunk/arch/x86/include/asm/uaccess.h index e0544597cfe7..8be5f54d9360 100644 --- a/trunk/arch/x86/include/asm/uaccess.h +++ b/trunk/arch/x86/include/asm/uaccess.h @@ -557,8 +557,6 @@ struct __large_struct { unsigned long buf[100]; }; extern unsigned long copy_from_user_nmi(void *to, const void __user *from, unsigned long n); -extern __must_check long -strncpy_from_user(char *dst, const char __user *src, long count); /* * movsl can be slow when source and dest are not both 8-byte aligned diff --git a/trunk/arch/x86/include/asm/uaccess_32.h b/trunk/arch/x86/include/asm/uaccess_32.h index 8084bc73b18c..566e803cc602 100644 --- a/trunk/arch/x86/include/asm/uaccess_32.h +++ b/trunk/arch/x86/include/asm/uaccess_32.h @@ -213,6 +213,11 @@ static inline unsigned long __must_check copy_from_user(void *to, return n; } +long __must_check strncpy_from_user(char *dst, const char __user *src, + long count); +long __must_check __strncpy_from_user(char *dst, + const char __user *src, long count); + /** * strlen_user: - Get the size of a string in user space. * @str: The string to measure. diff --git a/trunk/arch/x86/include/asm/uaccess_64.h b/trunk/arch/x86/include/asm/uaccess_64.h index fcd4b6f3ef02..1c66d30971ad 100644 --- a/trunk/arch/x86/include/asm/uaccess_64.h +++ b/trunk/arch/x86/include/asm/uaccess_64.h @@ -208,6 +208,10 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size) } } +__must_check long +strncpy_from_user(char *dst, const char __user *src, long count); +__must_check long +__strncpy_from_user(char *dst, const char __user *src, long count); __must_check long strnlen_user(const char __user *str, long n); __must_check long __strnlen_user(const char __user *str, long n); __must_check long strlen_user(const char __user *str); diff --git a/trunk/arch/x86/include/asm/unistd.h b/trunk/arch/x86/include/asm/unistd.h index 4437001d8e3d..37cdc9d99bb1 100644 --- a/trunk/arch/x86/include/asm/unistd.h +++ b/trunk/arch/x86/include/asm/unistd.h @@ -63,10 +63,10 @@ #else # ifdef __i386__ # include -# elif defined(__ILP32__) -# include -# else +# elif defined(__LP64__) # include +# else +# include # endif #endif diff --git a/trunk/arch/x86/include/asm/word-at-a-time.h b/trunk/arch/x86/include/asm/word-at-a-time.h deleted file mode 100644 index e58f03b206c3..000000000000 --- a/trunk/arch/x86/include/asm/word-at-a-time.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef _ASM_WORD_AT_A_TIME_H -#define _ASM_WORD_AT_A_TIME_H - -/* - * This is largely generic for little-endian machines, but the - * optimal byte mask counting is probably going to be something - * that is architecture-specific. If you have a reliably fast - * bit count instruction, that might be better than the multiply - * and shift, for example. - */ - -#ifdef CONFIG_64BIT - -/* - * Jan Achrenius on G+: microoptimized version of - * the simpler "(mask & ONEBYTES) * ONEBYTES >> 56" - * that works for the bytemasks without having to - * mask them first. - */ -static inline long count_masked_bytes(unsigned long mask) -{ - return mask*0x0001020304050608ul >> 56; -} - -#else /* 32-bit case */ - -/* Carl Chatfield / Jan Achrenius G+ version for 32-bit */ -static inline long count_masked_bytes(long mask) -{ - /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */ - long a = (0x0ff0001+mask) >> 23; - /* Fix the 1 for 00 case */ - return a & mask; -} - -#endif - -#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x)) - -/* Return the high bit set in the first byte that is a zero */ -static inline unsigned long has_zero(unsigned long a) -{ - return ((a - REPEAT_BYTE(0x01)) & ~a) & REPEAT_BYTE(0x80); -} - -/* - * Load an unaligned word from kernel space. - * - * In the (very unlikely) case of the word being a page-crosser - * and the next page not being mapped, take the exception and - * return zeroes in the non-existing part. - */ -static inline unsigned long load_unaligned_zeropad(const void *addr) -{ - unsigned long ret, dummy; - - asm( - "1:\tmov %2,%0\n" - "2:\n" - ".section .fixup,\"ax\"\n" - "3:\t" - "lea %2,%1\n\t" - "and %3,%1\n\t" - "mov (%1),%0\n\t" - "leal %2,%%ecx\n\t" - "andl %4,%%ecx\n\t" - "shll $3,%%ecx\n\t" - "shr %%cl,%0\n\t" - "jmp 2b\n" - ".previous\n" - _ASM_EXTABLE(1b, 3b) - :"=&r" (ret),"=&c" (dummy) - :"m" (*(unsigned long *)addr), - "i" (-sizeof(unsigned long)), - "i" (sizeof(unsigned long)-1)); - return ret; -} - -#endif /* _ASM_WORD_AT_A_TIME_H */ diff --git a/trunk/arch/x86/include/asm/x86_init.h b/trunk/arch/x86/include/asm/x86_init.h index 764b66a4cf89..baaca8defec8 100644 --- a/trunk/arch/x86/include/asm/x86_init.h +++ b/trunk/arch/x86/include/asm/x86_init.h @@ -195,5 +195,6 @@ extern struct x86_msi_ops x86_msi; extern void x86_init_noop(void); extern void x86_init_uint_noop(unsigned int unused); +extern void x86_default_fixup_cpu_id(struct cpuinfo_x86 *c, int node); #endif diff --git a/trunk/arch/x86/kernel/acpi/boot.c b/trunk/arch/x86/kernel/acpi/boot.c index a415b1f44365..0f42c2f44311 100644 --- a/trunk/arch/x86/kernel/acpi/boot.c +++ b/trunk/arch/x86/kernel/acpi/boot.c @@ -642,7 +642,6 @@ static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu) kfree(buffer.pointer); buffer.length = ACPI_ALLOCATE_BUFFER; buffer.pointer = NULL; - lapic = NULL; if (!alloc_cpumask_var(&tmp_map, GFP_KERNEL)) goto out; @@ -651,7 +650,7 @@ static int __cpuinit _acpi_map_lsapic(acpi_handle handle, int *pcpu) goto free_tmp_map; cpumask_copy(tmp_map, cpu_present_mask); - acpi_register_lapic(physid, ACPI_MADT_ENABLED); + acpi_register_lapic(physid, lapic->lapic_flags & ACPI_MADT_ENABLED); /* * If mp_register_lapic successfully generates a new logical cpu diff --git a/trunk/arch/x86/kernel/acpi/sleep.c b/trunk/arch/x86/kernel/acpi/sleep.c index 146a49c763a4..103b6ab368d3 100644 --- a/trunk/arch/x86/kernel/acpi/sleep.c +++ b/trunk/arch/x86/kernel/acpi/sleep.c @@ -24,10 +24,6 @@ unsigned long acpi_realmode_flags; static char temp_stack[4096]; #endif -asmlinkage void acpi_enter_s3(void) -{ - acpi_enter_sleep_state(3, wake_sleep_flags); -} /** * acpi_suspend_lowlevel - save kernel state * diff --git a/trunk/arch/x86/kernel/acpi/sleep.h b/trunk/arch/x86/kernel/acpi/sleep.h index d68677a2a010..416d4be13fef 100644 --- a/trunk/arch/x86/kernel/acpi/sleep.h +++ b/trunk/arch/x86/kernel/acpi/sleep.h @@ -3,16 +3,12 @@ */ #include -#include extern unsigned long saved_video_mode; extern long saved_magic; extern int wakeup_pmode_return; -extern u8 wake_sleep_flags; -extern asmlinkage void acpi_enter_s3(void); - extern unsigned long acpi_copy_wakeup_routine(unsigned long); extern void wakeup_long64(void); diff --git a/trunk/arch/x86/kernel/acpi/wakeup_32.S b/trunk/arch/x86/kernel/acpi/wakeup_32.S index 72610839f03b..13ab720573e3 100644 --- a/trunk/arch/x86/kernel/acpi/wakeup_32.S +++ b/trunk/arch/x86/kernel/acpi/wakeup_32.S @@ -74,7 +74,9 @@ restore_registers: ENTRY(do_suspend_lowlevel) call save_processor_state call save_registers - call acpi_enter_s3 + pushl $3 + call acpi_enter_sleep_state + addl $4, %esp # In case of S3 failure, we'll emerge here. Jump # to ret_point to recover diff --git a/trunk/arch/x86/kernel/acpi/wakeup_64.S b/trunk/arch/x86/kernel/acpi/wakeup_64.S index 014d1d28c397..8ea5164cbd04 100644 --- a/trunk/arch/x86/kernel/acpi/wakeup_64.S +++ b/trunk/arch/x86/kernel/acpi/wakeup_64.S @@ -71,7 +71,9 @@ ENTRY(do_suspend_lowlevel) movq %rsi, saved_rsi addq $8, %rsp - call acpi_enter_s3 + movl $3, %edi + xorl %eax, %eax + call acpi_enter_sleep_state /* in case something went wrong, restore the machine status and go on */ jmp resume_point diff --git a/trunk/arch/x86/kernel/amd_gart_64.c b/trunk/arch/x86/kernel/amd_gart_64.c index e66311200cbd..b1e7c7f7a0af 100644 --- a/trunk/arch/x86/kernel/amd_gart_64.c +++ b/trunk/arch/x86/kernel/amd_gart_64.c @@ -477,7 +477,7 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, /* allocate and map a coherent mapping */ static void * gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr, - gfp_t flag, struct dma_attrs *attrs) + gfp_t flag) { dma_addr_t paddr; unsigned long align_mask; @@ -500,8 +500,7 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr, } __free_pages(page, get_order(size)); } else - return dma_generic_alloc_coherent(dev, size, dma_addr, flag, - attrs); + return dma_generic_alloc_coherent(dev, size, dma_addr, flag); return NULL; } @@ -509,7 +508,7 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr, /* free a coherent mapping */ static void gart_free_coherent(struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_addr, struct dma_attrs *attrs) + dma_addr_t dma_addr) { gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, NULL); free_pages((unsigned long)vaddr, get_order(size)); @@ -701,8 +700,8 @@ static struct dma_map_ops gart_dma_ops = { .unmap_sg = gart_unmap_sg, .map_page = gart_map_page, .unmap_page = gart_unmap_page, - .alloc = gart_alloc_coherent, - .free = gart_free_coherent, + .alloc_coherent = gart_alloc_coherent, + .free_coherent = gart_free_coherent, .mapping_error = gart_mapping_error, }; diff --git a/trunk/arch/x86/kernel/apic/apic.c b/trunk/arch/x86/kernel/apic/apic.c index edc24480469f..11544d8f1e97 100644 --- a/trunk/arch/x86/kernel/apic/apic.c +++ b/trunk/arch/x86/kernel/apic/apic.c @@ -1637,11 +1637,9 @@ static int __init apic_verify(void) mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; /* The BIOS may have set up the APIC at some other address */ - if (boot_cpu_data.x86 >= 6) { - rdmsr(MSR_IA32_APICBASE, l, h); - if (l & MSR_IA32_APICBASE_ENABLE) - mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; - } + rdmsr(MSR_IA32_APICBASE, l, h); + if (l & MSR_IA32_APICBASE_ENABLE) + mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; pr_info("Found and enabled local APIC!\n"); return 0; @@ -1659,15 +1657,13 @@ int __init apic_force_enable(unsigned long addr) * MSR. This can only be done in software for Intel P6 or later * and AMD K7 (Model > 1) or later. */ - if (boot_cpu_data.x86 >= 6) { - rdmsr(MSR_IA32_APICBASE, l, h); - if (!(l & MSR_IA32_APICBASE_ENABLE)) { - pr_info("Local APIC disabled by BIOS -- reenabling.\n"); - l &= ~MSR_IA32_APICBASE_BASE; - l |= MSR_IA32_APICBASE_ENABLE | addr; - wrmsr(MSR_IA32_APICBASE, l, h); - enabled_via_apicbase = 1; - } + rdmsr(MSR_IA32_APICBASE, l, h); + if (!(l & MSR_IA32_APICBASE_ENABLE)) { + pr_info("Local APIC disabled by BIOS -- reenabling.\n"); + l &= ~MSR_IA32_APICBASE_BASE; + l |= MSR_IA32_APICBASE_ENABLE | addr; + wrmsr(MSR_IA32_APICBASE, l, h); + enabled_via_apicbase = 1; } return apic_verify(); } @@ -2213,12 +2209,10 @@ static void lapic_resume(void) * FIXME! This will be wrong if we ever support suspend on * SMP! We'll need to do this as part of the CPU restore! */ - if (boot_cpu_data.x86 >= 6) { - rdmsr(MSR_IA32_APICBASE, l, h); - l &= ~MSR_IA32_APICBASE_BASE; - l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; - wrmsr(MSR_IA32_APICBASE, l, h); - } + rdmsr(MSR_IA32_APICBASE, l, h); + l &= ~MSR_IA32_APICBASE_BASE; + l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; + wrmsr(MSR_IA32_APICBASE, l, h); } maxlvt = lapic_get_maxlvt(); diff --git a/trunk/arch/x86/kernel/apic/apic_numachip.c b/trunk/arch/x86/kernel/apic/apic_numachip.c index 23e75422e013..899803e03214 100644 --- a/trunk/arch/x86/kernel/apic/apic_numachip.c +++ b/trunk/arch/x86/kernel/apic/apic_numachip.c @@ -207,11 +207,8 @@ static void __init map_csrs(void) static void fixup_cpu_id(struct cpuinfo_x86 *c, int node) { - - if (c->phys_proc_id != node) { - c->phys_proc_id = node; - per_cpu(cpu_llc_id, smp_processor_id()) = node; - } + c->phys_proc_id = node; + per_cpu(cpu_llc_id, smp_processor_id()) = node; } static int __init numachip_system_init(void) diff --git a/trunk/arch/x86/kernel/apic/x2apic_phys.c b/trunk/arch/x86/kernel/apic/x2apic_phys.c index 991e315f4227..8a778db45e3a 100644 --- a/trunk/arch/x86/kernel/apic/x2apic_phys.c +++ b/trunk/arch/x86/kernel/apic/x2apic_phys.c @@ -24,12 +24,6 @@ static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) { if (x2apic_phys) return x2apic_enabled(); - else if ((acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) && - (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL) && - x2apic_enabled()) { - printk(KERN_DEBUG "System requires x2apic physical mode\n"); - return 1; - } else return 0; } diff --git a/trunk/arch/x86/kernel/cpu/amd.c b/trunk/arch/x86/kernel/cpu/amd.c index 146bb6218eec..0a44b90602b0 100644 --- a/trunk/arch/x86/kernel/cpu/amd.c +++ b/trunk/arch/x86/kernel/cpu/amd.c @@ -26,8 +26,7 @@ * contact AMD for precise details and a CPU swap. * * See http://www.multimania.com/poulot/k6bug.html - * and section 2.6.2 of "AMD-K6 Processor Revision Guide - Model 6" - * (Publication # 21266 Issue Date: August 1998) + * http://www.amd.com/K6/k6docs/revgd.html * * The following test is erm.. interesting. AMD neglected to up * the chip setting when fixing the bug but they also tweaked some @@ -95,6 +94,7 @@ static void __cpuinit init_amd_k6(struct cpuinfo_x86 *c) "system stability may be impaired when more than 32 MB are used.\n"); else printk(KERN_CONT "probably OK (after B9730xxxx).\n"); + printk(KERN_INFO "Please see http://membres.lycos.fr/poulot/k6bug.html\n"); } /* K6 with old style WHCR */ @@ -353,11 +353,10 @@ static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c) node = per_cpu(cpu_llc_id, cpu); /* - * On multi-fabric platform (e.g. Numascale NumaChip) a - * platform-specific handler needs to be called to fixup some - * IDs of the CPU. + * If core numbers are inconsistent, it's likely a multi-fabric platform, + * so invoke platform-specific handler */ - if (x86_cpuinit.fixup_cpu_id) + if (c->phys_proc_id != node) x86_cpuinit.fixup_cpu_id(c, node); if (!node_online(node)) { @@ -580,24 +579,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) } } - /* re-enable TopologyExtensions if switched off by BIOS */ - if ((c->x86 == 0x15) && - (c->x86_model >= 0x10) && (c->x86_model <= 0x1f) && - !cpu_has(c, X86_FEATURE_TOPOEXT)) { - u64 val; - - if (!rdmsrl_amd_safe(0xc0011005, &val)) { - val |= 1ULL << 54; - wrmsrl_amd_safe(0xc0011005, val); - rdmsrl(0xc0011005, val); - if (val & (1ULL << 54)) { - set_cpu_cap(c, X86_FEATURE_TOPOEXT); - printk(KERN_INFO FW_INFO "CPU: Re-enabling " - "disabled Topology Extensions Support\n"); - } - } - } - cpu_detect_cache_sizes(c); /* Multi core CPU? */ diff --git a/trunk/arch/x86/kernel/cpu/common.c b/trunk/arch/x86/kernel/cpu/common.c index cf79302198a6..67e258362a3d 100644 --- a/trunk/arch/x86/kernel/cpu/common.c +++ b/trunk/arch/x86/kernel/cpu/common.c @@ -1162,6 +1162,15 @@ static void dbg_restore_debug_regs(void) #define dbg_restore_debug_regs() #endif /* ! CONFIG_KGDB */ +/* + * Prints an error where the NUMA and configured core-number mismatch and the + * platform didn't override this to fix it up + */ +void __cpuinit x86_default_fixup_cpu_id(struct cpuinfo_x86 *c, int node) +{ + pr_err("NUMA core number %d differs from configured core number %d\n", node, c->phys_proc_id); +} + /* * cpu_init() initializes state that is per-CPU. Some data is already * initialized (naturally) in the bootstrap process, such as the GDT diff --git a/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c b/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c index b8f3653dddbc..73d08ed98a64 100644 --- a/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -433,14 +433,14 @@ int amd_set_l3_disable_slot(struct amd_northbridge *nb, int cpu, unsigned slot, /* check if @slot is already used or the index is already disabled */ ret = amd_get_l3_disable_slot(nb, slot); if (ret >= 0) - return -EEXIST; + return -EINVAL; if (index > nb->l3_cache.indices) return -EINVAL; /* check whether the other slot has disabled the same index already */ if (index == amd_get_l3_disable_slot(nb, !slot)) - return -EEXIST; + return -EINVAL; amd_l3_disable_index(nb, cpu, slot, index); @@ -468,8 +468,8 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, err = amd_set_l3_disable_slot(this_leaf->base.nb, cpu, slot, val); if (err) { if (err == -EEXIST) - pr_warning("L3 slot %d in use/index already disabled!\n", - slot); + printk(KERN_WARNING "L3 disable slot %d in use!\n", + slot); return err; } return count; diff --git a/trunk/arch/x86/kernel/cpu/perf_event.c b/trunk/arch/x86/kernel/cpu/perf_event.c index bb8e03407e18..40883ffe2da9 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event.c +++ b/trunk/arch/x86/kernel/cpu/perf_event.c @@ -1313,11 +1313,6 @@ static void __init pmu_check_apic(void) pr_info("no hardware sampling interrupt available.\n"); } -static struct attribute_group x86_pmu_format_group = { - .name = "format", - .attrs = NULL, -}; - static int __init init_hw_perf_events(void) { struct x86_pmu_quirk *quirk; @@ -1392,7 +1387,6 @@ static int __init init_hw_perf_events(void) } x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */ - x86_pmu_format_group.attrs = x86_pmu.format_attrs; pr_info("... version: %d\n", x86_pmu.version); pr_info("... bit width: %d\n", x86_pmu.cntval_bits); @@ -1621,9 +1615,6 @@ static int x86_pmu_event_idx(struct perf_event *event) { int idx = event->hw.idx; - if (!x86_pmu.attr_rdpmc) - return 0; - if (x86_pmu.num_counters_fixed && idx >= X86_PMC_IDX_FIXED) { idx -= X86_PMC_IDX_FIXED; idx |= 1 << 30; @@ -1676,7 +1667,6 @@ static struct attribute_group x86_pmu_attr_group = { static const struct attribute_group *x86_pmu_attr_groups[] = { &x86_pmu_attr_group, - &x86_pmu_format_group, NULL, }; @@ -1708,19 +1698,14 @@ static struct pmu pmu = { .flush_branch_stack = x86_pmu_flush_branch_stack, }; -void arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now) +void perf_update_user_clock(struct perf_event_mmap_page *userpg, u64 now) { - userpg->cap_usr_time = 0; - userpg->cap_usr_rdpmc = x86_pmu.attr_rdpmc; - userpg->pmc_width = x86_pmu.cntval_bits; - if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) return; if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) return; - userpg->cap_usr_time = 1; userpg->time_mult = this_cpu_read(cyc2ns); userpg->time_shift = CYC2NS_SCALE_FACTOR; userpg->time_offset = this_cpu_read(cyc2ns_offset) - now; diff --git a/trunk/arch/x86/kernel/cpu/perf_event.h b/trunk/arch/x86/kernel/cpu/perf_event.h index 6638aaf54493..8484e77c211e 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event.h +++ b/trunk/arch/x86/kernel/cpu/perf_event.h @@ -339,7 +339,6 @@ struct x86_pmu { * sysfs attrs */ int attr_rdpmc; - struct attribute **format_attrs; /* * CPU Hotplug hooks diff --git a/trunk/arch/x86/kernel/cpu/perf_event_amd.c b/trunk/arch/x86/kernel/cpu/perf_event_amd.c index 95e7fe1c5f0b..dd002faff7a6 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_amd.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_amd.c @@ -404,21 +404,6 @@ static void amd_pmu_cpu_dead(int cpu) } } -PMU_FORMAT_ATTR(event, "config:0-7,32-35"); -PMU_FORMAT_ATTR(umask, "config:8-15" ); -PMU_FORMAT_ATTR(edge, "config:18" ); -PMU_FORMAT_ATTR(inv, "config:23" ); -PMU_FORMAT_ATTR(cmask, "config:24-31" ); - -static struct attribute *amd_format_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_cmask.attr, - NULL, -}; - static __initconst const struct x86_pmu amd_pmu = { .name = "AMD", .handle_irq = x86_pmu_handle_irq, @@ -441,8 +426,6 @@ static __initconst const struct x86_pmu amd_pmu = { .get_event_constraints = amd_get_event_constraints, .put_event_constraints = amd_put_event_constraints, - .format_attrs = amd_format_attr, - .cpu_prepare = amd_pmu_cpu_prepare, .cpu_starting = amd_pmu_cpu_starting, .cpu_dead = amd_pmu_cpu_dead, @@ -613,7 +596,6 @@ static __initconst const struct x86_pmu amd_pmu_f15h = { .cpu_dead = amd_pmu_cpu_dead, #endif .cpu_starting = amd_pmu_cpu_starting, - .format_attrs = amd_format_attr, }; __init int amd_pmu_init(void) diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel.c b/trunk/arch/x86/kernel/cpu/perf_event_intel.c index 26b3e2fef104..6a84e7f28f05 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel.c @@ -1431,24 +1431,6 @@ static void core_pmu_enable_all(int added) } } -PMU_FORMAT_ATTR(event, "config:0-7" ); -PMU_FORMAT_ATTR(umask, "config:8-15" ); -PMU_FORMAT_ATTR(edge, "config:18" ); -PMU_FORMAT_ATTR(pc, "config:19" ); -PMU_FORMAT_ATTR(any, "config:21" ); /* v3 + */ -PMU_FORMAT_ATTR(inv, "config:23" ); -PMU_FORMAT_ATTR(cmask, "config:24-31" ); - -static struct attribute *intel_arch_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_pc.attr, - &format_attr_inv.attr, - &format_attr_cmask.attr, - NULL, -}; - static __initconst const struct x86_pmu core_pmu = { .name = "core", .handle_irq = x86_pmu_handle_irq, @@ -1473,7 +1455,6 @@ static __initconst const struct x86_pmu core_pmu = { .put_event_constraints = intel_put_event_constraints, .event_constraints = intel_core_event_constraints, .guest_get_msrs = core_guest_get_msrs, - .format_attrs = intel_arch_formats_attr, }; struct intel_shared_regs *allocate_shared_regs(int cpu) @@ -1572,21 +1553,6 @@ static void intel_pmu_flush_branch_stack(void) intel_pmu_lbr_reset(); } -PMU_FORMAT_ATTR(offcore_rsp, "config1:0-63"); - -static struct attribute *intel_arch3_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_pc.attr, - &format_attr_any.attr, - &format_attr_inv.attr, - &format_attr_cmask.attr, - - &format_attr_offcore_rsp.attr, /* XXX do NHM/WSM + SNB breakout */ - NULL, -}; - static __initconst const struct x86_pmu intel_pmu = { .name = "Intel", .handle_irq = intel_pmu_handle_irq, @@ -1610,8 +1576,6 @@ static __initconst const struct x86_pmu intel_pmu = { .get_event_constraints = intel_get_event_constraints, .put_event_constraints = intel_put_event_constraints, - .format_attrs = intel_arch3_formats_attr, - .cpu_prepare = intel_pmu_cpu_prepare, .cpu_starting = intel_pmu_cpu_starting, .cpu_dying = intel_pmu_cpu_dying, diff --git a/trunk/arch/x86/kernel/cpu/perf_event_p4.c b/trunk/arch/x86/kernel/cpu/perf_event_p4.c index a2dfacfd7103..ef484d9d0a25 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_p4.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_p4.c @@ -1271,17 +1271,6 @@ static int p4_pmu_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign return num ? -EINVAL : 0; } -PMU_FORMAT_ATTR(cccr, "config:0-31" ); -PMU_FORMAT_ATTR(escr, "config:32-62"); -PMU_FORMAT_ATTR(ht, "config:63" ); - -static struct attribute *intel_p4_formats_attr[] = { - &format_attr_cccr.attr, - &format_attr_escr.attr, - &format_attr_ht.attr, - NULL, -}; - static __initconst const struct x86_pmu p4_pmu = { .name = "Netburst P4/Xeon", .handle_irq = p4_pmu_handle_irq, @@ -1316,8 +1305,6 @@ static __initconst const struct x86_pmu p4_pmu = { * the former idea is taken from OProfile code */ .perfctr_second_write = 1, - - .format_attrs = intel_p4_formats_attr, }; __init int p4_pmu_init(void) diff --git a/trunk/arch/x86/kernel/cpu/perf_event_p6.c b/trunk/arch/x86/kernel/cpu/perf_event_p6.c index 32bcfc7dd230..c7181befecde 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_p6.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_p6.c @@ -87,23 +87,6 @@ static void p6_pmu_enable_event(struct perf_event *event) (void)checking_wrmsrl(hwc->config_base, val); } -PMU_FORMAT_ATTR(event, "config:0-7" ); -PMU_FORMAT_ATTR(umask, "config:8-15" ); -PMU_FORMAT_ATTR(edge, "config:18" ); -PMU_FORMAT_ATTR(pc, "config:19" ); -PMU_FORMAT_ATTR(inv, "config:23" ); -PMU_FORMAT_ATTR(cmask, "config:24-31" ); - -static struct attribute *intel_p6_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_pc.attr, - &format_attr_inv.attr, - &format_attr_cmask.attr, - NULL, -}; - static __initconst const struct x86_pmu p6_pmu = { .name = "p6", .handle_irq = x86_pmu_handle_irq, @@ -132,8 +115,6 @@ static __initconst const struct x86_pmu p6_pmu = { .cntval_mask = (1ULL << 32) - 1, .get_event_constraints = x86_get_event_constraints, .event_constraints = p6_event_constraints, - - .format_attrs = intel_p6_formats_attr, }; __init int p6_pmu_init(void) diff --git a/trunk/arch/x86/kernel/i387.c b/trunk/arch/x86/kernel/i387.c index 2d6e6498c176..7734bcbb5a3a 100644 --- a/trunk/arch/x86/kernel/i387.c +++ b/trunk/arch/x86/kernel/i387.c @@ -235,7 +235,6 @@ int init_fpu(struct task_struct *tsk) if (tsk_used_math(tsk)) { if (HAVE_HWFP && tsk == current) unlazy_fpu(tsk); - tsk->thread.fpu.last_cpu = ~0; return 0; } diff --git a/trunk/arch/x86/kernel/irq.c b/trunk/arch/x86/kernel/irq.c index 3dafc6003b7c..7943e0c21bde 100644 --- a/trunk/arch/x86/kernel/irq.c +++ b/trunk/arch/x86/kernel/irq.c @@ -282,13 +282,8 @@ void fixup_irqs(void) else if (!(warned++)) set_affinity = 0; - /* - * We unmask if the irq was not marked masked by the - * core code. That respects the lazy irq disable - * behaviour. - */ if (!irqd_can_move_in_process_context(data) && - !irqd_irq_masked(data) && chip->irq_unmask) + !irqd_irq_disabled(data) && chip->irq_unmask) chip->irq_unmask(data); raw_spin_unlock(&desc->lock); diff --git a/trunk/arch/x86/kernel/kdebugfs.c b/trunk/arch/x86/kernel/kdebugfs.c index 1d5d31ea686b..90fcf62854bb 100644 --- a/trunk/arch/x86/kernel/kdebugfs.c +++ b/trunk/arch/x86/kernel/kdebugfs.c @@ -68,9 +68,16 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf, return count; } +static int setup_data_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + + return 0; +} + static const struct file_operations fops_setup_data = { .read = setup_data_read, - .open = simple_open, + .open = setup_data_open, .llseek = default_llseek, }; diff --git a/trunk/arch/x86/kernel/kgdb.c b/trunk/arch/x86/kernel/kgdb.c index 8bfb6146f753..db6720edfdd0 100644 --- a/trunk/arch/x86/kernel/kgdb.c +++ b/trunk/arch/x86/kernel/kgdb.c @@ -43,8 +43,6 @@ #include #include #include -#include -#include #include #include @@ -743,64 +741,6 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip) regs->ip = ip; } -int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) -{ - int err; - char opc[BREAK_INSTR_SIZE]; - - bpt->type = BP_BREAKPOINT; - err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, - BREAK_INSTR_SIZE); - if (err) - return err; - err = probe_kernel_write((char *)bpt->bpt_addr, - arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE); -#ifdef CONFIG_DEBUG_RODATA - if (!err) - return err; - /* - * It is safe to call text_poke() because normal kernel execution - * is stopped on all cores, so long as the text_mutex is not locked. - */ - if (mutex_is_locked(&text_mutex)) - return -EBUSY; - text_poke((void *)bpt->bpt_addr, arch_kgdb_ops.gdb_bpt_instr, - BREAK_INSTR_SIZE); - err = probe_kernel_read(opc, (char *)bpt->bpt_addr, BREAK_INSTR_SIZE); - if (err) - return err; - if (memcmp(opc, arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE)) - return -EINVAL; - bpt->type = BP_POKE_BREAKPOINT; -#endif /* CONFIG_DEBUG_RODATA */ - return err; -} - -int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) -{ -#ifdef CONFIG_DEBUG_RODATA - int err; - char opc[BREAK_INSTR_SIZE]; - - if (bpt->type != BP_POKE_BREAKPOINT) - goto knl_write; - /* - * It is safe to call text_poke() because normal kernel execution - * is stopped on all cores, so long as the text_mutex is not locked. - */ - if (mutex_is_locked(&text_mutex)) - goto knl_write; - text_poke((void *)bpt->bpt_addr, bpt->saved_instr, BREAK_INSTR_SIZE); - err = probe_kernel_read(opc, (char *)bpt->bpt_addr, BREAK_INSTR_SIZE); - if (err || memcmp(opc, bpt->saved_instr, BREAK_INSTR_SIZE)) - goto knl_write; - return err; -knl_write: -#endif /* CONFIG_DEBUG_RODATA */ - return probe_kernel_write((char *)bpt->bpt_addr, - (char *)bpt->saved_instr, BREAK_INSTR_SIZE); -} - struct kgdb_arch arch_kgdb_ops = { /* Breakpoint instruction: */ .gdb_bpt_instr = { 0xcc }, diff --git a/trunk/arch/x86/kernel/kvm.c b/trunk/arch/x86/kernel/kvm.c index b8ba6e4a27e4..694d801bf606 100644 --- a/trunk/arch/x86/kernel/kvm.c +++ b/trunk/arch/x86/kernel/kvm.c @@ -38,7 +38,6 @@ #include #include #include -#include static int kvmapf = 1; @@ -254,10 +253,7 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code) kvm_async_pf_task_wait((u32)read_cr2()); break; case KVM_PV_REASON_PAGE_READY: - rcu_irq_enter(); - exit_idle(); kvm_async_pf_task_wake((u32)read_cr2()); - rcu_irq_exit(); break; } } diff --git a/trunk/arch/x86/kernel/microcode_amd.c b/trunk/arch/x86/kernel/microcode_amd.c index 8a2ce8fd41c0..73465aab28f8 100644 --- a/trunk/arch/x86/kernel/microcode_amd.c +++ b/trunk/arch/x86/kernel/microcode_amd.c @@ -82,6 +82,11 @@ static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) { struct cpuinfo_x86 *c = &cpu_data(cpu); + if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) { + pr_warning("CPU%d: family %d not supported\n", cpu, c->x86); + return -1; + } + csig->rev = c->microcode; pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev); @@ -375,13 +380,6 @@ static struct microcode_ops microcode_amd_ops = { struct microcode_ops * __init init_amd_microcode(void) { - struct cpuinfo_x86 *c = &cpu_data(0); - - if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) { - pr_warning("AMD CPU family 0x%x not supported\n", c->x86); - return NULL; - } - patch = (void *)get_zeroed_page(GFP_KERNEL); if (!patch) return NULL; diff --git a/trunk/arch/x86/kernel/microcode_core.c b/trunk/arch/x86/kernel/microcode_core.c index c9bda6d6035c..87a0f8688301 100644 --- a/trunk/arch/x86/kernel/microcode_core.c +++ b/trunk/arch/x86/kernel/microcode_core.c @@ -419,8 +419,10 @@ static int mc_device_add(struct device *dev, struct subsys_interface *sif) if (err) return err; - if (microcode_init_cpu(cpu) == UCODE_ERROR) + if (microcode_init_cpu(cpu) == UCODE_ERROR) { + sysfs_remove_group(&dev->kobj, &mc_attr_group); return -EINVAL; + } return err; } @@ -526,11 +528,11 @@ static int __init microcode_init(void) microcode_ops = init_intel_microcode(); else if (c->x86_vendor == X86_VENDOR_AMD) microcode_ops = init_amd_microcode(); - else - pr_err("no support for this CPU vendor\n"); - if (!microcode_ops) + if (!microcode_ops) { + pr_err("no support for this CPU vendor\n"); return -ENODEV; + } microcode_pdev = platform_device_register_simple("microcode", -1, NULL, 0); diff --git a/trunk/arch/x86/kernel/pci-calgary_64.c b/trunk/arch/x86/kernel/pci-calgary_64.c index d0b2fb9ccbb1..6ac5782f4d6b 100644 --- a/trunk/arch/x86/kernel/pci-calgary_64.c +++ b/trunk/arch/x86/kernel/pci-calgary_64.c @@ -430,7 +430,7 @@ static void calgary_unmap_page(struct device *dev, dma_addr_t dma_addr, } static void* calgary_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag, struct dma_attrs *attrs) + dma_addr_t *dma_handle, gfp_t flag) { void *ret = NULL; dma_addr_t mapping; @@ -463,8 +463,7 @@ static void* calgary_alloc_coherent(struct device *dev, size_t size, } static void calgary_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, - struct dma_attrs *attrs) + void *vaddr, dma_addr_t dma_handle) { unsigned int npages; struct iommu_table *tbl = find_iommu_table(dev); @@ -477,8 +476,8 @@ static void calgary_free_coherent(struct device *dev, size_t size, } static struct dma_map_ops calgary_dma_ops = { - .alloc = calgary_alloc_coherent, - .free = calgary_free_coherent, + .alloc_coherent = calgary_alloc_coherent, + .free_coherent = calgary_free_coherent, .map_sg = calgary_map_sg, .unmap_sg = calgary_unmap_sg, .map_page = calgary_map_page, diff --git a/trunk/arch/x86/kernel/pci-dma.c b/trunk/arch/x86/kernel/pci-dma.c index 3003250ac51d..28e5e06fcba4 100644 --- a/trunk/arch/x86/kernel/pci-dma.c +++ b/trunk/arch/x86/kernel/pci-dma.c @@ -96,8 +96,7 @@ void __init pci_iommu_alloc(void) } } void *dma_generic_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_addr, gfp_t flag, - struct dma_attrs *attrs) + dma_addr_t *dma_addr, gfp_t flag) { unsigned long dma_mask; struct page *page; diff --git a/trunk/arch/x86/kernel/pci-nommu.c b/trunk/arch/x86/kernel/pci-nommu.c index f96050685b46..3af4af810c07 100644 --- a/trunk/arch/x86/kernel/pci-nommu.c +++ b/trunk/arch/x86/kernel/pci-nommu.c @@ -75,7 +75,7 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, } static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_addr, struct dma_attrs *attrs) + dma_addr_t dma_addr) { free_pages((unsigned long)vaddr, get_order(size)); } @@ -96,8 +96,8 @@ static void nommu_sync_sg_for_device(struct device *dev, } struct dma_map_ops nommu_dma_ops = { - .alloc = dma_generic_alloc_coherent, - .free = nommu_free_coherent, + .alloc_coherent = dma_generic_alloc_coherent, + .free_coherent = nommu_free_coherent, .map_sg = nommu_map_sg, .map_page = nommu_map_page, .sync_single_for_device = nommu_sync_single_for_device, diff --git a/trunk/arch/x86/kernel/pci-swiotlb.c b/trunk/arch/x86/kernel/pci-swiotlb.c index 6c483ba98b9c..8f972cbddef0 100644 --- a/trunk/arch/x86/kernel/pci-swiotlb.c +++ b/trunk/arch/x86/kernel/pci-swiotlb.c @@ -15,30 +15,21 @@ int swiotlb __read_mostly; static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, - dma_addr_t *dma_handle, gfp_t flags, - struct dma_attrs *attrs) + dma_addr_t *dma_handle, gfp_t flags) { void *vaddr; - vaddr = dma_generic_alloc_coherent(hwdev, size, dma_handle, flags, - attrs); + vaddr = dma_generic_alloc_coherent(hwdev, size, dma_handle, flags); if (vaddr) return vaddr; return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags); } -static void x86_swiotlb_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_addr, - struct dma_attrs *attrs) -{ - swiotlb_free_coherent(dev, size, vaddr, dma_addr); -} - static struct dma_map_ops swiotlb_dma_ops = { .mapping_error = swiotlb_dma_mapping_error, - .alloc = x86_swiotlb_alloc_coherent, - .free = x86_swiotlb_free_coherent, + .alloc_coherent = x86_swiotlb_alloc_coherent, + .free_coherent = swiotlb_free_coherent, .sync_single_for_cpu = swiotlb_sync_single_for_cpu, .sync_single_for_device = swiotlb_sync_single_for_device, .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, diff --git a/trunk/arch/x86/kernel/process.c b/trunk/arch/x86/kernel/process.c index 1d92a5ab6e8b..a33afaa5ddb7 100644 --- a/trunk/arch/x86/kernel/process.c +++ b/trunk/arch/x86/kernel/process.c @@ -362,10 +362,34 @@ void (*pm_idle)(void); EXPORT_SYMBOL(pm_idle); #endif +#ifdef CONFIG_X86_32 +/* + * This halt magic was a workaround for ancient floppy DMA + * wreckage. It should be safe to remove. + */ +static int hlt_counter; +void disable_hlt(void) +{ + hlt_counter++; +} +EXPORT_SYMBOL(disable_hlt); + +void enable_hlt(void) +{ + hlt_counter--; +} +EXPORT_SYMBOL(enable_hlt); + +static inline int hlt_use_halt(void) +{ + return (!hlt_counter && boot_cpu_data.hlt_works_ok); +} +#else static inline int hlt_use_halt(void) { return 1; } +#endif #ifndef CONFIG_SMP static inline void play_dead(void) diff --git a/trunk/arch/x86/kernel/process_64.c b/trunk/arch/x86/kernel/process_64.c index 43d8b48b23e6..733ca39f367e 100644 --- a/trunk/arch/x86/kernel/process_64.c +++ b/trunk/arch/x86/kernel/process_64.c @@ -423,7 +423,6 @@ void set_personality_ia32(bool x32) current_thread_info()->status |= TS_COMPAT; } } -EXPORT_SYMBOL_GPL(set_personality_ia32); unsigned long get_wchan(struct task_struct *p) { diff --git a/trunk/arch/x86/kernel/smpboot.c b/trunk/arch/x86/kernel/smpboot.c index 6e1e406038c2..ce13315d48fb 100644 --- a/trunk/arch/x86/kernel/smpboot.c +++ b/trunk/arch/x86/kernel/smpboot.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include @@ -1405,8 +1404,7 @@ void native_play_dead(void) tboot_shutdown(TB_SHUTDOWN_WFS); mwait_play_dead(); /* Only returns on failure */ - if (cpuidle_play_dead()) - hlt_play_dead(); + hlt_play_dead(); } #else /* ... !CONFIG_HOTPLUG_CPU */ diff --git a/trunk/arch/x86/kernel/tboot.c b/trunk/arch/x86/kernel/tboot.c index 6410744ac5cb..e2410e27f97e 100644 --- a/trunk/arch/x86/kernel/tboot.c +++ b/trunk/arch/x86/kernel/tboot.c @@ -272,7 +272,7 @@ static void tboot_copy_fadt(const struct acpi_table_fadt *fadt) offsetof(struct acpi_table_facs, firmware_waking_vector); } -static int tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control) +void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control) { static u32 acpi_shutdown_map[ACPI_S_STATE_COUNT] = { /* S0,1,2: */ -1, -1, -1, @@ -281,7 +281,7 @@ static int tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control) /* S5: */ TB_SHUTDOWN_S5 }; if (!tboot_enabled()) - return 0; + return; tboot_copy_fadt(&acpi_gbl_FADT); tboot->acpi_sinfo.pm1a_cnt_val = pm1a_control; @@ -292,11 +292,10 @@ static int tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control) if (sleep_state >= ACPI_S_STATE_COUNT || acpi_shutdown_map[sleep_state] == -1) { pr_warning("unsupported sleep state 0x%x\n", sleep_state); - return -1; + return; } tboot_shutdown(acpi_shutdown_map[sleep_state]); - return 0; } static atomic_t ap_wfs_count; @@ -346,8 +345,6 @@ static __init int tboot_late_init(void) atomic_set(&ap_wfs_count, 0); register_hotcpu_notifier(&tboot_cpu_notifier); - - acpi_os_set_prepare_sleep(&tboot_sleep); return 0; } diff --git a/trunk/arch/x86/kernel/vsyscall_64.c b/trunk/arch/x86/kernel/vsyscall_64.c index 7515cf0e1805..f386dc49f988 100644 --- a/trunk/arch/x86/kernel/vsyscall_64.c +++ b/trunk/arch/x86/kernel/vsyscall_64.c @@ -216,9 +216,9 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) current_thread_info()->sig_on_uaccess_error = 1; /* - * NULL is a valid user pointer (in the access_ok sense) on 32-bit and + * 0 is a valid user pointer (in the access_ok sense) on 32-bit and * 64-bit, so we don't need to special-case it here. For all the - * vsyscalls, NULL means "don't write anything" not "write it at + * vsyscalls, 0 means "don't write anything" not "write it at * address 0". */ ret = -EFAULT; @@ -247,7 +247,7 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) ret = sys_getcpu((unsigned __user *)regs->di, (unsigned __user *)regs->si, - NULL); + 0); break; } diff --git a/trunk/arch/x86/kernel/x86_init.c b/trunk/arch/x86/kernel/x86_init.c index 9cf71d0b2d37..e9f265fd79ae 100644 --- a/trunk/arch/x86/kernel/x86_init.c +++ b/trunk/arch/x86/kernel/x86_init.c @@ -93,6 +93,7 @@ struct x86_init_ops x86_init __initdata = { struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = { .early_percpu_clock_init = x86_init_noop, .setup_percpu_clockev = setup_secondary_APIC_clock, + .fixup_cpu_id = x86_default_fixup_cpu_id, }; static void default_nmi_init(void) { }; diff --git a/trunk/arch/x86/kvm/pmu.c b/trunk/arch/x86/kvm/pmu.c index 2e88438ffd83..a73f0c104813 100644 --- a/trunk/arch/x86/kvm/pmu.c +++ b/trunk/arch/x86/kvm/pmu.c @@ -369,7 +369,7 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data) case MSR_CORE_PERF_FIXED_CTR_CTRL: if (pmu->fixed_ctr_ctrl == data) return 0; - if (!(data & 0xfffffffffffff444ull)) { + if (!(data & 0xfffffffffffff444)) { reprogram_fixed_counters(pmu, data); return 0; } @@ -459,17 +459,17 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu) pmu->available_event_types = ~entry->ebx & ((1ull << bitmap_len) - 1); if (pmu->version == 1) { - pmu->nr_arch_fixed_counters = 0; - } else { - pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f), - X86_PMC_MAX_FIXED); - pmu->counter_bitmask[KVM_PMC_FIXED] = - ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1; + pmu->global_ctrl = (1 << pmu->nr_arch_gp_counters) - 1; + return; } - pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) | - (((1ull << pmu->nr_arch_fixed_counters) - 1) << X86_PMC_IDX_FIXED); - pmu->global_ctrl_mask = ~pmu->global_ctrl; + pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f), + X86_PMC_MAX_FIXED); + pmu->counter_bitmask[KVM_PMC_FIXED] = + ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1; + pmu->global_ctrl_mask = ~(((1 << pmu->nr_arch_gp_counters) - 1) + | (((1ull << pmu->nr_arch_fixed_counters) - 1) + << X86_PMC_IDX_FIXED)); } void kvm_pmu_init(struct kvm_vcpu *vcpu) diff --git a/trunk/arch/x86/kvm/vmx.c b/trunk/arch/x86/kvm/vmx.c index 4ff0ab9bc3c8..280751c84724 100644 --- a/trunk/arch/x86/kvm/vmx.c +++ b/trunk/arch/x86/kvm/vmx.c @@ -2210,12 +2210,9 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) msr = find_msr_entry(vmx, msr_index); if (msr) { msr->data = data; - if (msr - vmx->guest_msrs < vmx->save_nmsrs) { - preempt_disable(); + if (msr - vmx->guest_msrs < vmx->save_nmsrs) kvm_set_shared_msr(msr->index, msr->data, msr->mask); - preempt_enable(); - } break; } ret = kvm_set_msr_common(vcpu, msr_index, data); @@ -3909,9 +3906,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu) vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->vpid); vmx->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET; - vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); vmx_set_cr0(&vmx->vcpu, kvm_read_cr0(vcpu)); /* enter rmode */ - srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); vmx_set_cr4(&vmx->vcpu, 0); vmx_set_efer(&vmx->vcpu, 0); vmx_fpu_activate(&vmx->vcpu); diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index 91a5e989abcf..4044ce0bf7c1 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -6336,11 +6336,13 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, if (npages && !old.rmap) { unsigned long userspace_addr; - userspace_addr = vm_mmap(NULL, 0, + down_write(¤t->mm->mmap_sem); + userspace_addr = do_mmap(NULL, 0, npages * PAGE_SIZE, PROT_READ | PROT_WRITE, map_flags, 0); + up_write(¤t->mm->mmap_sem); if (IS_ERR((void *)userspace_addr)) return PTR_ERR((void *)userspace_addr); @@ -6364,8 +6366,10 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, if (!user_alloc && !old.user_alloc && old.rmap && !npages) { int ret; - ret = vm_munmap(old.userspace_addr, + down_write(¤t->mm->mmap_sem); + ret = do_munmap(current->mm, old.userspace_addr, old.npages * PAGE_SIZE); + up_write(¤t->mm->mmap_sem); if (ret < 0) printk(KERN_WARNING "kvm_vm_ioctl_set_memory_region: " diff --git a/trunk/arch/x86/lib/insn.c b/trunk/arch/x86/lib/insn.c index b1e6c4b2e8eb..25feb1ae71c5 100644 --- a/trunk/arch/x86/lib/insn.c +++ b/trunk/arch/x86/lib/insn.c @@ -379,8 +379,8 @@ void insn_get_displacement(struct insn *insn) return; } -/* Decode moffset16/32/64. Return 0 if failed */ -static int __get_moffset(struct insn *insn) +/* Decode moffset16/32/64 */ +static void __get_moffset(struct insn *insn) { switch (insn->addr_bytes) { case 2: @@ -397,19 +397,15 @@ static int __get_moffset(struct insn *insn) insn->moffset2.value = get_next(int, insn); insn->moffset2.nbytes = 4; break; - default: /* opnd_bytes must be modified manually */ - goto err_out; } insn->moffset1.got = insn->moffset2.got = 1; - return 1; - err_out: - return 0; + return; } -/* Decode imm v32(Iz). Return 0 if failed */ -static int __get_immv32(struct insn *insn) +/* Decode imm v32(Iz) */ +static void __get_immv32(struct insn *insn) { switch (insn->opnd_bytes) { case 2: @@ -421,18 +417,14 @@ static int __get_immv32(struct insn *insn) insn->immediate.value = get_next(int, insn); insn->immediate.nbytes = 4; break; - default: /* opnd_bytes must be modified manually */ - goto err_out; } - return 1; - err_out: - return 0; + return; } -/* Decode imm v64(Iv/Ov), Return 0 if failed */ -static int __get_immv(struct insn *insn) +/* Decode imm v64(Iv/Ov) */ +static void __get_immv(struct insn *insn) { switch (insn->opnd_bytes) { case 2: @@ -449,18 +441,15 @@ static int __get_immv(struct insn *insn) insn->immediate2.value = get_next(int, insn); insn->immediate2.nbytes = 4; break; - default: /* opnd_bytes must be modified manually */ - goto err_out; } insn->immediate1.got = insn->immediate2.got = 1; - return 1; err_out: - return 0; + return; } /* Decode ptr16:16/32(Ap) */ -static int __get_immptr(struct insn *insn) +static void __get_immptr(struct insn *insn) { switch (insn->opnd_bytes) { case 2: @@ -473,17 +462,14 @@ static int __get_immptr(struct insn *insn) break; case 8: /* ptr16:64 is not exist (no segment) */ - return 0; - default: /* opnd_bytes must be modified manually */ - goto err_out; + return; } insn->immediate2.value = get_next(unsigned short, insn); insn->immediate2.nbytes = 2; insn->immediate1.got = insn->immediate2.got = 1; - return 1; err_out: - return 0; + return; } /** @@ -503,8 +489,7 @@ void insn_get_immediate(struct insn *insn) insn_get_displacement(insn); if (inat_has_moffset(insn->attr)) { - if (!__get_moffset(insn)) - goto err_out; + __get_moffset(insn); goto done; } @@ -532,20 +517,16 @@ void insn_get_immediate(struct insn *insn) insn->immediate2.nbytes = 4; break; case INAT_IMM_PTR: - if (!__get_immptr(insn)) - goto err_out; + __get_immptr(insn); break; case INAT_IMM_VWORD32: - if (!__get_immv32(insn)) - goto err_out; + __get_immv32(insn); break; case INAT_IMM_VWORD: - if (!__get_immv(insn)) - goto err_out; + __get_immv(insn); break; default: - /* Here, insn must have an immediate, but failed */ - goto err_out; + break; } if (inat_has_second_immediate(insn->attr)) { insn->immediate2.value = get_next(char, insn); diff --git a/trunk/arch/x86/lib/usercopy.c b/trunk/arch/x86/lib/usercopy.c index d6ae30bbd7bb..97be9cb54483 100644 --- a/trunk/arch/x86/lib/usercopy.c +++ b/trunk/arch/x86/lib/usercopy.c @@ -7,8 +7,6 @@ #include #include -#include - /* * best effort, GUP based copy_from_user() that is NMI-safe */ @@ -43,104 +41,3 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n) return len; } EXPORT_SYMBOL_GPL(copy_from_user_nmi); - -static inline unsigned long count_bytes(unsigned long mask) -{ - mask = (mask - 1) & ~mask; - mask >>= 7; - return count_masked_bytes(mask); -} - -/* - * Do a strncpy, return length of string without final '\0'. - * 'count' is the user-supplied count (return 'count' if we - * hit it), 'max' is the address space maximum (and we return - * -EFAULT if we hit it). - */ -static inline long do_strncpy_from_user(char *dst, const char __user *src, long count, unsigned long max) -{ - long res = 0; - - /* - * Truncate 'max' to the user-specified limit, so that - * we only have one limit we need to check in the loop - */ - if (max > count) - max = count; - - while (max >= sizeof(unsigned long)) { - unsigned long c; - - /* Fall back to byte-at-a-time if we get a page fault */ - if (unlikely(__get_user(c,(unsigned long __user *)(src+res)))) - break; - /* This can write a few bytes past the NUL character, but that's ok */ - *(unsigned long *)(dst+res) = c; - c = has_zero(c); - if (c) - return res + count_bytes(c); - res += sizeof(unsigned long); - max -= sizeof(unsigned long); - } - - while (max) { - char c; - - if (unlikely(__get_user(c,src+res))) - return -EFAULT; - dst[res] = c; - if (!c) - return res; - res++; - max--; - } - - /* - * Uhhuh. We hit 'max'. But was that the user-specified maximum - * too? If so, that's ok - we got as much as the user asked for. - */ - if (res >= count) - return res; - - /* - * Nope: we hit the address space limit, and we still had more - * characters the caller would have wanted. That's an EFAULT. - */ - return -EFAULT; -} - -/** - * strncpy_from_user: - Copy a NUL terminated string from userspace. - * @dst: Destination address, in kernel space. This buffer must be at - * least @count bytes long. - * @src: Source address, in user space. - * @count: Maximum number of bytes to copy, including the trailing NUL. - * - * Copies a NUL-terminated string from userspace to kernel space. - * - * On success, returns the length of the string (not including the trailing - * NUL). - * - * If access to userspace fails, returns -EFAULT (some data may have been - * copied). - * - * If @count is smaller than the length of the string, copies @count bytes - * and returns @count. - */ -long -strncpy_from_user(char *dst, const char __user *src, long count) -{ - unsigned long max_addr, src_addr; - - if (unlikely(count <= 0)) - return 0; - - max_addr = current_thread_info()->addr_limit.seg; - src_addr = (unsigned long)src; - if (likely(src_addr < max_addr)) { - unsigned long max = max_addr - src_addr; - return do_strncpy_from_user(dst, src, count, max); - } - return -EFAULT; -} -EXPORT_SYMBOL(strncpy_from_user); diff --git a/trunk/arch/x86/lib/usercopy_32.c b/trunk/arch/x86/lib/usercopy_32.c index ef2a6a5d78e3..d9b094ca7aaa 100644 --- a/trunk/arch/x86/lib/usercopy_32.c +++ b/trunk/arch/x86/lib/usercopy_32.c @@ -32,6 +32,93 @@ static inline int __movsl_is_ok(unsigned long a1, unsigned long a2, unsigned lon #define movsl_is_ok(a1, a2, n) \ __movsl_is_ok((unsigned long)(a1), (unsigned long)(a2), (n)) +/* + * Copy a null terminated string from userspace. + */ + +#define __do_strncpy_from_user(dst, src, count, res) \ +do { \ + int __d0, __d1, __d2; \ + might_fault(); \ + __asm__ __volatile__( \ + " testl %1,%1\n" \ + " jz 2f\n" \ + "0: lodsb\n" \ + " stosb\n" \ + " testb %%al,%%al\n" \ + " jz 1f\n" \ + " decl %1\n" \ + " jnz 0b\n" \ + "1: subl %1,%0\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: movl %5,%0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + _ASM_EXTABLE(0b,3b) \ + : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1), \ + "=&D" (__d2) \ + : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \ + : "memory"); \ +} while (0) + +/** + * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking. + * @dst: Destination address, in kernel space. This buffer must be at + * least @count bytes long. + * @src: Source address, in user space. + * @count: Maximum number of bytes to copy, including the trailing NUL. + * + * Copies a NUL-terminated string from userspace to kernel space. + * Caller must check the specified block with access_ok() before calling + * this function. + * + * On success, returns the length of the string (not including the trailing + * NUL). + * + * If access to userspace fails, returns -EFAULT (some data may have been + * copied). + * + * If @count is smaller than the length of the string, copies @count bytes + * and returns @count. + */ +long +__strncpy_from_user(char *dst, const char __user *src, long count) +{ + long res; + __do_strncpy_from_user(dst, src, count, res); + return res; +} +EXPORT_SYMBOL(__strncpy_from_user); + +/** + * strncpy_from_user: - Copy a NUL terminated string from userspace. + * @dst: Destination address, in kernel space. This buffer must be at + * least @count bytes long. + * @src: Source address, in user space. + * @count: Maximum number of bytes to copy, including the trailing NUL. + * + * Copies a NUL-terminated string from userspace to kernel space. + * + * On success, returns the length of the string (not including the trailing + * NUL). + * + * If access to userspace fails, returns -EFAULT (some data may have been + * copied). + * + * If @count is smaller than the length of the string, copies @count bytes + * and returns @count. + */ +long +strncpy_from_user(char *dst, const char __user *src, long count) +{ + long res = -EFAULT; + if (access_ok(VERIFY_READ, src, 1)) + __do_strncpy_from_user(dst, src, count, res); + return res; +} +EXPORT_SYMBOL(strncpy_from_user); + /* * Zero Userspace */ diff --git a/trunk/arch/x86/lib/usercopy_64.c b/trunk/arch/x86/lib/usercopy_64.c index 0d0326f388c0..b7c2849ffb66 100644 --- a/trunk/arch/x86/lib/usercopy_64.c +++ b/trunk/arch/x86/lib/usercopy_64.c @@ -8,6 +8,55 @@ #include #include +/* + * Copy a null terminated string from userspace. + */ + +#define __do_strncpy_from_user(dst,src,count,res) \ +do { \ + long __d0, __d1, __d2; \ + might_fault(); \ + __asm__ __volatile__( \ + " testq %1,%1\n" \ + " jz 2f\n" \ + "0: lodsb\n" \ + " stosb\n" \ + " testb %%al,%%al\n" \ + " jz 1f\n" \ + " decq %1\n" \ + " jnz 0b\n" \ + "1: subq %1,%0\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: movq %5,%0\n" \ + " jmp 2b\n" \ + ".previous\n" \ + _ASM_EXTABLE(0b,3b) \ + : "=&r"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1), \ + "=&D" (__d2) \ + : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \ + : "memory"); \ +} while (0) + +long +__strncpy_from_user(char *dst, const char __user *src, long count) +{ + long res; + __do_strncpy_from_user(dst, src, count, res); + return res; +} +EXPORT_SYMBOL(__strncpy_from_user); + +long +strncpy_from_user(char *dst, const char __user *src, long count) +{ + long res = -EFAULT; + if (access_ok(VERIFY_READ, src, 1)) + return __strncpy_from_user(dst, src, count); + return res; +} +EXPORT_SYMBOL(strncpy_from_user); + /* * Zero Userspace */ diff --git a/trunk/arch/x86/net/bpf_jit.S b/trunk/arch/x86/net/bpf_jit.S index 877b9a1b2152..66870223f8c5 100644 --- a/trunk/arch/x86/net/bpf_jit.S +++ b/trunk/arch/x86/net/bpf_jit.S @@ -18,16 +18,16 @@ * r9d : hlen = skb->len - skb->data_len */ #define SKBDATA %r8 -#define SKF_MAX_NEG_OFF $(-0x200000) /* SKF_LL_OFF from filter.h */ -sk_load_word: - .globl sk_load_word +sk_load_word_ind: + .globl sk_load_word_ind - test %esi,%esi - js bpf_slow_path_word_neg + add %ebx,%esi /* offset += X */ +# test %esi,%esi /* if (offset < 0) goto bpf_error; */ + js bpf_error -sk_load_word_positive_offset: - .globl sk_load_word_positive_offset +sk_load_word: + .globl sk_load_word mov %r9d,%eax # hlen sub %esi,%eax # hlen - offset @@ -37,14 +37,15 @@ sk_load_word_positive_offset: bswap %eax /* ntohl() */ ret -sk_load_half: - .globl sk_load_half - test %esi,%esi - js bpf_slow_path_half_neg +sk_load_half_ind: + .globl sk_load_half_ind + + add %ebx,%esi /* offset += X */ + js bpf_error -sk_load_half_positive_offset: - .globl sk_load_half_positive_offset +sk_load_half: + .globl sk_load_half mov %r9d,%eax sub %esi,%eax # hlen - offset @@ -54,15 +55,14 @@ sk_load_half_positive_offset: rol $8,%ax # ntohs() ret +sk_load_byte_ind: + .globl sk_load_byte_ind + add %ebx,%esi /* offset += X */ + js bpf_error + sk_load_byte: .globl sk_load_byte - test %esi,%esi - js bpf_slow_path_byte_neg - -sk_load_byte_positive_offset: - .globl sk_load_byte_positive_offset - cmp %esi,%r9d /* if (offset >= hlen) goto bpf_slow_path_byte */ jle bpf_slow_path_byte movzbl (SKBDATA,%rsi),%eax @@ -73,21 +73,25 @@ sk_load_byte_positive_offset: * * Implements BPF_S_LDX_B_MSH : ldxb 4*([offset]&0xf) * Must preserve A accumulator (%eax) - * Inputs : %esi is the offset value + * Inputs : %esi is the offset value, already known positive */ -sk_load_byte_msh: - .globl sk_load_byte_msh - test %esi,%esi - js bpf_slow_path_byte_msh_neg - -sk_load_byte_msh_positive_offset: - .globl sk_load_byte_msh_positive_offset +ENTRY(sk_load_byte_msh) + CFI_STARTPROC cmp %esi,%r9d /* if (offset >= hlen) goto bpf_slow_path_byte_msh */ jle bpf_slow_path_byte_msh movzbl (SKBDATA,%rsi),%ebx and $15,%bl shl $2,%bl ret + CFI_ENDPROC +ENDPROC(sk_load_byte_msh) + +bpf_error: +# force a return 0 from jit handler + xor %eax,%eax + mov -8(%rbp),%rbx + leaveq + ret /* rsi contains offset and can be scratched */ #define bpf_slow_path_common(LEN) \ @@ -134,67 +138,3 @@ bpf_slow_path_byte_msh: shl $2,%al xchg %eax,%ebx ret - -#define sk_negative_common(SIZE) \ - push %rdi; /* save skb */ \ - push %r9; \ - push SKBDATA; \ -/* rsi already has offset */ \ - mov $SIZE,%ecx; /* size */ \ - call bpf_internal_load_pointer_neg_helper; \ - test %rax,%rax; \ - pop SKBDATA; \ - pop %r9; \ - pop %rdi; \ - jz bpf_error - - -bpf_slow_path_word_neg: - cmp SKF_MAX_NEG_OFF, %esi /* test range */ - jl bpf_error /* offset lower -> error */ -sk_load_word_negative_offset: - .globl sk_load_word_negative_offset - sk_negative_common(4) - mov (%rax), %eax - bswap %eax - ret - -bpf_slow_path_half_neg: - cmp SKF_MAX_NEG_OFF, %esi - jl bpf_error -sk_load_half_negative_offset: - .globl sk_load_half_negative_offset - sk_negative_common(2) - mov (%rax),%ax - rol $8,%ax - movzwl %ax,%eax - ret - -bpf_slow_path_byte_neg: - cmp SKF_MAX_NEG_OFF, %esi - jl bpf_error -sk_load_byte_negative_offset: - .globl sk_load_byte_negative_offset - sk_negative_common(1) - movzbl (%rax), %eax - ret - -bpf_slow_path_byte_msh_neg: - cmp SKF_MAX_NEG_OFF, %esi - jl bpf_error -sk_load_byte_msh_negative_offset: - .globl sk_load_byte_msh_negative_offset - xchg %eax,%ebx /* dont lose A , X is about to be scratched */ - sk_negative_common(1) - movzbl (%rax),%eax - and $15,%al - shl $2,%al - xchg %eax,%ebx - ret - -bpf_error: -# force a return 0 from jit handler - xor %eax,%eax - mov -8(%rbp),%rbx - leaveq - ret diff --git a/trunk/arch/x86/net/bpf_jit_comp.c b/trunk/arch/x86/net/bpf_jit_comp.c index 0597f95b6da6..5671752f8d9c 100644 --- a/trunk/arch/x86/net/bpf_jit_comp.c +++ b/trunk/arch/x86/net/bpf_jit_comp.c @@ -30,10 +30,7 @@ int bpf_jit_enable __read_mostly; * assembly code in arch/x86/net/bpf_jit.S */ extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[]; -extern u8 sk_load_word_positive_offset[], sk_load_half_positive_offset[]; -extern u8 sk_load_byte_positive_offset[], sk_load_byte_msh_positive_offset[]; -extern u8 sk_load_word_negative_offset[], sk_load_half_negative_offset[]; -extern u8 sk_load_byte_negative_offset[], sk_load_byte_msh_negative_offset[]; +extern u8 sk_load_word_ind[], sk_load_half_ind[], sk_load_byte_ind[]; static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len) { @@ -120,8 +117,6 @@ static inline void bpf_flush_icache(void *start, void *end) set_fs(old_fs); } -#define CHOOSE_LOAD_FUNC(K, func) \ - ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset) void bpf_jit_compile(struct sk_filter *fp) { @@ -294,7 +289,7 @@ void bpf_jit_compile(struct sk_filter *fp) EMIT2(0x24, K & 0xFF); /* and imm8,%al */ } else if (K >= 0xFFFF0000) { EMIT2(0x66, 0x25); /* and imm16,%ax */ - EMIT(K, 2); + EMIT2(K, 2); } else { EMIT1_off32(0x25, K); /* and imm32,%eax */ } @@ -478,46 +473,44 @@ void bpf_jit_compile(struct sk_filter *fp) #endif break; case BPF_S_LD_W_ABS: - func = CHOOSE_LOAD_FUNC(K, sk_load_word); + func = sk_load_word; common_load: seen |= SEEN_DATAREF; + if ((int)K < 0) { + /* Abort the JIT because __load_pointer() is needed. */ + goto out; + } t_offset = func - (image + addrs[i]); EMIT1_off32(0xbe, K); /* mov imm32,%esi */ EMIT1_off32(0xe8, t_offset); /* call */ break; case BPF_S_LD_H_ABS: - func = CHOOSE_LOAD_FUNC(K, sk_load_half); + func = sk_load_half; goto common_load; case BPF_S_LD_B_ABS: - func = CHOOSE_LOAD_FUNC(K, sk_load_byte); + func = sk_load_byte; goto common_load; case BPF_S_LDX_B_MSH: - func = CHOOSE_LOAD_FUNC(K, sk_load_byte_msh); + if ((int)K < 0) { + /* Abort the JIT because __load_pointer() is needed. */ + goto out; + } seen |= SEEN_DATAREF | SEEN_XREG; - t_offset = func - (image + addrs[i]); + t_offset = sk_load_byte_msh - (image + addrs[i]); EMIT1_off32(0xbe, K); /* mov imm32,%esi */ EMIT1_off32(0xe8, t_offset); /* call sk_load_byte_msh */ break; case BPF_S_LD_W_IND: - func = sk_load_word; + func = sk_load_word_ind; common_load_ind: seen |= SEEN_DATAREF | SEEN_XREG; t_offset = func - (image + addrs[i]); - if (K) { - if (is_imm8(K)) { - EMIT3(0x8d, 0x73, K); /* lea imm8(%rbx), %esi */ - } else { - EMIT2(0x8d, 0xb3); /* lea imm32(%rbx),%esi */ - EMIT(K, 4); - } - } else { - EMIT2(0x89,0xde); /* mov %ebx,%esi */ - } + EMIT1_off32(0xbe, K); /* mov imm32,%esi */ EMIT1_off32(0xe8, t_offset); /* call sk_load_xxx_ind */ break; case BPF_S_LD_H_IND: - func = sk_load_half; + func = sk_load_half_ind; goto common_load_ind; case BPF_S_LD_B_IND: - func = sk_load_byte; + func = sk_load_byte_ind; goto common_load_ind; case BPF_S_JMP_JA: t_offset = addrs[i + K] - addrs[i]; diff --git a/trunk/arch/x86/platform/geode/net5501.c b/trunk/arch/x86/platform/geode/net5501.c index 646e3b5b4bb6..66d377e334f7 100644 --- a/trunk/arch/x86/platform/geode/net5501.c +++ b/trunk/arch/x86/platform/geode/net5501.c @@ -63,7 +63,7 @@ static struct gpio_led net5501_leds[] = { .name = "net5501:1", .gpio = 6, .default_trigger = "default-on", - .active_low = 0, + .active_low = 1, }, }; diff --git a/trunk/arch/x86/platform/mrst/mrst.c b/trunk/arch/x86/platform/mrst/mrst.c index e31bcd8f2eee..e0a37233c0af 100644 --- a/trunk/arch/x86/platform/mrst/mrst.c +++ b/trunk/arch/x86/platform/mrst/mrst.c @@ -805,7 +805,7 @@ void intel_scu_devices_create(void) } else i2c_register_board_info(i2c_bus[i], i2c_devs[i], 1); } - intel_scu_notifier_post(SCU_AVAILABLE, NULL); + intel_scu_notifier_post(SCU_AVAILABLE, 0L); } EXPORT_SYMBOL_GPL(intel_scu_devices_create); @@ -814,7 +814,7 @@ void intel_scu_devices_destroy(void) { int i; - intel_scu_notifier_post(SCU_DOWN, NULL); + intel_scu_notifier_post(SCU_DOWN, 0L); for (i = 0; i < ipc_next_dev; i++) platform_device_del(ipc_devs[i]); diff --git a/trunk/arch/x86/power/cpu.c b/trunk/arch/x86/power/cpu.c index 218cdb16163c..47936830968c 100644 --- a/trunk/arch/x86/power/cpu.c +++ b/trunk/arch/x86/power/cpu.c @@ -225,13 +225,13 @@ static void __restore_processor_state(struct saved_context *ctxt) fix_processor_context(); do_fpu_end(); - x86_platform.restore_sched_clock_state(); mtrr_bp_restore(); } /* Needed by apm.c */ void restore_processor_state(void) { + x86_platform.restore_sched_clock_state(); __restore_processor_state(&saved_context); } #ifdef CONFIG_X86_32 diff --git a/trunk/arch/x86/um/asm/barrier.h b/trunk/arch/x86/um/asm/barrier.h deleted file mode 100644 index 7d01b8c56c00..000000000000 --- a/trunk/arch/x86/um/asm/barrier.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef _ASM_UM_BARRIER_H_ -#define _ASM_UM_BARRIER_H_ - -#include -#include -#include -#include -#include - -#include -#include - -/* - * Force strict CPU ordering. - * And yes, this is required on UP too when we're talking - * to devices. - */ -#ifdef CONFIG_X86_32 - -#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) -#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) -#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) - -#else /* CONFIG_X86_32 */ - -#define mb() asm volatile("mfence" : : : "memory") -#define rmb() asm volatile("lfence" : : : "memory") -#define wmb() asm volatile("sfence" : : : "memory") - -#endif /* CONFIG_X86_32 */ - -#define read_barrier_depends() do { } while (0) - -#ifdef CONFIG_SMP - -#define smp_mb() mb() -#ifdef CONFIG_X86_PPRO_FENCE -#define smp_rmb() rmb() -#else /* CONFIG_X86_PPRO_FENCE */ -#define smp_rmb() barrier() -#endif /* CONFIG_X86_PPRO_FENCE */ - -#ifdef CONFIG_X86_OOSTORE -#define smp_wmb() wmb() -#else /* CONFIG_X86_OOSTORE */ -#define smp_wmb() barrier() -#endif /* CONFIG_X86_OOSTORE */ - -#define smp_read_barrier_depends() read_barrier_depends() -#define set_mb(var, value) do { (void)xchg(&var, value); } while (0) - -#else /* CONFIG_SMP */ - -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while (0) -#define set_mb(var, value) do { var = value; barrier(); } while (0) - -#endif /* CONFIG_SMP */ - -/* - * Stop RDTSC speculation. This is needed when you need to use RDTSC - * (or get_cycles or vread that possibly accesses the TSC) in a defined - * code region. - * - * (Could use an alternative three way for this if there was one.) - */ -static inline void rdtsc_barrier(void) -{ - alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); - alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); -} - -#endif diff --git a/trunk/arch/x86/um/asm/system.h b/trunk/arch/x86/um/asm/system.h new file mode 100644 index 000000000000..a459fd9b7598 --- /dev/null +++ b/trunk/arch/x86/um/asm/system.h @@ -0,0 +1,135 @@ +#ifndef _ASM_X86_SYSTEM_H_ +#define _ASM_X86_SYSTEM_H_ + +#include +#include +#include +#include +#include + +#include +#include + +/* entries in ARCH_DLINFO: */ +#ifdef CONFIG_IA32_EMULATION +# define AT_VECTOR_SIZE_ARCH 2 +#else +# define AT_VECTOR_SIZE_ARCH 1 +#endif + +extern unsigned long arch_align_stack(unsigned long sp); + +void default_idle(void); + +/* + * Force strict CPU ordering. + * And yes, this is required on UP too when we're talking + * to devices. + */ +#ifdef CONFIG_X86_32 +/* + * Some non-Intel clones support out of order store. wmb() ceases to be a + * nop for these. + */ +#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2) +#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2) +#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM) +#else +#define mb() asm volatile("mfence":::"memory") +#define rmb() asm volatile("lfence":::"memory") +#define wmb() asm volatile("sfence" ::: "memory") +#endif + +/** + * read_barrier_depends - Flush all pending reads that subsequents reads + * depend on. + * + * No data-dependent reads from memory-like regions are ever reordered + * over this barrier. All reads preceding this primitive are guaranteed + * to access memory (but not necessarily other CPUs' caches) before any + * reads following this primitive that depend on the data return by + * any of the preceding reads. This primitive is much lighter weight than + * rmb() on most CPUs, and is never heavier weight than is + * rmb(). + * + * These ordering constraints are respected by both the local CPU + * and the compiler. + * + * Ordering is not guaranteed by anything other than these primitives, + * not even by data dependencies. See the documentation for + * memory_barrier() for examples and URLs to more information. + * + * For example, the following code would force ordering (the initial + * value of "a" is zero, "b" is one, and "p" is "&a"): + * + * + * CPU 0 CPU 1 + * + * b = 2; + * memory_barrier(); + * p = &b; q = p; + * read_barrier_depends(); + * d = *q; + * + * + * because the read of "*q" depends on the read of "p" and these + * two reads are separated by a read_barrier_depends(). However, + * the following code, with the same initial values for "a" and "b": + * + * + * CPU 0 CPU 1 + * + * a = 2; + * memory_barrier(); + * b = 3; y = b; + * read_barrier_depends(); + * x = a; + * + * + * does not enforce ordering, since there is no data dependency between + * the read of "a" and the read of "b". Therefore, on some CPUs, such + * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() + * in cases like this where there are no data dependencies. + **/ + +#define read_barrier_depends() do { } while (0) + +#ifdef CONFIG_SMP +#define smp_mb() mb() +#ifdef CONFIG_X86_PPRO_FENCE +# define smp_rmb() rmb() +#else +# define smp_rmb() barrier() +#endif +#ifdef CONFIG_X86_OOSTORE +# define smp_wmb() wmb() +#else +# define smp_wmb() barrier() +#endif +#define smp_read_barrier_depends() read_barrier_depends() +#define set_mb(var, value) do { (void)xchg(&var, value); } while (0) +#else +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#define smp_read_barrier_depends() do { } while (0) +#define set_mb(var, value) do { var = value; barrier(); } while (0) +#endif + +/* + * Stop RDTSC speculation. This is needed when you need to use RDTSC + * (or get_cycles or vread that possibly accesses the TSC) in a defined + * code region. + * + * (Could use an alternative three way for this if there was one.) + */ +static inline void rdtsc_barrier(void) +{ + alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); + alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); +} + +extern void *_switch_to(void *prev, void *next, void *last); +#define switch_to(prev, next, last) prev = _switch_to(prev, next, last) + +#endif diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c index a8f8844b8d32..b132ade26f77 100644 --- a/trunk/arch/x86/xen/enlighten.c +++ b/trunk/arch/x86/xen/enlighten.c @@ -261,8 +261,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx, static bool __init xen_check_mwait(void) { -#if defined(CONFIG_ACPI) && !defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) && \ - !defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE) +#ifdef CONFIG_ACPI struct xen_platform_op op = { .cmd = XENPF_set_processor_pminfo, .u.set_pminfo.id = -1, @@ -350,6 +349,7 @@ static void __init xen_init_cpuid_mask(void) /* Xen will set CR4.OSXSAVE if supported and not disabled by force */ if ((cx & xsave_mask) != xsave_mask) cpuid_leaf1_ecx_mask &= ~xsave_mask; /* disable XSAVE & OSXSAVE */ + if (xen_check_mwait()) cpuid_leaf1_ecx_set_mask = (1 << (X86_FEATURE_MWAIT % 32)); } @@ -967,7 +967,7 @@ void xen_setup_shared_info(void) xen_setup_mfn_list_list(); } -/* This is called once we have the cpu_possible_mask */ +/* This is called once we have the cpu_possible_map */ void xen_setup_vcpu_info_placement(void) { int cpu; diff --git a/trunk/arch/x86/xen/mmu.c b/trunk/arch/x86/xen/mmu.c index b8e279479a6b..988828b479ed 100644 --- a/trunk/arch/x86/xen/mmu.c +++ b/trunk/arch/x86/xen/mmu.c @@ -1859,7 +1859,6 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, #endif /* CONFIG_X86_64 */ static unsigned char dummy_mapping[PAGE_SIZE] __page_aligned_bss; -static unsigned char fake_ioapic_mapping[PAGE_SIZE] __page_aligned_bss; static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) { @@ -1900,7 +1899,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) * We just don't map the IO APIC - all access is via * hypercalls. Keep the address in the pte for reference. */ - pte = pfn_pte(PFN_DOWN(__pa(fake_ioapic_mapping)), PAGE_KERNEL); + pte = pfn_pte(PFN_DOWN(__pa(dummy_mapping)), PAGE_KERNEL); break; #endif @@ -2065,7 +2064,6 @@ void __init xen_init_mmu_ops(void) pv_mmu_ops = xen_mmu_ops; memset(dummy_mapping, 0xff, PAGE_SIZE); - memset(fake_ioapic_mapping, 0xfd, PAGE_SIZE); } /* Protected by xen_reservation_lock. */ diff --git a/trunk/arch/x86/xen/pci-swiotlb-xen.c b/trunk/arch/x86/xen/pci-swiotlb-xen.c index 967633ad98c4..b480d4207a4c 100644 --- a/trunk/arch/x86/xen/pci-swiotlb-xen.c +++ b/trunk/arch/x86/xen/pci-swiotlb-xen.c @@ -12,8 +12,8 @@ int xen_swiotlb __read_mostly; static struct dma_map_ops xen_swiotlb_dma_ops = { .mapping_error = xen_swiotlb_dma_mapping_error, - .alloc = xen_swiotlb_alloc_coherent, - .free = xen_swiotlb_free_coherent, + .alloc_coherent = xen_swiotlb_alloc_coherent, + .free_coherent = xen_swiotlb_free_coherent, .sync_single_for_cpu = xen_swiotlb_sync_single_for_cpu, .sync_single_for_device = xen_swiotlb_sync_single_for_device, .sync_sg_for_cpu = xen_swiotlb_sync_sg_for_cpu, diff --git a/trunk/arch/x86/xen/smp.c b/trunk/arch/x86/xen/smp.c index 0503c0c493a9..02900e8ce26c 100644 --- a/trunk/arch/x86/xen/smp.c +++ b/trunk/arch/x86/xen/smp.c @@ -59,7 +59,7 @@ static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id) static void __cpuinit cpu_bringup(void) { - int cpu; + int cpu = smp_processor_id(); cpu_init(); touch_softlockup_watchdog(); @@ -178,7 +178,6 @@ static void __init xen_fill_possible_map(void) static void __init xen_filter_cpu_maps(void) { int i, rc; - unsigned int subtract = 0; if (!xen_initial_domain()) return; @@ -193,22 +192,8 @@ static void __init xen_filter_cpu_maps(void) } else { set_cpu_possible(i, false); set_cpu_present(i, false); - subtract++; } } -#ifdef CONFIG_HOTPLUG_CPU - /* This is akin to using 'nr_cpus' on the Linux command line. - * Which is OK as when we use 'dom0_max_vcpus=X' we can only - * have up to X, while nr_cpu_ids is greater than X. This - * normally is not a problem, except when CPU hotplugging - * is involved and then there might be more than X CPUs - * in the guest - which will not work as there is no - * hypercall to expand the max number of VCPUs an already - * running guest has. So cap it up to X. */ - if (subtract) - nr_cpu_ids = nr_cpu_ids - subtract; -#endif - } static void __init xen_smp_prepare_boot_cpu(void) diff --git a/trunk/arch/x86/xen/xen-asm.S b/trunk/arch/x86/xen/xen-asm.S index 3e45aa000718..79d7362ad6d1 100644 --- a/trunk/arch/x86/xen/xen-asm.S +++ b/trunk/arch/x86/xen/xen-asm.S @@ -96,7 +96,7 @@ ENTRY(xen_restore_fl_direct) /* check for unmasked and pending */ cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending - jnz 1f + jz 1f 2: call check_events 1: ENDPATCH(xen_restore_fl_direct) diff --git a/trunk/arch/xtensa/include/asm/hardirq.h b/trunk/arch/xtensa/include/asm/hardirq.h index 91695a135498..26664cef8f11 100644 --- a/trunk/arch/xtensa/include/asm/hardirq.h +++ b/trunk/arch/xtensa/include/asm/hardirq.h @@ -11,6 +11,9 @@ #ifndef _XTENSA_HARDIRQ_H #define _XTENSA_HARDIRQ_H +void ack_bad_irq(unsigned int irq); +#define ack_bad_irq ack_bad_irq + #include #endif /* _XTENSA_HARDIRQ_H */ diff --git a/trunk/arch/xtensa/include/asm/io.h b/trunk/arch/xtensa/include/asm/io.h index 4beb43c087d3..d04cd3a625fa 100644 --- a/trunk/arch/xtensa/include/asm/io.h +++ b/trunk/arch/xtensa/include/asm/io.h @@ -14,7 +14,6 @@ #ifdef __KERNEL__ #include #include -#include #include #include diff --git a/trunk/arch/xtensa/kernel/signal.c b/trunk/arch/xtensa/kernel/signal.c index d78869a00b11..b69b000349fc 100644 --- a/trunk/arch/xtensa/kernel/signal.c +++ b/trunk/arch/xtensa/kernel/signal.c @@ -496,7 +496,6 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { - int ret; /* Are we from a system call? */ diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index 1f61b74867e4..3a78b00edd71 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -483,7 +483,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) if (!q) return NULL; - q->id = ida_simple_get(&blk_queue_ida, 0, 0, gfp_mask); + q->id = ida_simple_get(&blk_queue_ida, 0, 0, GFP_KERNEL); if (q->id < 0) goto fail_q; @@ -1277,8 +1277,7 @@ static bool attempt_plug_merge(struct request_queue *q, struct bio *bio, list_for_each_entry_reverse(rq, &plug->list, queuelist) { int el_ret; - if (rq->q == q) - (*request_count)++; + (*request_count)++; if (rq->q != q || !blk_rq_merge_ok(rq, bio)) continue; diff --git a/trunk/block/blk-throttle.c b/trunk/block/blk-throttle.c index f2ddb94626bd..5eed6a76721d 100644 --- a/trunk/block/blk-throttle.c +++ b/trunk/block/blk-throttle.c @@ -1218,7 +1218,7 @@ void blk_throtl_drain(struct request_queue *q) struct bio_list bl; struct bio *bio; - queue_lockdep_assert_held(q); + WARN_ON_ONCE(!queue_is_locked(q)); bio_list_init(&bl); diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index 3c38536bd52c..457295253566 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -295,7 +295,6 @@ struct cfq_data { unsigned int cfq_slice_idle; unsigned int cfq_group_idle; unsigned int cfq_latency; - unsigned int cfq_target_latency; /* * Fallback dummy cfqq for extreme OOM conditions @@ -605,7 +604,7 @@ cfq_group_slice(struct cfq_data *cfqd, struct cfq_group *cfqg) { struct cfq_rb_root *st = &cfqd->grp_service_tree; - return cfqd->cfq_target_latency * cfqg->weight / st->total_weight; + return cfq_target_latency * cfqg->weight / st->total_weight; } static inline unsigned @@ -2272,8 +2271,7 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg) * to have higher weight. A more accurate thing would be to * calculate system wide asnc/sync ratio. */ - tmp = cfqd->cfq_target_latency * - cfqg_busy_async_queues(cfqd, cfqg); + tmp = cfq_target_latency * cfqg_busy_async_queues(cfqd, cfqg); tmp = tmp/cfqd->busy_queues; slice = min_t(unsigned, slice, tmp); @@ -3739,7 +3737,6 @@ static void *cfq_init_queue(struct request_queue *q) cfqd->cfq_back_penalty = cfq_back_penalty; cfqd->cfq_slice[0] = cfq_slice_async; cfqd->cfq_slice[1] = cfq_slice_sync; - cfqd->cfq_target_latency = cfq_target_latency; cfqd->cfq_slice_async_rq = cfq_slice_async_rq; cfqd->cfq_slice_idle = cfq_slice_idle; cfqd->cfq_group_idle = cfq_group_idle; @@ -3791,7 +3788,6 @@ SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1); SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1); SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0); SHOW_FUNCTION(cfq_low_latency_show, cfqd->cfq_latency, 0); -SHOW_FUNCTION(cfq_target_latency_show, cfqd->cfq_target_latency, 1); #undef SHOW_FUNCTION #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ @@ -3825,7 +3821,6 @@ STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1); STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, UINT_MAX, 0); STORE_FUNCTION(cfq_low_latency_store, &cfqd->cfq_latency, 0, 1, 0); -STORE_FUNCTION(cfq_target_latency_store, &cfqd->cfq_target_latency, 1, UINT_MAX, 1); #undef STORE_FUNCTION #define CFQ_ATTR(name) \ @@ -3843,7 +3838,6 @@ static struct elv_fs_entry cfq_attrs[] = { CFQ_ATTR(slice_idle), CFQ_ATTR(group_idle), CFQ_ATTR(low_latency), - CFQ_ATTR(target_latency), __ATTR_NULL }; diff --git a/trunk/crypto/Kconfig b/trunk/crypto/Kconfig index 8e84225c096b..21ff9d015432 100644 --- a/trunk/crypto/Kconfig +++ b/trunk/crypto/Kconfig @@ -627,7 +627,7 @@ config CRYPTO_BLOWFISH_COMMON config CRYPTO_BLOWFISH_X86_64 tristate "Blowfish cipher algorithm (x86_64)" - depends on X86 && 64BIT + depends on (X86 || UML_X86) && 64BIT select CRYPTO_ALGAPI select CRYPTO_BLOWFISH_COMMON help @@ -657,7 +657,7 @@ config CRYPTO_CAMELLIA config CRYPTO_CAMELLIA_X86_64 tristate "Camellia cipher algorithm (x86_64)" - depends on X86 && 64BIT + depends on (X86 || UML_X86) && 64BIT depends on CRYPTO select CRYPTO_ALGAPI select CRYPTO_LRW @@ -893,7 +893,7 @@ config CRYPTO_TWOFISH_X86_64 config CRYPTO_TWOFISH_X86_64_3WAY tristate "Twofish cipher algorithm (x86_64, 3-way parallel)" - depends on X86 && 64BIT + depends on (X86 || UML_X86) && 64BIT select CRYPTO_ALGAPI select CRYPTO_TWOFISH_COMMON select CRYPTO_TWOFISH_X86_64 diff --git a/trunk/crypto/ablkcipher.c b/trunk/crypto/ablkcipher.c index 8d3a056ebeea..a0f768c1d9aa 100644 --- a/trunk/crypto/ablkcipher.c +++ b/trunk/crypto/ablkcipher.c @@ -613,7 +613,8 @@ static int crypto_givcipher_default(struct crypto_alg *alg, u32 type, u32 mask) return err; } -struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type, u32 mask) +static struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type, + u32 mask) { struct crypto_alg *alg; @@ -651,7 +652,6 @@ struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type, u32 mask) return ERR_PTR(crypto_givcipher_default(alg, type, mask)); } -EXPORT_SYMBOL_GPL(crypto_lookup_skcipher); int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name, u32 type, u32 mask) diff --git a/trunk/crypto/aead.c b/trunk/crypto/aead.c index e4cb35159be4..04add3dca6fe 100644 --- a/trunk/crypto/aead.c +++ b/trunk/crypto/aead.c @@ -470,7 +470,8 @@ static int crypto_nivaead_default(struct crypto_alg *alg, u32 type, u32 mask) return err; } -struct crypto_alg *crypto_lookup_aead(const char *name, u32 type, u32 mask) +static struct crypto_alg *crypto_lookup_aead(const char *name, u32 type, + u32 mask) { struct crypto_alg *alg; @@ -502,7 +503,6 @@ struct crypto_alg *crypto_lookup_aead(const char *name, u32 type, u32 mask) return ERR_PTR(crypto_nivaead_default(alg, type, mask)); } -EXPORT_SYMBOL_GPL(crypto_lookup_aead); int crypto_grab_aead(struct crypto_aead_spawn *spawn, const char *name, u32 type, u32 mask) diff --git a/trunk/crypto/crypto_user.c b/trunk/crypto/crypto_user.c index f1ea0a064135..f76e42bcc6e7 100644 --- a/trunk/crypto/crypto_user.c +++ b/trunk/crypto/crypto_user.c @@ -21,13 +21,9 @@ #include #include #include -#include #include #include #include -#include -#include - #include "internal.h" DEFINE_MUTEX(crypto_cfg_mutex); @@ -305,60 +301,6 @@ static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh, return crypto_unregister_instance(alg); } -static struct crypto_alg *crypto_user_skcipher_alg(const char *name, u32 type, - u32 mask) -{ - int err; - struct crypto_alg *alg; - - type = crypto_skcipher_type(type); - mask = crypto_skcipher_mask(mask); - - for (;;) { - alg = crypto_lookup_skcipher(name, type, mask); - if (!IS_ERR(alg)) - return alg; - - err = PTR_ERR(alg); - if (err != -EAGAIN) - break; - if (signal_pending(current)) { - err = -EINTR; - break; - } - } - - return ERR_PTR(err); -} - -static struct crypto_alg *crypto_user_aead_alg(const char *name, u32 type, - u32 mask) -{ - int err; - struct crypto_alg *alg; - - type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV); - type |= CRYPTO_ALG_TYPE_AEAD; - mask &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV); - mask |= CRYPTO_ALG_TYPE_MASK; - - for (;;) { - alg = crypto_lookup_aead(name, type, mask); - if (!IS_ERR(alg)) - return alg; - - err = PTR_ERR(alg); - if (err != -EAGAIN) - break; - if (signal_pending(current)) { - err = -EINTR; - break; - } - } - - return ERR_PTR(err); -} - static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh, struct nlattr **attrs) { @@ -383,19 +325,7 @@ static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh, else name = p->cru_name; - switch (p->cru_type & p->cru_mask & CRYPTO_ALG_TYPE_MASK) { - case CRYPTO_ALG_TYPE_AEAD: - alg = crypto_user_aead_alg(name, p->cru_type, p->cru_mask); - break; - case CRYPTO_ALG_TYPE_GIVCIPHER: - case CRYPTO_ALG_TYPE_BLKCIPHER: - case CRYPTO_ALG_TYPE_ABLKCIPHER: - alg = crypto_user_skcipher_alg(name, p->cru_type, p->cru_mask); - break; - default: - alg = crypto_alg_mod_lookup(name, p->cru_type, p->cru_mask); - } - + alg = crypto_alg_mod_lookup(name, p->cru_type, p->cru_mask); if (IS_ERR(alg)) return PTR_ERR(alg); @@ -457,20 +387,12 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) && (nlh->nlmsg_flags & NLM_F_DUMP))) { - struct crypto_alg *alg; - u16 dump_alloc = 0; - if (link->dump == NULL) return -EINVAL; - - list_for_each_entry(alg, &crypto_alg_list, cra_list) - dump_alloc += CRYPTO_REPORT_MAXSIZE; - { struct netlink_dump_control c = { .dump = link->dump, .done = link->done, - .min_dump_alloc = dump_alloc, }; return netlink_dump_start(crypto_nlsk, skb, nlh, &c); } diff --git a/trunk/crypto/pcrypt.c b/trunk/crypto/pcrypt.c index b2c99dc1c5e2..29a89dad68b6 100644 --- a/trunk/crypto/pcrypt.c +++ b/trunk/crypto/pcrypt.c @@ -280,11 +280,11 @@ static int pcrypt_aead_init_tfm(struct crypto_tfm *tfm) ictx->tfm_count++; - cpu_index = ictx->tfm_count % cpumask_weight(cpu_online_mask); + cpu_index = ictx->tfm_count % cpumask_weight(cpu_active_mask); - ctx->cb_cpu = cpumask_first(cpu_online_mask); + ctx->cb_cpu = cpumask_first(cpu_active_mask); for (cpu = 0; cpu < cpu_index; cpu++) - ctx->cb_cpu = cpumask_next(ctx->cb_cpu, cpu_online_mask); + ctx->cb_cpu = cpumask_next(ctx->cb_cpu, cpu_active_mask); cipher = crypto_spawn_aead(crypto_instance_ctx(inst)); @@ -472,7 +472,7 @@ static int pcrypt_init_padata(struct padata_pcrypt *pcrypt, goto err_free_padata; } - cpumask_and(mask->mask, cpu_possible_mask, cpu_online_mask); + cpumask_and(mask->mask, cpu_possible_mask, cpu_active_mask); rcu_assign_pointer(pcrypt->cb_cpumask, mask); pcrypt->nblock.notifier_call = pcrypt_cpumask_change_notify; diff --git a/trunk/crypto/sha512_generic.c b/trunk/crypto/sha512_generic.c index dd30f40af9f5..107f6f7be5e1 100644 --- a/trunk/crypto/sha512_generic.c +++ b/trunk/crypto/sha512_generic.c @@ -174,7 +174,7 @@ sha512_update(struct shash_desc *desc, const u8 *data, unsigned int len) index = sctx->count[0] & 0x7f; /* Update number of bytes */ - if ((sctx->count[0] += len) < len) + if (!(sctx->count[0] += len)) sctx->count[1]++; part_len = 128 - index; diff --git a/trunk/drivers/Kconfig b/trunk/drivers/Kconfig index d236aef7e59f..6f0459cb745b 100644 --- a/trunk/drivers/Kconfig +++ b/trunk/drivers/Kconfig @@ -50,8 +50,6 @@ source "drivers/i2c/Kconfig" source "drivers/spi/Kconfig" -source "drivers/hsi/Kconfig" - source "drivers/pps/Kconfig" source "drivers/ptp/Kconfig" diff --git a/trunk/drivers/Makefile b/trunk/drivers/Makefile index 95952c82bf16..262b19d6b627 100644 --- a/trunk/drivers/Makefile +++ b/trunk/drivers/Makefile @@ -53,7 +53,6 @@ obj-$(CONFIG_ATA) += ata/ obj-$(CONFIG_TARGET_CORE) += target/ obj-$(CONFIG_MTD) += mtd/ obj-$(CONFIG_SPI) += spi/ -obj-y += hsi/ obj-y += net/ obj-$(CONFIG_ATM) += atm/ obj-$(CONFIG_FUSION) += message/ diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index 47768ff87343..7556913aba45 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -384,15 +384,6 @@ config ACPI_CUSTOM_METHOD load additional kernel modules after boot, this feature may be used to override that restriction). -config ACPI_BGRT - tristate "Boottime Graphics Resource Table support" - default n - help - This driver adds support for exposing the ACPI Boottime Graphics - Resource Table, which allows the operating system to obtain - data from the firmware boot splash. It will appear under - /sys/firmware/acpi/bgrt/ . - source "drivers/acpi/apei/Kconfig" endif # ACPI diff --git a/trunk/drivers/acpi/Makefile b/trunk/drivers/acpi/Makefile index 47199e2a9130..1567028d2038 100644 --- a/trunk/drivers/acpi/Makefile +++ b/trunk/drivers/acpi/Makefile @@ -62,7 +62,6 @@ obj-$(CONFIG_ACPI_SBS) += sbs.o obj-$(CONFIG_ACPI_HED) += hed.o obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o -obj-$(CONFIG_ACPI_BGRT) += bgrt.o # processor has its own "processor." module_param namespace processor-y := processor_driver.o processor_throttling.o diff --git a/trunk/drivers/acpi/acpica/Makefile b/trunk/drivers/acpi/acpica/Makefile index 793b8cc8e256..0ca208b6dcf0 100644 --- a/trunk/drivers/acpi/acpica/Makefile +++ b/trunk/drivers/acpi/acpica/Makefile @@ -68,14 +68,12 @@ acpi-y += \ acpi-y += \ hwacpi.o \ - hwesleep.o \ hwgpe.o \ hwpci.o \ hwregs.o \ hwsleep.o \ hwvalid.o \ - hwxface.o \ - hwxfsleep.o + hwxface.o acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o diff --git a/trunk/drivers/acpi/acpica/accommon.h b/trunk/drivers/acpi/acpica/accommon.h index 8a7d51bfb3b3..a44bd424f9f4 100644 --- a/trunk/drivers/acpi/acpica/accommon.h +++ b/trunk/drivers/acpi/acpica/accommon.h @@ -51,6 +51,7 @@ * * Note: The order of these include files is important. */ +#include "acconfig.h" /* Global configuration constants */ #include "acmacros.h" /* C macros */ #include "aclocal.h" /* Internal data types */ #include "acobject.h" /* ACPI internal object */ diff --git a/trunk/include/acpi/acconfig.h b/trunk/drivers/acpi/acpica/acconfig.h similarity index 92% rename from trunk/include/acpi/acconfig.h rename to trunk/drivers/acpi/acpica/acconfig.h index 03f14856bd09..1f30af613e87 100644 --- a/trunk/include/acpi/acconfig.h +++ b/trunk/drivers/acpi/acpica/acconfig.h @@ -85,23 +85,6 @@ */ #define ACPI_CHECKSUM_ABORT FALSE -/* - * Generate a version of ACPICA that only supports "reduced hardware" - * platforms (as defined in ACPI 5.0). Set to TRUE to generate a specialized - * version of ACPICA that ONLY supports the ACPI 5.0 "reduced hardware" - * model. In other words, no ACPI hardware is supported. - * - * If TRUE, this means no support for the following: - * PM Event and Control registers - * SCI interrupt (and handler) - * Fixed Events - * General Purpose Events (GPEs) - * Global Lock - * ACPI PM timer - * FACS table (Waking vectors and Global Lock) - */ -#define ACPI_REDUCED_HARDWARE FALSE - /****************************************************************************** * * Subsystem Constants @@ -110,7 +93,7 @@ /* Version of ACPI supported */ -#define ACPI_CA_SUPPORT_LEVEL 5 +#define ACPI_CA_SUPPORT_LEVEL 3 /* Maximum count for a semaphore object */ diff --git a/trunk/drivers/acpi/acpica/acdebug.h b/trunk/drivers/acpi/acpica/acdebug.h index 5e8abb07724f..deaa81979561 100644 --- a/trunk/drivers/acpi/acpica/acdebug.h +++ b/trunk/drivers/acpi/acpica/acdebug.h @@ -111,7 +111,7 @@ acpi_status acpi_db_find_name_in_namespace(char *name_arg); void acpi_db_set_scope(char *name); -ACPI_HW_DEPENDENT_RETURN_OK(acpi_status acpi_db_sleep(char *object_arg)) +acpi_status acpi_db_sleep(char *object_arg); void acpi_db_find_references(char *object_arg); @@ -119,13 +119,11 @@ void acpi_db_display_locks(void); void acpi_db_display_resources(char *object_arg); -ACPI_HW_DEPENDENT_RETURN_VOID(void acpi_db_display_gpes(void)) +void acpi_db_display_gpes(void); void acpi_db_check_integrity(void); -ACPI_HW_DEPENDENT_RETURN_VOID(void - acpi_db_generate_gpe(char *gpe_arg, - char *block_arg)) +void acpi_db_generate_gpe(char *gpe_arg, char *block_arg); void acpi_db_check_predefined_names(void); diff --git a/trunk/drivers/acpi/acpica/acevents.h b/trunk/drivers/acpi/acpica/acevents.h index d700f63e4701..c53caa521a30 100644 --- a/trunk/drivers/acpi/acpica/acevents.h +++ b/trunk/drivers/acpi/acpica/acevents.h @@ -69,10 +69,11 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node *node, */ acpi_status acpi_ev_init_global_lock_handler(void); -ACPI_HW_DEPENDENT_RETURN_OK(acpi_status - acpi_ev_acquire_global_lock(u16 timeout)) - ACPI_HW_DEPENDENT_RETURN_OK(acpi_status acpi_ev_release_global_lock(void)) - acpi_status acpi_ev_remove_global_lock_handler(void); +acpi_status acpi_ev_acquire_global_lock(u16 timeout); + +acpi_status acpi_ev_release_global_lock(void); + +acpi_status acpi_ev_remove_global_lock_handler(void); /* * evgpe - Low-level GPE support @@ -113,9 +114,7 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, struct acpi_gpe_block_info *gpe_block, void *context); -ACPI_HW_DEPENDENT_RETURN_OK(acpi_status - acpi_ev_delete_gpe_block(struct acpi_gpe_block_info - *gpe_block)) +acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block); u32 acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, @@ -127,10 +126,9 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, */ acpi_status acpi_ev_gpe_initialize(void); -ACPI_HW_DEPENDENT_RETURN_VOID(void - acpi_ev_update_gpes(acpi_owner_id table_owner_id)) +void acpi_ev_update_gpes(acpi_owner_id table_owner_id); - acpi_status +acpi_status acpi_ev_match_gpe_method(acpi_handle obj_handle, u32 level, void *context, void **return_value); @@ -239,5 +237,6 @@ acpi_status acpi_ev_remove_sci_handler(void); u32 acpi_ev_initialize_sCI(u32 program_sCI); -ACPI_HW_DEPENDENT_RETURN_VOID(void acpi_ev_terminate(void)) +void acpi_ev_terminate(void); + #endif /* __ACEVENTS_H__ */ diff --git a/trunk/drivers/acpi/acpica/acglobal.h b/trunk/drivers/acpi/acpica/acglobal.h index 4f7d3f57d05c..2853f7673f3b 100644 --- a/trunk/drivers/acpi/acpica/acglobal.h +++ b/trunk/drivers/acpi/acpica/acglobal.h @@ -147,7 +147,7 @@ u8 acpi_gbl_system_awake_and_running; */ u8 acpi_gbl_reduced_hardware; -#endif /* DEFINE_ACPI_GLOBALS */ +#endif /* Do not disassemble buffers to resource descriptors */ @@ -184,12 +184,8 @@ ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; * found in the RSDT/XSDT. */ ACPI_EXTERN struct acpi_table_list acpi_gbl_root_table_list; - -#if (!ACPI_REDUCED_HARDWARE) ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS; -#endif /* !ACPI_REDUCED_HARDWARE */ - /* These addresses are calculated from the FADT Event Block addresses */ ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_status; @@ -401,15 +397,10 @@ ACPI_EXTERN struct acpi_fixed_event_handler ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; ACPI_EXTERN struct acpi_gpe_block_info *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; - -#if (!ACPI_REDUCED_HARDWARE) - ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized; ACPI_EXTERN ACPI_GBL_EVENT_HANDLER acpi_gbl_global_event_handler; ACPI_EXTERN void *acpi_gbl_global_event_handler_context; -#endif /* !ACPI_REDUCED_HARDWARE */ - /***************************************************************************** * * Debugger globals diff --git a/trunk/drivers/acpi/acpica/achware.h b/trunk/drivers/acpi/acpica/achware.h index 5ccb99ae3a6f..677793e938f5 100644 --- a/trunk/drivers/acpi/acpica/achware.h +++ b/trunk/drivers/acpi/acpica/achware.h @@ -80,26 +80,6 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value); acpi_status acpi_hw_clear_acpi_status(void); -/* - * hwsleep - sleep/wake support (Legacy sleep registers) - */ -acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags); - -acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags); - -acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags); - -/* - * hwesleep - sleep/wake support (Extended FADT-V5 sleep registers) - */ -void acpi_hw_execute_sleep_method(char *method_name, u32 integer_argument); - -acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags); - -acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags); - -acpi_status acpi_hw_extended_wake(u8 sleep_state, u8 flags); - /* * hwvalid - Port I/O with validation */ @@ -148,4 +128,16 @@ acpi_status acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id, acpi_handle root_pci_device, acpi_handle pci_region); +#ifdef ACPI_FUTURE_USAGE +/* + * hwtimer - ACPI Timer prototypes + */ +acpi_status acpi_get_timer_resolution(u32 * resolution); + +acpi_status acpi_get_timer(u32 * ticks); + +acpi_status +acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed); +#endif /* ACPI_FUTURE_USAGE */ + #endif /* __ACHWARE_H__ */ diff --git a/trunk/drivers/acpi/acpica/aclocal.h b/trunk/drivers/acpi/acpica/aclocal.h index e3922ca20e7f..3f24068837d5 100644 --- a/trunk/drivers/acpi/acpica/aclocal.h +++ b/trunk/drivers/acpi/acpica/aclocal.h @@ -370,7 +370,6 @@ struct acpi_predefined_data { /* Defines for Flags field above */ #define ACPI_OBJECT_REPAIRED 1 -#define ACPI_OBJECT_WRAPPED 2 /* * Bitmapped return value types diff --git a/trunk/drivers/acpi/acpica/acmacros.h b/trunk/drivers/acpi/acpica/acmacros.h index f119f473f71a..ef338a96f5b2 100644 --- a/trunk/drivers/acpi/acpica/acmacros.h +++ b/trunk/drivers/acpi/acpica/acmacros.h @@ -516,12 +516,6 @@ #endif /* ACPI_DEBUG_OUTPUT */ -#if (!ACPI_REDUCED_HARDWARE) -#define ACPI_HW_OPTIONAL_FUNCTION(addr) addr -#else -#define ACPI_HW_OPTIONAL_FUNCTION(addr) NULL -#endif - /* * Some code only gets executed when the debugger is built in. * Note that this is entirely independent of whether the diff --git a/trunk/drivers/acpi/acpica/acnamesp.h b/trunk/drivers/acpi/acpica/acnamesp.h index 9b19d4b86424..2c9e0f049523 100644 --- a/trunk/drivers/acpi/acpica/acnamesp.h +++ b/trunk/drivers/acpi/acpica/acnamesp.h @@ -283,9 +283,8 @@ acpi_ns_repair_object(struct acpi_predefined_data *data, union acpi_operand_object **return_object_ptr); acpi_status -acpi_ns_wrap_with_package(struct acpi_predefined_data *data, - union acpi_operand_object *original_object, - union acpi_operand_object **obj_desc_ptr); +acpi_ns_repair_package_list(struct acpi_predefined_data *data, + union acpi_operand_object **obj_desc_ptr); acpi_status acpi_ns_repair_null_element(struct acpi_predefined_data *data, diff --git a/trunk/drivers/acpi/acpica/actables.h b/trunk/drivers/acpi/acpica/actables.h index 6712965ba8ae..d5bec304c823 100644 --- a/trunk/drivers/acpi/acpica/actables.h +++ b/trunk/drivers/acpi/acpica/actables.h @@ -67,11 +67,6 @@ acpi_status acpi_tb_resize_root_table_list(void); acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc); -struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header - *table_header, - struct acpi_table_desc - *table_desc); - acpi_status acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index); diff --git a/trunk/drivers/acpi/acpica/evevent.c b/trunk/drivers/acpi/acpica/evevent.c index 07e4dc44f81c..6729ebe2f1e6 100644 --- a/trunk/drivers/acpi/acpica/evevent.c +++ b/trunk/drivers/acpi/acpica/evevent.c @@ -47,7 +47,7 @@ #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evevent") -#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ + /* Local prototypes */ static acpi_status acpi_ev_fixed_event_initialize(void); @@ -291,5 +291,3 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event) return ((acpi_gbl_fixed_event_handlers[event]. handler) (acpi_gbl_fixed_event_handlers[event].context)); } - -#endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/trunk/drivers/acpi/acpica/evglock.c b/trunk/drivers/acpi/acpica/evglock.c index cfeab38795d8..5e5683cb1f0d 100644 --- a/trunk/drivers/acpi/acpica/evglock.c +++ b/trunk/drivers/acpi/acpica/evglock.c @@ -48,7 +48,7 @@ #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evglock") -#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ + /* Local prototypes */ static u32 acpi_ev_global_lock_handler(void *context); @@ -339,5 +339,3 @@ acpi_status acpi_ev_release_global_lock(void) acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex); return_ACPI_STATUS(status); } - -#endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/trunk/drivers/acpi/acpica/evgpe.c b/trunk/drivers/acpi/acpica/evgpe.c index 8ba0e5f17091..9e88cb6fb25e 100644 --- a/trunk/drivers/acpi/acpica/evgpe.c +++ b/trunk/drivers/acpi/acpica/evgpe.c @@ -48,7 +48,7 @@ #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evgpe") -#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ + /* Local prototypes */ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context); @@ -766,5 +766,3 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, return_UINT32(ACPI_INTERRUPT_HANDLED); } - -#endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/trunk/drivers/acpi/acpica/evgpeblk.c b/trunk/drivers/acpi/acpica/evgpeblk.c index 23a3ca86b2eb..be75339cd5dd 100644 --- a/trunk/drivers/acpi/acpica/evgpeblk.c +++ b/trunk/drivers/acpi/acpica/evgpeblk.c @@ -48,7 +48,7 @@ #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evgpeblk") -#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ + /* Local prototypes */ static acpi_status acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block, @@ -504,5 +504,3 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, return_ACPI_STATUS(AE_OK); } - -#endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/trunk/drivers/acpi/acpica/evgpeinit.c b/trunk/drivers/acpi/acpica/evgpeinit.c index da0add858f81..adf7494da9db 100644 --- a/trunk/drivers/acpi/acpica/evgpeinit.c +++ b/trunk/drivers/acpi/acpica/evgpeinit.c @@ -48,7 +48,7 @@ #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evgpeinit") -#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ + /* * Note: History of _PRW support in ACPICA * @@ -440,5 +440,3 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, name, gpe_number)); return_ACPI_STATUS(AE_OK); } - -#endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/trunk/drivers/acpi/acpica/evgpeutil.c b/trunk/drivers/acpi/acpica/evgpeutil.c index 3c43796b8361..25073932aa10 100644 --- a/trunk/drivers/acpi/acpica/evgpeutil.c +++ b/trunk/drivers/acpi/acpica/evgpeutil.c @@ -48,7 +48,6 @@ #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evgpeutil") -#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ /******************************************************************************* * * FUNCTION: acpi_ev_walk_gpe_list @@ -375,5 +374,3 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, return_ACPI_STATUS(AE_OK); } - -#endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/trunk/drivers/acpi/acpica/evmisc.c b/trunk/drivers/acpi/acpica/evmisc.c index 51ef9f5e002d..84966f416463 100644 --- a/trunk/drivers/acpi/acpica/evmisc.c +++ b/trunk/drivers/acpi/acpica/evmisc.c @@ -108,30 +108,27 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, ACPI_FUNCTION_NAME(ev_queue_notify_request); /* - * For value 0x03 (Ejection Request), may need to run a device method. - * For value 0x02 (Device Wake), if _PRW exists, may need to run - * the _PS0 method. + * For value 3 (Ejection Request), some device method may need to be run. + * For value 2 (Device Wake) if _PRW exists, the _PS0 method may need + * to be run. * For value 0x80 (Status Change) on the power button or sleep button, - * initiate soft-off or sleep operation. - * - * For all cases, simply dispatch the notify to the handler. + * initiate soft-off or sleep operation? */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n", - acpi_ut_get_node_name(node), - acpi_ut_get_type_name(node->type), notify_value, - acpi_ut_get_notify_name(notify_value), node)); + "Dispatching Notify on [%4.4s] Node %p Value 0x%2.2X (%s)\n", + acpi_ut_get_node_name(node), node, notify_value, + acpi_ut_get_notify_name(notify_value))); /* Get the notify object attached to the NS Node */ obj_desc = acpi_ns_get_attached_object(node); if (obj_desc) { - /* We have the notify object, Get the correct handler */ + /* We have the notify object, Get the right handler */ switch (node->type) { - /* Notify is allowed only on these types */ + /* Notify allowed only on these types */ case ACPI_TYPE_DEVICE: case ACPI_TYPE_THERMAL: @@ -155,7 +152,7 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, } /* - * If there is a handler to run, schedule the dispatcher. + * If there is any handler to run, schedule the dispatcher. * Check for: * 1) Global system notify handler * 2) Global device notify handler @@ -273,7 +270,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context) acpi_ut_delete_generic_state(notify_info); } -#if (!ACPI_REDUCED_HARDWARE) /****************************************************************************** * * FUNCTION: acpi_ev_terminate @@ -342,5 +338,3 @@ void acpi_ev_terminate(void) } return_VOID; } - -#endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/trunk/drivers/acpi/acpica/evsci.c b/trunk/drivers/acpi/acpica/evsci.c index 6a57aa2d70d1..26065c612e76 100644 --- a/trunk/drivers/acpi/acpica/evsci.c +++ b/trunk/drivers/acpi/acpica/evsci.c @@ -48,7 +48,7 @@ #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evsci") -#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ + /* Local prototypes */ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context); @@ -181,5 +181,3 @@ acpi_status acpi_ev_remove_sci_handler(void) return_ACPI_STATUS(status); } - -#endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/trunk/drivers/acpi/acpica/evxface.c b/trunk/drivers/acpi/acpica/evxface.c index 44bef5744ebb..61944e89565a 100644 --- a/trunk/drivers/acpi/acpica/evxface.c +++ b/trunk/drivers/acpi/acpica/evxface.c @@ -51,6 +51,222 @@ #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evxface") +/******************************************************************************* + * + * FUNCTION: acpi_install_exception_handler + * + * PARAMETERS: Handler - Pointer to the handler function for the + * event + * + * RETURN: Status + * + * DESCRIPTION: Saves the pointer to the handler function + * + ******************************************************************************/ +#ifdef ACPI_FUTURE_USAGE +acpi_status acpi_install_exception_handler(acpi_exception_handler handler) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(acpi_install_exception_handler); + + status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Don't allow two handlers. */ + + if (acpi_gbl_exception_handler) { + status = AE_ALREADY_EXISTS; + goto cleanup; + } + + /* Install the handler */ + + acpi_gbl_exception_handler = handler; + + cleanup: + (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); + return_ACPI_STATUS(status); +} + +ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) +#endif /* ACPI_FUTURE_USAGE */ + +/******************************************************************************* + * + * FUNCTION: acpi_install_global_event_handler + * + * PARAMETERS: Handler - Pointer to the global event handler function + * Context - Value passed to the handler on each event + * + * RETURN: Status + * + * DESCRIPTION: Saves the pointer to the handler function. The global handler + * is invoked upon each incoming GPE and Fixed Event. It is + * invoked at interrupt level at the time of the event dispatch. + * Can be used to update event counters, etc. + * + ******************************************************************************/ +acpi_status +acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, void *context) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(acpi_install_global_event_handler); + + /* Parameter validation */ + + if (!handler) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Don't allow two handlers. */ + + if (acpi_gbl_global_event_handler) { + status = AE_ALREADY_EXISTS; + goto cleanup; + } + + acpi_gbl_global_event_handler = handler; + acpi_gbl_global_event_handler_context = context; + + cleanup: + (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); + return_ACPI_STATUS(status); +} + +ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler) + +/******************************************************************************* + * + * FUNCTION: acpi_install_fixed_event_handler + * + * PARAMETERS: Event - Event type to enable. + * Handler - Pointer to the handler function for the + * event + * Context - Value passed to the handler on each GPE + * + * RETURN: Status + * + * DESCRIPTION: Saves the pointer to the handler function and then enables the + * event. + * + ******************************************************************************/ +acpi_status +acpi_install_fixed_event_handler(u32 event, + acpi_event_handler handler, void *context) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(acpi_install_fixed_event_handler); + + /* Parameter validation */ + + if (event > ACPI_EVENT_MAX) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Don't allow two handlers. */ + + if (NULL != acpi_gbl_fixed_event_handlers[event].handler) { + status = AE_ALREADY_EXISTS; + goto cleanup; + } + + /* Install the handler before enabling the event */ + + acpi_gbl_fixed_event_handlers[event].handler = handler; + acpi_gbl_fixed_event_handlers[event].context = context; + + status = acpi_clear_event(event); + if (ACPI_SUCCESS(status)) + status = acpi_enable_event(event, 0); + if (ACPI_FAILURE(status)) { + ACPI_WARNING((AE_INFO, "Could not enable fixed event 0x%X", + event)); + + /* Remove the handler */ + + acpi_gbl_fixed_event_handlers[event].handler = NULL; + acpi_gbl_fixed_event_handlers[event].context = NULL; + } else { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Enabled fixed event %X, Handler=%p\n", event, + handler)); + } + + cleanup: + (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); + return_ACPI_STATUS(status); +} + +ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler) + +/******************************************************************************* + * + * FUNCTION: acpi_remove_fixed_event_handler + * + * PARAMETERS: Event - Event type to disable. + * Handler - Address of the handler + * + * RETURN: Status + * + * DESCRIPTION: Disables the event and unregisters the event handler. + * + ******************************************************************************/ +acpi_status +acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler) +{ + acpi_status status = AE_OK; + + ACPI_FUNCTION_TRACE(acpi_remove_fixed_event_handler); + + /* Parameter validation */ + + if (event > ACPI_EVENT_MAX) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Disable the event before removing the handler */ + + status = acpi_disable_event(event, 0); + + /* Always Remove the handler */ + + acpi_gbl_fixed_event_handlers[event].handler = NULL; + acpi_gbl_fixed_event_handlers[event].context = NULL; + + if (ACPI_FAILURE(status)) { + ACPI_WARNING((AE_INFO, + "Could not write to fixed event enable register 0x%X", + event)); + } else { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event %X\n", + event)); + } + + (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); + return_ACPI_STATUS(status); +} + +ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler) /******************************************************************************* * @@ -118,7 +334,6 @@ acpi_add_handler_object(struct acpi_object_notify_handler *parent_obj, return AE_OK; } - /******************************************************************************* * * FUNCTION: acpi_install_notify_handler @@ -488,224 +703,6 @@ acpi_remove_notify_handler(acpi_handle device, ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler) -/******************************************************************************* - * - * FUNCTION: acpi_install_exception_handler - * - * PARAMETERS: Handler - Pointer to the handler function for the - * event - * - * RETURN: Status - * - * DESCRIPTION: Saves the pointer to the handler function - * - ******************************************************************************/ -#ifdef ACPI_FUTURE_USAGE -acpi_status acpi_install_exception_handler(acpi_exception_handler handler) -{ - acpi_status status; - - ACPI_FUNCTION_TRACE(acpi_install_exception_handler); - - status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Don't allow two handlers. */ - - if (acpi_gbl_exception_handler) { - status = AE_ALREADY_EXISTS; - goto cleanup; - } - - /* Install the handler */ - - acpi_gbl_exception_handler = handler; - - cleanup: - (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); - return_ACPI_STATUS(status); -} - -ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) -#endif /* ACPI_FUTURE_USAGE */ - -#if (!ACPI_REDUCED_HARDWARE) -/******************************************************************************* - * - * FUNCTION: acpi_install_global_event_handler - * - * PARAMETERS: Handler - Pointer to the global event handler function - * Context - Value passed to the handler on each event - * - * RETURN: Status - * - * DESCRIPTION: Saves the pointer to the handler function. The global handler - * is invoked upon each incoming GPE and Fixed Event. It is - * invoked at interrupt level at the time of the event dispatch. - * Can be used to update event counters, etc. - * - ******************************************************************************/ -acpi_status -acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, void *context) -{ - acpi_status status; - - ACPI_FUNCTION_TRACE(acpi_install_global_event_handler); - - /* Parameter validation */ - - if (!handler) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Don't allow two handlers. */ - - if (acpi_gbl_global_event_handler) { - status = AE_ALREADY_EXISTS; - goto cleanup; - } - - acpi_gbl_global_event_handler = handler; - acpi_gbl_global_event_handler_context = context; - - cleanup: - (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); - return_ACPI_STATUS(status); -} - -ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler) - -/******************************************************************************* - * - * FUNCTION: acpi_install_fixed_event_handler - * - * PARAMETERS: Event - Event type to enable. - * Handler - Pointer to the handler function for the - * event - * Context - Value passed to the handler on each GPE - * - * RETURN: Status - * - * DESCRIPTION: Saves the pointer to the handler function and then enables the - * event. - * - ******************************************************************************/ -acpi_status -acpi_install_fixed_event_handler(u32 event, - acpi_event_handler handler, void *context) -{ - acpi_status status; - - ACPI_FUNCTION_TRACE(acpi_install_fixed_event_handler); - - /* Parameter validation */ - - if (event > ACPI_EVENT_MAX) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Don't allow two handlers. */ - - if (NULL != acpi_gbl_fixed_event_handlers[event].handler) { - status = AE_ALREADY_EXISTS; - goto cleanup; - } - - /* Install the handler before enabling the event */ - - acpi_gbl_fixed_event_handlers[event].handler = handler; - acpi_gbl_fixed_event_handlers[event].context = context; - - status = acpi_clear_event(event); - if (ACPI_SUCCESS(status)) - status = acpi_enable_event(event, 0); - if (ACPI_FAILURE(status)) { - ACPI_WARNING((AE_INFO, "Could not enable fixed event 0x%X", - event)); - - /* Remove the handler */ - - acpi_gbl_fixed_event_handlers[event].handler = NULL; - acpi_gbl_fixed_event_handlers[event].context = NULL; - } else { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Enabled fixed event %X, Handler=%p\n", event, - handler)); - } - - cleanup: - (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); - return_ACPI_STATUS(status); -} - -ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler) - -/******************************************************************************* - * - * FUNCTION: acpi_remove_fixed_event_handler - * - * PARAMETERS: Event - Event type to disable. - * Handler - Address of the handler - * - * RETURN: Status - * - * DESCRIPTION: Disables the event and unregisters the event handler. - * - ******************************************************************************/ -acpi_status -acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler) -{ - acpi_status status = AE_OK; - - ACPI_FUNCTION_TRACE(acpi_remove_fixed_event_handler); - - /* Parameter validation */ - - if (event > ACPI_EVENT_MAX) { - return_ACPI_STATUS(AE_BAD_PARAMETER); - } - - status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Disable the event before removing the handler */ - - status = acpi_disable_event(event, 0); - - /* Always Remove the handler */ - - acpi_gbl_fixed_event_handlers[event].handler = NULL; - acpi_gbl_fixed_event_handlers[event].context = NULL; - - if (ACPI_FAILURE(status)) { - ACPI_WARNING((AE_INFO, - "Could not write to fixed event enable register 0x%X", - event)); - } else { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Disabled fixed event %X\n", - event)); - } - - (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); - return_ACPI_STATUS(status); -} - -ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler) - /******************************************************************************* * * FUNCTION: acpi_install_gpe_handler @@ -987,4 +984,3 @@ acpi_status acpi_release_global_lock(u32 handle) } ACPI_EXPORT_SYMBOL(acpi_release_global_lock) -#endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/trunk/drivers/acpi/acpica/evxfevnt.c b/trunk/drivers/acpi/acpica/evxfevnt.c index 77cee5a5e891..1768bbec1002 100644 --- a/trunk/drivers/acpi/acpica/evxfevnt.c +++ b/trunk/drivers/acpi/acpica/evxfevnt.c @@ -49,7 +49,6 @@ #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evxfevnt") -#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ /******************************************************************************* * * FUNCTION: acpi_enable @@ -353,4 +352,3 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) } ACPI_EXPORT_SYMBOL(acpi_get_event_status) -#endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/trunk/drivers/acpi/acpica/evxfgpe.c b/trunk/drivers/acpi/acpica/evxfgpe.c index 86f9b343ebd4..33388fd69df4 100644 --- a/trunk/drivers/acpi/acpica/evxfgpe.c +++ b/trunk/drivers/acpi/acpica/evxfgpe.c @@ -50,7 +50,6 @@ #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME("evxfgpe") -#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ /****************************************************************************** * * FUNCTION: acpi_update_all_gpes @@ -696,4 +695,3 @@ acpi_get_gpe_device(u32 index, acpi_handle *gpe_device) } ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) -#endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/trunk/drivers/acpi/acpica/hwacpi.c b/trunk/drivers/acpi/acpica/hwacpi.c index d0b9ed5df97e..d21ec5f0b3a9 100644 --- a/trunk/drivers/acpi/acpica/hwacpi.c +++ b/trunk/drivers/acpi/acpica/hwacpi.c @@ -48,7 +48,6 @@ #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME("hwacpi") -#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ /****************************************************************************** * * FUNCTION: acpi_hw_set_mode @@ -167,5 +166,3 @@ u32 acpi_hw_get_mode(void) return_UINT32(ACPI_SYS_MODE_LEGACY); } } - -#endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/trunk/drivers/acpi/acpica/hwesleep.c b/trunk/drivers/acpi/acpica/hwesleep.c deleted file mode 100644 index 29e859293edd..000000000000 --- a/trunk/drivers/acpi/acpica/hwesleep.c +++ /dev/null @@ -1,247 +0,0 @@ -/****************************************************************************** - * - * Name: hwesleep.c - ACPI Hardware Sleep/Wake Support functions for the - * extended FADT-V5 sleep registers. - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2012, Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - */ - -#include -#include "accommon.h" - -#define _COMPONENT ACPI_HARDWARE -ACPI_MODULE_NAME("hwesleep") - -/******************************************************************************* - * - * FUNCTION: acpi_hw_execute_sleep_method - * - * PARAMETERS: method_pathname - Pathname of method to execute - * integer_argument - Argument to pass to the method - * - * RETURN: None - * - * DESCRIPTION: Execute a sleep/wake related method with one integer argument - * and no return value. - * - ******************************************************************************/ -void acpi_hw_execute_sleep_method(char *method_pathname, u32 integer_argument) -{ - struct acpi_object_list arg_list; - union acpi_object arg; - acpi_status status; - - ACPI_FUNCTION_TRACE(hw_execute_sleep_method); - - /* One argument, integer_argument; No return value expected */ - - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = (u64)integer_argument; - - status = acpi_evaluate_object(NULL, method_pathname, &arg_list, NULL); - if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - ACPI_EXCEPTION((AE_INFO, status, "While executing method %s", - method_pathname)); - } - - return_VOID; -} - -/******************************************************************************* - * - * FUNCTION: acpi_hw_extended_sleep - * - * PARAMETERS: sleep_state - Which sleep state to enter - * Flags - ACPI_EXECUTE_GTS to run optional method - * - * RETURN: Status - * - * DESCRIPTION: Enter a system sleep state via the extended FADT sleep - * registers (V5 FADT). - * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED - * - ******************************************************************************/ - -acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags) -{ - acpi_status status; - u8 sleep_type_value; - u64 sleep_status; - - ACPI_FUNCTION_TRACE(hw_extended_sleep); - - /* Extended sleep registers must be valid */ - - if (!acpi_gbl_FADT.sleep_control.address || - !acpi_gbl_FADT.sleep_status.address) { - return_ACPI_STATUS(AE_NOT_EXIST); - } - - /* Clear wake status (WAK_STS) */ - - status = acpi_write(ACPI_X_WAKE_STATUS, &acpi_gbl_FADT.sleep_status); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - acpi_gbl_system_awake_and_running = FALSE; - - /* Optionally execute _GTS (Going To Sleep) */ - - if (flags & ACPI_EXECUTE_GTS) { - acpi_hw_execute_sleep_method(METHOD_PATHNAME__GTS, sleep_state); - } - - /* Flush caches, as per ACPI specification */ - - ACPI_FLUSH_CPU_CACHE(); - - /* - * Set the SLP_TYP and SLP_EN bits. - * - * Note: We only use the first value returned by the \_Sx method - * (acpi_gbl_sleep_type_a) - As per ACPI specification. - */ - ACPI_DEBUG_PRINT((ACPI_DB_INIT, - "Entering sleep state [S%u]\n", sleep_state)); - - sleep_type_value = - ((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) & - ACPI_X_SLEEP_TYPE_MASK); - - status = acpi_write((sleep_type_value | ACPI_X_SLEEP_ENABLE), - &acpi_gbl_FADT.sleep_control); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Wait for transition back to Working State */ - - do { - status = acpi_read(&sleep_status, &acpi_gbl_FADT.sleep_status); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - } while (!(((u8)sleep_status) & ACPI_X_WAKE_STATUS)); - - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_hw_extended_wake_prep - * - * PARAMETERS: sleep_state - Which sleep state we just exited - * Flags - ACPI_EXECUTE_BFS to run optional method - * - * RETURN: Status - * - * DESCRIPTION: Perform first part of OS-independent ACPI cleanup after - * a sleep. Called with interrupts ENABLED. - * - ******************************************************************************/ - -acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags) -{ - acpi_status status; - u8 sleep_type_value; - - ACPI_FUNCTION_TRACE(hw_extended_wake_prep); - - status = acpi_get_sleep_type_data(ACPI_STATE_S0, - &acpi_gbl_sleep_type_a, - &acpi_gbl_sleep_type_b); - if (ACPI_SUCCESS(status)) { - sleep_type_value = - ((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) & - ACPI_X_SLEEP_TYPE_MASK); - - (void)acpi_write((sleep_type_value | ACPI_X_SLEEP_ENABLE), - &acpi_gbl_FADT.sleep_control); - } - - /* Optionally execute _BFS (Back From Sleep) */ - - if (flags & ACPI_EXECUTE_BFS) { - acpi_hw_execute_sleep_method(METHOD_PATHNAME__BFS, sleep_state); - } - return_ACPI_STATUS(AE_OK); -} - -/******************************************************************************* - * - * FUNCTION: acpi_hw_extended_wake - * - * PARAMETERS: sleep_state - Which sleep state we just exited - * Flags - Reserved, set to zero - * - * RETURN: Status - * - * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep - * Called with interrupts ENABLED. - * - ******************************************************************************/ - -acpi_status acpi_hw_extended_wake(u8 sleep_state, u8 flags) -{ - ACPI_FUNCTION_TRACE(hw_extended_wake); - - /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ - - acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; - - /* Execute the wake methods */ - - acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WAKING); - acpi_hw_execute_sleep_method(METHOD_PATHNAME__WAK, sleep_state); - - /* - * Some BIOS code assumes that WAK_STS will be cleared on resume - * and use it to determine whether the system is rebooting or - * resuming. Clear WAK_STS for compatibility. - */ - (void)acpi_write(ACPI_X_WAKE_STATUS, &acpi_gbl_FADT.sleep_status); - acpi_gbl_system_awake_and_running = TRUE; - - acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING); - return_ACPI_STATUS(AE_OK); -} diff --git a/trunk/drivers/acpi/acpica/hwgpe.c b/trunk/drivers/acpi/acpica/hwgpe.c index 25bd28c4ae8d..1a6894afef79 100644 --- a/trunk/drivers/acpi/acpica/hwgpe.c +++ b/trunk/drivers/acpi/acpica/hwgpe.c @@ -48,7 +48,7 @@ #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME("hwgpe") -#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ + /* Local prototypes */ static acpi_status acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, @@ -479,5 +479,3 @@ acpi_status acpi_hw_enable_all_wakeup_gpes(void) status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block, NULL); return_ACPI_STATUS(status); } - -#endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/trunk/drivers/acpi/acpica/hwregs.c b/trunk/drivers/acpi/acpica/hwregs.c index 6b6c83b87b52..4ea4eeb51bfd 100644 --- a/trunk/drivers/acpi/acpica/hwregs.c +++ b/trunk/drivers/acpi/acpica/hwregs.c @@ -51,7 +51,6 @@ #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME("hwregs") -#if (!ACPI_REDUCED_HARDWARE) /* Local Prototypes */ static acpi_status acpi_hw_read_multiple(u32 *value, @@ -63,8 +62,6 @@ acpi_hw_write_multiple(u32 value, struct acpi_generic_address *register_a, struct acpi_generic_address *register_b); -#endif /* !ACPI_REDUCED_HARDWARE */ - /****************************************************************************** * * FUNCTION: acpi_hw_validate_register @@ -157,7 +154,6 @@ acpi_hw_validate_register(struct acpi_generic_address *reg, acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) { u64 address; - u64 value64; acpi_status status; ACPI_FUNCTION_NAME(hw_read); @@ -179,9 +175,7 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) */ if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { status = acpi_os_read_memory((acpi_physical_address) - address, &value64, reg->bit_width); - - *value = (u32)value64; + address, value, reg->bit_width); } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ status = acpi_hw_read_port((acpi_io_address) @@ -231,8 +225,7 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) */ if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { status = acpi_os_write_memory((acpi_physical_address) - address, (u64)value, - reg->bit_width); + address, value, reg->bit_width); } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ status = acpi_hw_write_port((acpi_io_address) @@ -247,7 +240,6 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) return (status); } -#if (!ACPI_REDUCED_HARDWARE) /******************************************************************************* * * FUNCTION: acpi_hw_clear_acpi_status @@ -293,7 +285,7 @@ acpi_status acpi_hw_clear_acpi_status(void) /******************************************************************************* * - * FUNCTION: acpi_hw_get_bit_register_info + * FUNCTION: acpi_hw_get_register_bit_mask * * PARAMETERS: register_id - Index of ACPI Register to access * @@ -666,5 +658,3 @@ acpi_hw_write_multiple(u32 value, return (status); } - -#endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/trunk/drivers/acpi/acpica/hwsleep.c b/trunk/drivers/acpi/acpica/hwsleep.c index 0ed85cac3231..3c4a922a9fc2 100644 --- a/trunk/drivers/acpi/acpica/hwsleep.c +++ b/trunk/drivers/acpi/acpica/hwsleep.c @@ -1,7 +1,7 @@ + /****************************************************************************** * - * Name: hwsleep.c - ACPI Hardware Sleep/Wake Support functions for the - * original/legacy sleep/PM registers. + * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface * *****************************************************************************/ @@ -43,37 +43,213 @@ */ #include -#include #include "accommon.h" +#include "actables.h" +#include #include #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME("hwsleep") -#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ /******************************************************************************* * - * FUNCTION: acpi_hw_legacy_sleep + * FUNCTION: acpi_set_firmware_waking_vector + * + * PARAMETERS: physical_address - 32-bit physical address of ACPI real mode + * entry point. + * + * RETURN: Status + * + * DESCRIPTION: Sets the 32-bit firmware_waking_vector field of the FACS + * + ******************************************************************************/ +acpi_status +acpi_set_firmware_waking_vector(u32 physical_address) +{ + ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector); + + + /* + * According to the ACPI specification 2.0c and later, the 64-bit + * waking vector should be cleared and the 32-bit waking vector should + * be used, unless we want the wake-up code to be called by the BIOS in + * Protected Mode. Some systems (for example HP dv5-1004nr) are known + * to fail to resume if the 64-bit vector is used. + */ + + /* Set the 32-bit vector */ + + acpi_gbl_FACS->firmware_waking_vector = physical_address; + + /* Clear the 64-bit vector if it exists */ + + if ((acpi_gbl_FACS->length > 32) && (acpi_gbl_FACS->version >= 1)) { + acpi_gbl_FACS->xfirmware_waking_vector = 0; + } + + return_ACPI_STATUS(AE_OK); +} + +ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) + +#if ACPI_MACHINE_WIDTH == 64 +/******************************************************************************* + * + * FUNCTION: acpi_set_firmware_waking_vector64 + * + * PARAMETERS: physical_address - 64-bit physical address of ACPI protected + * mode entry point. + * + * RETURN: Status + * + * DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if + * it exists in the table. This function is intended for use with + * 64-bit host operating systems. + * + ******************************************************************************/ +acpi_status +acpi_set_firmware_waking_vector64(u64 physical_address) +{ + ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector64); + + + /* Determine if the 64-bit vector actually exists */ + + if ((acpi_gbl_FACS->length <= 32) || (acpi_gbl_FACS->version < 1)) { + return_ACPI_STATUS(AE_NOT_EXIST); + } + + /* Clear 32-bit vector, set the 64-bit X_ vector */ + + acpi_gbl_FACS->firmware_waking_vector = 0; + acpi_gbl_FACS->xfirmware_waking_vector = physical_address; + + return_ACPI_STATUS(AE_OK); +} + +ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64) +#endif + +/******************************************************************************* + * + * FUNCTION: acpi_enter_sleep_state_prep + * + * PARAMETERS: sleep_state - Which sleep state to enter + * + * RETURN: Status + * + * DESCRIPTION: Prepare to enter a system sleep state (see ACPI 2.0 spec p 231) + * This function must execute with interrupts enabled. + * We break sleeping into 2 stages so that OSPM can handle + * various OS-specific tasks between the two steps. + * + ******************************************************************************/ +acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) +{ + acpi_status status; + struct acpi_object_list arg_list; + union acpi_object arg; + + ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep); + + /* _PSW methods could be run here to enable wake-on keyboard, LAN, etc. */ + + status = acpi_get_sleep_type_data(sleep_state, + &acpi_gbl_sleep_type_a, + &acpi_gbl_sleep_type_b); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Setup parameter object */ + + arg_list.count = 1; + arg_list.pointer = &arg; + + arg.type = ACPI_TYPE_INTEGER; + arg.integer.value = sleep_state; + + /* Run the _PTS method */ + + status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + return_ACPI_STATUS(status); + } + + /* Setup the argument to _SST */ + + switch (sleep_state) { + case ACPI_STATE_S0: + arg.integer.value = ACPI_SST_WORKING; + break; + + case ACPI_STATE_S1: + case ACPI_STATE_S2: + case ACPI_STATE_S3: + arg.integer.value = ACPI_SST_SLEEPING; + break; + + case ACPI_STATE_S4: + arg.integer.value = ACPI_SST_SLEEP_CONTEXT; + break; + + default: + arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is off */ + break; + } + + /* + * Set the system indicators to show the desired sleep state. + * _SST is an optional method (return no error if not found) + */ + status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + ACPI_EXCEPTION((AE_INFO, status, + "While executing method _SST")); + } + + return_ACPI_STATUS(AE_OK); +} + +ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) + +static unsigned int gts, bfs; +module_param(gts, uint, 0644); +module_param(bfs, uint, 0644); +MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend."); +MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".); + +/******************************************************************************* + * + * FUNCTION: acpi_enter_sleep_state * * PARAMETERS: sleep_state - Which sleep state to enter - * Flags - ACPI_EXECUTE_GTS to run optional method * * RETURN: Status * - * DESCRIPTION: Enter a system sleep state via the legacy FADT PM registers + * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231) * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED * ******************************************************************************/ -acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags) +acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) { - struct acpi_bit_register_info *sleep_type_reg_info; - struct acpi_bit_register_info *sleep_enable_reg_info; u32 pm1a_control; u32 pm1b_control; + struct acpi_bit_register_info *sleep_type_reg_info; + struct acpi_bit_register_info *sleep_enable_reg_info; u32 in_value; + struct acpi_object_list arg_list; + union acpi_object arg; acpi_status status; - ACPI_FUNCTION_TRACE(hw_legacy_sleep); + ACPI_FUNCTION_TRACE(acpi_enter_sleep_state); + + if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) || + (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) { + ACPI_ERROR((AE_INFO, "Sleep values out of range: A=0x%X B=0x%X", + acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b)); + return_ACPI_STATUS(AE_AML_OPERAND_VALUE); + } sleep_type_reg_info = acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE); @@ -95,18 +271,6 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags) return_ACPI_STATUS(status); } - if (sleep_state != ACPI_STATE_S5) { - /* - * Disable BM arbitration. This feature is contained within an - * optional register (PM2 Control), so ignore a BAD_ADDRESS - * exception. - */ - status = acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1); - if (ACPI_FAILURE(status) && (status != AE_BAD_ADDRESS)) { - return_ACPI_STATUS(status); - } - } - /* * 1) Disable/Clear all GPEs * 2) Enable all wakeup GPEs @@ -122,10 +286,18 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags) return_ACPI_STATUS(status); } - /* Optionally execute _GTS (Going To Sleep) */ + if (gts) { + /* Execute the _GTS method */ + + arg_list.count = 1; + arg_list.pointer = &arg; + arg.type = ACPI_TYPE_INTEGER; + arg.integer.value = sleep_state; - if (flags & ACPI_EXECUTE_GTS) { - acpi_hw_execute_sleep_method(METHOD_PATHNAME__GTS, sleep_state); + status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + return_ACPI_STATUS(status); + } } /* Get current value of PM1A control */ @@ -172,12 +344,8 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags) ACPI_FLUSH_CPU_CACHE(); - status = acpi_os_prepare_sleep(sleep_state, pm1a_control, - pm1b_control); - if (ACPI_SKIP(status)) - return_ACPI_STATUS(AE_OK); - if (ACPI_FAILURE(status)) - return_ACPI_STATUS(status); + tboot_sleep(sleep_state, pm1a_control, pm1b_control); + /* Write #2: Write both SLP_TYP + SLP_EN */ status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control); @@ -207,44 +375,114 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags) } } - /* Wait for transition back to Working State */ + /* Wait until we enter sleep state */ + + do { + status = acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, + &in_value); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Spin until we wake */ + + } while (!in_value); + + return_ACPI_STATUS(AE_OK); +} + +ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state) + +/******************************************************************************* + * + * FUNCTION: acpi_enter_sleep_state_s4bios + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Perform a S4 bios request. + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED + * + ******************************************************************************/ +acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) +{ + u32 in_value; + acpi_status status; + + ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios); + + /* Clear the wake status bit (PM1) */ + + status = + acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + status = acpi_hw_clear_acpi_status(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* + * 1) Disable/Clear all GPEs + * 2) Enable all wakeup GPEs + */ + status = acpi_hw_disable_all_gpes(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + acpi_gbl_system_awake_and_running = FALSE; + + status = acpi_hw_enable_all_wakeup_gpes(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + ACPI_FLUSH_CPU_CACHE(); + + status = acpi_hw_write_port(acpi_gbl_FADT.smi_command, + (u32) acpi_gbl_FADT.S4bios_request, 8); do { + acpi_os_stall(1000); status = acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - } while (!in_value); return_ACPI_STATUS(AE_OK); } +ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios) + /******************************************************************************* * - * FUNCTION: acpi_hw_legacy_wake_prep + * FUNCTION: acpi_leave_sleep_state_prep * - * PARAMETERS: sleep_state - Which sleep state we just exited - * Flags - ACPI_EXECUTE_BFS to run optional method + * PARAMETERS: sleep_state - Which sleep state we are exiting * * RETURN: Status * * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a * sleep. - * Called with interrupts ENABLED. + * Called with interrupts DISABLED. * ******************************************************************************/ - -acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags) +acpi_status acpi_leave_sleep_state_prep(u8 sleep_state) { + struct acpi_object_list arg_list; + union acpi_object arg; acpi_status status; struct acpi_bit_register_info *sleep_type_reg_info; struct acpi_bit_register_info *sleep_enable_reg_info; u32 pm1a_control; u32 pm1b_control; - ACPI_FUNCTION_TRACE(hw_legacy_wake_prep); + ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep); /* * Set SLP_TYPE and SLP_EN to state S0. @@ -287,20 +525,27 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags) } } - /* Optionally execute _BFS (Back From Sleep) */ + if (bfs) { + /* Execute the _BFS method */ - if (flags & ACPI_EXECUTE_BFS) { - acpi_hw_execute_sleep_method(METHOD_PATHNAME__BFS, sleep_state); + arg_list.count = 1; + arg_list.pointer = &arg; + arg.type = ACPI_TYPE_INTEGER; + arg.integer.value = sleep_state; + + status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); + } } return_ACPI_STATUS(status); } /******************************************************************************* * - * FUNCTION: acpi_hw_legacy_wake + * FUNCTION: acpi_leave_sleep_state * * PARAMETERS: sleep_state - Which sleep state we just exited - * Flags - Reserved, set to zero * * RETURN: Status * @@ -308,17 +553,31 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags) * Called with interrupts ENABLED. * ******************************************************************************/ - -acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags) +acpi_status acpi_leave_sleep_state(u8 sleep_state) { + struct acpi_object_list arg_list; + union acpi_object arg; acpi_status status; - ACPI_FUNCTION_TRACE(hw_legacy_wake); + ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; - acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WAKING); + + /* Setup parameter object */ + + arg_list.count = 1; + arg_list.pointer = &arg; + arg.type = ACPI_TYPE_INTEGER; + + /* Ignore any errors from these methods */ + + arg.integer.value = ACPI_SST_WAKING; + status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); + } /* * GPEs must be enabled before _WAK is called as GPEs @@ -332,50 +591,46 @@ acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags) if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - status = acpi_hw_enable_all_runtime_gpes(); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - /* - * Now we can execute _WAK, etc. Some machines require that the GPEs - * are enabled before the wake methods are executed. - */ - acpi_hw_execute_sleep_method(METHOD_PATHNAME__WAK, sleep_state); + arg.integer.value = sleep_state; + status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK")); + } + /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */ /* - * Some BIOS code assumes that WAK_STS will be cleared on resume - * and use it to determine whether the system is rebooting or - * resuming. Clear WAK_STS for compatibility. + * Some BIOSes assume that WAK_STS will be cleared on resume and use + * it to determine whether the system is rebooting or resuming. Clear + * it for compatibility. */ acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, 1); + acpi_gbl_system_awake_and_running = TRUE; /* Enable power button */ (void) acpi_write_bit_register(acpi_gbl_fixed_event_info - [ACPI_EVENT_POWER_BUTTON]. - enable_register_id, ACPI_ENABLE_EVENT); + [ACPI_EVENT_POWER_BUTTON]. + enable_register_id, ACPI_ENABLE_EVENT); (void) acpi_write_bit_register(acpi_gbl_fixed_event_info - [ACPI_EVENT_POWER_BUTTON]. - status_register_id, ACPI_CLEAR_STATUS); + [ACPI_EVENT_POWER_BUTTON]. + status_register_id, ACPI_CLEAR_STATUS); - /* - * Enable BM arbitration. This feature is contained within an - * optional register (PM2 Control), so ignore a BAD_ADDRESS - * exception. - */ - status = acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0); - if (ACPI_FAILURE(status) && (status != AE_BAD_ADDRESS)) { - return_ACPI_STATUS(status); + arg.integer.value = ACPI_SST_WORKING; + status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); } - acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING); return_ACPI_STATUS(status); } -#endif /* !ACPI_REDUCED_HARDWARE */ +ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state) diff --git a/trunk/drivers/acpi/acpica/hwtimer.c b/trunk/drivers/acpi/acpica/hwtimer.c index f1b2c3b94cac..d4973d9da9f1 100644 --- a/trunk/drivers/acpi/acpica/hwtimer.c +++ b/trunk/drivers/acpi/acpica/hwtimer.c @@ -49,7 +49,6 @@ #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME("hwtimer") -#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ /****************************************************************************** * * FUNCTION: acpi_get_timer_resolution @@ -188,4 +187,3 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed) } ACPI_EXPORT_SYMBOL(acpi_get_timer_duration) -#endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/trunk/drivers/acpi/acpica/hwxface.c b/trunk/drivers/acpi/acpica/hwxface.c index a716fede4f25..9d38eb6c0d0b 100644 --- a/trunk/drivers/acpi/acpica/hwxface.c +++ b/trunk/drivers/acpi/acpica/hwxface.c @@ -138,6 +138,11 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) return (status); } + width = reg->bit_width; + if (width == 64) { + width = 32; /* Break into two 32-bit transfers */ + } + /* Initialize entire 64-bit return value to zero */ *return_value = 0; @@ -149,17 +154,24 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) */ if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { status = acpi_os_read_memory((acpi_physical_address) - address, return_value, - reg->bit_width); + address, &value, width); if (ACPI_FAILURE(status)) { return (status); } - } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ + *return_value = value; + + if (reg->bit_width == 64) { - width = reg->bit_width; - if (width == 64) { - width = 32; /* Break into two 32-bit transfers */ + /* Read the top 32 bits */ + + status = acpi_os_read_memory((acpi_physical_address) + (address + 4), &value, 32); + if (ACPI_FAILURE(status)) { + return (status); + } + *return_value |= ((u64)value << 32); } + } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ status = acpi_hw_read_port((acpi_io_address) address, &value, width); @@ -219,22 +231,32 @@ acpi_status acpi_write(u64 value, struct acpi_generic_address *reg) return (status); } + width = reg->bit_width; + if (width == 64) { + width = 32; /* Break into two 32-bit transfers */ + } + /* * Two address spaces supported: Memory or IO. PCI_Config is * not supported here because the GAS structure is insufficient */ if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { status = acpi_os_write_memory((acpi_physical_address) - address, value, reg->bit_width); + address, ACPI_LODWORD(value), + width); if (ACPI_FAILURE(status)) { return (status); } - } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ - width = reg->bit_width; - if (width == 64) { - width = 32; /* Break into two 32-bit transfers */ + if (reg->bit_width == 64) { + status = acpi_os_write_memory((acpi_physical_address) + (address + 4), + ACPI_HIDWORD(value), 32); + if (ACPI_FAILURE(status)) { + return (status); + } } + } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ status = acpi_hw_write_port((acpi_io_address) address, ACPI_LODWORD(value), @@ -264,7 +286,6 @@ acpi_status acpi_write(u64 value, struct acpi_generic_address *reg) ACPI_EXPORT_SYMBOL(acpi_write) -#if (!ACPI_REDUCED_HARDWARE) /******************************************************************************* * * FUNCTION: acpi_read_bit_register @@ -432,7 +453,7 @@ acpi_status acpi_write_bit_register(u32 register_id, u32 value) } ACPI_EXPORT_SYMBOL(acpi_write_bit_register) -#endif /* !ACPI_REDUCED_HARDWARE */ + /******************************************************************************* * * FUNCTION: acpi_get_sleep_type_data diff --git a/trunk/drivers/acpi/acpica/hwxfsleep.c b/trunk/drivers/acpi/acpica/hwxfsleep.c deleted file mode 100644 index 762d059bb508..000000000000 --- a/trunk/drivers/acpi/acpica/hwxfsleep.c +++ /dev/null @@ -1,431 +0,0 @@ -/****************************************************************************** - * - * Name: hwxfsleep.c - ACPI Hardware Sleep/Wake External Interfaces - * - *****************************************************************************/ - -/* - * Copyright (C) 2000 - 2012, Intel Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - */ - -#include -#include "accommon.h" -#include - -#define _COMPONENT ACPI_HARDWARE -ACPI_MODULE_NAME("hwxfsleep") - -/* Local prototypes */ -static acpi_status -acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id); - -/* - * Dispatch table used to efficiently branch to the various sleep - * functions. - */ -#define ACPI_SLEEP_FUNCTION_ID 0 -#define ACPI_WAKE_PREP_FUNCTION_ID 1 -#define ACPI_WAKE_FUNCTION_ID 2 - -/* Legacy functions are optional, based upon ACPI_REDUCED_HARDWARE */ - -static struct acpi_sleep_functions acpi_sleep_dispatch[] = { - {ACPI_HW_OPTIONAL_FUNCTION(acpi_hw_legacy_sleep), - acpi_hw_extended_sleep}, - {ACPI_HW_OPTIONAL_FUNCTION(acpi_hw_legacy_wake_prep), - acpi_hw_extended_wake_prep}, - {ACPI_HW_OPTIONAL_FUNCTION(acpi_hw_legacy_wake), acpi_hw_extended_wake} -}; - -/* - * These functions are removed for the ACPI_REDUCED_HARDWARE case: - * acpi_set_firmware_waking_vector - * acpi_set_firmware_waking_vector64 - * acpi_enter_sleep_state_s4bios - */ - -#if (!ACPI_REDUCED_HARDWARE) -/******************************************************************************* - * - * FUNCTION: acpi_set_firmware_waking_vector - * - * PARAMETERS: physical_address - 32-bit physical address of ACPI real mode - * entry point. - * - * RETURN: Status - * - * DESCRIPTION: Sets the 32-bit firmware_waking_vector field of the FACS - * - ******************************************************************************/ - -acpi_status acpi_set_firmware_waking_vector(u32 physical_address) -{ - ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector); - - - /* - * According to the ACPI specification 2.0c and later, the 64-bit - * waking vector should be cleared and the 32-bit waking vector should - * be used, unless we want the wake-up code to be called by the BIOS in - * Protected Mode. Some systems (for example HP dv5-1004nr) are known - * to fail to resume if the 64-bit vector is used. - */ - - /* Set the 32-bit vector */ - - acpi_gbl_FACS->firmware_waking_vector = physical_address; - - /* Clear the 64-bit vector if it exists */ - - if ((acpi_gbl_FACS->length > 32) && (acpi_gbl_FACS->version >= 1)) { - acpi_gbl_FACS->xfirmware_waking_vector = 0; - } - - return_ACPI_STATUS(AE_OK); -} - -ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) - -#if ACPI_MACHINE_WIDTH == 64 -/******************************************************************************* - * - * FUNCTION: acpi_set_firmware_waking_vector64 - * - * PARAMETERS: physical_address - 64-bit physical address of ACPI protected - * mode entry point. - * - * RETURN: Status - * - * DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if - * it exists in the table. This function is intended for use with - * 64-bit host operating systems. - * - ******************************************************************************/ -acpi_status acpi_set_firmware_waking_vector64(u64 physical_address) -{ - ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector64); - - - /* Determine if the 64-bit vector actually exists */ - - if ((acpi_gbl_FACS->length <= 32) || (acpi_gbl_FACS->version < 1)) { - return_ACPI_STATUS(AE_NOT_EXIST); - } - - /* Clear 32-bit vector, set the 64-bit X_ vector */ - - acpi_gbl_FACS->firmware_waking_vector = 0; - acpi_gbl_FACS->xfirmware_waking_vector = physical_address; - return_ACPI_STATUS(AE_OK); -} - -ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64) -#endif - -/******************************************************************************* - * - * FUNCTION: acpi_enter_sleep_state_s4bios - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Perform a S4 bios request. - * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED - * - ******************************************************************************/ -acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) -{ - u32 in_value; - acpi_status status; - - ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios); - - /* Clear the wake status bit (PM1) */ - - status = - acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - status = acpi_hw_clear_acpi_status(); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * 1) Disable/Clear all GPEs - * 2) Enable all wakeup GPEs - */ - status = acpi_hw_disable_all_gpes(); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - acpi_gbl_system_awake_and_running = FALSE; - - status = acpi_hw_enable_all_wakeup_gpes(); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - ACPI_FLUSH_CPU_CACHE(); - - status = acpi_hw_write_port(acpi_gbl_FADT.smi_command, - (u32)acpi_gbl_FADT.S4bios_request, 8); - - do { - acpi_os_stall(1000); - status = - acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - } while (!in_value); - - return_ACPI_STATUS(AE_OK); -} - -ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios) -#endif /* !ACPI_REDUCED_HARDWARE */ -/******************************************************************************* - * - * FUNCTION: acpi_hw_sleep_dispatch - * - * PARAMETERS: sleep_state - Which sleep state to enter/exit - * function_id - Sleep, wake_prep, or Wake - * - * RETURN: Status from the invoked sleep handling function. - * - * DESCRIPTION: Dispatch a sleep/wake request to the appropriate handling - * function. - * - ******************************************************************************/ -static acpi_status -acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id) -{ - acpi_status status; - struct acpi_sleep_functions *sleep_functions = - &acpi_sleep_dispatch[function_id]; - -#if (!ACPI_REDUCED_HARDWARE) - - /* - * If the Hardware Reduced flag is set (from the FADT), we must - * use the extended sleep registers - */ - if (acpi_gbl_reduced_hardware || acpi_gbl_FADT.sleep_control.address) { - status = sleep_functions->extended_function(sleep_state, flags); - } else { - /* Legacy sleep */ - - status = sleep_functions->legacy_function(sleep_state, flags); - } - - return (status); - -#else - /* - * For the case where reduced-hardware-only code is being generated, - * we know that only the extended sleep registers are available - */ - status = sleep_functions->extended_function(sleep_state, flags); - return (status); - -#endif /* !ACPI_REDUCED_HARDWARE */ -} - -/******************************************************************************* - * - * FUNCTION: acpi_enter_sleep_state_prep - * - * PARAMETERS: sleep_state - Which sleep state to enter - * - * RETURN: Status - * - * DESCRIPTION: Prepare to enter a system sleep state. - * This function must execute with interrupts enabled. - * We break sleeping into 2 stages so that OSPM can handle - * various OS-specific tasks between the two steps. - * - ******************************************************************************/ - -acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) -{ - acpi_status status; - struct acpi_object_list arg_list; - union acpi_object arg; - u32 sst_value; - - ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep); - - status = acpi_get_sleep_type_data(sleep_state, - &acpi_gbl_sleep_type_a, - &acpi_gbl_sleep_type_b); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Execute the _PTS method (Prepare To Sleep) */ - - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = sleep_state; - - status = - acpi_evaluate_object(NULL, METHOD_PATHNAME__PTS, &arg_list, NULL); - if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - return_ACPI_STATUS(status); - } - - /* Setup the argument to the _SST method (System STatus) */ - - switch (sleep_state) { - case ACPI_STATE_S0: - sst_value = ACPI_SST_WORKING; - break; - - case ACPI_STATE_S1: - case ACPI_STATE_S2: - case ACPI_STATE_S3: - sst_value = ACPI_SST_SLEEPING; - break; - - case ACPI_STATE_S4: - sst_value = ACPI_SST_SLEEP_CONTEXT; - break; - - default: - sst_value = ACPI_SST_INDICATOR_OFF; /* Default is off */ - break; - } - - /* - * Set the system indicators to show the desired sleep state. - * _SST is an optional method (return no error if not found) - */ - acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, sst_value); - return_ACPI_STATUS(AE_OK); -} - -ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) - -/******************************************************************************* - * - * FUNCTION: acpi_enter_sleep_state - * - * PARAMETERS: sleep_state - Which sleep state to enter - * Flags - ACPI_EXECUTE_GTS to run optional method - * - * RETURN: Status - * - * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231) - * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED - * - ******************************************************************************/ -acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state, u8 flags) -{ - acpi_status status; - - ACPI_FUNCTION_TRACE(acpi_enter_sleep_state); - - if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) || - (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) { - ACPI_ERROR((AE_INFO, "Sleep values out of range: A=0x%X B=0x%X", - acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b)); - return_ACPI_STATUS(AE_AML_OPERAND_VALUE); - } - - status = - acpi_hw_sleep_dispatch(sleep_state, flags, ACPI_SLEEP_FUNCTION_ID); - return_ACPI_STATUS(status); -} - -ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state) - -/******************************************************************************* - * - * FUNCTION: acpi_leave_sleep_state_prep - * - * PARAMETERS: sleep_state - Which sleep state we are exiting - * Flags - ACPI_EXECUTE_BFS to run optional method - * - * RETURN: Status - * - * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a - * sleep. - * Called with interrupts DISABLED. - * - ******************************************************************************/ -acpi_status acpi_leave_sleep_state_prep(u8 sleep_state, u8 flags) -{ - acpi_status status; - - ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep); - - status = - acpi_hw_sleep_dispatch(sleep_state, flags, - ACPI_WAKE_PREP_FUNCTION_ID); - return_ACPI_STATUS(status); -} - -ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state_prep) - -/******************************************************************************* - * - * FUNCTION: acpi_leave_sleep_state - * - * PARAMETERS: sleep_state - Which sleep state we are exiting - * - * RETURN: Status - * - * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep - * Called with interrupts ENABLED. - * - ******************************************************************************/ -acpi_status acpi_leave_sleep_state(u8 sleep_state) -{ - acpi_status status; - - ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); - - - status = acpi_hw_sleep_dispatch(sleep_state, 0, ACPI_WAKE_FUNCTION_ID); - return_ACPI_STATUS(status); -} - -ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state) diff --git a/trunk/drivers/acpi/acpica/nsdump.c b/trunk/drivers/acpi/acpica/nsdump.c index 3f7f3f6e7dd5..b7f2b3be79ac 100644 --- a/trunk/drivers/acpi/acpica/nsdump.c +++ b/trunk/drivers/acpi/acpica/nsdump.c @@ -242,20 +242,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, if (!obj_desc) { - /* No attached object. Some types should always have an object */ - - switch (type) { - case ACPI_TYPE_INTEGER: - case ACPI_TYPE_PACKAGE: - case ACPI_TYPE_BUFFER: - case ACPI_TYPE_STRING: - case ACPI_TYPE_METHOD: - acpi_os_printf(""); - break; - - default: - break; - } + /* No attached object, we are done */ acpi_os_printf("\n"); return (AE_OK); diff --git a/trunk/drivers/acpi/acpica/nsdumpdv.c b/trunk/drivers/acpi/acpica/nsdumpdv.c index 3b5acb0eb406..30ea5bc53a78 100644 --- a/trunk/drivers/acpi/acpica/nsdumpdv.c +++ b/trunk/drivers/acpi/acpica/nsdumpdv.c @@ -121,7 +121,7 @@ void acpi_ns_dump_root_devices(void) return; } - status = acpi_get_handle(NULL, METHOD_NAME__SB_, &sys_bus_handle); + status = acpi_get_handle(NULL, ACPI_NS_SYSTEM_BUS, &sys_bus_handle); if (ACPI_FAILURE(status)) { return; } diff --git a/trunk/drivers/acpi/acpica/nspredef.c b/trunk/drivers/acpi/acpica/nspredef.c index 23ce09686418..bbe46a447d34 100644 --- a/trunk/drivers/acpi/acpica/nspredef.c +++ b/trunk/drivers/acpi/acpica/nspredef.c @@ -638,8 +638,8 @@ acpi_ns_check_package(struct acpi_predefined_data *data, /* Create the new outer package and populate it */ status = - acpi_ns_wrap_with_package(data, *elements, - return_object_ptr); + acpi_ns_repair_package_list(data, + return_object_ptr); if (ACPI_FAILURE(status)) { return (status); } diff --git a/trunk/drivers/acpi/acpica/nsrepair.c b/trunk/drivers/acpi/acpica/nsrepair.c index 5519a64a353f..9c35d20eb52b 100644 --- a/trunk/drivers/acpi/acpica/nsrepair.c +++ b/trunk/drivers/acpi/acpica/nsrepair.c @@ -71,10 +71,11 @@ ACPI_MODULE_NAME("nsrepair") * Buffer -> String * Buffer -> Package of Integers * Package -> Package of one Package - * An incorrect standalone object is wrapped with required outer package * * Additional possible repairs: + * * Required package elements that are NULL replaced by Integer/String/Buffer + * Incorrect standalone package wrapped with required outer package * ******************************************************************************/ /* Local prototypes */ @@ -90,6 +91,10 @@ static acpi_status acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, union acpi_operand_object **return_object); +static acpi_status +acpi_ns_convert_to_package(union acpi_operand_object *original_object, + union acpi_operand_object **return_object); + /******************************************************************************* * * FUNCTION: acpi_ns_repair_object @@ -146,24 +151,9 @@ acpi_ns_repair_object(struct acpi_predefined_data *data, } } if (expected_btypes & ACPI_RTYPE_PACKAGE) { - /* - * A package is expected. We will wrap the existing object with a - * new package object. It is often the case that if a variable-length - * package is required, but there is only a single object needed, the - * BIOS will return that object instead of wrapping it with a Package - * object. Note: after the wrapping, the package will be validated - * for correct contents (expected object type or types). - */ - status = - acpi_ns_wrap_with_package(data, return_object, &new_object); + status = acpi_ns_convert_to_package(return_object, &new_object); if (ACPI_SUCCESS(status)) { - /* - * The original object just had its reference count - * incremented for being inserted into the new package. - */ - *return_object_ptr = new_object; /* New Package object */ - data->flags |= ACPI_OBJECT_REPAIRED; - return (AE_OK); + goto object_repaired; } } @@ -175,27 +165,22 @@ acpi_ns_repair_object(struct acpi_predefined_data *data, /* Object was successfully repaired */ + /* + * If the original object is a package element, we need to: + * 1. Set the reference count of the new object to match the + * reference count of the old object. + * 2. Decrement the reference count of the original object. + */ if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { - /* - * The original object is a package element. We need to - * decrement the reference count of the original object, - * for removing it from the package. - * - * However, if the original object was just wrapped with a - * package object as part of the repair, we don't need to - * change the reference count. - */ - if (!(data->flags & ACPI_OBJECT_WRAPPED)) { - new_object->common.reference_count = - return_object->common.reference_count; + new_object->common.reference_count = + return_object->common.reference_count; - if (return_object->common.reference_count > 1) { - return_object->common.reference_count--; - } + if (return_object->common.reference_count > 1) { + return_object->common.reference_count--; } ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, - "%s: Converted %s to expected %s at Package index %u\n", + "%s: Converted %s to expected %s at index %u\n", data->pathname, acpi_ut_get_object_type_name(return_object), acpi_ut_get_object_type_name(new_object), @@ -466,6 +451,65 @@ acpi_ns_convert_to_buffer(union acpi_operand_object *original_object, return (AE_OK); } +/******************************************************************************* + * + * FUNCTION: acpi_ns_convert_to_package + * + * PARAMETERS: original_object - Object to be converted + * return_object - Where the new converted object is returned + * + * RETURN: Status. AE_OK if conversion was successful. + * + * DESCRIPTION: Attempt to convert a Buffer object to a Package. Each byte of + * the buffer is converted to a single integer package element. + * + ******************************************************************************/ + +static acpi_status +acpi_ns_convert_to_package(union acpi_operand_object *original_object, + union acpi_operand_object **return_object) +{ + union acpi_operand_object *new_object; + union acpi_operand_object **elements; + u32 length; + u8 *buffer; + + switch (original_object->common.type) { + case ACPI_TYPE_BUFFER: + + /* Buffer-to-Package conversion */ + + length = original_object->buffer.length; + new_object = acpi_ut_create_package_object(length); + if (!new_object) { + return (AE_NO_MEMORY); + } + + /* Convert each buffer byte to an integer package element */ + + elements = new_object->package.elements; + buffer = original_object->buffer.pointer; + + while (length--) { + *elements = + acpi_ut_create_integer_object((u64) *buffer); + if (!*elements) { + acpi_ut_remove_reference(new_object); + return (AE_NO_MEMORY); + } + elements++; + buffer++; + } + break; + + default: + return (AE_AML_OPERAND_TYPE); + } + + *return_object = new_object; + return (AE_OK); +} + /******************************************************************************* * * FUNCTION: acpi_ns_repair_null_element @@ -633,56 +677,55 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data, /******************************************************************************* * - * FUNCTION: acpi_ns_wrap_with_package + * FUNCTION: acpi_ns_repair_package_list * * PARAMETERS: Data - Pointer to validation data structure - * original_object - Pointer to the object to repair. - * obj_desc_ptr - The new package object is returned here + * obj_desc_ptr - Pointer to the object to repair. The new + * package object is returned here, + * overwriting the old object. * * RETURN: Status, new object in *obj_desc_ptr * - * DESCRIPTION: Repair a common problem with objects that are defined to - * return a variable-length Package of sub-objects. If there is - * only one sub-object, some BIOS code mistakenly simply declares - * the single object instead of a Package with one sub-object. - * This function attempts to repair this error by wrapping a - * Package object around the original object, creating the - * correct and expected Package with one sub-object. + * DESCRIPTION: Repair a common problem with objects that are defined to return + * a variable-length Package of Packages. If the variable-length + * is one, some BIOS code mistakenly simply declares a single + * Package instead of a Package with one sub-Package. This + * function attempts to repair this error by wrapping a Package + * object around the original Package, creating the correct + * Package with one sub-Package. * * Names that can be repaired in this manner include: - * _ALR, _CSD, _HPX, _MLS, _PLD, _PRT, _PSS, _TRT, _TSS, - * _BCL, _DOD, _FIX, _Sx + * _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS * ******************************************************************************/ acpi_status -acpi_ns_wrap_with_package(struct acpi_predefined_data *data, - union acpi_operand_object *original_object, - union acpi_operand_object **obj_desc_ptr) +acpi_ns_repair_package_list(struct acpi_predefined_data *data, + union acpi_operand_object **obj_desc_ptr) { union acpi_operand_object *pkg_obj_desc; - ACPI_FUNCTION_NAME(ns_wrap_with_package); + ACPI_FUNCTION_NAME(ns_repair_package_list); /* * Create the new outer package and populate it. The new package will - * have a single element, the lone sub-object. + * have a single element, the lone subpackage. */ pkg_obj_desc = acpi_ut_create_package_object(1); if (!pkg_obj_desc) { return (AE_NO_MEMORY); } - pkg_obj_desc->package.elements[0] = original_object; - - ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, - "%s: Wrapped %s with expected Package object\n", - data->pathname, - acpi_ut_get_object_type_name(original_object))); + pkg_obj_desc->package.elements[0] = *obj_desc_ptr; /* Return the new object in the object pointer */ *obj_desc_ptr = pkg_obj_desc; - data->flags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED; + data->flags |= ACPI_OBJECT_REPAIRED; + + ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, + "%s: Repaired incorrectly formed Package\n", + data->pathname)); + return (AE_OK); } diff --git a/trunk/drivers/acpi/acpica/nsutils.c b/trunk/drivers/acpi/acpica/nsutils.c index 75113759f69d..a535b7afda5c 100644 --- a/trunk/drivers/acpi/acpica/nsutils.c +++ b/trunk/drivers/acpi/acpica/nsutils.c @@ -341,7 +341,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info) if (!acpi_ns_valid_path_separator(*external_name) && (*external_name != 0)) { - return_ACPI_STATUS(AE_BAD_PATHNAME); + return_ACPI_STATUS(AE_BAD_PARAMETER); } /* Move on the next segment */ diff --git a/trunk/drivers/acpi/acpica/tbfadt.c b/trunk/drivers/acpi/acpica/tbfadt.c index 4c9c760db4a4..c5d870406f41 100644 --- a/trunk/drivers/acpi/acpica/tbfadt.c +++ b/trunk/drivers/acpi/acpica/tbfadt.c @@ -363,6 +363,10 @@ static void acpi_tb_convert_fadt(void) u32 address32; u32 i; + /* Update the local FADT table header length */ + + acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt); + /* * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary. * Later code will always use the X 64-bit field. Also, check for an @@ -404,10 +408,6 @@ static void acpi_tb_convert_fadt(void) acpi_gbl_FADT.boot_flags = 0; } - /* Update the local FADT table header length */ - - acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt); - /* * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" * generic address structures as necessary. Later code will always use diff --git a/trunk/drivers/acpi/acpica/tbinstal.c b/trunk/drivers/acpi/acpica/tbinstal.c index c03500b4cc7a..1aecf7baa4e0 100644 --- a/trunk/drivers/acpi/acpica/tbinstal.c +++ b/trunk/drivers/acpi/acpica/tbinstal.c @@ -114,6 +114,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) { u32 i; acpi_status status = AE_OK; + struct acpi_table_header *override_table = NULL; ACPI_FUNCTION_TRACE(tb_add_table); @@ -223,10 +224,25 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) /* * ACPI Table Override: * Allow the host to override dynamically loaded tables. - * NOTE: the table is fully mapped at this point, and the mapping will - * be deleted by tb_table_override if the table is actually overridden. */ - (void)acpi_tb_table_override(table_desc->pointer, table_desc); + status = acpi_os_table_override(table_desc->pointer, &override_table); + if (ACPI_SUCCESS(status) && override_table) { + ACPI_INFO((AE_INFO, + "%4.4s @ 0x%p Table override, replaced with:", + table_desc->pointer->signature, + ACPI_CAST_PTR(void, table_desc->address))); + + /* We can delete the table that was passed as a parameter */ + + acpi_tb_delete_table(table_desc); + + /* Setup descriptor for the new table */ + + table_desc->address = ACPI_PTR_TO_PHYSADDR(override_table); + table_desc->pointer = override_table; + table_desc->length = override_table->length; + table_desc->flags = ACPI_TABLE_ORIGIN_OVERRIDE; + } /* Add the table to the global root table list */ @@ -245,95 +261,6 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) return_ACPI_STATUS(status); } -/******************************************************************************* - * - * FUNCTION: acpi_tb_table_override - * - * PARAMETERS: table_header - Header for the original table - * table_desc - Table descriptor initialized for the - * original table. May or may not be mapped. - * - * RETURN: Pointer to the entire new table. NULL if table not overridden. - * If overridden, installs the new table within the input table - * descriptor. - * - * DESCRIPTION: Attempt table override by calling the OSL override functions. - * Note: If the table is overridden, then the entire new table - * is mapped and returned by this function. - * - ******************************************************************************/ - -struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header - *table_header, - struct acpi_table_desc - *table_desc) -{ - acpi_status status; - struct acpi_table_header *new_table = NULL; - acpi_physical_address new_address = 0; - u32 new_table_length = 0; - u8 new_flags; - char *override_type; - - /* (1) Attempt logical override (returns a logical address) */ - - status = acpi_os_table_override(table_header, &new_table); - if (ACPI_SUCCESS(status) && new_table) { - new_address = ACPI_PTR_TO_PHYSADDR(new_table); - new_table_length = new_table->length; - new_flags = ACPI_TABLE_ORIGIN_OVERRIDE; - override_type = "Logical"; - goto finish_override; - } - - /* (2) Attempt physical override (returns a physical address) */ - - status = acpi_os_physical_table_override(table_header, - &new_address, - &new_table_length); - if (ACPI_SUCCESS(status) && new_address && new_table_length) { - - /* Map the entire new table */ - - new_table = acpi_os_map_memory(new_address, new_table_length); - if (!new_table) { - ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, - "%4.4s %p Attempted physical table override failed", - table_header->signature, - ACPI_CAST_PTR(void, - table_desc->address))); - return (NULL); - } - - override_type = "Physical"; - new_flags = ACPI_TABLE_ORIGIN_MAPPED; - goto finish_override; - } - - return (NULL); /* There was no override */ - - finish_override: - - ACPI_INFO((AE_INFO, - "%4.4s %p %s table override, new table: %p", - table_header->signature, - ACPI_CAST_PTR(void, table_desc->address), - override_type, new_table)); - - /* We can now unmap/delete the original table (if fully mapped) */ - - acpi_tb_delete_table(table_desc); - - /* Setup descriptor for the new table */ - - table_desc->address = new_address; - table_desc->pointer = new_table; - table_desc->length = new_table_length; - table_desc->flags = new_flags; - - return (new_table); -} - /******************************************************************************* * * FUNCTION: acpi_tb_resize_root_table_list @@ -469,11 +396,7 @@ void acpi_tb_delete_table(struct acpi_table_desc *table_desc) case ACPI_TABLE_ORIGIN_ALLOCATED: ACPI_FREE(table_desc->pointer); break; - - /* Not mapped or allocated, there is nothing we can do */ - - default: - return; + default:; } table_desc->pointer = NULL; diff --git a/trunk/drivers/acpi/acpica/tbutils.c b/trunk/drivers/acpi/acpica/tbutils.c index 0a706cac37de..09ca39e14337 100644 --- a/trunk/drivers/acpi/acpica/tbutils.c +++ b/trunk/drivers/acpi/acpica/tbutils.c @@ -118,7 +118,6 @@ acpi_tb_check_xsdt(acpi_physical_address address) return AE_OK; } -#if (!ACPI_REDUCED_HARDWARE) /******************************************************************************* * * FUNCTION: acpi_tb_initialize_facs @@ -149,7 +148,6 @@ acpi_status acpi_tb_initialize_facs(void) &acpi_gbl_FACS)); return status; } -#endif /* !ACPI_REDUCED_HARDWARE */ /******************************************************************************* * @@ -446,7 +444,7 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index) * RETURN: None * * DESCRIPTION: Install an ACPI table into the global data structure. The - * table override mechanism is called to allow the host + * table override mechanism is implemented here to allow the host * OS to replace any table before it is installed in the root * table array. * @@ -456,9 +454,11 @@ void acpi_tb_install_table(acpi_physical_address address, char *signature, u32 table_index) { - struct acpi_table_header *table; - struct acpi_table_header *final_table; - struct acpi_table_desc *table_desc; + u8 flags; + acpi_status status; + struct acpi_table_header *table_to_install; + struct acpi_table_header *mapped_table; + struct acpi_table_header *override_table = NULL; if (!address) { ACPI_ERROR((AE_INFO, @@ -469,78 +469,69 @@ acpi_tb_install_table(acpi_physical_address address, /* Map just the table header */ - table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); - if (!table) { - ACPI_ERROR((AE_INFO, - "Could not map memory for table [%s] at %p", - signature, ACPI_CAST_PTR(void, address))); + mapped_table = + acpi_os_map_memory(address, sizeof(struct acpi_table_header)); + if (!mapped_table) { return; } /* If a particular signature is expected (DSDT/FACS), it must match */ - if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) { + if (signature && !ACPI_COMPARE_NAME(mapped_table->signature, signature)) { ACPI_ERROR((AE_INFO, "Invalid signature 0x%X for ACPI table, expected [%s]", - *ACPI_CAST_PTR(u32, table->signature), signature)); + *ACPI_CAST_PTR(u32, mapped_table->signature), + signature)); goto unmap_and_exit; } - /* - * Initialize the table entry. Set the pointer to NULL, since the - * table is not fully mapped at this time. - */ - table_desc = &acpi_gbl_root_table_list.tables[table_index]; - - table_desc->address = address; - table_desc->pointer = NULL; - table_desc->length = table->length; - table_desc->flags = ACPI_TABLE_ORIGIN_MAPPED; - ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature); - /* * ACPI Table Override: * * Before we install the table, let the host OS override it with a new * one if desired. Any table within the RSDT/XSDT can be replaced, * including the DSDT which is pointed to by the FADT. - * - * NOTE: If the table is overridden, then final_table will contain a - * mapped pointer to the full new table. If the table is not overridden, - * or if there has been a physical override, then the table will be - * fully mapped later (in verify table). In any case, we must - * unmap the header that was mapped above. */ - final_table = acpi_tb_table_override(table, table_desc); - if (!final_table) { - final_table = table; /* There was no override */ + status = acpi_os_table_override(mapped_table, &override_table); + if (ACPI_SUCCESS(status) && override_table) { + ACPI_INFO((AE_INFO, + "%4.4s @ 0x%p Table override, replaced with:", + mapped_table->signature, ACPI_CAST_PTR(void, + address))); + + acpi_gbl_root_table_list.tables[table_index].pointer = + override_table; + address = ACPI_PTR_TO_PHYSADDR(override_table); + + table_to_install = override_table; + flags = ACPI_TABLE_ORIGIN_OVERRIDE; + } else { + table_to_install = mapped_table; + flags = ACPI_TABLE_ORIGIN_MAPPED; } - acpi_tb_print_table_header(table_desc->address, final_table); + /* Initialize the table entry */ - /* Set the global integer width (based upon revision of the DSDT) */ + acpi_gbl_root_table_list.tables[table_index].address = address; + acpi_gbl_root_table_list.tables[table_index].length = + table_to_install->length; + acpi_gbl_root_table_list.tables[table_index].flags = flags; + + ACPI_MOVE_32_TO_32(& + (acpi_gbl_root_table_list.tables[table_index]. + signature), table_to_install->signature); + + acpi_tb_print_table_header(address, table_to_install); if (table_index == ACPI_TABLE_INDEX_DSDT) { - acpi_ut_set_integer_width(final_table->revision); - } - /* - * If we have a physical override during this early loading of the ACPI - * tables, unmap the table for now. It will be mapped again later when - * it is actually used. This supports very early loading of ACPI tables, - * before virtual memory is fully initialized and running within the - * host OS. Note: A logical override has the ACPI_TABLE_ORIGIN_OVERRIDE - * flag set and will not be deleted below. - */ - if (final_table != table) { - acpi_tb_delete_table(table_desc); + /* Global integer width is based upon revision of the DSDT */ + + acpi_ut_set_integer_width(table_to_install->revision); } unmap_and_exit: - - /* Always unmap the table header that we mapped above */ - - acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); + acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header)); } /******************************************************************************* diff --git a/trunk/drivers/acpi/acpica/utdecode.c b/trunk/drivers/acpi/acpica/utdecode.c index 684849949bf3..d42ede5260c7 100644 --- a/trunk/drivers/acpi/acpica/utdecode.c +++ b/trunk/drivers/acpi/acpica/utdecode.c @@ -497,20 +497,19 @@ char *acpi_ut_get_mutex_name(u32 mutex_id) /* Names for Notify() values, used for debug output */ -static const char *acpi_gbl_notify_value_names[ACPI_NOTIFY_MAX + 1] = { - /* 00 */ "Bus Check", - /* 01 */ "Device Check", - /* 02 */ "Device Wake", - /* 03 */ "Eject Request", - /* 04 */ "Device Check Light", - /* 05 */ "Frequency Mismatch", - /* 06 */ "Bus Mode Mismatch", - /* 07 */ "Power Fault", - /* 08 */ "Capabilities Check", - /* 09 */ "Device PLD Check", - /* 10 */ "Reserved", - /* 11 */ "System Locality Update", - /* 12 */ "Shutdown Request" +static const char *acpi_gbl_notify_value_names[] = { + "Bus Check", + "Device Check", + "Device Wake", + "Eject Request", + "Device Check Light", + "Frequency Mismatch", + "Bus Mode Mismatch", + "Power Fault", + "Capabilities Check", + "Device PLD Check", + "Reserved", + "System Locality Update" }; const char *acpi_ut_get_notify_name(u32 notify_value) @@ -520,10 +519,9 @@ const char *acpi_ut_get_notify_name(u32 notify_value) return (acpi_gbl_notify_value_names[notify_value]); } else if (notify_value <= ACPI_MAX_SYS_NOTIFY) { return ("Reserved"); - } else if (notify_value <= ACPI_MAX_DEVICE_SPECIFIC_NOTIFY) { - return ("Device Specific"); - } else { - return ("Hardware Specific"); + } else { /* Greater or equal to 0x80 */ + + return ("**Device Specific**"); } } #endif diff --git a/trunk/drivers/acpi/acpica/utglobal.c b/trunk/drivers/acpi/acpica/utglobal.c index 90f53b42eca9..4153584cf526 100644 --- a/trunk/drivers/acpi/acpica/utglobal.c +++ b/trunk/drivers/acpi/acpica/utglobal.c @@ -140,7 +140,6 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = { {NULL, ACPI_TYPE_ANY, NULL} }; -#if (!ACPI_REDUCED_HARDWARE) /****************************************************************************** * * Event and Hardware globals @@ -237,7 +236,6 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] = ACPI_BITMASK_RT_CLOCK_STATUS, ACPI_BITMASK_RT_CLOCK_ENABLE}, }; -#endif /* !ACPI_REDUCED_HARDWARE */ /******************************************************************************* * @@ -288,8 +286,6 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; -#if (!ACPI_REDUCED_HARDWARE) - /* GPE support */ acpi_gbl_gpe_xrupt_list_head = NULL; @@ -298,10 +294,6 @@ acpi_status acpi_ut_init_globals(void) acpi_current_gpe_count = 0; acpi_gbl_all_gpes_initialized = FALSE; - acpi_gbl_global_event_handler = NULL; - -#endif /* !ACPI_REDUCED_HARDWARE */ - /* Global handlers */ acpi_gbl_system_notify.handler = NULL; @@ -310,6 +302,7 @@ acpi_status acpi_ut_init_globals(void) acpi_gbl_init_handler = NULL; acpi_gbl_table_handler = NULL; acpi_gbl_interface_handler = NULL; + acpi_gbl_global_event_handler = NULL; /* Global Lock support */ diff --git a/trunk/drivers/acpi/acpica/utinit.c b/trunk/drivers/acpi/acpica/utinit.c index 246798e4c938..8359c0c5dc98 100644 --- a/trunk/drivers/acpi/acpica/utinit.c +++ b/trunk/drivers/acpi/acpica/utinit.c @@ -53,35 +53,27 @@ ACPI_MODULE_NAME("utinit") /* Local prototypes */ static void acpi_ut_terminate(void); -#if (!ACPI_REDUCED_HARDWARE) - -static void acpi_ut_free_gpe_lists(void); - -#else - -#define acpi_ut_free_gpe_lists() -#endif /* !ACPI_REDUCED_HARDWARE */ - -#if (!ACPI_REDUCED_HARDWARE) /****************************************************************************** * - * FUNCTION: acpi_ut_free_gpe_lists + * FUNCTION: acpi_ut_terminate * * PARAMETERS: none * * RETURN: none * - * DESCRIPTION: Free global GPE lists + * DESCRIPTION: Free global memory * ******************************************************************************/ -static void acpi_ut_free_gpe_lists(void) +static void acpi_ut_terminate(void) { struct acpi_gpe_block_info *gpe_block; struct acpi_gpe_block_info *next_gpe_block; struct acpi_gpe_xrupt_info *gpe_xrupt_info; struct acpi_gpe_xrupt_info *next_gpe_xrupt_info; + ACPI_FUNCTION_TRACE(ut_terminate); + /* Free global GPE blocks and related info structures */ gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; @@ -99,26 +91,7 @@ static void acpi_ut_free_gpe_lists(void) ACPI_FREE(gpe_xrupt_info); gpe_xrupt_info = next_gpe_xrupt_info; } -} -#endif /* !ACPI_REDUCED_HARDWARE */ - -/****************************************************************************** - * - * FUNCTION: acpi_ut_terminate - * - * PARAMETERS: none - * - * RETURN: none - * - * DESCRIPTION: Free global memory - * - ******************************************************************************/ - -static void acpi_ut_terminate(void) -{ - ACPI_FUNCTION_TRACE(ut_terminate); - acpi_ut_free_gpe_lists(); acpi_ut_delete_address_lists(); return_VOID; } diff --git a/trunk/drivers/acpi/acpica/utxface.c b/trunk/drivers/acpi/acpica/utxface.c index afa94f51ff0b..644e8c8ebc4b 100644 --- a/trunk/drivers/acpi/acpica/utxface.c +++ b/trunk/drivers/acpi/acpica/utxface.c @@ -145,8 +145,6 @@ acpi_status acpi_enable_subsystem(u32 flags) ACPI_FUNCTION_TRACE(acpi_enable_subsystem); -#if (!ACPI_REDUCED_HARDWARE) - /* Enable ACPI mode */ if (!(flags & ACPI_NO_ACPI_ENABLE)) { @@ -171,7 +169,6 @@ acpi_status acpi_enable_subsystem(u32 flags) ACPI_WARNING((AE_INFO, "Could not map the FACS table")); return_ACPI_STATUS(status); } -#endif /* !ACPI_REDUCED_HARDWARE */ /* * Install the default op_region handlers. These are installed unless @@ -187,7 +184,7 @@ acpi_status acpi_enable_subsystem(u32 flags) return_ACPI_STATUS(status); } } -#if (!ACPI_REDUCED_HARDWARE) + /* * Initialize ACPI Event handling (Fixed and General Purpose) * @@ -223,7 +220,6 @@ acpi_status acpi_enable_subsystem(u32 flags) return_ACPI_STATUS(status); } } -#endif /* !ACPI_REDUCED_HARDWARE */ return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/apei/apei-base.c b/trunk/drivers/acpi/apei/apei-base.c index 5577762daee1..e5d53b7ddc7e 100644 --- a/trunk/drivers/acpi/apei/apei-base.c +++ b/trunk/drivers/acpi/apei/apei-base.c @@ -558,48 +558,33 @@ void apei_resources_release(struct apei_resources *resources) } EXPORT_SYMBOL_GPL(apei_resources_release); -static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr, - u32 *access_bit_width) +static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr) { - u32 bit_width, bit_offset, access_size_code, space_id; + u32 width, space_id; - bit_width = reg->bit_width; - bit_offset = reg->bit_offset; - access_size_code = reg->access_width; + width = reg->bit_width; space_id = reg->space_id; /* Handle possible alignment issues */ memcpy(paddr, ®->address, sizeof(*paddr)); if (!*paddr) { pr_warning(FW_BUG APEI_PFX - "Invalid physical address in GAR [0x%llx/%u/%u/%u/%u]\n", - *paddr, bit_width, bit_offset, access_size_code, - space_id); + "Invalid physical address in GAR [0x%llx/%u/%u]\n", + *paddr, width, space_id); return -EINVAL; } - if (access_size_code < 1 || access_size_code > 4) { + if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) { pr_warning(FW_BUG APEI_PFX - "Invalid access size code in GAR [0x%llx/%u/%u/%u/%u]\n", - *paddr, bit_width, bit_offset, access_size_code, - space_id); - return -EINVAL; - } - *access_bit_width = 1UL << (access_size_code + 2); - - if ((bit_width + bit_offset) > *access_bit_width) { - pr_warning(FW_BUG APEI_PFX - "Invalid bit width + offset in GAR [0x%llx/%u/%u/%u/%u]\n", - *paddr, bit_width, bit_offset, access_size_code, - space_id); + "Invalid bit width in GAR [0x%llx/%u/%u]\n", + *paddr, width, space_id); return -EINVAL; } if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY && space_id != ACPI_ADR_SPACE_SYSTEM_IO) { pr_warning(FW_BUG APEI_PFX - "Invalid address space type in GAR [0x%llx/%u/%u/%u/%u]\n", - *paddr, bit_width, bit_offset, access_size_code, - space_id); + "Invalid address space type in GAR [0x%llx/%u/%u]\n", + *paddr, width, space_id); return -EINVAL; } @@ -610,25 +595,23 @@ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr, int apei_read(u64 *val, struct acpi_generic_address *reg) { int rc; - u32 access_bit_width; u64 address; acpi_status status; - rc = apei_check_gar(reg, &address, &access_bit_width); + rc = apei_check_gar(reg, &address); if (rc) return rc; *val = 0; switch(reg->space_id) { case ACPI_ADR_SPACE_SYSTEM_MEMORY: - status = acpi_os_read_memory((acpi_physical_address) address, - val, access_bit_width); + status = acpi_os_read_memory64((acpi_physical_address) + address, val, reg->bit_width); if (ACPI_FAILURE(status)) return -EIO; break; case ACPI_ADR_SPACE_SYSTEM_IO: - status = acpi_os_read_port(address, (u32 *)val, - access_bit_width); + status = acpi_os_read_port(address, (u32 *)val, reg->bit_width); if (ACPI_FAILURE(status)) return -EIO; break; @@ -644,23 +627,22 @@ EXPORT_SYMBOL_GPL(apei_read); int apei_write(u64 val, struct acpi_generic_address *reg) { int rc; - u32 access_bit_width; u64 address; acpi_status status; - rc = apei_check_gar(reg, &address, &access_bit_width); + rc = apei_check_gar(reg, &address); if (rc) return rc; switch (reg->space_id) { case ACPI_ADR_SPACE_SYSTEM_MEMORY: - status = acpi_os_write_memory((acpi_physical_address) address, - val, access_bit_width); + status = acpi_os_write_memory64((acpi_physical_address) + address, val, reg->bit_width); if (ACPI_FAILURE(status)) return -EIO; break; case ACPI_ADR_SPACE_SYSTEM_IO: - status = acpi_os_write_port(address, val, access_bit_width); + status = acpi_os_write_port(address, val, reg->bit_width); if (ACPI_FAILURE(status)) return -EIO; break; @@ -679,24 +661,23 @@ static int collect_res_callback(struct apei_exec_context *ctx, struct apei_resources *resources = data; struct acpi_generic_address *reg = &entry->register_region; u8 ins = entry->instruction; - u32 access_bit_width; u64 paddr; int rc; if (!(ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER)) return 0; - rc = apei_check_gar(reg, &paddr, &access_bit_width); + rc = apei_check_gar(reg, &paddr); if (rc) return rc; switch (reg->space_id) { case ACPI_ADR_SPACE_SYSTEM_MEMORY: return apei_res_add(&resources->iomem, paddr, - access_bit_width / 8); + reg->bit_width / 8); case ACPI_ADR_SPACE_SYSTEM_IO: return apei_res_add(&resources->ioport, paddr, - access_bit_width / 8); + reg->bit_width / 8); default: return -EINVAL; } diff --git a/trunk/drivers/acpi/apei/cper.c b/trunk/drivers/acpi/apei/cper.c index e6defd86b424..5d4189464d63 100644 --- a/trunk/drivers/acpi/apei/cper.c +++ b/trunk/drivers/acpi/apei/cper.c @@ -362,7 +362,6 @@ void apei_estatus_print(const char *pfx, gedata_len = gdata->error_data_length; apei_estatus_print_section(pfx, gdata, sec_no); data_len -= gedata_len + sizeof(*gdata); - gdata = (void *)(gdata + 1) + gedata_len; sec_no++; } } @@ -397,7 +396,6 @@ int apei_estatus_check(const struct acpi_hest_generic_status *estatus) if (gedata_len > data_len - sizeof(*gdata)) return -EINVAL; data_len -= gedata_len + sizeof(*gdata); - gdata = (void *)(gdata + 1) + gedata_len; } if (data_len) return -EINVAL; diff --git a/trunk/drivers/acpi/apei/einj.c b/trunk/drivers/acpi/apei/einj.c index 8e1793649ec0..4ca087dd5f4f 100644 --- a/trunk/drivers/acpi/apei/einj.c +++ b/trunk/drivers/acpi/apei/einj.c @@ -74,8 +74,6 @@ struct vendor_error_type_extension { u8 reserved[3]; }; -static u32 notrigger; - static u32 vendor_flags; static struct debugfs_blob_wrapper vendor_blob; static char vendor_dev[64]; @@ -240,7 +238,7 @@ static void *einj_get_parameter_address(void) return v5param; } } - if (param_extension && paddrv4) { + if (paddrv4) { struct einj_parameter *v4param; v4param = acpi_os_map_memory(paddrv4, sizeof(*v4param)); @@ -498,11 +496,9 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2) if (rc) return rc; trigger_paddr = apei_exec_ctx_get_output(&ctx); - if (notrigger == 0) { - rc = __einj_error_trigger(trigger_paddr, type, param1, param2); - if (rc) - return rc; - } + rc = __einj_error_trigger(trigger_paddr, type, param1, param2); + if (rc) + return rc; rc = apei_exec_run_optional(&ctx, ACPI_EINJ_END_OPERATION); return rc; @@ -704,11 +700,6 @@ static int __init einj_init(void) einj_debug_dir, &error_param2); if (!fentry) goto err_unmap; - - fentry = debugfs_create_x32("notrigger", S_IRUSR | S_IWUSR, - einj_debug_dir, ¬rigger); - if (!fentry) - goto err_unmap; } if (vendor_dev[0]) { diff --git a/trunk/drivers/acpi/apei/erst.c b/trunk/drivers/acpi/apei/erst.c index e4d9d24eb73d..eb9fab5b96e4 100644 --- a/trunk/drivers/acpi/apei/erst.c +++ b/trunk/drivers/acpi/apei/erst.c @@ -917,7 +917,7 @@ static int erst_check_table(struct acpi_table_erst *erst_tab) { if ((erst_tab->header_length != (sizeof(struct acpi_table_erst) - sizeof(erst_tab->header))) - && (erst_tab->header_length != sizeof(struct acpi_table_erst))) + && (erst_tab->header_length != sizeof(struct acpi_table_einj))) return -EINVAL; if (erst_tab->header.length < sizeof(struct acpi_table_erst)) return -EINVAL; diff --git a/trunk/drivers/acpi/bgrt.c b/trunk/drivers/acpi/bgrt.c deleted file mode 100644 index 8cf6c46e99fb..000000000000 --- a/trunk/drivers/acpi/bgrt.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2012 Red Hat, Inc - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -static struct acpi_table_bgrt *bgrt_tab; -static struct kobject *bgrt_kobj; - -struct bmp_header { - u16 id; - u32 size; -} __attribute ((packed)); - -static struct bmp_header bmp_header; - -static ssize_t show_version(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->version); -} -static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); - -static ssize_t show_status(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->status); -} -static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); - -static ssize_t show_type(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_type); -} -static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); - -static ssize_t show_xoffset(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_offset_x); -} -static DEVICE_ATTR(xoffset, S_IRUGO, show_xoffset, NULL); - -static ssize_t show_yoffset(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_offset_y); -} -static DEVICE_ATTR(yoffset, S_IRUGO, show_yoffset, NULL); - -static ssize_t show_image(struct file *file, struct kobject *kobj, - struct bin_attribute *attr, char *buf, loff_t off, size_t count) -{ - int size = attr->size; - void __iomem *image = attr->private; - - if (off >= size) { - count = 0; - } else { - if (off + count > size) - count = size - off; - - memcpy_fromio(buf, image+off, count); - } - - return count; -} - -static struct bin_attribute image_attr = { - .attr = { - .name = "image", - .mode = S_IRUGO, - }, - .read = show_image, -}; - -static struct attribute *bgrt_attributes[] = { - &dev_attr_version.attr, - &dev_attr_status.attr, - &dev_attr_type.attr, - &dev_attr_xoffset.attr, - &dev_attr_yoffset.attr, - NULL, -}; - -static struct attribute_group bgrt_attribute_group = { - .attrs = bgrt_attributes, -}; - -static int __init bgrt_init(void) -{ - acpi_status status; - int ret; - void __iomem *bgrt; - - if (acpi_disabled) - return -ENODEV; - - status = acpi_get_table("BGRT", 0, - (struct acpi_table_header **)&bgrt_tab); - - if (ACPI_FAILURE(status)) - return -ENODEV; - - sysfs_bin_attr_init(&image_attr); - - bgrt = ioremap(bgrt_tab->image_address, sizeof(struct bmp_header)); - - if (!bgrt) { - ret = -EINVAL; - goto out_err; - } - - memcpy_fromio(&bmp_header, bgrt, sizeof(bmp_header)); - image_attr.size = bmp_header.size; - iounmap(bgrt); - - image_attr.private = ioremap(bgrt_tab->image_address, image_attr.size); - - if (!image_attr.private) { - ret = -EINVAL; - goto out_err; - } - - - bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj); - if (!bgrt_kobj) { - ret = -EINVAL; - goto out_iounmap; - } - - ret = sysfs_create_group(bgrt_kobj, &bgrt_attribute_group); - if (ret) - goto out_kobject; - - ret = sysfs_create_bin_file(bgrt_kobj, &image_attr); - if (ret) - goto out_group; - - return 0; - -out_group: - sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group); -out_kobject: - kobject_put(bgrt_kobj); -out_iounmap: - iounmap(image_attr.private); -out_err: - return ret; -} - -static void __exit bgrt_exit(void) -{ - iounmap(image_attr.private); - sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group); - sysfs_remove_bin_file(bgrt_kobj, &image_attr); -} - -module_init(bgrt_init); -module_exit(bgrt_exit); - -MODULE_AUTHOR("Matthew Garrett"); -MODULE_DESCRIPTION("BGRT boot graphic support"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/acpi/bus.c b/trunk/drivers/acpi/bus.c index 3263b68cdfa3..9ecec98bc76e 100644 --- a/trunk/drivers/acpi/bus.c +++ b/trunk/drivers/acpi/bus.c @@ -1010,7 +1010,6 @@ static int __init acpi_bus_init(void) } struct kobject *acpi_kobj; -EXPORT_SYMBOL_GPL(acpi_kobj); static int __init acpi_init(void) { diff --git a/trunk/drivers/acpi/ec.c b/trunk/drivers/acpi/ec.c index 7edaccce6640..e37615f310d7 100644 --- a/trunk/drivers/acpi/ec.c +++ b/trunk/drivers/acpi/ec.c @@ -822,10 +822,10 @@ static int acpi_ec_add(struct acpi_device *device) first_ec = ec; device->driver_data = ec; - ret = !!request_region(ec->data_addr, 1, "EC data"); - WARN(!ret, "Could not request EC data io port 0x%lx", ec->data_addr); - ret = !!request_region(ec->command_addr, 1, "EC cmd"); - WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr); + WARN(!request_region(ec->data_addr, 1, "EC data"), + "Could not request EC data io port 0x%lx", ec->data_addr); + WARN(!request_region(ec->command_addr, 1, "EC cmd"), + "Could not request EC cmd io port 0x%lx", ec->command_addr); pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", ec->gpe, ec->command_addr, ec->data_addr); diff --git a/trunk/drivers/acpi/ec_sys.c b/trunk/drivers/acpi/ec_sys.c index 7586544fddb4..b258cab9061c 100644 --- a/trunk/drivers/acpi/ec_sys.c +++ b/trunk/drivers/acpi/ec_sys.c @@ -27,6 +27,12 @@ MODULE_PARM_DESC(write_support, "Dangerous, reboot and removal of battery may " static struct dentry *acpi_ec_debugfs_dir; +static int acpi_ec_open_io(struct inode *i, struct file *f) +{ + f->private_data = i->i_private; + return 0; +} + static ssize_t acpi_ec_read_io(struct file *f, char __user *buf, size_t count, loff_t *off) { @@ -89,7 +95,7 @@ static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf, static const struct file_operations acpi_ec_io_ops = { .owner = THIS_MODULE, - .open = simple_open, + .open = acpi_ec_open_io, .read = acpi_ec_read_io, .write = acpi_ec_write_io, .llseek = default_llseek, diff --git a/trunk/drivers/acpi/nvs.c b/trunk/drivers/acpi/nvs.c index 266bc58ce0ce..7a2035fa8c71 100644 --- a/trunk/drivers/acpi/nvs.c +++ b/trunk/drivers/acpi/nvs.c @@ -95,8 +95,8 @@ static int suspend_nvs_register(unsigned long start, unsigned long size) { struct nvs_page *entry, *next; - pr_info("PM: Registering ACPI NVS region [mem %#010lx-%#010lx] (%ld bytes)\n", - start, start + size - 1, size); + pr_info("PM: Registering ACPI NVS region at %lx (%ld bytes)\n", + start, size); while (size > 0) { unsigned int nr_bytes; diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index c3881b2eb8b2..412a1e04a922 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -77,9 +77,6 @@ EXPORT_SYMBOL(acpi_in_debugger); extern char line_buf[80]; #endif /*ENABLE_DEBUGGER */ -static int (*__acpi_os_prepare_sleep)(u8 sleep_state, u32 pm1a_ctrl, - u32 pm1b_ctrl); - static acpi_osd_handler acpi_irq_handler; static void *acpi_irq_context; static struct workqueue_struct *kacpid_wq; @@ -350,7 +347,7 @@ static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr) unsigned long pfn; pfn = pg_off >> PAGE_SHIFT; - if (should_use_kmap(pfn)) + if (page_is_ram(pfn)) kunmap(pfn_to_page(pfn)); else iounmap(vaddr); @@ -557,15 +554,6 @@ acpi_os_table_override(struct acpi_table_header * existing_table, return AE_OK; } -acpi_status -acpi_os_physical_table_override(struct acpi_table_header *existing_table, - acpi_physical_address * new_address, - u32 *new_table_length) -{ - return AE_SUPPORT; -} - - static irqreturn_t acpi_irq(int irq, void *dev_id) { u32 handled; @@ -711,6 +699,49 @@ acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width) EXPORT_SYMBOL(acpi_os_write_port); +acpi_status +acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) +{ + void __iomem *virt_addr; + unsigned int size = width / 8; + bool unmap = false; + u32 dummy; + + rcu_read_lock(); + virt_addr = acpi_map_vaddr_lookup(phys_addr, size); + if (!virt_addr) { + rcu_read_unlock(); + virt_addr = acpi_os_ioremap(phys_addr, size); + if (!virt_addr) + return AE_BAD_ADDRESS; + unmap = true; + } + + if (!value) + value = &dummy; + + switch (width) { + case 8: + *(u8 *) value = readb(virt_addr); + break; + case 16: + *(u16 *) value = readw(virt_addr); + break; + case 32: + *(u32 *) value = readl(virt_addr); + break; + default: + BUG(); + } + + if (unmap) + iounmap(virt_addr); + else + rcu_read_unlock(); + + return AE_OK; +} + #ifdef readq static inline u64 read64(const volatile void __iomem *addr) { @@ -727,7 +758,7 @@ static inline u64 read64(const volatile void __iomem *addr) #endif acpi_status -acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width) +acpi_os_read_memory64(acpi_physical_address phys_addr, u64 *value, u32 width) { void __iomem *virt_addr; unsigned int size = width / 8; @@ -772,6 +803,45 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width) return AE_OK; } +acpi_status +acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) +{ + void __iomem *virt_addr; + unsigned int size = width / 8; + bool unmap = false; + + rcu_read_lock(); + virt_addr = acpi_map_vaddr_lookup(phys_addr, size); + if (!virt_addr) { + rcu_read_unlock(); + virt_addr = acpi_os_ioremap(phys_addr, size); + if (!virt_addr) + return AE_BAD_ADDRESS; + unmap = true; + } + + switch (width) { + case 8: + writeb(value, virt_addr); + break; + case 16: + writew(value, virt_addr); + break; + case 32: + writel(value, virt_addr); + break; + default: + BUG(); + } + + if (unmap) + iounmap(virt_addr); + else + rcu_read_unlock(); + + return AE_OK; +} + #ifdef writeq static inline void write64(u64 val, volatile void __iomem *addr) { @@ -786,7 +856,7 @@ static inline void write64(u64 val, volatile void __iomem *addr) #endif acpi_status -acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width) +acpi_os_write_memory64(acpi_physical_address phys_addr, u64 value, u32 width) { void __iomem *virt_addr; unsigned int size = width / 8; @@ -1571,24 +1641,3 @@ acpi_status acpi_os_terminate(void) return AE_OK; } - -acpi_status acpi_os_prepare_sleep(u8 sleep_state, u32 pm1a_control, - u32 pm1b_control) -{ - int rc = 0; - if (__acpi_os_prepare_sleep) - rc = __acpi_os_prepare_sleep(sleep_state, - pm1a_control, pm1b_control); - if (rc < 0) - return AE_ERROR; - else if (rc > 0) - return AE_CTRL_SKIP; - - return AE_OK; -} - -void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state, - u32 pm1a_ctrl, u32 pm1b_ctrl)) -{ - __acpi_os_prepare_sleep = func; -} diff --git a/trunk/drivers/acpi/power.c b/trunk/drivers/acpi/power.c index 330bb4d75852..9ac2a9fa90ff 100644 --- a/trunk/drivers/acpi/power.c +++ b/trunk/drivers/acpi/power.c @@ -40,11 +40,9 @@ #include #include #include -#include #include #include #include "sleep.h" -#include "internal.h" #define PREFIX "ACPI: " @@ -79,20 +77,6 @@ static struct acpi_driver acpi_power_driver = { }, }; -/* - * A power managed device - * A device may rely on multiple power resources. - * */ -struct acpi_power_managed_device { - struct device *dev; /* The physical device */ - acpi_handle *handle; -}; - -struct acpi_power_resource_device { - struct acpi_power_managed_device *device; - struct acpi_power_resource_device *next; -}; - struct acpi_power_resource { struct acpi_device * device; acpi_bus_id name; @@ -100,9 +84,6 @@ struct acpi_power_resource { u32 order; unsigned int ref_count; struct mutex resource_lock; - - /* List of devices relying on this power resource */ - struct acpi_power_resource_device *devices; }; static struct list_head acpi_power_resource_list; @@ -202,26 +183,8 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) return 0; } -/* Resume the device when all power resources in _PR0 are on */ -static void acpi_power_on_device(struct acpi_power_managed_device *device) -{ - struct acpi_device *acpi_dev; - acpi_handle handle = device->handle; - int state; - - if (acpi_bus_get_device(handle, &acpi_dev)) - return; - - if(acpi_power_get_inferred_state(acpi_dev, &state)) - return; - - if (state == ACPI_STATE_D0 && pm_runtime_suspended(device->dev)) - pm_request_resume(device->dev); -} - static int __acpi_power_on(struct acpi_power_resource *resource) { - struct acpi_power_resource_device *device_list = resource->devices; acpi_status status = AE_OK; status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); @@ -234,12 +197,6 @@ static int __acpi_power_on(struct acpi_power_resource *resource) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n", resource->name)); - while (device_list) { - acpi_power_on_device(device_list->device); - - device_list = device_list->next; - } - return 0; } @@ -342,125 +299,6 @@ static int acpi_power_on_list(struct acpi_handle_list *list) return result; } -static void __acpi_power_resource_unregister_device(struct device *dev, - acpi_handle res_handle) -{ - struct acpi_power_resource *resource = NULL; - struct acpi_power_resource_device *prev, *curr; - - if (acpi_power_get_context(res_handle, &resource)) - return; - - mutex_lock(&resource->resource_lock); - prev = NULL; - curr = resource->devices; - while (curr) { - if (curr->device->dev == dev) { - if (!prev) - resource->devices = curr->next; - else - prev->next = curr->next; - - kfree(curr); - break; - } - - prev = curr; - curr = curr->next; - } - mutex_unlock(&resource->resource_lock); -} - -/* Unlink dev from all power resources in _PR0 */ -void acpi_power_resource_unregister_device(struct device *dev, acpi_handle handle) -{ - struct acpi_device *acpi_dev; - struct acpi_handle_list *list; - int i; - - if (!dev || !handle) - return; - - if (acpi_bus_get_device(handle, &acpi_dev)) - return; - - list = &acpi_dev->power.states[ACPI_STATE_D0].resources; - - for (i = 0; i < list->count; i++) - __acpi_power_resource_unregister_device(dev, - list->handles[i]); -} - -static int __acpi_power_resource_register_device( - struct acpi_power_managed_device *powered_device, acpi_handle handle) -{ - struct acpi_power_resource *resource = NULL; - struct acpi_power_resource_device *power_resource_device; - int result; - - result = acpi_power_get_context(handle, &resource); - if (result) - return result; - - power_resource_device = kzalloc( - sizeof(*power_resource_device), GFP_KERNEL); - if (!power_resource_device) - return -ENOMEM; - - power_resource_device->device = powered_device; - - mutex_lock(&resource->resource_lock); - power_resource_device->next = resource->devices; - resource->devices = power_resource_device; - mutex_unlock(&resource->resource_lock); - - return 0; -} - -/* Link dev to all power resources in _PR0 */ -int acpi_power_resource_register_device(struct device *dev, acpi_handle handle) -{ - struct acpi_device *acpi_dev; - struct acpi_handle_list *list; - struct acpi_power_managed_device *powered_device; - int i, ret; - - if (!dev || !handle) - return -ENODEV; - - ret = acpi_bus_get_device(handle, &acpi_dev); - if (ret) - goto no_power_resource; - - if (!acpi_dev->power.flags.power_resources) - goto no_power_resource; - - powered_device = kzalloc(sizeof(*powered_device), GFP_KERNEL); - if (!powered_device) - return -ENOMEM; - - powered_device->dev = dev; - powered_device->handle = handle; - - list = &acpi_dev->power.states[ACPI_STATE_D0].resources; - - for (i = 0; i < list->count; i++) { - ret = __acpi_power_resource_register_device(powered_device, - list->handles[i]); - - if (ret) { - acpi_power_resource_unregister_device(dev, handle); - break; - } - } - - return ret; - -no_power_resource: - printk(KERN_WARNING PREFIX "Invalid Power Resource to register!"); - return -ENODEV; -} - /** * acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in * ACPI 3.0) _PSW (Power State Wake) @@ -631,7 +469,7 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state) * We know a device's inferred power state when all the resources * required for a given D-state are 'on'. */ - for (i = ACPI_STATE_D0; i < ACPI_STATE_D3_HOT; i++) { + for (i = ACPI_STATE_D0; i < ACPI_STATE_D3; i++) { list = &device->power.states[i].resources; if (list->count < 1) continue; @@ -662,14 +500,14 @@ int acpi_power_transition(struct acpi_device *device, int state) { int result; - if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD)) + if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) return -EINVAL; if (device->power.state == state) return 0; if ((device->power.state < ACPI_STATE_D0) - || (device->power.state > ACPI_STATE_D3_COLD)) + || (device->power.state > ACPI_STATE_D3)) return -ENODEV; /* TBD: Resources must be ordered. */ diff --git a/trunk/drivers/acpi/processor_driver.c b/trunk/drivers/acpi/processor_driver.c index 0734086537b8..d4d9cb7e016a 100644 --- a/trunk/drivers/acpi/processor_driver.c +++ b/trunk/drivers/acpi/processor_driver.c @@ -67,7 +67,6 @@ #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 #define ACPI_PROCESSOR_NOTIFY_POWER 0x81 #define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82 -#define ACPI_PROCESSOR_DEVICE_HID "ACPI0007" #define ACPI_PROCESSOR_LIMIT_USER 0 #define ACPI_PROCESSOR_LIMIT_THERMAL 1 @@ -88,7 +87,7 @@ static int acpi_processor_start(struct acpi_processor *pr); static const struct acpi_device_id processor_device_ids[] = { {ACPI_PROCESSOR_OBJECT_HID, 0}, - {ACPI_PROCESSOR_DEVICE_HID, 0}, + {"ACPI0007", 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, processor_device_ids); @@ -536,8 +535,8 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) return -ENOMEM; if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) { - result = -ENOMEM; - goto err_free_pr; + kfree(pr); + return -ENOMEM; } pr->handle = device->handle; @@ -577,7 +576,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) dev = get_cpu_device(pr->id); if (sysfs_create_link(&device->dev.kobj, &dev->kobj, "sysdev")) { result = -EFAULT; - goto err_clear_processor; + goto err_free_cpumask; } /* @@ -595,15 +594,9 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) err_remove_sysfs: sysfs_remove_link(&device->dev.kobj, "sysdev"); -err_clear_processor: - /* - * processor_device_array is not cleared to allow checks for buggy BIOS - */ - per_cpu(processors, pr->id) = NULL; err_free_cpumask: free_cpumask_var(pr->throttling.shared_cpu_map); -err_free_pr: - kfree(pr); + return result; } @@ -748,46 +741,20 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, return; } -static acpi_status is_processor_device(acpi_handle handle) -{ - struct acpi_device_info *info; - char *hid; - acpi_status status; - - status = acpi_get_object_info(handle, &info); - if (ACPI_FAILURE(status)) - return status; - - if (info->type == ACPI_TYPE_PROCESSOR) { - kfree(info); - return AE_OK; /* found a processor object */ - } - - if (!(info->valid & ACPI_VALID_HID)) { - kfree(info); - return AE_ERROR; - } - - hid = info->hardware_id.string; - if ((hid == NULL) || strcmp(hid, ACPI_PROCESSOR_DEVICE_HID)) { - kfree(info); - return AE_ERROR; - } - - kfree(info); - return AE_OK; /* found a processor device object */ -} - static acpi_status processor_walk_namespace_cb(acpi_handle handle, u32 lvl, void *context, void **rv) { acpi_status status; int *action = context; + acpi_object_type type = 0; - status = is_processor_device(handle); + status = acpi_get_type(handle, &type); if (ACPI_FAILURE(status)) - return AE_OK; /* not a processor; continue to walk */ + return (AE_OK); + + if (type != ACPI_TYPE_PROCESSOR) + return (AE_OK); switch (*action) { case INSTALL_NOTIFY_HANDLER: @@ -805,8 +772,7 @@ processor_walk_namespace_cb(acpi_handle handle, break; } - /* found a processor; skip walking underneath */ - return AE_CTRL_DEPTH; + return (AE_OK); } static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr) @@ -864,7 +830,7 @@ void acpi_processor_install_hotplug_notify(void) { #ifdef CONFIG_ACPI_HOTPLUG_CPU int action = INSTALL_NOTIFY_HANDLER; - acpi_walk_namespace(ACPI_TYPE_ANY, + acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, processor_walk_namespace_cb, NULL, &action, NULL); @@ -877,7 +843,7 @@ void acpi_processor_uninstall_hotplug_notify(void) { #ifdef CONFIG_ACPI_HOTPLUG_CPU int action = UNINSTALL_NOTIFY_HANDLER; - acpi_walk_namespace(ACPI_TYPE_ANY, + acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, processor_walk_namespace_cb, NULL, &action, NULL); diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index f3decb30223f..0e8e2de2ed3e 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -770,35 +770,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, return index; } - -/** - * acpi_idle_play_dead - enters an ACPI state for long-term idle (i.e. off-lining) - * @dev: the target CPU - * @index: the index of suggested state - */ -static int acpi_idle_play_dead(struct cpuidle_device *dev, int index) -{ - struct cpuidle_state_usage *state_usage = &dev->states_usage[index]; - struct acpi_processor_cx *cx = cpuidle_get_statedata(state_usage); - - ACPI_FLUSH_CPU_CACHE(); - - while (1) { - - if (cx->entry_method == ACPI_CSTATE_HALT) - safe_halt(); - else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) { - inb(cx->address); - /* See comment in acpi_idle_do_entry() */ - inl(acpi_gbl_FADT.xpm_timer_block.address); - } else - return -ENODEV; - } - - /* Never reached */ - return 0; -} - /** * acpi_idle_enter_simple - enters an ACPI state without BM handling * @dev: the target CPU @@ -1106,14 +1077,12 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr) state->flags |= CPUIDLE_FLAG_TIME_VALID; state->enter = acpi_idle_enter_c1; - state->enter_dead = acpi_idle_play_dead; drv->safe_state_index = count; break; case ACPI_STATE_C2: state->flags |= CPUIDLE_FLAG_TIME_VALID; state->enter = acpi_idle_enter_simple; - state->enter_dead = acpi_idle_play_dead; drv->safe_state_index = count; break; @@ -1190,7 +1159,8 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) * to make the code that updates C-States be called once. */ - if (pr->id == 0 && cpuidle_get_driver() == &acpi_idle_driver) { + if (smp_processor_id() == 0 && + cpuidle_get_driver() == &acpi_idle_driver) { cpuidle_pause_and_lock(); /* Protect against cpu-hotplug */ diff --git a/trunk/drivers/acpi/processor_thermal.c b/trunk/drivers/acpi/processor_thermal.c index 641b5450a0db..3b599abf2b40 100644 --- a/trunk/drivers/acpi/processor_thermal.c +++ b/trunk/drivers/acpi/processor_thermal.c @@ -57,27 +57,6 @@ ACPI_MODULE_NAME("processor_thermal"); static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg); static unsigned int acpi_thermal_cpufreq_is_init = 0; -#define reduction_pctg(cpu) \ - per_cpu(cpufreq_thermal_reduction_pctg, phys_package_first_cpu(cpu)) - -/* - * Emulate "per package data" using per cpu data (which should really be - * provided elsewhere) - * - * Note we can lose a CPU on cpu hotunplug, in this case we forget the state - * temporarily. Fortunately that's not a big issue here (I hope) - */ -static int phys_package_first_cpu(int cpu) -{ - int i; - int id = topology_physical_package_id(cpu); - - for_each_online_cpu(i) - if (topology_physical_package_id(i) == id) - return i; - return 0; -} - static int cpu_has_cpufreq(unsigned int cpu) { struct cpufreq_policy policy; @@ -97,7 +76,7 @@ static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb, max_freq = ( policy->cpuinfo.max_freq * - (100 - reduction_pctg(policy->cpu) * 20) + (100 - per_cpu(cpufreq_thermal_reduction_pctg, policy->cpu) * 20) ) / 100; cpufreq_verify_within_limits(policy, 0, max_freq); @@ -123,28 +102,16 @@ static int cpufreq_get_cur_state(unsigned int cpu) if (!cpu_has_cpufreq(cpu)) return 0; - return reduction_pctg(cpu); + return per_cpu(cpufreq_thermal_reduction_pctg, cpu); } static int cpufreq_set_cur_state(unsigned int cpu, int state) { - int i; - if (!cpu_has_cpufreq(cpu)) return 0; - reduction_pctg(cpu) = state; - - /* - * Update all the CPUs in the same package because they all - * contribute to the temperature and often share the same - * frequency. - */ - for_each_online_cpu(i) { - if (topology_physical_package_id(i) == - topology_physical_package_id(cpu)) - cpufreq_update_policy(i); - } + per_cpu(cpufreq_thermal_reduction_pctg, cpu) = state; + cpufreq_update_policy(cpu); return 0; } @@ -152,6 +119,10 @@ void acpi_thermal_cpufreq_init(void) { int i; + for (i = 0; i < nr_cpu_ids; i++) + if (cpu_present(i)) + per_cpu(cpufreq_thermal_reduction_pctg, i) = 0; + i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER); if (!i) diff --git a/trunk/drivers/acpi/processor_throttling.c b/trunk/drivers/acpi/processor_throttling.c index 1d02b7b5ade0..605a2954ef17 100644 --- a/trunk/drivers/acpi/processor_throttling.c +++ b/trunk/drivers/acpi/processor_throttling.c @@ -769,7 +769,7 @@ static int acpi_read_throttling_status(struct acpi_processor *pr, u64 *value) { u32 bit_width, bit_offset; - u32 ptc_value; + u64 ptc_value; u64 ptc_mask; struct acpi_processor_throttling *throttling; int ret = -1; @@ -777,11 +777,12 @@ static int acpi_read_throttling_status(struct acpi_processor *pr, throttling = &pr->throttling; switch (throttling->status_register.space_id) { case ACPI_ADR_SPACE_SYSTEM_IO: + ptc_value = 0; bit_width = throttling->status_register.bit_width; bit_offset = throttling->status_register.bit_offset; acpi_os_read_port((acpi_io_address) throttling->status_register. - address, &ptc_value, + address, (u32 *) &ptc_value, (u32) (bit_width + bit_offset)); ptc_mask = (1 << bit_width) - 1; *value = (u64) ((ptc_value >> bit_offset) & ptc_mask); diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index 7417267e88fa..8ab80bafe3f1 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -869,7 +869,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) /* * Enumerate supported power management states */ - for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) { + for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) { struct acpi_device_power_state *ps = &device->power.states[i]; char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' }; @@ -880,6 +880,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) int j; device->power.flags.power_resources = 1; + ps->flags.valid = 1; for (j = 0; j < ps->resources.count; j++) acpi_bus_add_power_resource(ps->resources.handles[j]); } @@ -887,15 +888,13 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) /* Evaluate "_PSx" to see if we can do explicit sets */ object_name[2] = 'S'; status = acpi_get_handle(device->handle, object_name, &handle); - if (ACPI_SUCCESS(status)) + if (ACPI_SUCCESS(status)) { ps->flags.explicit_set = 1; + ps->flags.valid = 1; + } - /* - * State is valid if there are means to put the device into it. - * D3hot is only valid if _PR3 present. - */ - if (ps->resources.count || - (ps->flags.explicit_set && i < ACPI_STATE_D3_HOT)) + /* State is valid if we have some power control */ + if (ps->resources.count || ps->flags.explicit_set) ps->flags.valid = 1; ps->power = -1; /* Unknown - driver assigned */ diff --git a/trunk/drivers/acpi/sleep.c b/trunk/drivers/acpi/sleep.c index eb6fd233764b..ca191ff97844 100644 --- a/trunk/drivers/acpi/sleep.c +++ b/trunk/drivers/acpi/sleep.c @@ -17,8 +17,6 @@ #include #include #include -#include -#include #include @@ -28,34 +26,6 @@ #include "internal.h" #include "sleep.h" -u8 wake_sleep_flags = ACPI_NO_OPTIONAL_METHODS; -static unsigned int gts, bfs; -static int set_param_wake_flag(const char *val, struct kernel_param *kp) -{ - int ret = param_set_int(val, kp); - - if (ret) - return ret; - - if (kp->arg == (const char *)>s) { - if (gts) - wake_sleep_flags |= ACPI_EXECUTE_GTS; - else - wake_sleep_flags &= ~ACPI_EXECUTE_GTS; - } - if (kp->arg == (const char *)&bfs) { - if (bfs) - wake_sleep_flags |= ACPI_EXECUTE_BFS; - else - wake_sleep_flags &= ~ACPI_EXECUTE_BFS; - } - return ret; -} -module_param_call(gts, set_param_wake_flag, param_get_int, >s, 0644); -module_param_call(bfs, set_param_wake_flag, param_get_int, &bfs, 0644); -MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend."); -MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".); - static u8 sleep_states[ACPI_S_STATE_COUNT]; static void acpi_sleep_tts_switch(u32 acpi_state) @@ -280,7 +250,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state) switch (acpi_state) { case ACPI_STATE_S1: barrier(); - status = acpi_enter_sleep_state(acpi_state, wake_sleep_flags); + status = acpi_enter_sleep_state(acpi_state); break; case ACPI_STATE_S3: @@ -295,7 +265,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state) acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); /* Reprogram control registers and execute _BFS */ - acpi_leave_sleep_state_prep(acpi_state, wake_sleep_flags); + acpi_leave_sleep_state_prep(acpi_state); /* ACPI 3.0 specs (P62) says that it's the responsibility * of the OSPM to clear the status bit [ implying that the @@ -564,9 +534,9 @@ static int acpi_hibernation_enter(void) ACPI_FLUSH_CPU_CACHE(); /* This shouldn't return. If it returns, we have a problem */ - status = acpi_enter_sleep_state(ACPI_STATE_S4, wake_sleep_flags); + status = acpi_enter_sleep_state(ACPI_STATE_S4); /* Reprogram control registers and execute _BFS */ - acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags); + acpi_leave_sleep_state_prep(ACPI_STATE_S4); return ACPI_SUCCESS(status) ? 0 : -EFAULT; } @@ -579,7 +549,7 @@ static void acpi_hibernation_leave(void) */ acpi_enable(); /* Reprogram control registers and execute _BFS */ - acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags); + acpi_leave_sleep_state_prep(ACPI_STATE_S4); /* Check the hardware signature */ if (facs && s4_hardware_signature != facs->hardware_signature) { printk(KERN_EMERG "ACPI: Hardware changed while hibernated, " @@ -759,40 +729,6 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) #endif /* CONFIG_PM */ #ifdef CONFIG_PM_SLEEP -/** - * acpi_pm_device_run_wake - Enable/disable wake-up for given device. - * @phys_dev: Device to enable/disable the platform to wake-up the system for. - * @enable: Whether enable or disable the wake-up functionality. - * - * Find the ACPI device object corresponding to @pci_dev and try to - * enable/disable the GPE associated with it. - */ -int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) -{ - struct acpi_device *dev; - acpi_handle handle; - - if (!device_run_wake(phys_dev)) - return -EINVAL; - - handle = DEVICE_ACPI_HANDLE(phys_dev); - if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) { - dev_dbg(phys_dev, "ACPI handle has no context in %s!\n", - __func__); - return -ENODEV; - } - - if (enable) { - acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0); - acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); - } else { - acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); - acpi_disable_wakeup_device_power(dev); - } - - return 0; -} - /** * acpi_pm_device_sleep_wake - enable or disable the system wake-up * capability of given device @@ -837,7 +773,7 @@ static void acpi_power_off(void) /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ printk(KERN_DEBUG "%s called\n", __func__); local_irq_disable(); - acpi_enter_sleep_state(ACPI_STATE_S5, wake_sleep_flags); + acpi_enter_sleep_state(ACPI_STATE_S5); } /* @@ -852,13 +788,13 @@ static void __init acpi_gts_bfs_check(void) { acpi_handle dummy; - if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_PATHNAME__GTS, &dummy))) + if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_NAME__GTS, &dummy))) { printk(KERN_NOTICE PREFIX "BIOS offers _GTS\n"); printk(KERN_NOTICE PREFIX "If \"acpi.gts=1\" improves suspend, " "please notify linux-acpi@vger.kernel.org\n"); } - if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_PATHNAME__BFS, &dummy))) + if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_NAME__BFS, &dummy))) { printk(KERN_NOTICE PREFIX "BIOS offers _BFS\n"); printk(KERN_NOTICE PREFIX "If \"acpi.bfs=1\" improves resume, " diff --git a/trunk/drivers/acpi/thermal.c b/trunk/drivers/acpi/thermal.c index 7dbebea1ec31..48fbc647b178 100644 --- a/trunk/drivers/acpi/thermal.c +++ b/trunk/drivers/acpi/thermal.c @@ -941,13 +941,13 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz) if (!tz) return -EINVAL; - /* Get trip points [_CRT, _PSV, etc.] (required) */ - result = acpi_thermal_get_trip_points(tz); + /* Get temperature [_TMP] (required) */ + result = acpi_thermal_get_temperature(tz); if (result) return result; - /* Get temperature [_TMP] (required) */ - result = acpi_thermal_get_temperature(tz); + /* Get trip points [_CRT, _PSV, etc.] (required) */ + result = acpi_thermal_get_trip_points(tz); if (result) return result; diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index 9577b6fa2650..eaef02afc7cf 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -548,27 +548,27 @@ acpi_video_device_EDID(struct acpi_video_device *device, * 1. The system BIOS should NOT automatically control the brightness * level of the LCD when the power changes from AC to DC. * Return Value: - * -EINVAL wrong arg. + * -1 wrong arg. */ static int acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) { - acpi_status status; + u64 status = 0; union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list args = { 1, &arg0 }; - if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) - return -EINVAL; + if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) { + status = -1; + goto Failed; + } arg0.integer.value = (lcd_flag << 2) | bios_flag; video->dos_setting = arg0.integer.value; - status = acpi_evaluate_object(video->device->handle, "_DOS", - &args, NULL); - if (ACPI_FAILURE(status)) - return -EIO; + acpi_evaluate_object(video->device->handle, "_DOS", &args, NULL); - return 0; + Failed: + return status; } /* @@ -1343,17 +1343,15 @@ static int acpi_video_bus_get_devices(struct acpi_video_bus *video, struct acpi_device *device) { - int status; + int status = 0; struct acpi_device *dev; - status = acpi_video_device_enumerate(video); - if (status) - return status; + acpi_video_device_enumerate(video); list_for_each_entry(dev, &device->children, node) { status = acpi_video_bus_get_one_device(dev, video); - if (status) { + if (ACPI_FAILURE(status)) { printk(KERN_WARNING PREFIX "Can't attach device\n"); continue; @@ -1655,20 +1653,15 @@ static int acpi_video_bus_add(struct acpi_device *device) mutex_init(&video->device_list_lock); INIT_LIST_HEAD(&video->video_device_list); - error = acpi_video_bus_get_devices(video, device); - if (error) - goto err_free_video; + acpi_video_bus_get_devices(video, device); + acpi_video_bus_start_devices(video); video->input = input = input_allocate_device(); if (!input) { error = -ENOMEM; - goto err_put_video; + goto err_stop_video; } - error = acpi_video_bus_start_devices(video); - if (error) - goto err_free_input_dev; - snprintf(video->phys, sizeof(video->phys), "%s/video/input0", acpi_device_hid(video->device)); @@ -1689,7 +1682,7 @@ static int acpi_video_bus_add(struct acpi_device *device) error = input_register_device(input); if (error) - goto err_stop_video; + goto err_free_input_dev; printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), @@ -1699,19 +1692,14 @@ static int acpi_video_bus_add(struct acpi_device *device) video->pm_nb.notifier_call = acpi_video_resume; video->pm_nb.priority = 0; - error = register_pm_notifier(&video->pm_nb); - if (error) - goto err_unregister_input_dev; + register_pm_notifier(&video->pm_nb); return 0; - err_unregister_input_dev: - input_unregister_device(input); - err_stop_video: - acpi_video_bus_stop_devices(video); err_free_input_dev: input_free_device(input); - err_put_video: + err_stop_video: + acpi_video_bus_stop_devices(video); acpi_video_bus_put_devices(video); kfree(video->attached_array); err_free_video: diff --git a/trunk/drivers/amba/bus.c b/trunk/drivers/amba/bus.c index cc273226dbd0..01c2cf4efcdd 100644 --- a/trunk/drivers/amba/bus.c +++ b/trunk/drivers/amba/bus.c @@ -247,7 +247,8 @@ static int amba_pm_restore(struct device *dev) /* * Hooks to provide runtime PM of the pclk (bus clock). It is safe to * enable/disable the bus clock at runtime PM suspend/resume as this - * does not result in loss of context. + * does not result in loss of context. However, disabling vcore power + * would do, so we leave that to the driver. */ static int amba_pm_runtime_suspend(struct device *dev) { @@ -353,6 +354,39 @@ static void amba_put_disable_pclk(struct amba_device *pcdev) clk_put(pclk); } +static int amba_get_enable_vcore(struct amba_device *pcdev) +{ + struct regulator *vcore = regulator_get(&pcdev->dev, "vcore"); + int ret; + + pcdev->vcore = vcore; + + if (IS_ERR(vcore)) { + /* It is OK not to supply a vcore regulator */ + if (PTR_ERR(vcore) == -ENODEV) + return 0; + return PTR_ERR(vcore); + } + + ret = regulator_enable(vcore); + if (ret) { + regulator_put(vcore); + pcdev->vcore = ERR_PTR(-ENODEV); + } + + return ret; +} + +static void amba_put_disable_vcore(struct amba_device *pcdev) +{ + struct regulator *vcore = pcdev->vcore; + + if (!IS_ERR(vcore)) { + regulator_disable(vcore); + regulator_put(vcore); + } +} + /* * These are the device model conversion veneers; they convert the * device model structures to our more specific structures. @@ -365,6 +399,10 @@ static int amba_probe(struct device *dev) int ret; do { + ret = amba_get_enable_vcore(pcdev); + if (ret) + break; + ret = amba_get_enable_pclk(pcdev); if (ret) break; @@ -382,6 +420,7 @@ static int amba_probe(struct device *dev) pm_runtime_put_noidle(dev); amba_put_disable_pclk(pcdev); + amba_put_disable_vcore(pcdev); } while (0); return ret; @@ -403,6 +442,7 @@ static int amba_remove(struct device *dev) pm_runtime_put_noidle(dev); amba_put_disable_pclk(pcdev); + amba_put_disable_vcore(pcdev); return ret; } diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index ebaf67e4b2bc..79a1e9dd56d9 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -394,8 +394,6 @@ static const struct pci_device_id ahci_pci_tbl[] = { .driver_data = board_ahci_yes_fbs }, /* 88se9128 */ { PCI_DEVICE(0x1b4b, 0x9125), .driver_data = board_ahci_yes_fbs }, /* 88se9125 */ - { PCI_DEVICE(0x1b4b, 0x917a), - .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ { PCI_DEVICE(0x1b4b, 0x91a3), .driver_data = board_ahci_yes_fbs }, diff --git a/trunk/drivers/ata/ahci_platform.c b/trunk/drivers/ata/ahci_platform.c index 9e419e1c2006..0c86c77764bc 100644 --- a/trunk/drivers/ata/ahci_platform.c +++ b/trunk/drivers/ata/ahci_platform.c @@ -280,7 +280,6 @@ static struct dev_pm_ops ahci_pm_ops = { static const struct of_device_id ahci_of_match[] = { { .compatible = "calxeda,hb-ahci", }, - { .compatible = "snps,spear-ahci", }, {}, }; MODULE_DEVICE_TABLE(of, ahci_of_match); diff --git a/trunk/drivers/ata/ata_piix.c b/trunk/drivers/ata/ata_piix.c index 7857e8fd0a3e..68013f96729f 100644 --- a/trunk/drivers/ata/ata_piix.c +++ b/trunk/drivers/ata/ata_piix.c @@ -329,8 +329,6 @@ static const struct pci_device_id piix_pci_tbl[] = { { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, /* SATA Controller IDE (Lynx Point) */ { 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, - /* SATA Controller IDE (DH89xxCC) */ - { 0x8086, 0x2326, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, { } /* terminate list */ }; diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index 23763a1ec570..e0bda9ff89cd 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -95,7 +95,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev); static void ata_dev_xfermask(struct ata_device *dev); static unsigned long ata_dev_blacklisted(const struct ata_device *dev); -atomic_t ata_print_id = ATOMIC_INIT(0); +unsigned int ata_print_id = 1; struct ata_force_param { const char *name; @@ -6029,7 +6029,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) /* give ports names and add SCSI hosts */ for (i = 0; i < host->n_ports; i++) - host->ports[i]->print_id = atomic_inc_return(&ata_print_id); + host->ports[i]->print_id = ata_print_id++; /* Create associated sysfs transport objects */ diff --git a/trunk/drivers/ata/libata-eh.c b/trunk/drivers/ata/libata-eh.c index d1fbd59ead16..c61316e9d2f7 100644 --- a/trunk/drivers/ata/libata-eh.c +++ b/trunk/drivers/ata/libata-eh.c @@ -3501,8 +3501,7 @@ static int ata_count_probe_trials_cb(struct ata_ering_entry *ent, void *void_arg u64 now = get_jiffies_64(); int *trials = void_arg; - if ((ent->eflags & ATA_EFLAG_OLD_ER) || - (ent->timestamp < now - min(now, interval))) + if (ent->timestamp < now - min(now, interval)) return -1; (*trials)++; diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index 22226350cd0c..1ee00c8b5b04 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -3399,8 +3399,7 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) */ shost->max_host_blocked = 1; - rc = scsi_add_host_with_dma(ap->scsi_host, - &ap->tdev, ap->host->dev); + rc = scsi_add_host(ap->scsi_host, &ap->tdev); if (rc) goto err_add; } @@ -3839,25 +3838,18 @@ void ata_sas_port_stop(struct ata_port *ap) } EXPORT_SYMBOL_GPL(ata_sas_port_stop); -/** - * ata_sas_async_probe - simply schedule probing and return - * @ap: Port to probe - * - * For batch scheduling of probe for sas attached ata devices, assumes - * the port has already been through ata_sas_port_init() - */ -void ata_sas_async_probe(struct ata_port *ap) +int ata_sas_async_port_init(struct ata_port *ap) { - __ata_port_probe(ap); -} -EXPORT_SYMBOL_GPL(ata_sas_async_probe); + int rc = ap->ops->port_start(ap); -int ata_sas_sync_probe(struct ata_port *ap) -{ - return ata_port_probe(ap); -} -EXPORT_SYMBOL_GPL(ata_sas_sync_probe); + if (!rc) { + ap->print_id = ata_print_id++; + __ata_port_probe(ap); + } + return rc; +} +EXPORT_SYMBOL_GPL(ata_sas_async_port_init); /** * ata_sas_port_init - Initialize a SATA device @@ -3874,10 +3866,12 @@ int ata_sas_port_init(struct ata_port *ap) { int rc = ap->ops->port_start(ap); - if (rc) - return rc; - ap->print_id = atomic_inc_return(&ata_print_id); - return 0; + if (!rc) { + ap->print_id = ata_print_id++; + rc = ata_port_probe(ap); + } + + return rc; } EXPORT_SYMBOL_GPL(ata_sas_port_init); diff --git a/trunk/drivers/ata/libata-transport.c b/trunk/drivers/ata/libata-transport.c index c34190485377..74aaee30e264 100644 --- a/trunk/drivers/ata/libata-transport.c +++ b/trunk/drivers/ata/libata-transport.c @@ -294,7 +294,6 @@ int ata_tport_add(struct device *parent, device_enable_async_suspend(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); - pm_runtime_forbid(dev); transport_add_device(dev); transport_configure_device(dev); diff --git a/trunk/drivers/ata/libata.h b/trunk/drivers/ata/libata.h index 9d0fd0b71852..2e26fcaf635b 100644 --- a/trunk/drivers/ata/libata.h +++ b/trunk/drivers/ata/libata.h @@ -53,7 +53,7 @@ enum { ATA_DNXFER_QUIET = (1 << 31), }; -extern atomic_t ata_print_id; +extern unsigned int ata_print_id; extern int atapi_passthru16; extern int libata_fua; extern int libata_noacpi; diff --git a/trunk/drivers/ata/pata_arasan_cf.c b/trunk/drivers/ata/pata_arasan_cf.c index 3239517f4d90..fc2db2a89a6b 100644 --- a/trunk/drivers/ata/pata_arasan_cf.c +++ b/trunk/drivers/ata/pata_arasan_cf.c @@ -943,9 +943,9 @@ static int arasan_cf_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(arasan_cf_pm_ops, arasan_cf_suspend, arasan_cf_resume); +#endif static struct platform_driver arasan_cf_driver = { .probe = arasan_cf_probe, @@ -953,7 +953,9 @@ static struct platform_driver arasan_cf_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, +#ifdef CONFIG_PM .pm = &arasan_cf_pm_ops, +#endif }, }; diff --git a/trunk/drivers/ata/sata_mv.c b/trunk/drivers/ata/sata_mv.c index 7336d4a7ab31..38950ea8398a 100644 --- a/trunk/drivers/ata/sata_mv.c +++ b/trunk/drivers/ata/sata_mv.c @@ -4025,8 +4025,7 @@ static int mv_platform_probe(struct platform_device *pdev) struct ata_host *host; struct mv_host_priv *hpriv; struct resource *res; - int n_ports = 0; - int rc; + int n_ports, rc; ata_print_version_once(&pdev->dev, DRV_VERSION); diff --git a/trunk/drivers/base/firmware_class.c b/trunk/drivers/base/firmware_class.c index 5401814c874d..6c9387d646ec 100644 --- a/trunk/drivers/base/firmware_class.c +++ b/trunk/drivers/base/firmware_class.c @@ -16,11 +16,10 @@ #include #include #include -#include +#include #include #include #include -#include #define to_dev(obj) container_of(obj, struct device, kobj) @@ -82,11 +81,6 @@ enum { static int loading_timeout = 60; /* In seconds */ -static inline long firmware_loading_timeout(void) -{ - return loading_timeout > 0 ? loading_timeout * HZ : MAX_SCHEDULE_TIMEOUT; -} - /* fw_lock could be moved to 'struct firmware_priv' but since it is just * guarding for corner cases a global lock should be OK */ static DEFINE_MUTEX(fw_lock); @@ -446,11 +440,13 @@ fw_create_instance(struct firmware *firmware, const char *fw_name, { struct firmware_priv *fw_priv; struct device *f_dev; + int error; fw_priv = kzalloc(sizeof(*fw_priv) + strlen(fw_name) + 1 , GFP_KERNEL); if (!fw_priv) { dev_err(device, "%s: kmalloc failed\n", __func__); - return ERR_PTR(-ENOMEM); + error = -ENOMEM; + goto err_out; } fw_priv->fw = firmware; @@ -467,80 +463,98 @@ fw_create_instance(struct firmware *firmware, const char *fw_name, f_dev->parent = device; f_dev->class = &firmware_class; - return fw_priv; -} - -static struct firmware_priv * -_request_firmware_prepare(const struct firmware **firmware_p, const char *name, - struct device *device, bool uevent, bool nowait) -{ - struct firmware *firmware; - struct firmware_priv *fw_priv; + dev_set_uevent_suppress(f_dev, true); - if (!firmware_p) - return ERR_PTR(-EINVAL); + /* Need to pin this module until class device is destroyed */ + __module_get(THIS_MODULE); - *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); - if (!firmware) { - dev_err(device, "%s: kmalloc(struct firmware) failed\n", - __func__); - return ERR_PTR(-ENOMEM); + error = device_add(f_dev); + if (error) { + dev_err(device, "%s: device_register failed\n", __func__); + goto err_put_dev; } - if (fw_get_builtin_firmware(firmware, name)) { - dev_dbg(device, "firmware: using built-in firmware %s\n", name); - return NULL; + error = device_create_bin_file(f_dev, &firmware_attr_data); + if (error) { + dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__); + goto err_del_dev; } - fw_priv = fw_create_instance(firmware, name, device, uevent, nowait); - if (IS_ERR(fw_priv)) { - release_firmware(firmware); - *firmware_p = NULL; + error = device_create_file(f_dev, &dev_attr_loading); + if (error) { + dev_err(device, "%s: device_create_file failed\n", __func__); + goto err_del_bin_attr; } + + if (uevent) + dev_set_uevent_suppress(f_dev, false); + return fw_priv; + +err_del_bin_attr: + device_remove_bin_file(f_dev, &firmware_attr_data); +err_del_dev: + device_del(f_dev); +err_put_dev: + put_device(f_dev); +err_out: + return ERR_PTR(error); } -static void _request_firmware_cleanup(const struct firmware **firmware_p) +static void fw_destroy_instance(struct firmware_priv *fw_priv) { - release_firmware(*firmware_p); - *firmware_p = NULL; + struct device *f_dev = &fw_priv->dev; + + device_remove_file(f_dev, &dev_attr_loading); + device_remove_bin_file(f_dev, &firmware_attr_data); + device_unregister(f_dev); } -static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, - long timeout) +static int _request_firmware(const struct firmware **firmware_p, + const char *name, struct device *device, + bool uevent, bool nowait) { + struct firmware_priv *fw_priv; + struct firmware *firmware; int retval = 0; - struct device *f_dev = &fw_priv->dev; - dev_set_uevent_suppress(f_dev, true); + if (!firmware_p) + return -EINVAL; - /* Need to pin this module until class device is destroyed */ - __module_get(THIS_MODULE); + *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); + if (!firmware) { + dev_err(device, "%s: kmalloc(struct firmware) failed\n", + __func__); + return -ENOMEM; + } - retval = device_add(f_dev); - if (retval) { - dev_err(f_dev, "%s: device_register failed\n", __func__); - goto err_put_dev; + if (fw_get_builtin_firmware(firmware, name)) { + dev_dbg(device, "firmware: using built-in firmware %s\n", name); + return 0; } - retval = device_create_bin_file(f_dev, &firmware_attr_data); - if (retval) { - dev_err(f_dev, "%s: sysfs_create_bin_file failed\n", __func__); - goto err_del_dev; + read_lock_usermodehelper(); + + if (WARN_ON(usermodehelper_is_disabled())) { + dev_err(device, "firmware: %s will not be loaded\n", name); + retval = -EBUSY; + goto out; } - retval = device_create_file(f_dev, &dev_attr_loading); - if (retval) { - dev_err(f_dev, "%s: device_create_file failed\n", __func__); - goto err_del_bin_attr; + if (uevent) + dev_dbg(device, "firmware: requesting %s\n", name); + + fw_priv = fw_create_instance(firmware, name, device, uevent, nowait); + if (IS_ERR(fw_priv)) { + retval = PTR_ERR(fw_priv); + goto out; } if (uevent) { - dev_set_uevent_suppress(f_dev, false); - dev_dbg(f_dev, "firmware: requesting %s\n", fw_priv->fw_id); - if (timeout != MAX_SCHEDULE_TIMEOUT) + if (loading_timeout > 0) mod_timer(&fw_priv->timeout, - round_jiffies_up(jiffies + timeout)); + round_jiffies_up(jiffies + + loading_timeout * HZ)); kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD); } @@ -556,13 +570,16 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, fw_priv->fw = NULL; mutex_unlock(&fw_lock); - device_remove_file(f_dev, &dev_attr_loading); -err_del_bin_attr: - device_remove_bin_file(f_dev, &firmware_attr_data); -err_del_dev: - device_del(f_dev); -err_put_dev: - put_device(f_dev); + fw_destroy_instance(fw_priv); + +out: + read_unlock_usermodehelper(); + + if (retval) { + release_firmware(firmware); + *firmware_p = NULL; + } + return retval; } @@ -585,26 +602,7 @@ int request_firmware(const struct firmware **firmware_p, const char *name, struct device *device) { - struct firmware_priv *fw_priv; - int ret; - - fw_priv = _request_firmware_prepare(firmware_p, name, device, true, - false); - if (IS_ERR_OR_NULL(fw_priv)) - return PTR_RET(fw_priv); - - ret = usermodehelper_read_trylock(); - if (WARN_ON(ret)) { - dev_err(device, "firmware: %s will not be loaded\n", name); - } else { - ret = _request_firmware_load(fw_priv, true, - firmware_loading_timeout()); - usermodehelper_read_unlock(); - } - if (ret) - _request_firmware_cleanup(firmware_p); - - return ret; + return _request_firmware(firmware_p, name, device, true, false); } /** @@ -631,39 +629,25 @@ struct firmware_work { bool uevent; }; -static void request_firmware_work_func(struct work_struct *work) +static int request_firmware_work_func(void *arg) { - struct firmware_work *fw_work; + struct firmware_work *fw_work = arg; const struct firmware *fw; - struct firmware_priv *fw_priv; - long timeout; int ret; - fw_work = container_of(work, struct firmware_work, work); - fw_priv = _request_firmware_prepare(&fw, fw_work->name, fw_work->device, - fw_work->uevent, true); - if (IS_ERR_OR_NULL(fw_priv)) { - ret = PTR_RET(fw_priv); - goto out; - } - - timeout = usermodehelper_read_lock_wait(firmware_loading_timeout()); - if (timeout) { - ret = _request_firmware_load(fw_priv, fw_work->uevent, timeout); - usermodehelper_read_unlock(); - } else { - dev_dbg(fw_work->device, "firmware: %s loading timed out\n", - fw_work->name); - ret = -EAGAIN; + if (!arg) { + WARN_ON(1); + return 0; } - if (ret) - _request_firmware_cleanup(&fw); - out: + ret = _request_firmware(&fw, fw_work->name, fw_work->device, + fw_work->uevent, true); fw_work->cont(fw, fw_work->context); module_put(fw_work->module); kfree(fw_work); + + return ret; } /** @@ -689,6 +673,7 @@ request_firmware_nowait( const char *name, struct device *device, gfp_t gfp, void *context, void (*cont)(const struct firmware *fw, void *context)) { + struct task_struct *task; struct firmware_work *fw_work; fw_work = kzalloc(sizeof (struct firmware_work), gfp); @@ -707,8 +692,15 @@ request_firmware_nowait( return -EFAULT; } - INIT_WORK(&fw_work->work, request_firmware_work_func); - schedule_work(&fw_work->work); + task = kthread_run(request_firmware_work_func, fw_work, + "firmware/%s", name); + if (IS_ERR(task)) { + fw_work->cont(NULL, fw_work->context); + module_put(fw_work->module); + kfree(fw_work); + return PTR_ERR(task); + } + return 0; } diff --git a/trunk/drivers/base/power/runtime.c b/trunk/drivers/base/power/runtime.c index bd0f3949bcf9..541f821d4ea6 100644 --- a/trunk/drivers/base/power/runtime.c +++ b/trunk/drivers/base/power/runtime.c @@ -532,8 +532,6 @@ static int rpm_suspend(struct device *dev, int rpmflags) dev->power.suspend_time = ktime_set(0, 0); dev->power.max_time_suspended_ns = -1; dev->power.deferred_resume = false; - wake_up_all(&dev->power.wait_queue); - if (retval == -EAGAIN || retval == -EBUSY) { dev->power.runtime_error = 0; @@ -549,6 +547,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) } else { pm_runtime_cancel_pending(dev); } + wake_up_all(&dev->power.wait_queue); goto out; } diff --git a/trunk/drivers/base/regmap/regcache-rbtree.c b/trunk/drivers/base/regmap/regcache-rbtree.c index 92b779ee002b..5157fa04c2f0 100644 --- a/trunk/drivers/base/regmap/regcache-rbtree.c +++ b/trunk/drivers/base/regmap/regcache-rbtree.c @@ -138,7 +138,6 @@ static int rbtree_show(struct seq_file *s, void *ignored) unsigned int base, top; int nodes = 0; int registers = 0; - int average; mutex_lock(&map->lock); @@ -153,13 +152,8 @@ static int rbtree_show(struct seq_file *s, void *ignored) registers += top - base + 1; } - if (nodes) - average = registers / nodes; - else - average = 0; - seq_printf(s, "%d nodes, %d registers, average %d registers\n", - nodes, registers, average); + nodes, registers, registers / nodes); mutex_unlock(&map->lock); @@ -402,7 +396,7 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min, map->cache_word_size); /* Is this the hardware default? If so skip. */ - ret = regcache_lookup_reg(map, regtmp); + ret = regcache_lookup_reg(map, i); if (ret >= 0 && val == map->reg_defaults[ret].def) continue; diff --git a/trunk/drivers/base/regmap/regcache.c b/trunk/drivers/base/regmap/regcache.c index 74b69095def6..87f54dbf601b 100644 --- a/trunk/drivers/base/regmap/regcache.c +++ b/trunk/drivers/base/regmap/regcache.c @@ -346,7 +346,6 @@ int regcache_sync_region(struct regmap *map, unsigned int min, return ret; } -EXPORT_SYMBOL_GPL(regcache_sync_region); /** * regcache_cache_only: Put a register map into cache only mode diff --git a/trunk/drivers/base/regmap/regmap-debugfs.c b/trunk/drivers/base/regmap/regmap-debugfs.c index 251eb70f83e7..58517a5dac13 100644 --- a/trunk/drivers/base/regmap/regmap-debugfs.c +++ b/trunk/drivers/base/regmap/regmap-debugfs.c @@ -27,6 +27,12 @@ static size_t regmap_calc_reg_len(int max_val, char *buf, size_t buf_size) return strlen(buf); } +static int regmap_open_file(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static ssize_t regmap_name_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -51,7 +57,7 @@ static ssize_t regmap_name_read_file(struct file *file, } static const struct file_operations regmap_name_fops = { - .open = simple_open, + .open = regmap_open_file, .read = regmap_name_read_file, .llseek = default_llseek, }; @@ -168,7 +174,7 @@ static ssize_t regmap_map_write_file(struct file *file, #endif static const struct file_operations regmap_map_fops = { - .open = simple_open, + .open = regmap_open_file, .read = regmap_map_read_file, .write = regmap_map_write_file, .llseek = default_llseek, @@ -237,7 +243,7 @@ static ssize_t regmap_access_read_file(struct file *file, } static const struct file_operations regmap_access_fops = { - .open = simple_open, + .open = regmap_open_file, .read = regmap_access_read_file, .llseek = default_llseek, }; diff --git a/trunk/drivers/base/soc.c b/trunk/drivers/base/soc.c index ba29b2e73d48..05f150382da8 100644 --- a/trunk/drivers/base/soc.c +++ b/trunk/drivers/base/soc.c @@ -15,7 +15,7 @@ #include #include -static DEFINE_IDA(soc_ida); +static DEFINE_IDR(soc_ida); static DEFINE_SPINLOCK(soc_lock); static ssize_t soc_info_get(struct device *dev, @@ -168,6 +168,8 @@ void soc_device_unregister(struct soc_device *soc_dev) static int __init soc_bus_register(void) { + spin_lock_init(&soc_lock); + return bus_register(&soc_bus_type); } core_initcall(soc_bus_register); diff --git a/trunk/drivers/bcma/Kconfig b/trunk/drivers/bcma/Kconfig index fb7c80fb721e..c1172dafdffa 100644 --- a/trunk/drivers/bcma/Kconfig +++ b/trunk/drivers/bcma/Kconfig @@ -29,7 +29,7 @@ config BCMA_HOST_PCI config BCMA_DRIVER_PCI_HOSTMODE bool "Driver for PCI core working in hostmode" - depends on BCMA && MIPS && BCMA_HOST_PCI + depends on BCMA && MIPS help PCI core hostmode operation (external PCI bus). diff --git a/trunk/drivers/bcma/driver_pci_host.c b/trunk/drivers/bcma/driver_pci_host.c index d2097a11c3c7..4e20bcfa7ec5 100644 --- a/trunk/drivers/bcma/driver_pci_host.c +++ b/trunk/drivers/bcma/driver_pci_host.c @@ -10,7 +10,6 @@ */ #include "bcma_private.h" -#include #include #include #include diff --git a/trunk/drivers/bcma/sprom.c b/trunk/drivers/bcma/sprom.c index 3e2a6002aae6..cdcf75c0954f 100644 --- a/trunk/drivers/bcma/sprom.c +++ b/trunk/drivers/bcma/sprom.c @@ -404,19 +404,16 @@ int bcma_sprom_get(struct bcma_bus *bus) return -EOPNOTSUPP; if (!bcma_sprom_ext_available(bus)) { - bool sprom_onchip; - /* * External SPROM takes precedence so check * on-chip OTP only when no external SPROM * is present. */ - sprom_onchip = bcma_sprom_onchip_available(bus); - if (sprom_onchip) { + if (bcma_sprom_onchip_available(bus)) { /* determine offset */ offset = bcma_sprom_onchip_offset(bus); } - if (!offset || !sprom_onchip) { + if (!offset) { /* * Maybe there is no SPROM on the device? * Now we ask the arch code if there is some sprom diff --git a/trunk/drivers/block/cciss_scsi.c b/trunk/drivers/block/cciss_scsi.c index acda773b3720..e820b68d2f6c 100644 --- a/trunk/drivers/block/cciss_scsi.c +++ b/trunk/drivers/block/cciss_scsi.c @@ -866,7 +866,6 @@ cciss_scsi_detect(ctlr_info_t *h) sh->can_queue = cciss_tape_cmds; sh->sg_tablesize = h->maxsgentries; sh->max_cmd_len = MAX_COMMAND_SIZE; - sh->max_sectors = h->cciss_max_sectors; ((struct cciss_scsi_adapter_data_t *) h->scsi_ctlr)->scsi_host = sh; @@ -1411,7 +1410,7 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *c, /* track how many SG entries we are using */ if (request_nsgs > h->maxSG) h->maxSG = request_nsgs; - c->Header.SGTotal = (u16) request_nsgs + chained; + c->Header.SGTotal = (__u8) request_nsgs + chained; if (request_nsgs > h->max_cmd_sgentries) c->Header.SGList = h->max_cmd_sgentries; else diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index b0b00d70c166..76a08236430a 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -1030,6 +1030,37 @@ static int fd_wait_for_completion(unsigned long delay, timeout_fn function) return 0; } +static DEFINE_SPINLOCK(floppy_hlt_lock); +static int hlt_disabled; +static void floppy_disable_hlt(void) +{ + unsigned long flags; + + WARN_ONCE(1, "floppy_disable_hlt() scheduled for removal in 2012"); + spin_lock_irqsave(&floppy_hlt_lock, flags); + if (!hlt_disabled) { + hlt_disabled = 1; +#ifdef HAVE_DISABLE_HLT + disable_hlt(); +#endif + } + spin_unlock_irqrestore(&floppy_hlt_lock, flags); +} + +static void floppy_enable_hlt(void) +{ + unsigned long flags; + + spin_lock_irqsave(&floppy_hlt_lock, flags); + if (hlt_disabled) { + hlt_disabled = 0; +#ifdef HAVE_DISABLE_HLT + enable_hlt(); +#endif + } + spin_unlock_irqrestore(&floppy_hlt_lock, flags); +} + static void setup_DMA(void) { unsigned long f; @@ -1074,6 +1105,7 @@ static void setup_DMA(void) fd_enable_dma(); release_dma_lock(f); #endif + floppy_disable_hlt(); } static void show_floppy(void); @@ -1675,6 +1707,7 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id) fd_disable_dma(); release_dma_lock(f); + floppy_enable_hlt(); do_floppy = NULL; if (fdc >= N_FDC || FDCS->address == -1) { /* we don't even know which FDC is the culprit */ @@ -1823,6 +1856,8 @@ static void floppy_shutdown(unsigned long data) show_floppy(); cancel_activity(); + floppy_enable_hlt(); + flags = claim_dma_lock(); fd_disable_dma(); release_dma_lock(flags); @@ -4473,6 +4508,7 @@ static void floppy_release_irq_and_dma(void) #if N_FDC > 1 set_dor(1, ~8, 0); #endif + floppy_enable_hlt(); if (floppy_track_buffer && max_buffer_sectors) { tmpsize = max_buffer_sectors * 1024; diff --git a/trunk/drivers/block/mtip32xx/Kconfig b/trunk/drivers/block/mtip32xx/Kconfig index 0ba837fc62a8..b5dd14e072f2 100644 --- a/trunk/drivers/block/mtip32xx/Kconfig +++ b/trunk/drivers/block/mtip32xx/Kconfig @@ -4,6 +4,6 @@ config BLK_DEV_PCIESSD_MTIP32XX tristate "Block Device Driver for Micron PCIe SSDs" - depends on PCI + depends on HOTPLUG_PCI_PCIE help This enables the block driver for Micron PCIe SSDs. diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.c b/trunk/drivers/block/mtip32xx/mtip32xx.c index 00f9fc992090..8eb81c96608f 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.c +++ b/trunk/drivers/block/mtip32xx/mtip32xx.c @@ -36,7 +36,6 @@ #include #include #include <../drivers/ata/ahci.h> -#include #include "mtip32xx.h" #define HW_CMD_SLOT_SZ (MTIP_MAX_COMMAND_SLOTS * 32) @@ -45,7 +44,6 @@ #define HW_PORT_PRIV_DMA_SZ \ (HW_CMD_SLOT_SZ + HW_CMD_TBL_AR_SZ + AHCI_RX_FIS_SZ) -#define HOST_CAP_NZDMA (1 << 19) #define HOST_HSORG 0xFC #define HSORG_DISABLE_SLOTGRP_INTR (1<<24) #define HSORG_DISABLE_SLOTGRP_PXIS (1<<16) @@ -141,12 +139,6 @@ static void mtip_command_cleanup(struct driver_data *dd) int group = 0, commandslot = 0, commandindex = 0; struct mtip_cmd *command; struct mtip_port *port = dd->port; - static int in_progress; - - if (in_progress) - return; - - in_progress = 1; for (group = 0; group < 4; group++) { for (commandslot = 0; commandslot < 32; commandslot++) { @@ -173,8 +165,7 @@ static void mtip_command_cleanup(struct driver_data *dd) up(&port->cmd_slot); - set_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag); - in_progress = 0; + atomic_set(&dd->drv_cleanup_done, true); } /* @@ -271,9 +262,6 @@ static int hba_reset_nosleep(struct driver_data *dd) && time_before(jiffies, timeout)) mdelay(1); - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) - return -1; - if (readl(dd->mmio + HOST_CTL) & HOST_RESET) return -1; @@ -306,10 +294,6 @@ static inline void mtip_issue_ncq_command(struct mtip_port *port, int tag) port->cmd_issue[MTIP_TAG_INDEX(tag)]); spin_unlock_irqrestore(&port->cmd_issue_lock, flags); - - /* Set the command's timeout value.*/ - port->commands[tag].comp_time = jiffies + msecs_to_jiffies( - MTIP_NCQ_COMMAND_TIMEOUT_MS); } /* @@ -436,12 +420,7 @@ static void mtip_init_port(struct mtip_port *port) writel(0xFFFFFFFF, port->completed[i]); /* Clear any pending interrupts for this port */ - writel(readl(port->dd->mmio + PORT_IRQ_STAT), - port->dd->mmio + PORT_IRQ_STAT); - - /* Clear any pending interrupts on the HBA. */ - writel(readl(port->dd->mmio + HOST_IRQ_STAT), - port->dd->mmio + HOST_IRQ_STAT); + writel(readl(port->mmio + PORT_IRQ_STAT), port->mmio + PORT_IRQ_STAT); /* Enable port interrupts */ writel(DEF_PORT_IRQ, port->mmio + PORT_IRQ_MASK); @@ -468,9 +447,6 @@ static void mtip_restart_port(struct mtip_port *port) && time_before(jiffies, timeout)) ; - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) - return; - /* * Chip quirk: escalate to hba reset if * PxCMD.CR not clear after 500 ms @@ -499,9 +475,6 @@ static void mtip_restart_port(struct mtip_port *port) while (time_before(jiffies, timeout)) ; - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) - return; - /* Clear PxSCTL.DET */ writel(readl(port->mmio + PORT_SCR_CTL) & ~1, port->mmio + PORT_SCR_CTL); @@ -513,35 +486,15 @@ static void mtip_restart_port(struct mtip_port *port) && time_before(jiffies, timeout)) ; - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) - return; - if ((readl(port->mmio + PORT_SCR_STAT) & 0x01) == 0) dev_warn(&port->dd->pdev->dev, "COM reset failed\n"); - mtip_init_port(port); - mtip_start_port(port); - -} - -/* - * Helper function for tag logging - */ -static void print_tags(struct driver_data *dd, - char *msg, - unsigned long *tagbits, - int cnt) -{ - unsigned char tagmap[128]; - int group, tagmap_len = 0; + /* Clear SError, the PxSERR.DIAG.x should be set so clear it */ + writel(readl(port->mmio + PORT_SCR_ERR), port->mmio + PORT_SCR_ERR); - memset(tagmap, 0, sizeof(tagmap)); - for (group = SLOTBITS_IN_LONGS; group > 0; group--) - tagmap_len = sprintf(tagmap + tagmap_len, "%016lX ", - tagbits[group-1]); - dev_warn(&dd->pdev->dev, - "%d command(s) %s: tagmap [%s]", cnt, msg, tagmap); + /* Enable the DMA engine */ + mtip_enable_engine(port, 1); } /* @@ -561,18 +514,15 @@ static void mtip_timeout_function(unsigned long int data) int tag, cmdto_cnt = 0; unsigned int bit, group; unsigned int num_command_slots = port->dd->slot_groups * 32; - unsigned long to, tagaccum[SLOTBITS_IN_LONGS]; if (unlikely(!port)) return; - if (test_bit(MTIP_DDF_RESUME_BIT, &port->dd->dd_flag)) { + if (atomic_read(&port->dd->resumeflag) == true) { mod_timer(&port->cmd_timer, jiffies + msecs_to_jiffies(30000)); return; } - /* clear the tag accumulator */ - memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); for (tag = 0; tag < num_command_slots; tag++) { /* @@ -590,10 +540,12 @@ static void mtip_timeout_function(unsigned long int data) command = &port->commands[tag]; fis = (struct host_to_dev_fis *) command->command; - set_bit(tag, tagaccum); + dev_warn(&port->dd->pdev->dev, + "Timeout for command tag %d\n", tag); + cmdto_cnt++; if (cmdto_cnt == 1) - set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); + set_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); /* * Clear the completed bit. This should prevent @@ -626,29 +578,15 @@ static void mtip_timeout_function(unsigned long int data) } } - if (cmdto_cnt && !test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) { - print_tags(port->dd, "timed out", tagaccum, cmdto_cnt); - + if (cmdto_cnt) { + dev_warn(&port->dd->pdev->dev, + "%d commands timed out: restarting port", + cmdto_cnt); mtip_restart_port(port); - clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); + clear_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); wake_up_interruptible(&port->svc_wait); } - if (port->ic_pause_timer) { - to = port->ic_pause_timer + msecs_to_jiffies(1000); - if (time_after(jiffies, to)) { - if (!test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) { - port->ic_pause_timer = 0; - clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); - clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags); - clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); - wake_up_interruptible(&port->svc_wait); - } - - - } - } - /* Restart the timer */ mod_timer(&port->cmd_timer, jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); @@ -743,18 +681,23 @@ static void mtip_completion(struct mtip_port *port, complete(waiting); } -static void mtip_null_completion(struct mtip_port *port, - int tag, - void *data, - int status) +/* + * Helper function for tag logging + */ +static void print_tags(struct driver_data *dd, + char *msg, + unsigned long *tagbits) { - return; + unsigned int tag, count = 0; + + for (tag = 0; tag < (dd->slot_groups) * 32; tag++) { + if (test_bit(tag, tagbits)) + count++; + } + if (count) + dev_info(&dd->pdev->dev, "%s [%i tags]\n", msg, count); } -static int mtip_read_log_page(struct mtip_port *port, u8 page, u16 *buffer, - dma_addr_t buffer_dma, unsigned int sectors); -static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id, - struct smart_attr *attrib); /* * Handle an error. * @@ -765,16 +708,12 @@ static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id, */ static void mtip_handle_tfe(struct driver_data *dd) { - int group, tag, bit, reissue, rv; + int group, tag, bit, reissue; struct mtip_port *port; - struct mtip_cmd *cmd; + struct mtip_cmd *command; u32 completed; struct host_to_dev_fis *fis; unsigned long tagaccum[SLOTBITS_IN_LONGS]; - unsigned int cmd_cnt = 0; - unsigned char *buf; - char *fail_reason = NULL; - int fail_all_ncq_write = 0, fail_all_ncq_cmds = 0; dev_warn(&dd->pdev->dev, "Taskfile error\n"); @@ -783,11 +722,8 @@ static void mtip_handle_tfe(struct driver_data *dd) /* Stop the timer to prevent command timeouts. */ del_timer(&port->cmd_timer); - /* clear the tag accumulator */ - memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); - /* Set eh_active */ - set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); + set_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); /* Loop through all the groups */ for (group = 0; group < dd->slot_groups; group++) { @@ -796,6 +732,9 @@ static void mtip_handle_tfe(struct driver_data *dd) /* clear completed status register in the hardware.*/ writel(completed, port->completed[group]); + /* clear the tag accumulator */ + memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); + /* Process successfully completed commands */ for (bit = 0; bit < 32 && completed; bit++) { if (!(completed & (1<commands[tag]; - if (likely(cmd->comp_func)) { + command = &port->commands[tag]; + if (likely(command->comp_func)) { set_bit(tag, tagaccum); - cmd_cnt++; - atomic_set(&cmd->active, 0); - cmd->comp_func(port, + atomic_set(&port->commands[tag].active, 0); + command->comp_func(port, tag, - cmd->comp_data, + command->comp_data, 0); } else { dev_err(&port->dd->pdev->dev, @@ -827,45 +765,12 @@ static void mtip_handle_tfe(struct driver_data *dd) } } } - - print_tags(dd, "completed (TFE)", tagaccum, cmd_cnt); + print_tags(dd, "TFE tags completed:", tagaccum); /* Restart the port */ mdelay(20); mtip_restart_port(port); - /* Trying to determine the cause of the error */ - rv = mtip_read_log_page(dd->port, ATA_LOG_SATA_NCQ, - dd->port->log_buf, - dd->port->log_buf_dma, 1); - if (rv) { - dev_warn(&dd->pdev->dev, - "Error in READ LOG EXT (10h) command\n"); - /* non-critical error, don't fail the load */ - } else { - buf = (unsigned char *)dd->port->log_buf; - if (buf[259] & 0x1) { - dev_info(&dd->pdev->dev, - "Write protect bit is set.\n"); - set_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag); - fail_all_ncq_write = 1; - fail_reason = "write protect"; - } - if (buf[288] == 0xF7) { - dev_info(&dd->pdev->dev, - "Exceeded Tmax, drive in thermal shutdown.\n"); - set_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag); - fail_all_ncq_cmds = 1; - fail_reason = "thermal shutdown"; - } - if (buf[288] == 0xBF) { - dev_info(&dd->pdev->dev, - "Drive indicates rebuild has failed.\n"); - fail_all_ncq_cmds = 1; - fail_reason = "rebuild failed"; - } - } - /* clear the tag accumulator */ memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); @@ -874,47 +779,32 @@ static void mtip_handle_tfe(struct driver_data *dd) for (bit = 0; bit < 32; bit++) { reissue = 1; tag = (group << 5) + bit; - cmd = &port->commands[tag]; /* If the active bit is set re-issue the command */ - if (atomic_read(&cmd->active) == 0) + if (atomic_read(&port->commands[tag].active) == 0) continue; - fis = (struct host_to_dev_fis *)cmd->command; + fis = (struct host_to_dev_fis *) + port->commands[tag].command; /* Should re-issue? */ if (tag == MTIP_TAG_INTERNAL || fis->command == ATA_CMD_SET_FEATURES) reissue = 0; - else { - if (fail_all_ncq_cmds || - (fail_all_ncq_write && - fis->command == ATA_CMD_FPDMA_WRITE)) { - dev_warn(&dd->pdev->dev, - " Fail: %s w/tag %d [%s].\n", - fis->command == ATA_CMD_FPDMA_WRITE ? - "write" : "read", - tag, - fail_reason != NULL ? - fail_reason : "unknown"); - atomic_set(&cmd->active, 0); - if (cmd->comp_func) { - cmd->comp_func(port, tag, - cmd->comp_data, - -ENODATA); - } - continue; - } - } /* * First check if this command has * exceeded its retries. */ - if (reissue && (cmd->retries-- > 0)) { + if (reissue && + (port->commands[tag].retries-- > 0)) { set_bit(tag, tagaccum); + /* Update the timeout value. */ + port->commands[tag].comp_time = + jiffies + msecs_to_jiffies( + MTIP_NCQ_COMMAND_TIMEOUT_MS); /* Re-issue the command. */ mtip_issue_ncq_command(port, tag); @@ -924,13 +814,13 @@ static void mtip_handle_tfe(struct driver_data *dd) /* Retire a command that will not be reissued */ dev_warn(&port->dd->pdev->dev, "retiring tag %d\n", tag); - atomic_set(&cmd->active, 0); + atomic_set(&port->commands[tag].active, 0); - if (cmd->comp_func) - cmd->comp_func( + if (port->commands[tag].comp_func) + port->commands[tag].comp_func( port, tag, - cmd->comp_data, + port->commands[tag].comp_data, PORT_IRQ_TF_ERR); else dev_warn(&port->dd->pdev->dev, @@ -938,10 +828,10 @@ static void mtip_handle_tfe(struct driver_data *dd) tag); } } - print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt); + print_tags(dd, "TFE tags reissued:", tagaccum); /* clear eh_active */ - clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); + clear_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags); wake_up_interruptible(&port->svc_wait); mod_timer(&port->cmd_timer, @@ -1009,7 +899,7 @@ static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat) struct mtip_port *port = dd->port; struct mtip_cmd *cmd = &port->commands[MTIP_TAG_INTERNAL]; - if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) && + if (test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) && (cmd != NULL) && !(readl(port->cmd_issue[MTIP_TAG_INTERNAL]) & (1 << MTIP_TAG_INTERNAL))) { if (cmd->comp_func) { @@ -1021,6 +911,8 @@ static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat) } } + dev_warn(&dd->pdev->dev, "IRQ status 0x%x ignored.\n", port_stat); + return; } @@ -1076,9 +968,6 @@ static inline irqreturn_t mtip_handle_irq(struct driver_data *data) /* don't proceed further */ return IRQ_HANDLED; } - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &dd->dd_flag)) - return rv; mtip_process_errors(dd, port_stat & PORT_IRQ_ERR); } @@ -1126,39 +1015,6 @@ static void mtip_issue_non_ncq_command(struct mtip_port *port, int tag) port->cmd_issue[MTIP_TAG_INDEX(tag)]); } -static bool mtip_pause_ncq(struct mtip_port *port, - struct host_to_dev_fis *fis) -{ - struct host_to_dev_fis *reply; - unsigned long task_file_data; - - reply = port->rxfis + RX_FIS_D2H_REG; - task_file_data = readl(port->mmio+PORT_TFDATA); - - if ((task_file_data & 1) || (fis->command == ATA_CMD_SEC_ERASE_UNIT)) - return false; - - if (fis->command == ATA_CMD_SEC_ERASE_PREP) { - set_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); - port->ic_pause_timer = jiffies; - return true; - } else if ((fis->command == ATA_CMD_DOWNLOAD_MICRO) && - (fis->features == 0x03)) { - set_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags); - port->ic_pause_timer = jiffies; - return true; - } else if ((fis->command == ATA_CMD_SEC_ERASE_UNIT) || - ((fis->command == 0xFC) && - (fis->features == 0x27 || fis->features == 0x72 || - fis->features == 0x62 || fis->features == 0x26))) { - /* Com reset after secure erase or lowlevel format */ - mtip_restart_port(port); - return false; - } - - return false; -} - /* * Wait for port to quiesce * @@ -1177,13 +1033,11 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) to = jiffies + msecs_to_jiffies(timeout); do { - if (test_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags) && - test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) { + if (test_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags) && + test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) { msleep(20); continue; /* svc thd is actively issuing commands */ } - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) - return -EFAULT; /* * Ignore s_active bit 0 of array element 0. * This bit will always be set @@ -1220,7 +1074,7 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) * -EAGAIN Time out waiting for command to complete. */ static int mtip_exec_internal_command(struct mtip_port *port, - struct host_to_dev_fis *fis, + void *fis, int fis_len, dma_addr_t buffer, int buf_len, @@ -1230,9 +1084,8 @@ static int mtip_exec_internal_command(struct mtip_port *port, { struct mtip_cmd_sg *command_sg; DECLARE_COMPLETION_ONSTACK(wait); - int rv = 0, ready2go = 1; + int rv = 0; struct mtip_cmd *int_cmd = &port->commands[MTIP_TAG_INTERNAL]; - unsigned long to; /* Make sure the buffer is 8 byte aligned. This is asic specific. */ if (buffer & 0x00000007) { @@ -1241,38 +1094,23 @@ static int mtip_exec_internal_command(struct mtip_port *port, return -EFAULT; } - to = jiffies + msecs_to_jiffies(timeout); - do { - ready2go = !test_and_set_bit(MTIP_TAG_INTERNAL, - port->allocated); - if (ready2go) - break; - mdelay(100); - } while (time_before(jiffies, to)); - if (!ready2go) { + /* Only one internal command should be running at a time */ + if (test_and_set_bit(MTIP_TAG_INTERNAL, port->allocated)) { dev_warn(&port->dd->pdev->dev, - "Internal cmd active. new cmd [%02X]\n", fis->command); + "Internal command already active\n"); return -EBUSY; } - set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); - port->ic_pause_timer = 0; - - if (fis->command == ATA_CMD_SEC_ERASE_UNIT) - clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); - else if (fis->command == ATA_CMD_DOWNLOAD_MICRO) - clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags); + set_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags); if (atomic == GFP_KERNEL) { - if (fis->command != ATA_CMD_STANDBYNOW1) { - /* wait for io to complete if non atomic */ - if (mtip_quiesce_io(port, 5000) < 0) { - dev_warn(&port->dd->pdev->dev, - "Failed to quiesce IO\n"); - release_slot(port, MTIP_TAG_INTERNAL); - clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); - wake_up_interruptible(&port->svc_wait); - return -EBUSY; - } + /* wait for io to complete if non atomic */ + if (mtip_quiesce_io(port, 5000) < 0) { + dev_warn(&port->dd->pdev->dev, + "Failed to quiesce IO\n"); + release_slot(port, MTIP_TAG_INTERNAL); + clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags); + wake_up_interruptible(&port->svc_wait); + return -EBUSY; } /* Set the completion function and data for the command. */ @@ -1282,7 +1120,7 @@ static int mtip_exec_internal_command(struct mtip_port *port, } else { /* Clear completion - we're going to poll */ int_cmd->comp_data = NULL; - int_cmd->comp_func = mtip_null_completion; + int_cmd->comp_func = NULL; } /* Copy the command to the command table */ @@ -1321,12 +1159,6 @@ static int mtip_exec_internal_command(struct mtip_port *port, "Internal command did not complete [%d] " "within timeout of %lu ms\n", atomic, timeout); - if (mtip_check_surprise_removal(port->dd->pdev) || - test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &port->dd->dd_flag)) { - rv = -ENXIO; - goto exec_ic_exit; - } rv = -EAGAIN; } @@ -1334,59 +1166,31 @@ static int mtip_exec_internal_command(struct mtip_port *port, & (1 << MTIP_TAG_INTERNAL)) { dev_warn(&port->dd->pdev->dev, "Retiring internal command but CI is 1.\n"); - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &port->dd->dd_flag)) { - hba_reset_nosleep(port->dd); - rv = -ENXIO; - } else { - mtip_restart_port(port); - rv = -EAGAIN; - } - goto exec_ic_exit; } } else { /* Spin for checking if command still outstanding */ timeout = jiffies + msecs_to_jiffies(timeout); - while ((readl(port->cmd_issue[MTIP_TAG_INTERNAL]) - & (1 << MTIP_TAG_INTERNAL)) - && time_before(jiffies, timeout)) { - if (mtip_check_surprise_removal(port->dd->pdev)) { - rv = -ENXIO; - goto exec_ic_exit; - } - if ((fis->command != ATA_CMD_STANDBYNOW1) && - test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &port->dd->dd_flag)) { - rv = -ENXIO; - goto exec_ic_exit; - } - } + + while ((readl( + port->cmd_issue[MTIP_TAG_INTERNAL]) + & (1 << MTIP_TAG_INTERNAL)) + && time_before(jiffies, timeout)) + ; if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) & (1 << MTIP_TAG_INTERNAL)) { dev_err(&port->dd->pdev->dev, - "Internal command did not complete [atomic]\n"); + "Internal command did not complete [%d]\n", + atomic); rv = -EAGAIN; - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &port->dd->dd_flag)) { - hba_reset_nosleep(port->dd); - rv = -ENXIO; - } else { - mtip_restart_port(port); - rv = -EAGAIN; - } } } -exec_ic_exit: + /* Clear the allocated and active bits for the internal command. */ atomic_set(&int_cmd->active, 0); release_slot(port, MTIP_TAG_INTERNAL); - if (rv >= 0 && mtip_pause_ncq(port, fis)) { - /* NCQ paused */ - return rv; - } - clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); + clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags); wake_up_interruptible(&port->svc_wait); return rv; @@ -1436,9 +1240,6 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer) int rv = 0; struct host_to_dev_fis fis; - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) - return -EFAULT; - /* Build the FIS. */ memset(&fis, 0, sizeof(struct host_to_dev_fis)); fis.type = 0x27; @@ -1512,7 +1313,6 @@ static int mtip_standby_immediate(struct mtip_port *port) { int rv; struct host_to_dev_fis fis; - unsigned long start; /* Build the FIS. */ memset(&fis, 0, sizeof(struct host_to_dev_fis)); @@ -1520,150 +1320,15 @@ static int mtip_standby_immediate(struct mtip_port *port) fis.opts = 1 << 7; fis.command = ATA_CMD_STANDBYNOW1; - start = jiffies; + /* Execute the command. Use a 15-second timeout for large drives. */ rv = mtip_exec_internal_command(port, &fis, 5, 0, 0, 0, - GFP_ATOMIC, + GFP_KERNEL, 15000); - dbg_printk(MTIP_DRV_NAME "Time taken to complete standby cmd: %d ms\n", - jiffies_to_msecs(jiffies - start)); - if (rv) - dev_warn(&port->dd->pdev->dev, - "STANDBY IMMEDIATE command failed.\n"); - - return rv; -} - -/* - * Issue a READ LOG EXT command to the device. - * - * @port pointer to the port structure. - * @page page number to fetch - * @buffer pointer to buffer - * @buffer_dma dma address corresponding to @buffer - * @sectors page length to fetch, in sectors - * - * return value - * @rv return value from mtip_exec_internal_command() - */ -static int mtip_read_log_page(struct mtip_port *port, u8 page, u16 *buffer, - dma_addr_t buffer_dma, unsigned int sectors) -{ - struct host_to_dev_fis fis; - - memset(&fis, 0, sizeof(struct host_to_dev_fis)); - fis.type = 0x27; - fis.opts = 1 << 7; - fis.command = ATA_CMD_READ_LOG_EXT; - fis.sect_count = sectors & 0xFF; - fis.sect_cnt_ex = (sectors >> 8) & 0xFF; - fis.lba_low = page; - fis.lba_mid = 0; - fis.device = ATA_DEVICE_OBS; - - memset(buffer, 0, sectors * ATA_SECT_SIZE); - - return mtip_exec_internal_command(port, - &fis, - 5, - buffer_dma, - sectors * ATA_SECT_SIZE, - 0, - GFP_ATOMIC, - MTIP_INTERNAL_COMMAND_TIMEOUT_MS); -} - -/* - * Issue a SMART READ DATA command to the device. - * - * @port pointer to the port structure. - * @buffer pointer to buffer - * @buffer_dma dma address corresponding to @buffer - * - * return value - * @rv return value from mtip_exec_internal_command() - */ -static int mtip_get_smart_data(struct mtip_port *port, u8 *buffer, - dma_addr_t buffer_dma) -{ - struct host_to_dev_fis fis; - - memset(&fis, 0, sizeof(struct host_to_dev_fis)); - fis.type = 0x27; - fis.opts = 1 << 7; - fis.command = ATA_CMD_SMART; - fis.features = 0xD0; - fis.sect_count = 1; - fis.lba_mid = 0x4F; - fis.lba_hi = 0xC2; - fis.device = ATA_DEVICE_OBS; - - return mtip_exec_internal_command(port, - &fis, - 5, - buffer_dma, - ATA_SECT_SIZE, - 0, - GFP_ATOMIC, - 15000); -} - -/* - * Get the value of a smart attribute - * - * @port pointer to the port structure - * @id attribute number - * @attrib pointer to return attrib information corresponding to @id - * - * return value - * -EINVAL NULL buffer passed or unsupported attribute @id. - * -EPERM Identify data not valid, SMART not supported or not enabled - */ -static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id, - struct smart_attr *attrib) -{ - int rv, i; - struct smart_attr *pattr; - - if (!attrib) - return -EINVAL; - - if (!port->identify_valid) { - dev_warn(&port->dd->pdev->dev, "IDENTIFY DATA not valid\n"); - return -EPERM; - } - if (!(port->identify[82] & 0x1)) { - dev_warn(&port->dd->pdev->dev, "SMART not supported\n"); - return -EPERM; - } - if (!(port->identify[85] & 0x1)) { - dev_warn(&port->dd->pdev->dev, "SMART not enabled\n"); - return -EPERM; - } - - memset(port->smart_buf, 0, ATA_SECT_SIZE); - rv = mtip_get_smart_data(port, port->smart_buf, port->smart_buf_dma); - if (rv) { - dev_warn(&port->dd->pdev->dev, "Failed to ge SMART data\n"); - return rv; - } - - pattr = (struct smart_attr *)(port->smart_buf + 2); - for (i = 0; i < 29; i++, pattr++) - if (pattr->attr_id == id) { - memcpy(attrib, pattr, sizeof(struct smart_attr)); - break; - } - - if (i == 29) { - dev_warn(&port->dd->pdev->dev, - "Query for invalid SMART attribute ID\n"); - rv = -EINVAL; - } return rv; } @@ -1839,7 +1504,10 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) fis.cyl_hi = command[5]; fis.device = command[6] & ~0x10; /* Clear the dev bit*/ - dbg_printk(MTIP_DRV_NAME " %s: User Command: cmd %x, feat %x, nsect %x, sect %x, lcyl %x, hcyl %x, sel %x\n", + + dbg_printk(MTIP_DRV_NAME "%s: User Command: cmd %x, feat %x, " + "nsect %x, sect %x, lcyl %x, " + "hcyl %x, sel %x\n", __func__, command[0], command[1], @@ -1866,7 +1534,8 @@ static int exec_drive_task(struct mtip_port *port, u8 *command) command[4] = reply->cyl_low; command[5] = reply->cyl_hi; - dbg_printk(MTIP_DRV_NAME " %s: Completion Status: stat %x, err %x , cyl_lo %x cyl_hi %x\n", + dbg_printk(MTIP_DRV_NAME "%s: Completion Status: stat %x, " + "err %x , cyl_lo %x cyl_hi %x\n", __func__, command[0], command[1], @@ -1909,7 +1578,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, } dbg_printk(MTIP_DRV_NAME - " %s: User Command: cmd %x, sect %x, " + "%s: User Command: cmd %x, sect %x, " "feat %x, sectcnt %x\n", __func__, command[0], @@ -1938,7 +1607,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, command[2] = command[3]; dbg_printk(MTIP_DRV_NAME - " %s: Completion Status: stat %x, " + "%s: Completion Status: stat %x, " "err %x, cmd %x\n", __func__, command[0], @@ -2141,10 +1810,9 @@ static int exec_drive_taskfile(struct driver_data *dd, } dbg_printk(MTIP_DRV_NAME - " %s: cmd %x, feat %x, nsect %x," + "taskfile: cmd %x, feat %x, nsect %x," " sect/lbal %x, lcyl/lbam %x, hcyl/lbah %x," " head/dev %x\n", - __func__, fis.command, fis.features, fis.sect_count, @@ -2155,8 +1823,8 @@ static int exec_drive_taskfile(struct driver_data *dd, switch (fis.command) { case ATA_CMD_DOWNLOAD_MICRO: - /* Change timeout for Download Microcode to 2 minutes */ - timeout = 120000; + /* Change timeout for Download Microcode to 60 seconds.*/ + timeout = 60000; break; case ATA_CMD_SEC_ERASE_UNIT: /* Change timeout for Security Erase Unit to 4 minutes.*/ @@ -2172,8 +1840,8 @@ static int exec_drive_taskfile(struct driver_data *dd, timeout = 10000; break; case ATA_CMD_SMART: - /* Change timeout for vendor unique command to 15 secs */ - timeout = 15000; + /* Change timeout for vendor unique command to 10 secs */ + timeout = 10000; break; default: timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS; @@ -2235,8 +1903,18 @@ static int exec_drive_taskfile(struct driver_data *dd, req_task->hob_ports[1] = reply->features_ex; req_task->hob_ports[2] = reply->sect_cnt_ex; } + + /* Com rest after secure erase or lowlevel format */ + if (((fis.command == ATA_CMD_SEC_ERASE_UNIT) || + ((fis.command == 0xFC) && + (fis.features == 0x27 || fis.features == 0x72 || + fis.features == 0x62 || fis.features == 0x26))) && + !(reply->command & 1)) { + mtip_restart_port(dd->port); + } + dbg_printk(MTIP_DRV_NAME - " %s: Completion: stat %x," + "%s: Completion: stat %x," "err %x, sect_cnt %x, lbalo %x," "lbamid %x, lbahi %x, dev %x\n", __func__, @@ -2402,10 +2080,14 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, struct host_to_dev_fis *fis; struct mtip_port *port = dd->port; struct mtip_cmd *command = &port->commands[tag]; - int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; /* Map the scatter list for DMA access */ - nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir); + if (dir == READ) + nents = dma_map_sg(&dd->pdev->dev, command->sg, + nents, DMA_FROM_DEVICE); + else + nents = dma_map_sg(&dd->pdev->dev, command->sg, + nents, DMA_TO_DEVICE); command->scatter_ents = nents; @@ -2445,7 +2127,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, */ command->comp_data = dd; command->comp_func = mtip_async_complete; - command->direction = dma_dir; + command->direction = (dir == READ ? DMA_FROM_DEVICE : DMA_TO_DEVICE); /* * Set the completion function and data for the command passed @@ -2458,16 +2140,19 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, * To prevent this command from being issued * if an internal command is in progress or error handling is active. */ - if (port->flags & MTIP_PF_PAUSE_IO) { + if (unlikely(test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) || + test_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags))) { set_bit(tag, port->cmds_to_issue); - set_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags); + set_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags); return; } /* Issue the command to the hardware */ mtip_issue_ncq_command(port, tag); - return; + /* Set the command's timeout value.*/ + port->commands[tag].comp_time = jiffies + msecs_to_jiffies( + MTIP_NCQ_COMMAND_TIMEOUT_MS); } /* @@ -2506,10 +2191,6 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, down(&dd->port->cmd_slot); *tag = get_slot(dd->port); - if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) { - up(&dd->port->cmd_slot); - return NULL; - } if (unlikely(*tag < 0)) return NULL; @@ -2526,7 +2207,7 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, * return value * The size, in bytes, of the data copied into buf. */ -static ssize_t mtip_hw_show_registers(struct device *dev, +static ssize_t hw_show_registers(struct device *dev, struct device_attribute *attr, char *buf) { @@ -2535,7 +2216,7 @@ static ssize_t mtip_hw_show_registers(struct device *dev, int size = 0; int n; - size += sprintf(&buf[size], "S ACTive:\n"); + size += sprintf(&buf[size], "%s:\ns_active:\n", __func__); for (n = 0; n < dd->slot_groups; n++) size += sprintf(&buf[size], "0x%08x\n", @@ -2559,39 +2240,20 @@ static ssize_t mtip_hw_show_registers(struct device *dev, group_allocated); } - size += sprintf(&buf[size], "Completed:\n"); + size += sprintf(&buf[size], "completed:\n"); for (n = 0; n < dd->slot_groups; n++) size += sprintf(&buf[size], "0x%08x\n", readl(dd->port->completed[n])); - size += sprintf(&buf[size], "PORT IRQ STAT : 0x%08x\n", + size += sprintf(&buf[size], "PORT_IRQ_STAT 0x%08x\n", readl(dd->port->mmio + PORT_IRQ_STAT)); - size += sprintf(&buf[size], "HOST IRQ STAT : 0x%08x\n", + size += sprintf(&buf[size], "HOST_IRQ_STAT 0x%08x\n", readl(dd->mmio + HOST_IRQ_STAT)); return size; } - -static ssize_t mtip_hw_show_status(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct driver_data *dd = dev_to_disk(dev)->private_data; - int size = 0; - - if (test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag)) - size += sprintf(buf, "%s", "thermal_shutdown\n"); - else if (test_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag)) - size += sprintf(buf, "%s", "write_protect\n"); - else - size += sprintf(buf, "%s", "online\n"); - - return size; -} - -static DEVICE_ATTR(registers, S_IRUGO, mtip_hw_show_registers, NULL); -static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); +static DEVICE_ATTR(registers, S_IRUGO, hw_show_registers, NULL); /* * Create the sysfs related attributes. @@ -2610,10 +2272,7 @@ static int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj) if (sysfs_create_file(kobj, &dev_attr_registers.attr)) dev_warn(&dd->pdev->dev, - "Error creating 'registers' sysfs entry\n"); - if (sysfs_create_file(kobj, &dev_attr_status.attr)) - dev_warn(&dd->pdev->dev, - "Error creating 'status' sysfs entry\n"); + "Error creating registers sysfs entry\n"); return 0; } @@ -2633,7 +2292,6 @@ static int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj) return -EINVAL; sysfs_remove_file(kobj, &dev_attr_registers.attr); - sysfs_remove_file(kobj, &dev_attr_status.attr); return 0; } @@ -2726,12 +2384,10 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) "FTL rebuild in progress. Polling for completion.\n"); start = jiffies; + dd->ftlrebuildflag = 1; timeout = jiffies + msecs_to_jiffies(MTIP_FTL_REBUILD_TIMEOUT_MS); do { - if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &dd->dd_flag))) - return -EFAULT; if (mtip_check_surprise_removal(dd->pdev)) return -EFAULT; @@ -2752,17 +2408,22 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) dev_warn(&dd->pdev->dev, "FTL rebuild complete (%d secs).\n", jiffies_to_msecs(jiffies - start) / 1000); + dd->ftlrebuildflag = 0; mtip_block_initialize(dd); - return 0; + break; } ssleep(10); } while (time_before(jiffies, timeout)); /* Check for timeout */ - dev_err(&dd->pdev->dev, + if (dd->ftlrebuildflag) { + dev_err(&dd->pdev->dev, "Timed out waiting for FTL rebuild to complete (%d secs).\n", jiffies_to_msecs(jiffies - start) / 1000); - return -EFAULT; + return -EFAULT; + } + + return 0; } /* @@ -2787,17 +2448,14 @@ static int mtip_service_thread(void *data) * is in progress nor error handling is active */ wait_event_interruptible(port->svc_wait, (port->flags) && - !(port->flags & MTIP_PF_PAUSE_IO)); + !test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) && + !test_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags)); if (kthread_should_stop()) break; - if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &dd->dd_flag))) - break; - - set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); - if (test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) { + set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); + if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) { slot = 1; /* used to restrict the loop to one iteration */ slot_start = num_cmd_slots; @@ -2822,19 +2480,21 @@ static int mtip_service_thread(void *data) /* Issue the command to the hardware */ mtip_issue_ncq_command(port, slot); + /* Set the command's timeout value.*/ + port->commands[slot].comp_time = jiffies + + msecs_to_jiffies(MTIP_NCQ_COMMAND_TIMEOUT_MS); + clear_bit(slot, port->cmds_to_issue); } - clear_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags); - } else if (test_bit(MTIP_PF_REBUILD_BIT, &port->flags)) { - if (!mtip_ftl_rebuild_poll(dd)) - set_bit(MTIP_DDF_REBUILD_FAILED_BIT, - &dd->dd_flag); - clear_bit(MTIP_PF_REBUILD_BIT, &port->flags); + clear_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags); + } else if (test_bit(MTIP_FLAG_REBUILD_BIT, &port->flags)) { + mtip_ftl_rebuild_poll(dd); + clear_bit(MTIP_FLAG_REBUILD_BIT, &port->flags); } - clear_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); + clear_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); - if (test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags)) + if (test_bit(MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT, &port->flags)) break; } return 0; @@ -2853,9 +2513,6 @@ static int mtip_hw_init(struct driver_data *dd) int i; int rv; unsigned int num_command_slots; - unsigned long timeout, timetaken; - unsigned char *buf; - struct smart_attr attr242; dd->mmio = pcim_iomap_table(dd->pdev)[MTIP_ABAR]; @@ -2890,7 +2547,7 @@ static int mtip_hw_init(struct driver_data *dd) /* Allocate memory for the command list. */ dd->port->command_list = dmam_alloc_coherent(&dd->pdev->dev, - HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4), + HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2), &dd->port->command_list_dma, GFP_KERNEL); if (!dd->port->command_list) { @@ -2903,7 +2560,7 @@ static int mtip_hw_init(struct driver_data *dd) /* Clear the memory we have allocated. */ memset(dd->port->command_list, 0, - HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4)); + HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2)); /* Setup the addresse of the RX FIS. */ dd->port->rxfis = dd->port->command_list + HW_CMD_SLOT_SZ; @@ -2919,19 +2576,10 @@ static int mtip_hw_init(struct driver_data *dd) dd->port->identify_dma = dd->port->command_tbl_dma + HW_CMD_TBL_AR_SZ; - /* Setup the address of the sector buffer - for some non-ncq cmds */ + /* Setup the address of the sector buffer. */ dd->port->sector_buffer = (void *) dd->port->identify + ATA_SECT_SIZE; dd->port->sector_buffer_dma = dd->port->identify_dma + ATA_SECT_SIZE; - /* Setup the address of the log buf - for read log command */ - dd->port->log_buf = (void *)dd->port->sector_buffer + ATA_SECT_SIZE; - dd->port->log_buf_dma = dd->port->sector_buffer_dma + ATA_SECT_SIZE; - - /* Setup the address of the smart buf - for smart read data command */ - dd->port->smart_buf = (void *)dd->port->log_buf + ATA_SECT_SIZE; - dd->port->smart_buf_dma = dd->port->log_buf_dma + ATA_SECT_SIZE; - - /* Point the command headers at the command tables. */ for (i = 0; i < num_command_slots; i++) { dd->port->commands[i].command_header = @@ -2975,43 +2623,14 @@ static int mtip_hw_init(struct driver_data *dd) dd->port->mmio + i*0x80 + PORT_SDBV; } - timetaken = jiffies; - timeout = jiffies + msecs_to_jiffies(30000); - while (((readl(dd->port->mmio + PORT_SCR_STAT) & 0x0F) != 0x03) && - time_before(jiffies, timeout)) { - mdelay(100); - } - if (unlikely(mtip_check_surprise_removal(dd->pdev))) { - timetaken = jiffies - timetaken; - dev_warn(&dd->pdev->dev, - "Surprise removal detected at %u ms\n", - jiffies_to_msecs(timetaken)); - rv = -ENODEV; - goto out2 ; - } - if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) { - timetaken = jiffies - timetaken; - dev_warn(&dd->pdev->dev, - "Removal detected at %u ms\n", - jiffies_to_msecs(timetaken)); - rv = -EFAULT; + /* Reset the HBA. */ + if (mtip_hba_reset(dd) < 0) { + dev_err(&dd->pdev->dev, + "Card did not reset within timeout\n"); + rv = -EIO; goto out2; } - /* Conditionally reset the HBA. */ - if (!(readl(dd->mmio + HOST_CAP) & HOST_CAP_NZDMA)) { - if (mtip_hba_reset(dd) < 0) { - dev_err(&dd->pdev->dev, - "Card did not reset within timeout\n"); - rv = -EIO; - goto out2; - } - } else { - /* Clear any pending interrupts on the HBA */ - writel(readl(dd->mmio + HOST_IRQ_STAT), - dd->mmio + HOST_IRQ_STAT); - } - mtip_init_port(dd->port); mtip_start_port(dd->port); @@ -3041,12 +2660,6 @@ static int mtip_hw_init(struct driver_data *dd) mod_timer(&dd->port->cmd_timer, jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD)); - - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) { - rv = -EFAULT; - goto out3; - } - if (mtip_get_identify(dd->port, NULL) < 0) { rv = -EFAULT; goto out3; @@ -3054,47 +2667,10 @@ static int mtip_hw_init(struct driver_data *dd) if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) == MTIP_FTL_REBUILD_MAGIC) { - set_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags); + set_bit(MTIP_FLAG_REBUILD_BIT, &dd->port->flags); return MTIP_FTL_REBUILD_MAGIC; } mtip_dump_identify(dd->port); - - /* check write protect, over temp and rebuild statuses */ - rv = mtip_read_log_page(dd->port, ATA_LOG_SATA_NCQ, - dd->port->log_buf, - dd->port->log_buf_dma, 1); - if (rv) { - dev_warn(&dd->pdev->dev, - "Error in READ LOG EXT (10h) command\n"); - /* non-critical error, don't fail the load */ - } else { - buf = (unsigned char *)dd->port->log_buf; - if (buf[259] & 0x1) { - dev_info(&dd->pdev->dev, - "Write protect bit is set.\n"); - set_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag); - } - if (buf[288] == 0xF7) { - dev_info(&dd->pdev->dev, - "Exceeded Tmax, drive in thermal shutdown.\n"); - set_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag); - } - if (buf[288] == 0xBF) { - dev_info(&dd->pdev->dev, - "Drive indicates rebuild has failed.\n"); - /* TODO */ - } - } - - /* get write protect progess */ - memset(&attr242, 0, sizeof(struct smart_attr)); - if (mtip_get_smart_attr(dd->port, 242, &attr242)) - dev_warn(&dd->pdev->dev, - "Unable to check write protect progress\n"); - else - dev_info(&dd->pdev->dev, - "Write protect progress: %d%% (%d blocks)\n", - attr242.cur, attr242.data); return rv; out3: @@ -3112,7 +2688,7 @@ static int mtip_hw_init(struct driver_data *dd) /* Free the command/command header memory. */ dmam_free_coherent(&dd->pdev->dev, - HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4), + HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2), dd->port->command_list, dd->port->command_list_dma); out1: @@ -3136,12 +2712,9 @@ static int mtip_hw_exit(struct driver_data *dd) * Send standby immediate (E0h) to the drive so that it * saves its state. */ - if (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) { + if (atomic_read(&dd->drv_cleanup_done) != true) { - if (!test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags)) - if (mtip_standby_immediate(dd->port)) - dev_warn(&dd->pdev->dev, - "STANDBY IMMEDIATE failed\n"); + mtip_standby_immediate(dd->port); /* de-initialize the port. */ mtip_deinit_port(dd->port); @@ -3161,7 +2734,7 @@ static int mtip_hw_exit(struct driver_data *dd) /* Free the command/command header memory. */ dmam_free_coherent(&dd->pdev->dev, - HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4), + HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2), dd->port->command_list, dd->port->command_list_dma); /* Free the memory allocated for the for structure. */ @@ -3319,9 +2892,6 @@ static int mtip_block_ioctl(struct block_device *dev, if (!dd) return -ENOTTY; - if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) - return -ENOTTY; - switch (cmd) { case BLKFLSBUF: return -ENOTTY; @@ -3357,9 +2927,6 @@ static int mtip_block_compat_ioctl(struct block_device *dev, if (!dd) return -ENOTTY; - if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) - return -ENOTTY; - switch (cmd) { case BLKFLSBUF: return -ENOTTY; @@ -3482,24 +3049,6 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) int nents = 0; int tag = 0; - if (unlikely(dd->dd_flag & MTIP_DDF_STOP_IO)) { - if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, - &dd->dd_flag))) { - bio_endio(bio, -ENXIO); - return; - } - if (unlikely(test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag))) { - bio_endio(bio, -ENODATA); - return; - } - if (unlikely(test_bit(MTIP_DDF_WRITE_PROTECT_BIT, - &dd->dd_flag) && - bio_data_dir(bio))) { - bio_endio(bio, -ENODATA); - return; - } - } - if (unlikely(!bio_has_data(bio))) { blk_queue_flush(queue, 0); bio_endio(bio, 0); @@ -3512,7 +3061,7 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) if (unlikely((bio)->bi_vcnt > MTIP_MAX_SG)) { dev_warn(&dd->pdev->dev, - "Maximum number of SGL entries exceeded\n"); + "Maximum number of SGL entries exceeded"); bio_io_error(bio); mtip_hw_release_scatterlist(dd, tag); return; @@ -3661,10 +3210,8 @@ static int mtip_block_initialize(struct driver_data *dd) kobject_put(kobj); } - if (dd->mtip_svc_handler) { - set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); + if (dd->mtip_svc_handler) return rv; /* service thread created for handling rebuild */ - } start_service_thread: sprintf(thd_name, "mtip_svc_thd_%02d", index); @@ -3673,15 +3220,12 @@ static int mtip_block_initialize(struct driver_data *dd) dd, thd_name); if (IS_ERR(dd->mtip_svc_handler)) { - dev_err(&dd->pdev->dev, "service thread failed to start\n"); + printk(KERN_ERR "mtip32xx: service thread failed to start\n"); dd->mtip_svc_handler = NULL; rv = -EFAULT; goto kthread_run_error; } - if (wait_for_rebuild == MTIP_FTL_REBUILD_MAGIC) - rv = wait_for_rebuild; - return rv; kthread_run_error: @@ -3722,18 +3266,16 @@ static int mtip_block_remove(struct driver_data *dd) struct kobject *kobj; if (dd->mtip_svc_handler) { - set_bit(MTIP_PF_SVC_THD_STOP_BIT, &dd->port->flags); + set_bit(MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT, &dd->port->flags); wake_up_interruptible(&dd->port->svc_wait); kthread_stop(dd->mtip_svc_handler); } - /* Clean up the sysfs attributes, if created */ - if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag)) { - kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); - if (kobj) { - mtip_hw_sysfs_exit(dd, kobj); - kobject_put(kobj); - } + /* Clean up the sysfs attributes managed by the protocol layer. */ + kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); + if (kobj) { + mtip_hw_sysfs_exit(dd, kobj); + kobject_put(kobj); } /* @@ -3741,11 +3283,6 @@ static int mtip_block_remove(struct driver_data *dd) * from /dev */ del_gendisk(dd->disk); - - spin_lock(&rssd_index_lock); - ida_remove(&rssd_index_ida, dd->index); - spin_unlock(&rssd_index_lock); - blk_cleanup_queue(dd->queue); dd->disk = NULL; dd->queue = NULL; @@ -3775,11 +3312,6 @@ static int mtip_block_shutdown(struct driver_data *dd) /* Delete our gendisk structure, and cleanup the blk queue. */ del_gendisk(dd->disk); - - spin_lock(&rssd_index_lock); - ida_remove(&rssd_index_ida, dd->index); - spin_unlock(&rssd_index_lock); - blk_cleanup_queue(dd->queue); dd->disk = NULL; dd->queue = NULL; @@ -3827,6 +3359,11 @@ static int mtip_pci_probe(struct pci_dev *pdev, return -ENOMEM; } + /* Set the atomic variable as 1 in case of SRSI */ + atomic_set(&dd->drv_cleanup_done, true); + + atomic_set(&dd->resumeflag, false); + /* Attach the private data to this PCI device. */ pci_set_drvdata(pdev, dd); @@ -3883,8 +3420,7 @@ static int mtip_pci_probe(struct pci_dev *pdev, * instance number. */ instance++; - if (rv != MTIP_FTL_REBUILD_MAGIC) - set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); + goto done; block_initialize_err: @@ -3898,6 +3434,9 @@ static int mtip_pci_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, NULL); return rv; done: + /* Set the atomic variable as 0 in case of SRSI */ + atomic_set(&dd->drv_cleanup_done, true); + return rv; } @@ -3913,10 +3452,8 @@ static void mtip_pci_remove(struct pci_dev *pdev) struct driver_data *dd = pci_get_drvdata(pdev); int counter = 0; - set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag); - if (mtip_check_surprise_removal(pdev)) { - while (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) { + while (atomic_read(&dd->drv_cleanup_done) == false) { counter++; msleep(20); if (counter == 10) { @@ -3926,6 +3463,8 @@ static void mtip_pci_remove(struct pci_dev *pdev) } } } + /* Set the atomic variable as 1 in case of SRSI */ + atomic_set(&dd->drv_cleanup_done, true); /* Clean up the block layer. */ mtip_block_remove(dd); @@ -3954,7 +3493,7 @@ static int mtip_pci_suspend(struct pci_dev *pdev, pm_message_t mesg) return -EFAULT; } - set_bit(MTIP_DDF_RESUME_BIT, &dd->dd_flag); + atomic_set(&dd->resumeflag, true); /* Disable ports & interrupts then send standby immediate */ rv = mtip_block_suspend(dd); @@ -4020,7 +3559,7 @@ static int mtip_pci_resume(struct pci_dev *pdev) dev_err(&pdev->dev, "Unable to resume\n"); err: - clear_bit(MTIP_DDF_RESUME_BIT, &dd->dd_flag); + atomic_set(&dd->resumeflag, false); return rv; } @@ -4069,25 +3608,18 @@ MODULE_DEVICE_TABLE(pci, mtip_pci_tbl); */ static int __init mtip_init(void) { - int error; - printk(KERN_INFO MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n"); /* Allocate a major block device number to use with this driver. */ - error = register_blkdev(0, MTIP_DRV_NAME); - if (error <= 0) { + mtip_major = register_blkdev(0, MTIP_DRV_NAME); + if (mtip_major < 0) { printk(KERN_ERR "Unable to register block device (%d)\n", - error); + mtip_major); return -EBUSY; } - mtip_major = error; /* Register our PCI operations. */ - error = pci_register_driver(&mtip_pci_driver); - if (error) - unregister_blkdev(mtip_major, MTIP_DRV_NAME); - - return error; + return pci_register_driver(&mtip_pci_driver); } /* diff --git a/trunk/drivers/block/mtip32xx/mtip32xx.h b/trunk/drivers/block/mtip32xx/mtip32xx.h index 4ef58336310a..e0554a8f2233 100644 --- a/trunk/drivers/block/mtip32xx/mtip32xx.h +++ b/trunk/drivers/block/mtip32xx/mtip32xx.h @@ -34,8 +34,8 @@ /* offset of Device Control register in PCIe extended capabilites space */ #define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48 -/* # of times to retry timed out/failed IOs */ -#define MTIP_MAX_RETRIES 2 +/* # of times to retry timed out IOs */ +#define MTIP_MAX_RETRIES 5 /* Various timeout values in ms */ #define MTIP_NCQ_COMMAND_TIMEOUT_MS 5000 @@ -114,41 +114,12 @@ #define __force_bit2int (unsigned int __force) /* below are bit numbers in 'flags' defined in mtip_port */ -#define MTIP_PF_IC_ACTIVE_BIT 0 /* pio/ioctl */ -#define MTIP_PF_EH_ACTIVE_BIT 1 /* error handling */ -#define MTIP_PF_SE_ACTIVE_BIT 2 /* secure erase */ -#define MTIP_PF_DM_ACTIVE_BIT 3 /* download microcde */ -#define MTIP_PF_PAUSE_IO ((1 << MTIP_PF_IC_ACTIVE_BIT) | \ - (1 << MTIP_PF_EH_ACTIVE_BIT) | \ - (1 << MTIP_PF_SE_ACTIVE_BIT) | \ - (1 << MTIP_PF_DM_ACTIVE_BIT)) - -#define MTIP_PF_SVC_THD_ACTIVE_BIT 4 -#define MTIP_PF_ISSUE_CMDS_BIT 5 -#define MTIP_PF_REBUILD_BIT 6 -#define MTIP_PF_SVC_THD_STOP_BIT 8 - -/* below are bit numbers in 'dd_flag' defined in driver_data */ -#define MTIP_DDF_REMOVE_PENDING_BIT 1 -#define MTIP_DDF_OVER_TEMP_BIT 2 -#define MTIP_DDF_WRITE_PROTECT_BIT 3 -#define MTIP_DDF_STOP_IO ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \ - (1 << MTIP_DDF_OVER_TEMP_BIT) | \ - (1 << MTIP_DDF_WRITE_PROTECT_BIT)) - -#define MTIP_DDF_CLEANUP_BIT 5 -#define MTIP_DDF_RESUME_BIT 6 -#define MTIP_DDF_INIT_DONE_BIT 7 -#define MTIP_DDF_REBUILD_FAILED_BIT 8 - -__packed struct smart_attr{ - u8 attr_id; - u16 flags; - u8 cur; - u8 worst; - u32 data; - u8 res[3]; -}; +#define MTIP_FLAG_IC_ACTIVE_BIT 0 +#define MTIP_FLAG_EH_ACTIVE_BIT 1 +#define MTIP_FLAG_SVC_THD_ACTIVE_BIT 2 +#define MTIP_FLAG_ISSUE_CMDS_BIT 4 +#define MTIP_FLAG_REBUILD_BIT 5 +#define MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT 8 /* Register Frame Information Structure (FIS), host to device. */ struct host_to_dev_fis { @@ -374,12 +345,6 @@ struct mtip_port { * when the command slot and all associated data structures * are no longer needed. */ - u16 *log_buf; - dma_addr_t log_buf_dma; - - u8 *smart_buf; - dma_addr_t smart_buf_dma; - unsigned long allocated[SLOTBITS_IN_LONGS]; /* * used to queue commands when an internal command is in progress @@ -403,7 +368,6 @@ struct mtip_port { * Timer used to complete commands that have been active for too long. */ struct timer_list cmd_timer; - unsigned long ic_pause_timer; /* * Semaphore used to block threads if there are no * command slots available. @@ -440,9 +404,13 @@ struct driver_data { unsigned slot_groups; /* number of slot groups the product supports */ + atomic_t drv_cleanup_done; /* Atomic variable for SRSI */ + unsigned long index; /* Index to determine the disk name */ - unsigned long dd_flag; /* NOTE: use atomic bit operations on this */ + unsigned int ftlrebuildflag; /* FTL rebuild flag */ + + atomic_t resumeflag; /* Atomic variable to track suspend/resume */ struct task_struct *mtip_svc_handler; /* task_struct of svc thd */ }; diff --git a/trunk/drivers/block/virtio_blk.c b/trunk/drivers/block/virtio_blk.c index 0d39f2f4294a..c4a60badf252 100644 --- a/trunk/drivers/block/virtio_blk.c +++ b/trunk/drivers/block/virtio_blk.c @@ -351,7 +351,6 @@ static void virtblk_config_changed_work(struct work_struct *work) cap_str_10, cap_str_2); set_capacity(vblk->disk, capacity); - revalidate_disk(vblk->disk); done: mutex_unlock(&vblk->config_lock); } @@ -375,34 +374,6 @@ static int init_vq(struct virtio_blk *vblk) return err; } -/* - * Legacy naming scheme used for virtio devices. We are stuck with it for - * virtio blk but don't ever use it for any new driver. - */ -static int virtblk_name_format(char *prefix, int index, char *buf, int buflen) -{ - const int base = 'z' - 'a' + 1; - char *begin = buf + strlen(prefix); - char *end = buf + buflen; - char *p; - int unit; - - p = end - 1; - *p = '\0'; - unit = base; - do { - if (p == begin) - return -EINVAL; - *--p = 'a' + (index % unit); - index = (index / unit) - 1; - } while (index >= 0); - - memmove(begin, p, end - p); - memcpy(buf, prefix, strlen(prefix)); - - return 0; -} - static int __devinit virtblk_probe(struct virtio_device *vdev) { struct virtio_blk *vblk; @@ -471,7 +442,18 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) q->queuedata = vblk; - virtblk_name_format("vd", index, vblk->disk->disk_name, DISK_NAME_LEN); + if (index < 26) { + sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26); + } else if (index < (26 + 1) * 26) { + sprintf(vblk->disk->disk_name, "vd%c%c", + 'a' + index / 26 - 1, 'a' + index % 26); + } else { + const unsigned int m1 = (index / 26 - 1) / 26 - 1; + const unsigned int m2 = (index / 26 - 1) % 26; + const unsigned int m3 = index % 26; + sprintf(vblk->disk->disk_name, "vd%c%c%c", + 'a' + m1, 'a' + m2, 'a' + m3); + } vblk->disk->major = major; vblk->disk->first_minor = index_to_minor(index); diff --git a/trunk/drivers/block/xen-blkback/blkback.c b/trunk/drivers/block/xen-blkback/blkback.c index 73f196ca713f..0088bf60f368 100644 --- a/trunk/drivers/block/xen-blkback/blkback.c +++ b/trunk/drivers/block/xen-blkback/blkback.c @@ -321,7 +321,6 @@ struct seg_buf { static void xen_blkbk_unmap(struct pending_req *req) { struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; - struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; unsigned int i, invcount = 0; grant_handle_t handle; int ret; @@ -333,12 +332,25 @@ static void xen_blkbk_unmap(struct pending_req *req) gnttab_set_unmap_op(&unmap[invcount], vaddr(req, i), GNTMAP_host_map, handle); pending_handle(req, i) = BLKBACK_INVALID_HANDLE; - pages[invcount] = virt_to_page(vaddr(req, i)); invcount++; } - ret = gnttab_unmap_refs(unmap, pages, invcount, false); + ret = HYPERVISOR_grant_table_op( + GNTTABOP_unmap_grant_ref, unmap, invcount); BUG_ON(ret); + /* + * Note, we use invcount, so nr->pages, so we can't index + * using vaddr(req, i). + */ + for (i = 0; i < invcount; i++) { + ret = m2p_remove_override( + virt_to_page(unmap[i].host_addr), false); + if (ret) { + pr_alert(DRV_PFX "Failed to remove M2P override for %lx\n", + (unsigned long)unmap[i].host_addr); + continue; + } + } } static int xen_blkbk_map(struct blkif_request *req, @@ -366,7 +378,7 @@ static int xen_blkbk_map(struct blkif_request *req, pending_req->blkif->domid); } - ret = gnttab_map_refs(map, NULL, &blkbk->pending_page(pending_req, 0), nseg); + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg); BUG_ON(ret); /* @@ -386,6 +398,15 @@ static int xen_blkbk_map(struct blkif_request *req, if (ret) continue; + ret = m2p_add_override(PFN_DOWN(map[i].dev_bus_addr), + blkbk->pending_page(pending_req, i), NULL); + if (ret) { + pr_alert(DRV_PFX "Failed to install M2P override for %lx (ret: %d)\n", + (unsigned long)map[i].dev_bus_addr, ret); + /* We could switch over to GNTTABOP_copy */ + continue; + } + seg[i].buf = map[i].dev_bus_addr | (req->u.rw.seg[i].first_sect << 9); } @@ -398,18 +419,21 @@ static int dispatch_discard_io(struct xen_blkif *blkif, int err = 0; int status = BLKIF_RSP_OKAY; struct block_device *bdev = blkif->vbd.bdev; - unsigned long secure; blkif->st_ds_req++; xen_blkif_get(blkif); - secure = (blkif->vbd.discard_secure && - (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ? - BLKDEV_DISCARD_SECURE : 0; - - err = blkdev_issue_discard(bdev, req->u.discard.sector_number, - req->u.discard.nr_sectors, - GFP_KERNEL, secure); + if (blkif->blk_backend_type == BLKIF_BACKEND_PHY || + blkif->blk_backend_type == BLKIF_BACKEND_FILE) { + unsigned long secure = (blkif->vbd.discard_secure && + (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ? + BLKDEV_DISCARD_SECURE : 0; + err = blkdev_issue_discard(bdev, + req->u.discard.sector_number, + req->u.discard.nr_sectors, + GFP_KERNEL, secure); + } else + err = -EOPNOTSUPP; if (err == -EOPNOTSUPP) { pr_debug(DRV_PFX "discard op failed, not supported\n"); @@ -806,7 +830,7 @@ static int __init xen_blkif_init(void) int i, mmap_pages; int rc = 0; - if (!xen_domain()) + if (!xen_pv_domain()) return -ENODEV; blkbk = kzalloc(sizeof(struct xen_blkbk), GFP_KERNEL); diff --git a/trunk/drivers/block/xen-blkback/common.h b/trunk/drivers/block/xen-blkback/common.h index 773cf27dc23f..d0ee7edc9be8 100644 --- a/trunk/drivers/block/xen-blkback/common.h +++ b/trunk/drivers/block/xen-blkback/common.h @@ -146,6 +146,11 @@ enum blkif_protocol { BLKIF_PROTOCOL_X86_64 = 3, }; +enum blkif_backend_type { + BLKIF_BACKEND_PHY = 1, + BLKIF_BACKEND_FILE = 2, +}; + struct xen_vbd { /* What the domain refers to this vbd as. */ blkif_vdev_t handle; @@ -172,6 +177,7 @@ struct xen_blkif { unsigned int irq; /* Comms information. */ enum blkif_protocol blk_protocol; + enum blkif_backend_type blk_backend_type; union blkif_back_rings blk_rings; void *blk_ring; /* The VBD attached to this interface. */ diff --git a/trunk/drivers/block/xen-blkback/xenbus.c b/trunk/drivers/block/xen-blkback/xenbus.c index 4f66171c6683..24a2fb57e5d0 100644 --- a/trunk/drivers/block/xen-blkback/xenbus.c +++ b/trunk/drivers/block/xen-blkback/xenbus.c @@ -381,49 +381,72 @@ int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt, err = xenbus_printf(xbt, dev->nodename, "feature-flush-cache", "%d", state); if (err) - dev_warn(&dev->dev, "writing feature-flush-cache (%d)", err); + xenbus_dev_fatal(dev, err, "writing feature-flush-cache"); return err; } -static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be) +int xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be) { struct xenbus_device *dev = be->dev; struct xen_blkif *blkif = be->blkif; + char *type; int err; int state = 0; - struct block_device *bdev = be->blkif->vbd.bdev; - struct request_queue *q = bdev_get_queue(bdev); - if (blk_queue_discard(q)) { - err = xenbus_printf(xbt, dev->nodename, - "discard-granularity", "%u", - q->limits.discard_granularity); - if (err) { - dev_warn(&dev->dev, "writing discard-granularity (%d)", err); - return; + type = xenbus_read(XBT_NIL, dev->nodename, "type", NULL); + if (!IS_ERR(type)) { + if (strncmp(type, "file", 4) == 0) { + state = 1; + blkif->blk_backend_type = BLKIF_BACKEND_FILE; } - err = xenbus_printf(xbt, dev->nodename, - "discard-alignment", "%u", - q->limits.discard_alignment); - if (err) { - dev_warn(&dev->dev, "writing discard-alignment (%d)", err); - return; - } - state = 1; - /* Optional. */ - err = xenbus_printf(xbt, dev->nodename, - "discard-secure", "%d", - blkif->vbd.discard_secure); - if (err) { - dev_warn(&dev->dev, "writing discard-secure (%d)", err); - return; + if (strncmp(type, "phy", 3) == 0) { + struct block_device *bdev = be->blkif->vbd.bdev; + struct request_queue *q = bdev_get_queue(bdev); + if (blk_queue_discard(q)) { + err = xenbus_printf(xbt, dev->nodename, + "discard-granularity", "%u", + q->limits.discard_granularity); + if (err) { + xenbus_dev_fatal(dev, err, + "writing discard-granularity"); + goto kfree; + } + err = xenbus_printf(xbt, dev->nodename, + "discard-alignment", "%u", + q->limits.discard_alignment); + if (err) { + xenbus_dev_fatal(dev, err, + "writing discard-alignment"); + goto kfree; + } + state = 1; + blkif->blk_backend_type = BLKIF_BACKEND_PHY; + } + /* Optional. */ + err = xenbus_printf(xbt, dev->nodename, + "discard-secure", "%d", + blkif->vbd.discard_secure); + if (err) { + xenbus_dev_fatal(dev, err, + "writting discard-secure"); + goto kfree; + } } + } else { + err = PTR_ERR(type); + xenbus_dev_fatal(dev, err, "reading type"); + goto out; } + err = xenbus_printf(xbt, dev->nodename, "feature-discard", "%d", state); if (err) - dev_warn(&dev->dev, "writing feature-discard (%d)", err); + xenbus_dev_fatal(dev, err, "writing feature-discard"); +kfree: + kfree(type); +out: + return err; } int xen_blkbk_barrier(struct xenbus_transaction xbt, struct backend_info *be, int state) @@ -434,7 +457,7 @@ int xen_blkbk_barrier(struct xenbus_transaction xbt, err = xenbus_printf(xbt, dev->nodename, "feature-barrier", "%d", state); if (err) - dev_warn(&dev->dev, "writing feature-barrier (%d)", err); + xenbus_dev_fatal(dev, err, "writing feature-barrier"); return err; } @@ -666,12 +689,14 @@ static void connect(struct backend_info *be) return; } - /* If we can't advertise it is OK. */ - xen_blkbk_flush_diskcache(xbt, be, be->blkif->vbd.flush_support); + err = xen_blkbk_flush_diskcache(xbt, be, be->blkif->vbd.flush_support); + if (err) + goto abort; - xen_blkbk_discard(xbt, be); + err = xen_blkbk_discard(xbt, be); - xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support); + /* If we can't advertise it is OK. */ + err = xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support); err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu", (unsigned long long)vbd_sz(&be->blkif->vbd)); diff --git a/trunk/drivers/block/xen-blkfront.c b/trunk/drivers/block/xen-blkfront.c index 4e86393a09cf..d5e1ab956740 100644 --- a/trunk/drivers/block/xen-blkfront.c +++ b/trunk/drivers/block/xen-blkfront.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include @@ -82,7 +81,6 @@ static const struct block_device_operations xlvbd_block_fops; */ struct blkfront_info { - spinlock_t io_lock; struct mutex mutex; struct xenbus_device *xbdev; struct gendisk *gd; @@ -107,6 +105,8 @@ struct blkfront_info int is_ready; }; +static DEFINE_SPINLOCK(blkif_io_lock); + static unsigned int nr_minors; static unsigned long *minors; static DEFINE_SPINLOCK(minor_lock); @@ -177,7 +177,8 @@ static int xlbd_reserve_minors(unsigned int minor, unsigned int nr) spin_lock(&minor_lock); if (find_next_bit(minors, end, minor) >= end) { - bitmap_set(minors, minor, nr); + for (; minor < end; ++minor) + __set_bit(minor, minors); rc = 0; } else rc = -EBUSY; @@ -192,7 +193,8 @@ static void xlbd_release_minors(unsigned int minor, unsigned int nr) BUG_ON(end > nr_minors); spin_lock(&minor_lock); - bitmap_clear(minors, minor, nr); + for (; minor < end; ++minor) + __clear_bit(minor, minors); spin_unlock(&minor_lock); } @@ -417,7 +419,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size) struct request_queue *rq; struct blkfront_info *info = gd->private_data; - rq = blk_init_queue(do_blkif_request, &info->io_lock); + rq = blk_init_queue(do_blkif_request, &blkif_io_lock); if (rq == NULL) return -1; @@ -634,14 +636,14 @@ static void xlvbd_release_gendisk(struct blkfront_info *info) if (info->rq == NULL) return; - spin_lock_irqsave(&info->io_lock, flags); + spin_lock_irqsave(&blkif_io_lock, flags); /* No more blkif_request(). */ blk_stop_queue(info->rq); /* No more gnttab callback work. */ gnttab_cancel_free_callback(&info->callback); - spin_unlock_irqrestore(&info->io_lock, flags); + spin_unlock_irqrestore(&blkif_io_lock, flags); /* Flush gnttab callback work. Must be done with no locks held. */ flush_work_sync(&info->work); @@ -673,16 +675,16 @@ static void blkif_restart_queue(struct work_struct *work) { struct blkfront_info *info = container_of(work, struct blkfront_info, work); - spin_lock_irq(&info->io_lock); + spin_lock_irq(&blkif_io_lock); if (info->connected == BLKIF_STATE_CONNECTED) kick_pending_request_queues(info); - spin_unlock_irq(&info->io_lock); + spin_unlock_irq(&blkif_io_lock); } static void blkif_free(struct blkfront_info *info, int suspend) { /* Prevent new requests being issued until we fix things up. */ - spin_lock_irq(&info->io_lock); + spin_lock_irq(&blkif_io_lock); info->connected = suspend ? BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED; /* No more blkif_request(). */ @@ -690,7 +692,7 @@ static void blkif_free(struct blkfront_info *info, int suspend) blk_stop_queue(info->rq); /* No more gnttab callback work. */ gnttab_cancel_free_callback(&info->callback); - spin_unlock_irq(&info->io_lock); + spin_unlock_irq(&blkif_io_lock); /* Flush gnttab callback work. Must be done with no locks held. */ flush_work_sync(&info->work); @@ -726,10 +728,10 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) struct blkfront_info *info = (struct blkfront_info *)dev_id; int error; - spin_lock_irqsave(&info->io_lock, flags); + spin_lock_irqsave(&blkif_io_lock, flags); if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) { - spin_unlock_irqrestore(&info->io_lock, flags); + spin_unlock_irqrestore(&blkif_io_lock, flags); return IRQ_HANDLED; } @@ -814,7 +816,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) kick_pending_request_queues(info); - spin_unlock_irqrestore(&info->io_lock, flags); + spin_unlock_irqrestore(&blkif_io_lock, flags); return IRQ_HANDLED; } @@ -989,7 +991,6 @@ static int blkfront_probe(struct xenbus_device *dev, } mutex_init(&info->mutex); - spin_lock_init(&info->io_lock); info->xbdev = dev; info->vdevice = vdevice; info->connected = BLKIF_STATE_DISCONNECTED; @@ -1067,7 +1068,7 @@ static int blkif_recover(struct blkfront_info *info) xenbus_switch_state(info->xbdev, XenbusStateConnected); - spin_lock_irq(&info->io_lock); + spin_lock_irq(&blkif_io_lock); /* Now safe for us to use the shared ring */ info->connected = BLKIF_STATE_CONNECTED; @@ -1078,7 +1079,7 @@ static int blkif_recover(struct blkfront_info *info) /* Kick any other new requests queued since we resumed */ kick_pending_request_queues(info); - spin_unlock_irq(&info->io_lock); + spin_unlock_irq(&blkif_io_lock); return 0; } @@ -1276,10 +1277,10 @@ static void blkfront_connect(struct blkfront_info *info) xenbus_switch_state(info->xbdev, XenbusStateConnected); /* Kick pending requests. */ - spin_lock_irq(&info->io_lock); + spin_lock_irq(&blkif_io_lock); info->connected = BLKIF_STATE_CONNECTED; kick_pending_request_queues(info); - spin_unlock_irq(&info->io_lock); + spin_unlock_irq(&blkif_io_lock); add_disk(info->gd); @@ -1409,6 +1410,7 @@ static int blkif_release(struct gendisk *disk, fmode_t mode) mutex_lock(&blkfront_mutex); bdev = bdget_disk(disk, 0); + bdput(bdev); if (bdev->bd_openers) goto out; @@ -1439,7 +1441,6 @@ static int blkif_release(struct gendisk *disk, fmode_t mode) } out: - bdput(bdev); mutex_unlock(&blkfront_mutex); return 0; } @@ -1474,7 +1475,7 @@ static int __init xlblk_init(void) if (!xen_domain()) return -ENODEV; - if (xen_hvm_domain() && !xen_platform_pci_unplug) + if (!xen_platform_pci_unplug) return -ENODEV; if (register_blkdev(XENVBD_MAJOR, DEV_NAME)) { diff --git a/trunk/drivers/bluetooth/ath3k.c b/trunk/drivers/bluetooth/ath3k.c index 57fd867553d7..48442476ec00 100644 --- a/trunk/drivers/bluetooth/ath3k.c +++ b/trunk/drivers/bluetooth/ath3k.c @@ -72,11 +72,7 @@ static struct usb_device_id ath3k_table[] = { /* Atheros AR3012 with sflash firmware*/ { USB_DEVICE(0x0CF3, 0x3004) }, - { USB_DEVICE(0x0CF3, 0x311D) }, { USB_DEVICE(0x13d3, 0x3375) }, - { USB_DEVICE(0x04CA, 0x3005) }, - { USB_DEVICE(0x13d3, 0x3362) }, - { USB_DEVICE(0x0CF3, 0xE004) }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xE02C) }, @@ -93,11 +89,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { /* Atheros AR3012 with sflash firmware*/ { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, { } /* Terminating entry */ }; diff --git a/trunk/drivers/bluetooth/btmrvl_debugfs.c b/trunk/drivers/bluetooth/btmrvl_debugfs.c index 428dbb7574bd..6c20bbb54b71 100644 --- a/trunk/drivers/bluetooth/btmrvl_debugfs.c +++ b/trunk/drivers/bluetooth/btmrvl_debugfs.c @@ -45,6 +45,12 @@ struct btmrvl_debugfs_data { struct dentry *txdnldready; }; +static int btmrvl_open_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static ssize_t btmrvl_hscfgcmd_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) { @@ -87,7 +93,7 @@ static ssize_t btmrvl_hscfgcmd_read(struct file *file, char __user *userbuf, static const struct file_operations btmrvl_hscfgcmd_fops = { .read = btmrvl_hscfgcmd_read, .write = btmrvl_hscfgcmd_write, - .open = simple_open, + .open = btmrvl_open_generic, .llseek = default_llseek, }; @@ -128,7 +134,7 @@ static ssize_t btmrvl_psmode_read(struct file *file, char __user *userbuf, static const struct file_operations btmrvl_psmode_fops = { .read = btmrvl_psmode_read, .write = btmrvl_psmode_write, - .open = simple_open, + .open = btmrvl_open_generic, .llseek = default_llseek, }; @@ -174,7 +180,7 @@ static ssize_t btmrvl_pscmd_read(struct file *file, char __user *userbuf, static const struct file_operations btmrvl_pscmd_fops = { .read = btmrvl_pscmd_read, .write = btmrvl_pscmd_write, - .open = simple_open, + .open = btmrvl_open_generic, .llseek = default_llseek, }; @@ -215,7 +221,7 @@ static ssize_t btmrvl_gpiogap_read(struct file *file, char __user *userbuf, static const struct file_operations btmrvl_gpiogap_fops = { .read = btmrvl_gpiogap_read, .write = btmrvl_gpiogap_write, - .open = simple_open, + .open = btmrvl_open_generic, .llseek = default_llseek, }; @@ -259,7 +265,7 @@ static ssize_t btmrvl_hscmd_read(struct file *file, char __user *userbuf, static const struct file_operations btmrvl_hscmd_fops = { .read = btmrvl_hscmd_read, .write = btmrvl_hscmd_write, - .open = simple_open, + .open = btmrvl_open_generic, .llseek = default_llseek, }; @@ -299,7 +305,7 @@ static ssize_t btmrvl_hsmode_read(struct file *file, char __user * userbuf, static const struct file_operations btmrvl_hsmode_fops = { .read = btmrvl_hsmode_read, .write = btmrvl_hsmode_write, - .open = simple_open, + .open = btmrvl_open_generic, .llseek = default_llseek, }; @@ -317,7 +323,7 @@ static ssize_t btmrvl_curpsmode_read(struct file *file, char __user *userbuf, static const struct file_operations btmrvl_curpsmode_fops = { .read = btmrvl_curpsmode_read, - .open = simple_open, + .open = btmrvl_open_generic, .llseek = default_llseek, }; @@ -335,7 +341,7 @@ static ssize_t btmrvl_psstate_read(struct file *file, char __user * userbuf, static const struct file_operations btmrvl_psstate_fops = { .read = btmrvl_psstate_read, - .open = simple_open, + .open = btmrvl_open_generic, .llseek = default_llseek, }; @@ -353,7 +359,7 @@ static ssize_t btmrvl_hsstate_read(struct file *file, char __user *userbuf, static const struct file_operations btmrvl_hsstate_fops = { .read = btmrvl_hsstate_read, - .open = simple_open, + .open = btmrvl_open_generic, .llseek = default_llseek, }; @@ -372,7 +378,7 @@ static ssize_t btmrvl_txdnldready_read(struct file *file, char __user *userbuf, static const struct file_operations btmrvl_txdnldready_fops = { .read = btmrvl_txdnldready_read, - .open = simple_open, + .open = btmrvl_open_generic, .llseek = default_llseek, }; diff --git a/trunk/drivers/bluetooth/btusb.c b/trunk/drivers/bluetooth/btusb.c index 9217121362e1..480cad920048 100644 --- a/trunk/drivers/bluetooth/btusb.c +++ b/trunk/drivers/bluetooth/btusb.c @@ -61,7 +61,7 @@ static struct usb_device_id btusb_table[] = { { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, /* Broadcom SoftSailing reporting vendor specific */ - { USB_DEVICE(0x0a5c, 0x21e1) }, + { USB_DEVICE(0x05ac, 0x21e1) }, /* Apple MacBookPro 7,1 */ { USB_DEVICE(0x05ac, 0x8213) }, @@ -101,16 +101,11 @@ static struct usb_device_id btusb_table[] = { { USB_DEVICE(0x0c10, 0x0000) }, /* Broadcom BCM20702A0 */ - { USB_DEVICE(0x0489, 0xe042) }, { USB_DEVICE(0x0a5c, 0x21e3) }, { USB_DEVICE(0x0a5c, 0x21e6) }, - { USB_DEVICE(0x0a5c, 0x21e8) }, { USB_DEVICE(0x0a5c, 0x21f3) }, { USB_DEVICE(0x413c, 0x8197) }, - /* Foxconn - Hon Hai */ - { USB_DEVICE(0x0489, 0xe033) }, - { } /* Terminating entry */ }; @@ -134,11 +129,7 @@ static struct usb_device_id blacklist_table[] = { /* Atheros 3012 with sflash firmware */ { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, diff --git a/trunk/drivers/bluetooth/hci_ldisc.c b/trunk/drivers/bluetooth/hci_ldisc.c index 98a8c05d4f23..fd5adb408f44 100644 --- a/trunk/drivers/bluetooth/hci_ldisc.c +++ b/trunk/drivers/bluetooth/hci_ldisc.c @@ -299,11 +299,11 @@ static void hci_uart_tty_close(struct tty_struct *tty) hci_uart_close(hdev); if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) { + hu->proto->close(hu); if (hdev) { hci_unregister_dev(hdev); hci_free_dev(hdev); } - hu->proto->close(hu); } kfree(hu); diff --git a/trunk/drivers/char/agp/intel-agp.h b/trunk/drivers/char/agp/intel-agp.h index 7ea18a5fe71c..5da67f165afa 100644 --- a/trunk/drivers/char/agp/intel-agp.h +++ b/trunk/drivers/char/agp/intel-agp.h @@ -234,7 +234,6 @@ #define PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_GT2_IG 0x0166 #define PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_HB 0x0158 /* Server */ #define PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT1_IG 0x015A -#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT2_IG 0x016A int intel_gmch_probe(struct pci_dev *pdev, struct agp_bridge_data *bridge); diff --git a/trunk/drivers/char/agp/intel-gtt.c b/trunk/drivers/char/agp/intel-gtt.c index 7f025fb620de..5cf47ac2d401 100644 --- a/trunk/drivers/char/agp/intel-gtt.c +++ b/trunk/drivers/char/agp/intel-gtt.c @@ -1190,6 +1190,7 @@ static inline int needs_idle_maps(void) { #ifdef CONFIG_INTEL_IOMMU const unsigned short gpu_devid = intel_private.pcidev->device; + extern int intel_iommu_gfx_mapped; /* Query intel_iommu to see if we need the workaround. Presumably that * was loaded first. @@ -1458,8 +1459,6 @@ static const struct intel_gtt_driver_description { "Ivybridge", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT1_IG, "Ivybridge", &sandybridge_gtt_driver }, - { PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT2_IG, - "Ivybridge", &sandybridge_gtt_driver }, { 0, NULL, NULL } }; diff --git a/trunk/drivers/char/apm-emulation.c b/trunk/drivers/char/apm-emulation.c index 46118f845948..57501ca9204b 100644 --- a/trunk/drivers/char/apm-emulation.c +++ b/trunk/drivers/char/apm-emulation.c @@ -301,7 +301,7 @@ apm_ioctl(struct file *filp, u_int cmd, u_long arg) * anything critical, chill a bit on each iteration. */ while (wait_event_freezable(apm_suspend_waitqueue, - as->suspend_state != SUSPEND_ACKED)) + as->suspend_state == SUSPEND_DONE)) msleep(10); break; case SUSPEND_ACKTO: diff --git a/trunk/drivers/char/hpet.c b/trunk/drivers/char/hpet.c index dfd7876f127c..3845ab44c330 100644 --- a/trunk/drivers/char/hpet.c +++ b/trunk/drivers/char/hpet.c @@ -906,8 +906,8 @@ int hpet_alloc(struct hpet_data *hdp) hpetp->hp_which, hdp->hd_phys_address, hpetp->hp_ntimer > 1 ? "s" : ""); for (i = 0; i < hpetp->hp_ntimer; i++) - printk(KERN_CONT "%s %d", i > 0 ? "," : "", hdp->hd_irq[i]); - printk(KERN_CONT "\n"); + printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]); + printk("\n"); temp = hpetp->hp_tick_freq; remainder = do_div(temp, 1000000); diff --git a/trunk/drivers/char/random.c b/trunk/drivers/char/random.c index 4ec04a754733..54ca8b23cde3 100644 --- a/trunk/drivers/char/random.c +++ b/trunk/drivers/char/random.c @@ -1260,15 +1260,10 @@ static int proc_do_uuid(ctl_table *table, int write, uuid = table->data; if (!uuid) { uuid = tmp_uuid; - generate_random_uuid(uuid); - } else { - static DEFINE_SPINLOCK(bootid_spinlock); - - spin_lock(&bootid_spinlock); - if (!uuid[8]) - generate_random_uuid(uuid); - spin_unlock(&bootid_spinlock); + uuid[8] = 0; } + if (uuid[8] == 0) + generate_random_uuid(uuid); sprintf(buf, "%pU", uuid); diff --git a/trunk/drivers/char/tile-srom.c b/trunk/drivers/char/tile-srom.c index 3b22a606f79d..4dc019408fac 100644 --- a/trunk/drivers/char/tile-srom.c +++ b/trunk/drivers/char/tile-srom.c @@ -194,17 +194,17 @@ static ssize_t srom_read(struct file *filp, char __user *buf, hv_retval = _srom_read(srom->hv_devhdl, kernbuf, *f_pos, bytes_this_pass); - if (hv_retval <= 0) { + if (hv_retval > 0) { + if (copy_to_user(buf, kernbuf, hv_retval) != 0) { + retval = -EFAULT; + break; + } + } else if (hv_retval <= 0) { if (retval == 0) retval = hv_retval; break; } - if (copy_to_user(buf, kernbuf, hv_retval) != 0) { - retval = -EFAULT; - break; - } - retval += hv_retval; *f_pos += hv_retval; buf += hv_retval; diff --git a/trunk/drivers/char/virtio_console.c b/trunk/drivers/char/virtio_console.c index ddf86b6500b7..b58b56187065 100644 --- a/trunk/drivers/char/virtio_console.c +++ b/trunk/drivers/char/virtio_console.c @@ -1038,6 +1038,12 @@ static struct attribute_group port_attribute_group = { .attrs = port_sysfs_entries, }; +static int debugfs_open(struct inode *inode, struct file *filp) +{ + filp->private_data = inode->i_private; + return 0; +} + static ssize_t debugfs_read(struct file *filp, char __user *ubuf, size_t count, loff_t *offp) { @@ -1081,7 +1087,7 @@ static ssize_t debugfs_read(struct file *filp, char __user *ubuf, static const struct file_operations port_debugfs_ops = { .owner = THIS_MODULE, - .open = simple_open, + .open = debugfs_open, .read = debugfs_read, }; diff --git a/trunk/drivers/clocksource/acpi_pm.c b/trunk/drivers/clocksource/acpi_pm.c index 6b5cf02c35c8..82e882028fcf 100644 --- a/trunk/drivers/clocksource/acpi_pm.c +++ b/trunk/drivers/clocksource/acpi_pm.c @@ -23,6 +23,7 @@ #include #include #include +#include #include /* @@ -179,17 +180,15 @@ static int verify_pmtmr_rate(void) /* Number of reads we try to get two different values */ #define ACPI_PM_READ_CHECKS 10000 -static int __init init_acpi_pm_clocksource(void) +static void __init acpi_pm_clocksource_async(void *unused, async_cookie_t cookie) { cycle_t value1, value2; unsigned int i, j = 0; - if (!pmtmr_ioport) - return -ENODEV; /* "verify" this timing source: */ for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) { - udelay(100 * j); + usleep_range(100 * j, 100 * j + 100); value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm); for (i = 0; i < ACPI_PM_READ_CHECKS; i++) { value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm); @@ -203,25 +202,34 @@ static int __init init_acpi_pm_clocksource(void) " 0x%#llx, 0x%#llx - aborting.\n", value1, value2); pmtmr_ioport = 0; - return -EINVAL; + return; } if (i == ACPI_PM_READ_CHECKS) { printk(KERN_INFO "PM-Timer failed consistency check " " (0x%#llx) - aborting.\n", value1); pmtmr_ioport = 0; - return -ENODEV; + return; } } if (verify_pmtmr_rate() != 0){ pmtmr_ioport = 0; - return -ENODEV; + return; } - return clocksource_register_hz(&clocksource_acpi_pm, + clocksource_register_hz(&clocksource_acpi_pm, PMTMR_TICKS_PER_SEC); } +static int __init init_acpi_pm_clocksource(void) +{ + if (!pmtmr_ioport) + return -ENODEV; + + async_schedule(acpi_pm_clocksource_async, NULL); + return 0; +} + /* We use fs_initcall because we want the PCI fixups to have run * but we still need to load before device_initcall */ diff --git a/trunk/drivers/cpufreq/Kconfig.arm b/trunk/drivers/cpufreq/Kconfig.arm index 5961e6415f08..32d790dd8180 100644 --- a/trunk/drivers/cpufreq/Kconfig.arm +++ b/trunk/drivers/cpufreq/Kconfig.arm @@ -4,7 +4,6 @@ config ARM_OMAP2PLUS_CPUFREQ bool "TI OMAP2+" - depends on ARCH_OMAP2PLUS default ARCH_OMAP2PLUS select CPU_FREQ_TABLE @@ -52,6 +51,9 @@ config ARM_S5PV210_CPUFREQ config ARM_EXYNOS_CPUFREQ bool "SAMSUNG EXYNOS SoCs" depends on ARCH_EXYNOS + select ARM_EXYNOS4210_CPUFREQ if CPU_EXYNOS4210 + select ARM_EXYNOS4X12_CPUFREQ if (SOC_EXYNOS4212 || SOC_EXYNOS4412) + select ARM_EXYNOS5250_CPUFREQ if SOC_EXYNOS5250 default y help This adds the CPUFreq driver common part for Samsung @@ -60,19 +62,20 @@ config ARM_EXYNOS_CPUFREQ If in doubt, say N. config ARM_EXYNOS4210_CPUFREQ - def_bool CPU_EXYNOS4210 + bool "Samsung EXYNOS4210" + depends on ARCH_EXYNOS help This adds the CPUFreq driver for Samsung EXYNOS4210 SoC (S5PV310 or S5PC210). config ARM_EXYNOS4X12_CPUFREQ - def_bool (SOC_EXYNOS4212 || SOC_EXYNOS4412) + bool "Samsung EXYNOS4X12" help This adds the CPUFreq driver for Samsung EXYNOS4X12 SoC (EXYNOS4212 or EXYNOS4412). config ARM_EXYNOS5250_CPUFREQ - def_bool SOC_EXYNOS5250 + bool "Samsung EXYNOS5250" help This adds the CPUFreq driver for Samsung EXYNOS5250 SoC. diff --git a/trunk/drivers/cpufreq/db8500-cpufreq.c b/trunk/drivers/cpufreq/db8500-cpufreq.c index 0bf1b8910eeb..a22ffa5bff9f 100644 --- a/trunk/drivers/cpufreq/db8500-cpufreq.c +++ b/trunk/drivers/cpufreq/db8500-cpufreq.c @@ -142,7 +142,7 @@ static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy) policy->cpuinfo.transition_latency = 20 * 1000; /* in ns */ /* policy sharing between dual CPUs */ - cpumask_copy(policy->cpus, cpu_present_mask); + cpumask_copy(policy->cpus, &cpu_present_map); policy->shared_type = CPUFREQ_SHARED_TYPE_ALL; diff --git a/trunk/drivers/cpuidle/cpuidle.c b/trunk/drivers/cpuidle/cpuidle.c index 2f0083a51a9a..6588f43017bd 100644 --- a/trunk/drivers/cpuidle/cpuidle.c +++ b/trunk/drivers/cpuidle/cpuidle.c @@ -53,55 +53,6 @@ static void cpuidle_kick_cpus(void) {} static int __cpuidle_register_device(struct cpuidle_device *dev); -static inline int cpuidle_enter(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index) -{ - struct cpuidle_state *target_state = &drv->states[index]; - return target_state->enter(dev, drv, index); -} - -static inline int cpuidle_enter_tk(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index) -{ - return cpuidle_wrap_enter(dev, drv, index, cpuidle_enter); -} - -typedef int (*cpuidle_enter_t)(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index); - -static cpuidle_enter_t cpuidle_enter_ops; - -/** - * cpuidle_play_dead - cpu off-lining - * - * Returns in case of an error or no driver - */ -int cpuidle_play_dead(void) -{ - struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); - struct cpuidle_driver *drv = cpuidle_get_driver(); - int i, dead_state = -1; - int power_usage = -1; - - if (!drv) - return -ENODEV; - - /* Find lowest-power state that supports long-term idle */ - for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) { - struct cpuidle_state *s = &drv->states[i]; - - if (s->power_usage < power_usage && s->enter_dead) { - power_usage = s->power_usage; - dead_state = i; - } - } - - if (dead_state != -1) - return drv->states[dead_state].enter_dead(dev, dead_state); - - return -ENODEV; -} - /** * cpuidle_idle_call - the main idle loop * @@ -112,6 +63,7 @@ int cpuidle_idle_call(void) { struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); struct cpuidle_driver *drv = cpuidle_get_driver(); + struct cpuidle_state *target_state; int next_state, entered_state; if (off) @@ -140,10 +92,12 @@ int cpuidle_idle_call(void) return 0; } + target_state = &drv->states[next_state]; + trace_power_start_rcuidle(POWER_CSTATE, next_state, dev->cpu); trace_cpu_idle_rcuidle(next_state, dev->cpu); - entered_state = cpuidle_enter_ops(dev, drv, next_state); + entered_state = target_state->enter(dev, drv, next_state); trace_power_end_rcuidle(dev->cpu); trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu); @@ -156,8 +110,6 @@ int cpuidle_idle_call(void) dev->states_usage[entered_state].time += (unsigned long long)dev->last_residency; dev->states_usage[entered_state].usage++; - } else { - dev->last_residency = 0; } /* give the governor an opportunity to reflect on the outcome */ @@ -212,37 +164,6 @@ void cpuidle_resume_and_unlock(void) EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock); -/** - * cpuidle_wrap_enter - performs timekeeping and irqen around enter function - * @dev: pointer to a valid cpuidle_device object - * @drv: pointer to a valid cpuidle_driver object - * @index: index of the target cpuidle state. - */ -int cpuidle_wrap_enter(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index, - int (*enter)(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index)) -{ - ktime_t time_start, time_end; - s64 diff; - - time_start = ktime_get(); - - index = enter(dev, drv, index); - - time_end = ktime_get(); - - local_irq_enable(); - - diff = ktime_to_us(ktime_sub(time_end, time_start)); - if (diff > INT_MAX) - diff = INT_MAX; - - dev->last_residency = (int) diff; - - return index; -} - #ifdef CONFIG_ARCH_HAS_CPU_RELAX static int poll_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) @@ -276,7 +197,6 @@ static void poll_idle_init(struct cpuidle_driver *drv) state->power_usage = -1; state->flags = 0; state->enter = poll_idle; - state->disable = 0; } #else static void poll_idle_init(struct cpuidle_driver *drv) {} @@ -292,14 +212,13 @@ static void poll_idle_init(struct cpuidle_driver *drv) {} int cpuidle_enable_device(struct cpuidle_device *dev) { int ret, i; - struct cpuidle_driver *drv = cpuidle_get_driver(); if (dev->enabled) return 0; - if (!drv || !cpuidle_curr_governor) + if (!cpuidle_get_driver() || !cpuidle_curr_governor) return -EIO; if (!dev->state_count) - dev->state_count = drv->state_count; + return -EINVAL; if (dev->registered == 0) { ret = __cpuidle_register_device(dev); @@ -307,16 +226,13 @@ int cpuidle_enable_device(struct cpuidle_device *dev) return ret; } - cpuidle_enter_ops = drv->en_core_tk_irqen ? - cpuidle_enter_tk : cpuidle_enter; - - poll_idle_init(drv); + poll_idle_init(cpuidle_get_driver()); if ((ret = cpuidle_add_state_sysfs(dev))) return ret; if (cpuidle_curr_governor->enable && - (ret = cpuidle_curr_governor->enable(drv, dev))) + (ret = cpuidle_curr_governor->enable(cpuidle_get_driver(), dev))) goto fail_sysfs; for (i = 0; i < dev->state_count; i++) { diff --git a/trunk/drivers/cpuidle/driver.c b/trunk/drivers/cpuidle/driver.c index 40cd3f3024df..284d7af5a9c8 100644 --- a/trunk/drivers/cpuidle/driver.c +++ b/trunk/drivers/cpuidle/driver.c @@ -47,7 +47,7 @@ static void __cpuidle_register_driver(struct cpuidle_driver *drv) */ int cpuidle_register_driver(struct cpuidle_driver *drv) { - if (!drv || !drv->state_count) + if (!drv) return -EINVAL; if (cpuidle_disabled()) diff --git a/trunk/drivers/cpuidle/governors/menu.c b/trunk/drivers/cpuidle/governors/menu.c index 06335756ea14..ad0952601ae2 100644 --- a/trunk/drivers/cpuidle/governors/menu.c +++ b/trunk/drivers/cpuidle/governors/menu.c @@ -236,7 +236,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) { struct menu_device *data = &__get_cpu_var(menu_devices); int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); - int power_usage = -1; + unsigned int power_usage = -1; int i; int multiplier; struct timespec t; @@ -280,8 +280,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) * We want to default to C1 (hlt), not to busy polling * unless the timer is happening really really soon. */ - if (data->expected_us > 5 && - drv->states[CPUIDLE_DRIVER_STATE_START].disable == 0) + if (data->expected_us > 5) data->last_state_idx = CPUIDLE_DRIVER_STATE_START; /* @@ -291,8 +290,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) { struct cpuidle_state *s = &drv->states[i]; - if (s->disable) - continue; if (s->target_residency > data->predicted_us) continue; if (s->exit_latency > latency_req) diff --git a/trunk/drivers/cpuidle/sysfs.c b/trunk/drivers/cpuidle/sysfs.c index 88032b4dc6d2..3fe41fe4851a 100644 --- a/trunk/drivers/cpuidle/sysfs.c +++ b/trunk/drivers/cpuidle/sysfs.c @@ -11,7 +11,6 @@ #include #include #include -#include #include "cpuidle.h" @@ -223,9 +222,6 @@ struct cpuidle_state_attr { #define define_one_state_ro(_name, show) \ static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0444, show, NULL) -#define define_one_state_rw(_name, show, store) \ -static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0644, show, store) - #define define_show_state_function(_name) \ static ssize_t show_state_##_name(struct cpuidle_state *state, \ struct cpuidle_state_usage *state_usage, char *buf) \ @@ -233,24 +229,6 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, \ return sprintf(buf, "%u\n", state->_name);\ } -#define define_store_state_function(_name) \ -static ssize_t store_state_##_name(struct cpuidle_state *state, \ - const char *buf, size_t size) \ -{ \ - long value; \ - int err; \ - if (!capable(CAP_SYS_ADMIN)) \ - return -EPERM; \ - err = kstrtol(buf, 0, &value); \ - if (err) \ - return err; \ - if (value) \ - state->disable = 1; \ - else \ - state->disable = 0; \ - return size; \ -} - #define define_show_state_ull_function(_name) \ static ssize_t show_state_##_name(struct cpuidle_state *state, \ struct cpuidle_state_usage *state_usage, char *buf) \ @@ -273,8 +251,6 @@ define_show_state_ull_function(usage) define_show_state_ull_function(time) define_show_state_str_function(name) define_show_state_str_function(desc) -define_show_state_function(disable) -define_store_state_function(disable) define_one_state_ro(name, show_state_name); define_one_state_ro(desc, show_state_desc); @@ -282,7 +258,6 @@ define_one_state_ro(latency, show_state_exit_latency); define_one_state_ro(power, show_state_power_usage); define_one_state_ro(usage, show_state_usage); define_one_state_ro(time, show_state_time); -define_one_state_rw(disable, show_state_disable, store_state_disable); static struct attribute *cpuidle_state_default_attrs[] = { &attr_name.attr, @@ -291,7 +266,6 @@ static struct attribute *cpuidle_state_default_attrs[] = { &attr_power.attr, &attr_usage.attr, &attr_time.attr, - &attr_disable.attr, NULL }; @@ -313,22 +287,8 @@ static ssize_t cpuidle_state_show(struct kobject * kobj, return ret; } -static ssize_t cpuidle_state_store(struct kobject *kobj, - struct attribute *attr, const char *buf, size_t size) -{ - int ret = -EIO; - struct cpuidle_state *state = kobj_to_state(kobj); - struct cpuidle_state_attr *cattr = attr_to_stateattr(attr); - - if (cattr->store) - ret = cattr->store(state, buf, size); - - return ret; -} - static const struct sysfs_ops cpuidle_state_sysfs_ops = { .show = cpuidle_state_show, - .store = cpuidle_state_store, }; static void cpuidle_state_sysfs_release(struct kobject *kobj) diff --git a/trunk/drivers/crypto/ixp4xx_crypto.c b/trunk/drivers/crypto/ixp4xx_crypto.c index 8f3f74ce8c7f..0053d7ebb5ca 100644 --- a/trunk/drivers/crypto/ixp4xx_crypto.c +++ b/trunk/drivers/crypto/ixp4xx_crypto.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/crypto/talitos.c b/trunk/drivers/crypto/talitos.c index 921039e56f87..dc641c796526 100644 --- a/trunk/drivers/crypto/talitos.c +++ b/trunk/drivers/crypto/talitos.c @@ -124,9 +124,6 @@ struct talitos_private { void __iomem *reg; int irq[2]; - /* SEC global registers lock */ - spinlock_t reg_lock ____cacheline_aligned; - /* SEC version geometry (from device tree node) */ unsigned int num_channels; unsigned int chfifo_len; @@ -415,7 +412,6 @@ static void talitos_done_##name(unsigned long data) \ { \ struct device *dev = (struct device *)data; \ struct talitos_private *priv = dev_get_drvdata(dev); \ - unsigned long flags; \ \ if (ch_done_mask & 1) \ flush_channel(dev, 0, 0, 0); \ @@ -431,10 +427,8 @@ static void talitos_done_##name(unsigned long data) \ out: \ /* At this point, all completed channels have been processed */ \ /* Unmask done interrupts for channels completed later on. */ \ - spin_lock_irqsave(&priv->reg_lock, flags); \ setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); \ - spin_unlock_irqrestore(&priv->reg_lock, flags); \ } DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE) DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE) @@ -625,28 +619,22 @@ static irqreturn_t talitos_interrupt_##name(int irq, void *data) \ struct device *dev = data; \ struct talitos_private *priv = dev_get_drvdata(dev); \ u32 isr, isr_lo; \ - unsigned long flags; \ \ - spin_lock_irqsave(&priv->reg_lock, flags); \ isr = in_be32(priv->reg + TALITOS_ISR); \ isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \ /* Acknowledge interrupt */ \ out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \ out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \ \ - if (unlikely(isr & ch_err_mask || isr_lo)) { \ - spin_unlock_irqrestore(&priv->reg_lock, flags); \ - talitos_error(dev, isr & ch_err_mask, isr_lo); \ - } \ - else { \ + if (unlikely((isr & ~TALITOS_ISR_4CHDONE) & ch_err_mask || isr_lo)) \ + talitos_error(dev, isr, isr_lo); \ + else \ if (likely(isr & ch_done_mask)) { \ /* mask further done interrupts. */ \ clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ /* done_task will unmask done interrupts at exit */ \ tasklet_schedule(&priv->done_task[tlet]); \ } \ - spin_unlock_irqrestore(&priv->reg_lock, flags); \ - } \ \ return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \ IRQ_NONE; \ @@ -2731,8 +2719,6 @@ static int talitos_probe(struct platform_device *ofdev) priv->ofdev = ofdev; - spin_lock_init(&priv->reg_lock); - err = talitos_probe_irq(ofdev); if (err) goto err_out; diff --git a/trunk/drivers/dma/Kconfig b/trunk/drivers/dma/Kconfig index ef378b5b17e4..cf9da362d64f 100644 --- a/trunk/drivers/dma/Kconfig +++ b/trunk/drivers/dma/Kconfig @@ -91,10 +91,11 @@ config DW_DMAC config AT_HDMAC tristate "Atmel AHB DMA support" - depends on ARCH_AT91 + depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 select DMA_ENGINE help - Support the Atmel AHB DMA controller. + Support the Atmel AHB DMA controller. This can be integrated in + chips such as the Atmel AT91SAM9RL. config FSL_DMA tristate "Freescale Elo and Elo Plus DMA support" diff --git a/trunk/drivers/dma/amba-pl08x.c b/trunk/drivers/dma/amba-pl08x.c index 3d704abd7912..c301a8ec31aa 100644 --- a/trunk/drivers/dma/amba-pl08x.c +++ b/trunk/drivers/dma/amba-pl08x.c @@ -1429,7 +1429,6 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, * signal */ release_phy_channel(plchan); - plchan->phychan_hold = 0; } /* Dequeue jobs and free LLIs */ if (plchan->at) { diff --git a/trunk/drivers/dma/at_hdmac.c b/trunk/drivers/dma/at_hdmac.c index 445fdf811695..7aa58d204892 100644 --- a/trunk/drivers/dma/at_hdmac.c +++ b/trunk/drivers/dma/at_hdmac.c @@ -221,6 +221,10 @@ static void atc_dostart(struct at_dma_chan *atchan, struct at_desc *first) vdbg_dump_regs(atchan); + /* clear any pending interrupt */ + while (dma_readl(atdma, EBCISR)) + cpu_relax(); + channel_writel(atchan, SADDR, 0); channel_writel(atchan, DADDR, 0); channel_writel(atchan, CTRLA, 0); diff --git a/trunk/drivers/dma/coh901318.c b/trunk/drivers/dma/coh901318.c index 750925f9638b..dc89455f5550 100644 --- a/trunk/drivers/dma/coh901318.c +++ b/trunk/drivers/dma/coh901318.c @@ -104,6 +104,13 @@ static void coh901318_list_print(struct coh901318_chan *cohc, static struct coh901318_base *debugfs_dma_base; static struct dentry *dma_dentry; +static int coh901318_debugfs_open(struct inode *inode, struct file *file) +{ + + file->private_data = inode->i_private; + return 0; +} + static int coh901318_debugfs_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos) { @@ -151,7 +158,7 @@ static int coh901318_debugfs_read(struct file *file, char __user *buf, static const struct file_operations coh901318_debugfs_status_operations = { .owner = THIS_MODULE, - .open = simple_open, + .open = coh901318_debugfs_open, .read = coh901318_debugfs_read, .llseek = default_llseek, }; diff --git a/trunk/drivers/dma/dmaengine.c b/trunk/drivers/dma/dmaengine.c index 2397f6f451b1..767bcc31b365 100644 --- a/trunk/drivers/dma/dmaengine.c +++ b/trunk/drivers/dma/dmaengine.c @@ -332,20 +332,6 @@ struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type) } EXPORT_SYMBOL(dma_find_channel); -/* - * net_dma_find_channel - find a channel for net_dma - * net_dma has alignment requirements - */ -struct dma_chan *net_dma_find_channel(void) -{ - struct dma_chan *chan = dma_find_channel(DMA_MEMCPY); - if (chan && !is_dma_copy_aligned(chan->device, 1, 1, 1)) - return NULL; - - return chan; -} -EXPORT_SYMBOL(net_dma_find_channel); - /** * dma_issue_pending_all - flush all pending operations across all channels */ diff --git a/trunk/drivers/dma/imx-dma.c b/trunk/drivers/dma/imx-dma.c index bb787d8e1529..a45b5d2a5987 100644 --- a/trunk/drivers/dma/imx-dma.c +++ b/trunk/drivers/dma/imx-dma.c @@ -571,14 +571,11 @@ static void imxdma_tasklet(unsigned long data) if (desc->desc.callback) desc->desc.callback(desc->desc.callback_param); - /* If we are dealing with a cyclic descriptor keep it on ld_active - * and dont mark the descripor as complete. - * Only in non-cyclic cases it would be marked as complete - */ + dma_cookie_complete(&desc->desc); + + /* If we are dealing with a cyclic descriptor keep it on ld_active */ if (imxdma_chan_is_doing_cyclic(imxdmac)) goto out; - else - dma_cookie_complete(&desc->desc); /* Free 2D slot if it was an interleaved transfer */ if (imxdmac->enabled_2d) { diff --git a/trunk/drivers/dma/ioat/dma.c b/trunk/drivers/dma/ioat/dma.c index 73b2b65cb1de..31493d80e0e9 100644 --- a/trunk/drivers/dma/ioat/dma.c +++ b/trunk/drivers/dma/ioat/dma.c @@ -546,9 +546,9 @@ void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags, PCI_DMA_TODEVICE, flags, 0); } -dma_addr_t ioat_get_current_completion(struct ioat_chan_common *chan) +unsigned long ioat_get_current_completion(struct ioat_chan_common *chan) { - dma_addr_t phys_complete; + unsigned long phys_complete; u64 completion; completion = *chan->completion; @@ -569,7 +569,7 @@ dma_addr_t ioat_get_current_completion(struct ioat_chan_common *chan) } bool ioat_cleanup_preamble(struct ioat_chan_common *chan, - dma_addr_t *phys_complete) + unsigned long *phys_complete) { *phys_complete = ioat_get_current_completion(chan); if (*phys_complete == chan->last_completion) @@ -580,14 +580,14 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan, return true; } -static void __cleanup(struct ioat_dma_chan *ioat, dma_addr_t phys_complete) +static void __cleanup(struct ioat_dma_chan *ioat, unsigned long phys_complete) { struct ioat_chan_common *chan = &ioat->base; struct list_head *_desc, *n; struct dma_async_tx_descriptor *tx; - dev_dbg(to_dev(chan), "%s: phys_complete: %llx\n", - __func__, (unsigned long long) phys_complete); + dev_dbg(to_dev(chan), "%s: phys_complete: %lx\n", + __func__, phys_complete); list_for_each_safe(_desc, n, &ioat->used_desc) { struct ioat_desc_sw *desc; @@ -652,7 +652,7 @@ static void __cleanup(struct ioat_dma_chan *ioat, dma_addr_t phys_complete) static void ioat1_cleanup(struct ioat_dma_chan *ioat) { struct ioat_chan_common *chan = &ioat->base; - dma_addr_t phys_complete; + unsigned long phys_complete; prefetch(chan->completion); @@ -698,7 +698,7 @@ static void ioat1_timer_event(unsigned long data) mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT); spin_unlock_bh(&ioat->desc_lock); } else if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) { - dma_addr_t phys_complete; + unsigned long phys_complete; spin_lock_bh(&ioat->desc_lock); /* if we haven't made progress and we have already diff --git a/trunk/drivers/dma/ioat/dma.h b/trunk/drivers/dma/ioat/dma.h index 5e8fe01ba69d..c7888bccd974 100644 --- a/trunk/drivers/dma/ioat/dma.h +++ b/trunk/drivers/dma/ioat/dma.h @@ -88,7 +88,7 @@ struct ioatdma_device { struct ioat_chan_common { struct dma_chan common; void __iomem *reg_base; - dma_addr_t last_completion; + unsigned long last_completion; spinlock_t cleanup_lock; unsigned long state; #define IOAT_COMPLETION_PENDING 0 @@ -310,7 +310,7 @@ int __devinit ioat_dma_self_test(struct ioatdma_device *device); void __devexit ioat_dma_remove(struct ioatdma_device *device); struct dca_provider * __devinit ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase); -dma_addr_t ioat_get_current_completion(struct ioat_chan_common *chan); +unsigned long ioat_get_current_completion(struct ioat_chan_common *chan); void ioat_init_channel(struct ioatdma_device *device, struct ioat_chan_common *chan, int idx); enum dma_status ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie, @@ -318,7 +318,7 @@ enum dma_status ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie, void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags, size_t len, struct ioat_dma_descriptor *hw); bool ioat_cleanup_preamble(struct ioat_chan_common *chan, - dma_addr_t *phys_complete); + unsigned long *phys_complete); void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type); void ioat_kobject_del(struct ioatdma_device *device); extern const struct sysfs_ops ioat_sysfs_ops; diff --git a/trunk/drivers/dma/ioat/dma_v2.c b/trunk/drivers/dma/ioat/dma_v2.c index 86895760b598..e8e110ff3d96 100644 --- a/trunk/drivers/dma/ioat/dma_v2.c +++ b/trunk/drivers/dma/ioat/dma_v2.c @@ -128,7 +128,7 @@ static void ioat2_start_null_desc(struct ioat2_dma_chan *ioat) spin_unlock_bh(&ioat->prep_lock); } -static void __cleanup(struct ioat2_dma_chan *ioat, dma_addr_t phys_complete) +static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) { struct ioat_chan_common *chan = &ioat->base; struct dma_async_tx_descriptor *tx; @@ -179,7 +179,7 @@ static void __cleanup(struct ioat2_dma_chan *ioat, dma_addr_t phys_complete) static void ioat2_cleanup(struct ioat2_dma_chan *ioat) { struct ioat_chan_common *chan = &ioat->base; - dma_addr_t phys_complete; + unsigned long phys_complete; spin_lock_bh(&chan->cleanup_lock); if (ioat_cleanup_preamble(chan, &phys_complete)) @@ -260,7 +260,7 @@ int ioat2_reset_sync(struct ioat_chan_common *chan, unsigned long tmo) static void ioat2_restart_channel(struct ioat2_dma_chan *ioat) { struct ioat_chan_common *chan = &ioat->base; - dma_addr_t phys_complete; + unsigned long phys_complete; ioat2_quiesce(chan, 0); if (ioat_cleanup_preamble(chan, &phys_complete)) @@ -275,7 +275,7 @@ void ioat2_timer_event(unsigned long data) struct ioat_chan_common *chan = &ioat->base; if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) { - dma_addr_t phys_complete; + unsigned long phys_complete; u64 status; status = ioat_chansts(chan); @@ -572,9 +572,9 @@ bool reshape_ring(struct ioat2_dma_chan *ioat, int order) */ struct ioat_chan_common *chan = &ioat->base; struct dma_chan *c = &chan->common; - const u32 curr_size = ioat2_ring_size(ioat); + const u16 curr_size = ioat2_ring_size(ioat); const u16 active = ioat2_ring_active(ioat); - const u32 new_size = 1 << order; + const u16 new_size = 1 << order; struct ioat_ring_ent **ring; u16 i; diff --git a/trunk/drivers/dma/ioat/dma_v2.h b/trunk/drivers/dma/ioat/dma_v2.h index be2a55b95c23..a2c413b2b8d8 100644 --- a/trunk/drivers/dma/ioat/dma_v2.h +++ b/trunk/drivers/dma/ioat/dma_v2.h @@ -74,7 +74,7 @@ static inline struct ioat2_dma_chan *to_ioat2_chan(struct dma_chan *c) return container_of(chan, struct ioat2_dma_chan, base); } -static inline u32 ioat2_ring_size(struct ioat2_dma_chan *ioat) +static inline u16 ioat2_ring_size(struct ioat2_dma_chan *ioat) { return 1 << ioat->alloc_order; } @@ -91,7 +91,7 @@ static inline u16 ioat2_ring_pending(struct ioat2_dma_chan *ioat) return CIRC_CNT(ioat->head, ioat->issued, ioat2_ring_size(ioat)); } -static inline u32 ioat2_ring_space(struct ioat2_dma_chan *ioat) +static inline u16 ioat2_ring_space(struct ioat2_dma_chan *ioat) { return ioat2_ring_size(ioat) - ioat2_ring_active(ioat); } diff --git a/trunk/drivers/dma/ioat/dma_v3.c b/trunk/drivers/dma/ioat/dma_v3.c index f7f1dc62c15c..2c4476c0e405 100644 --- a/trunk/drivers/dma/ioat/dma_v3.c +++ b/trunk/drivers/dma/ioat/dma_v3.c @@ -257,7 +257,7 @@ static bool desc_has_ext(struct ioat_ring_ent *desc) * The difference from the dma_v2.c __cleanup() is that this routine * handles extended descriptors and dma-unmapping raid operations. */ -static void __cleanup(struct ioat2_dma_chan *ioat, dma_addr_t phys_complete) +static void __cleanup(struct ioat2_dma_chan *ioat, unsigned long phys_complete) { struct ioat_chan_common *chan = &ioat->base; struct ioat_ring_ent *desc; @@ -314,7 +314,7 @@ static void __cleanup(struct ioat2_dma_chan *ioat, dma_addr_t phys_complete) static void ioat3_cleanup(struct ioat2_dma_chan *ioat) { struct ioat_chan_common *chan = &ioat->base; - dma_addr_t phys_complete; + unsigned long phys_complete; spin_lock_bh(&chan->cleanup_lock); if (ioat_cleanup_preamble(chan, &phys_complete)) @@ -333,7 +333,7 @@ static void ioat3_cleanup_event(unsigned long data) static void ioat3_restart_channel(struct ioat2_dma_chan *ioat) { struct ioat_chan_common *chan = &ioat->base; - dma_addr_t phys_complete; + unsigned long phys_complete; ioat2_quiesce(chan, 0); if (ioat_cleanup_preamble(chan, &phys_complete)) @@ -348,7 +348,7 @@ static void ioat3_timer_event(unsigned long data) struct ioat_chan_common *chan = &ioat->base; if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) { - dma_addr_t phys_complete; + unsigned long phys_complete; u64 status; status = ioat_chansts(chan); @@ -1149,44 +1149,6 @@ static int ioat3_reset_hw(struct ioat_chan_common *chan) return ioat2_reset_sync(chan, msecs_to_jiffies(200)); } -static bool is_jf_ioat(struct pci_dev *pdev) -{ - switch (pdev->device) { - case PCI_DEVICE_ID_INTEL_IOAT_JSF0: - case PCI_DEVICE_ID_INTEL_IOAT_JSF1: - case PCI_DEVICE_ID_INTEL_IOAT_JSF2: - case PCI_DEVICE_ID_INTEL_IOAT_JSF3: - case PCI_DEVICE_ID_INTEL_IOAT_JSF4: - case PCI_DEVICE_ID_INTEL_IOAT_JSF5: - case PCI_DEVICE_ID_INTEL_IOAT_JSF6: - case PCI_DEVICE_ID_INTEL_IOAT_JSF7: - case PCI_DEVICE_ID_INTEL_IOAT_JSF8: - case PCI_DEVICE_ID_INTEL_IOAT_JSF9: - return true; - default: - return false; - } -} - -static bool is_snb_ioat(struct pci_dev *pdev) -{ - switch (pdev->device) { - case PCI_DEVICE_ID_INTEL_IOAT_SNB0: - case PCI_DEVICE_ID_INTEL_IOAT_SNB1: - case PCI_DEVICE_ID_INTEL_IOAT_SNB2: - case PCI_DEVICE_ID_INTEL_IOAT_SNB3: - case PCI_DEVICE_ID_INTEL_IOAT_SNB4: - case PCI_DEVICE_ID_INTEL_IOAT_SNB5: - case PCI_DEVICE_ID_INTEL_IOAT_SNB6: - case PCI_DEVICE_ID_INTEL_IOAT_SNB7: - case PCI_DEVICE_ID_INTEL_IOAT_SNB8: - case PCI_DEVICE_ID_INTEL_IOAT_SNB9: - return true; - default: - return false; - } -} - int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) { struct pci_dev *pdev = device->pdev; @@ -1207,9 +1169,6 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) dma->device_alloc_chan_resources = ioat2_alloc_chan_resources; dma->device_free_chan_resources = ioat2_free_chan_resources; - if (is_jf_ioat(pdev) || is_snb_ioat(pdev)) - dma->copy_align = 6; - dma_cap_set(DMA_INTERRUPT, dma->cap_mask); dma->device_prep_dma_interrupt = ioat3_prep_interrupt_lock; diff --git a/trunk/drivers/dma/iop-adma.c b/trunk/drivers/dma/iop-adma.c index 79e3eba29702..da6c4c2c066a 100644 --- a/trunk/drivers/dma/iop-adma.c +++ b/trunk/drivers/dma/iop-adma.c @@ -1252,8 +1252,8 @@ iop_adma_pq_zero_sum_self_test(struct iop_adma_device *device) struct page **pq_hw = &pq[IOP_ADMA_NUM_SRC_TEST+2]; /* address conversion buffers (dma_map / page_address) */ void *pq_sw[IOP_ADMA_NUM_SRC_TEST+2]; - dma_addr_t pq_src[IOP_ADMA_NUM_SRC_TEST+2]; - dma_addr_t *pq_dest = &pq_src[IOP_ADMA_NUM_SRC_TEST]; + dma_addr_t pq_src[IOP_ADMA_NUM_SRC_TEST]; + dma_addr_t pq_dest[2]; int i; struct dma_async_tx_descriptor *tx; diff --git a/trunk/drivers/dma/mxs-dma.c b/trunk/drivers/dma/mxs-dma.c index 655d4ce6ed0d..65334c49b71e 100644 --- a/trunk/drivers/dma/mxs-dma.c +++ b/trunk/drivers/dma/mxs-dma.c @@ -22,10 +22,10 @@ #include #include #include -#include #include #include +#include #include #include "dmaengine.h" @@ -201,6 +201,10 @@ static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan) static dma_cookie_t mxs_dma_tx_submit(struct dma_async_tx_descriptor *tx) { + struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(tx->chan); + + mxs_dma_enable_chan(mxs_chan); + return dma_cookie_assign(tx); } @@ -333,32 +337,10 @@ static void mxs_dma_free_chan_resources(struct dma_chan *chan) clk_disable_unprepare(mxs_dma->clk); } -/* - * How to use the flags for ->device_prep_slave_sg() : - * [1] If there is only one DMA command in the DMA chain, the code should be: - * ...... - * ->device_prep_slave_sg(DMA_CTRL_ACK); - * ...... - * [2] If there are two DMA commands in the DMA chain, the code should be - * ...... - * ->device_prep_slave_sg(0); - * ...... - * ->device_prep_slave_sg(DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - * ...... - * [3] If there are more than two DMA commands in the DMA chain, the code - * should be: - * ...... - * ->device_prep_slave_sg(0); // First - * ...... - * ->device_prep_slave_sg(DMA_PREP_INTERRUPT [| DMA_CTRL_ACK]); - * ...... - * ->device_prep_slave_sg(DMA_PREP_INTERRUPT | DMA_CTRL_ACK); // Last - * ...... - */ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg( struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction direction, - unsigned long flags, void *context) + unsigned long append, void *context) { struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan); struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma; @@ -366,7 +348,6 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg( struct scatterlist *sg; int i, j; u32 *pio; - bool append = flags & DMA_PREP_INTERRUPT; int idx = append ? mxs_chan->desc_count : 0; if (mxs_chan->status == DMA_IN_PROGRESS && !append) @@ -393,6 +374,7 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg( ccw->bits |= CCW_CHAIN; ccw->bits &= ~CCW_IRQ; ccw->bits &= ~CCW_DEC_SEM; + ccw->bits &= ~CCW_WAIT4END; } else { idx = 0; } @@ -407,8 +389,7 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg( ccw->bits = 0; ccw->bits |= CCW_IRQ; ccw->bits |= CCW_DEC_SEM; - if (flags & DMA_CTRL_ACK) - ccw->bits |= CCW_WAIT4END; + ccw->bits |= CCW_WAIT4END; ccw->bits |= CCW_HALT_ON_TERM; ccw->bits |= CCW_TERM_FLUSH; ccw->bits |= BF_CCW(sg_len, PIO_NUM); @@ -439,8 +420,7 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg( ccw->bits &= ~CCW_CHAIN; ccw->bits |= CCW_IRQ; ccw->bits |= CCW_DEC_SEM; - if (flags & DMA_CTRL_ACK) - ccw->bits |= CCW_WAIT4END; + ccw->bits |= CCW_WAIT4END; } } } @@ -554,9 +534,9 @@ static enum dma_status mxs_dma_tx_status(struct dma_chan *chan, static void mxs_dma_issue_pending(struct dma_chan *chan) { - struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan); - - mxs_dma_enable_chan(mxs_chan); + /* + * Nothing to do. We only have a single descriptor. + */ } static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma) diff --git a/trunk/drivers/dma/pl330.c b/trunk/drivers/dma/pl330.c index 2ee6e23930ad..282caf118be8 100644 --- a/trunk/drivers/dma/pl330.c +++ b/trunk/drivers/dma/pl330.c @@ -2225,9 +2225,12 @@ static inline void free_desc_list(struct list_head *list) { struct dma_pl330_dmac *pdmac; struct dma_pl330_desc *desc; - struct dma_pl330_chan *pch = NULL; + struct dma_pl330_chan *pch; unsigned long flags; + if (list_empty(list)) + return; + /* Finish off the work list */ list_for_each_entry(desc, list, node) { dma_async_tx_callback callback; @@ -2244,10 +2247,6 @@ static inline void free_desc_list(struct list_head *list) desc->pchan = NULL; } - /* pch will be unset if list was empty */ - if (!pch) - return; - pdmac = pch->dmac; spin_lock_irqsave(&pdmac->pool_lock, flags); @@ -2258,9 +2257,12 @@ static inline void free_desc_list(struct list_head *list) static inline void handle_cyclic_desc_list(struct list_head *list) { struct dma_pl330_desc *desc; - struct dma_pl330_chan *pch = NULL; + struct dma_pl330_chan *pch; unsigned long flags; + if (list_empty(list)) + return; + list_for_each_entry(desc, list, node) { dma_async_tx_callback callback; @@ -2272,10 +2274,6 @@ static inline void handle_cyclic_desc_list(struct list_head *list) callback(desc->txd.callback_param); } - /* pch will be unset if list was empty */ - if (!pch) - return; - spin_lock_irqsave(&pch->lock, flags); list_splice_tail_init(list, &pch->work_list); spin_unlock_irqrestore(&pch->lock, flags); @@ -2928,11 +2926,8 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) INIT_LIST_HEAD(&pd->channels); /* Initialize channel parameters */ - if (pdat) - num_chan = max_t(int, pdat->nr_valid_peri, pi->pcfg.num_chan); - else - num_chan = max_t(int, pi->pcfg.num_peri, pi->pcfg.num_chan); - + num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri, + (u8)pi->pcfg.num_chan); pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL); for (i = 0; i < num_chan; i++) { diff --git a/trunk/drivers/dma/sa11x0-dma.c b/trunk/drivers/dma/sa11x0-dma.c index ec78ccef9132..16a6b48883cf 100644 --- a/trunk/drivers/dma/sa11x0-dma.c +++ b/trunk/drivers/dma/sa11x0-dma.c @@ -585,7 +585,7 @@ static dma_cookie_t sa11x0_dma_tx_submit(struct dma_async_tx_descriptor *tx) static struct dma_async_tx_descriptor *sa11x0_dma_prep_slave_sg( struct dma_chan *chan, struct scatterlist *sg, unsigned int sglen, - enum dma_transfer_direction dir, unsigned long flags, void *context) + enum dma_transfer_direction dir, unsigned long flags) { struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); struct sa11x0_dma_desc *txd; diff --git a/trunk/drivers/dma/ste_dma40.c b/trunk/drivers/dma/ste_dma40.c index 2ed1ac3513f3..bdd41d4bfa8d 100644 --- a/trunk/drivers/dma/ste_dma40.c +++ b/trunk/drivers/dma/ste_dma40.c @@ -18,7 +18,6 @@ #include #include #include -#include #include @@ -69,22 +68,6 @@ enum d40_command { D40_DMA_SUSPENDED = 3 }; -/* - * enum d40_events - The different Event Enables for the event lines. - * - * @D40_DEACTIVATE_EVENTLINE: De-activate Event line, stopping the logical chan. - * @D40_ACTIVATE_EVENTLINE: Activate the Event line, to start a logical chan. - * @D40_SUSPEND_REQ_EVENTLINE: Requesting for suspending a event line. - * @D40_ROUND_EVENTLINE: Status check for event line. - */ - -enum d40_events { - D40_DEACTIVATE_EVENTLINE = 0, - D40_ACTIVATE_EVENTLINE = 1, - D40_SUSPEND_REQ_EVENTLINE = 2, - D40_ROUND_EVENTLINE = 3 -}; - /* * These are the registers that has to be saved and later restored * when the DMA hw is powered off. @@ -887,8 +870,8 @@ static void d40_save_restore_registers(struct d40_base *base, bool save) } #endif -static int __d40_execute_command_phy(struct d40_chan *d40c, - enum d40_command command) +static int d40_channel_execute_command(struct d40_chan *d40c, + enum d40_command command) { u32 status; int i; @@ -897,12 +880,6 @@ static int __d40_execute_command_phy(struct d40_chan *d40c, unsigned long flags; u32 wmask; - if (command == D40_DMA_STOP) { - ret = __d40_execute_command_phy(d40c, D40_DMA_SUSPEND_REQ); - if (ret) - return ret; - } - spin_lock_irqsave(&d40c->base->execmd_lock, flags); if (d40c->phy_chan->num % 2 == 0) @@ -996,109 +973,67 @@ static void d40_term_all(struct d40_chan *d40c) } d40c->pending_tx = 0; + d40c->busy = false; } -static void __d40_config_set_event(struct d40_chan *d40c, - enum d40_events event_type, u32 event, - int reg) +static void __d40_config_set_event(struct d40_chan *d40c, bool enable, + u32 event, int reg) { void __iomem *addr = chan_base(d40c) + reg; int tries; - u32 status; - - switch (event_type) { - - case D40_DEACTIVATE_EVENTLINE: + if (!enable) { writel((D40_DEACTIVATE_EVENTLINE << D40_EVENTLINE_POS(event)) | ~D40_EVENTLINE_MASK(event), addr); - break; - - case D40_SUSPEND_REQ_EVENTLINE: - status = (readl(addr) & D40_EVENTLINE_MASK(event)) >> - D40_EVENTLINE_POS(event); - - if (status == D40_DEACTIVATE_EVENTLINE || - status == D40_SUSPEND_REQ_EVENTLINE) - break; - - writel((D40_SUSPEND_REQ_EVENTLINE << D40_EVENTLINE_POS(event)) - | ~D40_EVENTLINE_MASK(event), addr); - - for (tries = 0 ; tries < D40_SUSPEND_MAX_IT; tries++) { - - status = (readl(addr) & D40_EVENTLINE_MASK(event)) >> - D40_EVENTLINE_POS(event); - - cpu_relax(); - /* - * Reduce the number of bus accesses while - * waiting for the DMA to suspend. - */ - udelay(3); - - if (status == D40_DEACTIVATE_EVENTLINE) - break; - } - - if (tries == D40_SUSPEND_MAX_IT) { - chan_err(d40c, - "unable to stop the event_line chl %d (log: %d)" - "status %x\n", d40c->phy_chan->num, - d40c->log_num, status); - } - break; + return; + } - case D40_ACTIVATE_EVENTLINE: /* * The hardware sometimes doesn't register the enable when src and dst * event lines are active on the same logical channel. Retry to ensure * it does. Usually only one retry is sufficient. */ - tries = 100; - while (--tries) { - writel((D40_ACTIVATE_EVENTLINE << - D40_EVENTLINE_POS(event)) | - ~D40_EVENTLINE_MASK(event), addr); - - if (readl(addr) & D40_EVENTLINE_MASK(event)) - break; - } - - if (tries != 99) - dev_dbg(chan2dev(d40c), - "[%s] workaround enable S%cLNK (%d tries)\n", - __func__, reg == D40_CHAN_REG_SSLNK ? 'S' : 'D', - 100 - tries); + tries = 100; + while (--tries) { + writel((D40_ACTIVATE_EVENTLINE << D40_EVENTLINE_POS(event)) + | ~D40_EVENTLINE_MASK(event), addr); - WARN_ON(!tries); - break; + if (readl(addr) & D40_EVENTLINE_MASK(event)) + break; + } - case D40_ROUND_EVENTLINE: - BUG(); - break; + if (tries != 99) + dev_dbg(chan2dev(d40c), + "[%s] workaround enable S%cLNK (%d tries)\n", + __func__, reg == D40_CHAN_REG_SSLNK ? 'S' : 'D', + 100 - tries); - } + WARN_ON(!tries); } -static void d40_config_set_event(struct d40_chan *d40c, - enum d40_events event_type) +static void d40_config_set_event(struct d40_chan *d40c, bool do_enable) { + unsigned long flags; + + spin_lock_irqsave(&d40c->phy_chan->lock, flags); + /* Enable event line connected to device (or memcpy) */ if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) || (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) { u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type); - __d40_config_set_event(d40c, event_type, event, + __d40_config_set_event(d40c, do_enable, event, D40_CHAN_REG_SSLNK); } if (d40c->dma_cfg.dir != STEDMA40_PERIPH_TO_MEM) { u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type); - __d40_config_set_event(d40c, event_type, event, + __d40_config_set_event(d40c, do_enable, event, D40_CHAN_REG_SDLNK); } + + spin_unlock_irqrestore(&d40c->phy_chan->lock, flags); } static u32 d40_chan_has_events(struct d40_chan *d40c) @@ -1112,64 +1047,6 @@ static u32 d40_chan_has_events(struct d40_chan *d40c) return val; } -static int -__d40_execute_command_log(struct d40_chan *d40c, enum d40_command command) -{ - unsigned long flags; - int ret = 0; - u32 active_status; - void __iomem *active_reg; - - if (d40c->phy_chan->num % 2 == 0) - active_reg = d40c->base->virtbase + D40_DREG_ACTIVE; - else - active_reg = d40c->base->virtbase + D40_DREG_ACTIVO; - - - spin_lock_irqsave(&d40c->phy_chan->lock, flags); - - switch (command) { - case D40_DMA_STOP: - case D40_DMA_SUSPEND_REQ: - - active_status = (readl(active_reg) & - D40_CHAN_POS_MASK(d40c->phy_chan->num)) >> - D40_CHAN_POS(d40c->phy_chan->num); - - if (active_status == D40_DMA_RUN) - d40_config_set_event(d40c, D40_SUSPEND_REQ_EVENTLINE); - else - d40_config_set_event(d40c, D40_DEACTIVATE_EVENTLINE); - - if (!d40_chan_has_events(d40c) && (command == D40_DMA_STOP)) - ret = __d40_execute_command_phy(d40c, command); - - break; - - case D40_DMA_RUN: - - d40_config_set_event(d40c, D40_ACTIVATE_EVENTLINE); - ret = __d40_execute_command_phy(d40c, command); - break; - - case D40_DMA_SUSPENDED: - BUG(); - break; - } - - spin_unlock_irqrestore(&d40c->phy_chan->lock, flags); - return ret; -} - -static int d40_channel_execute_command(struct d40_chan *d40c, - enum d40_command command) -{ - if (chan_is_logical(d40c)) - return __d40_execute_command_log(d40c, command); - else - return __d40_execute_command_phy(d40c, command); -} - static u32 d40_get_prmo(struct d40_chan *d40c) { static const unsigned int phy_map[] = { @@ -1272,7 +1149,15 @@ static int d40_pause(struct d40_chan *d40c) spin_lock_irqsave(&d40c->lock, flags); res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); - + if (res == 0) { + if (chan_is_logical(d40c)) { + d40_config_set_event(d40c, false); + /* Resume the other logical channels if any */ + if (d40_chan_has_events(d40c)) + res = d40_channel_execute_command(d40c, + D40_DMA_RUN); + } + } pm_runtime_mark_last_busy(d40c->base->dev); pm_runtime_put_autosuspend(d40c->base->dev); spin_unlock_irqrestore(&d40c->lock, flags); @@ -1289,17 +1174,45 @@ static int d40_resume(struct d40_chan *d40c) spin_lock_irqsave(&d40c->lock, flags); pm_runtime_get_sync(d40c->base->dev); + if (d40c->base->rev == 0) + if (chan_is_logical(d40c)) { + res = d40_channel_execute_command(d40c, + D40_DMA_SUSPEND_REQ); + goto no_suspend; + } /* If bytes left to transfer or linked tx resume job */ - if (d40_residue(d40c) || d40_tx_is_linked(d40c)) + if (d40_residue(d40c) || d40_tx_is_linked(d40c)) { + + if (chan_is_logical(d40c)) + d40_config_set_event(d40c, true); + res = d40_channel_execute_command(d40c, D40_DMA_RUN); + } +no_suspend: pm_runtime_mark_last_busy(d40c->base->dev); pm_runtime_put_autosuspend(d40c->base->dev); spin_unlock_irqrestore(&d40c->lock, flags); return res; } +static int d40_terminate_all(struct d40_chan *chan) +{ + unsigned long flags; + int ret = 0; + + ret = d40_pause(chan); + if (!ret && chan_is_physical(chan)) + ret = d40_channel_execute_command(chan, D40_DMA_STOP); + + spin_lock_irqsave(&chan->lock, flags); + d40_term_all(chan); + spin_unlock_irqrestore(&chan->lock, flags); + + return ret; +} + static dma_cookie_t d40_tx_submit(struct dma_async_tx_descriptor *tx) { struct d40_chan *d40c = container_of(tx->chan, @@ -1319,6 +1232,20 @@ static dma_cookie_t d40_tx_submit(struct dma_async_tx_descriptor *tx) static int d40_start(struct d40_chan *d40c) { + if (d40c->base->rev == 0) { + int err; + + if (chan_is_logical(d40c)) { + err = d40_channel_execute_command(d40c, + D40_DMA_SUSPEND_REQ); + if (err) + return err; + } + } + + if (chan_is_logical(d40c)) + d40_config_set_event(d40c, true); + return d40_channel_execute_command(d40c, D40_DMA_RUN); } @@ -1331,10 +1258,10 @@ static struct d40_desc *d40_queue_start(struct d40_chan *d40c) d40d = d40_first_queued(d40c); if (d40d != NULL) { - if (!d40c->busy) { + if (!d40c->busy) d40c->busy = true; - pm_runtime_get_sync(d40c->base->dev); - } + + pm_runtime_get_sync(d40c->base->dev); /* Remove from queue */ d40_desc_remove(d40d); @@ -1461,8 +1388,8 @@ static void dma_tasklet(unsigned long data) return; -err: - /* Rescue manouver if receiving double interrupts */ + err: + /* Rescue manoeuvre if receiving double interrupts */ if (d40c->pending_tx > 0) d40c->pending_tx--; spin_unlock_irqrestore(&d40c->lock, flags); @@ -1843,6 +1770,7 @@ static int d40_config_memcpy(struct d40_chan *d40c) return 0; } + static int d40_free_dma(struct d40_chan *d40c) { @@ -1878,18 +1806,43 @@ static int d40_free_dma(struct d40_chan *d40c) } pm_runtime_get_sync(d40c->base->dev); - res = d40_channel_execute_command(d40c, D40_DMA_STOP); + res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); if (res) { - chan_err(d40c, "stop failed\n"); + chan_err(d40c, "suspend failed\n"); goto out; } - d40_alloc_mask_free(phy, is_src, chan_is_logical(d40c) ? event : 0); + if (chan_is_logical(d40c)) { + /* Release logical channel, deactivate the event line */ - if (chan_is_logical(d40c)) + d40_config_set_event(d40c, false); d40c->base->lookup_log_chans[d40c->log_num] = NULL; - else - d40c->base->lookup_phy_chans[phy->num] = NULL; + + /* + * Check if there are more logical allocation + * on this phy channel. + */ + if (!d40_alloc_mask_free(phy, is_src, event)) { + /* Resume the other logical channels if any */ + if (d40_chan_has_events(d40c)) { + res = d40_channel_execute_command(d40c, + D40_DMA_RUN); + if (res) + chan_err(d40c, + "Executing RUN command\n"); + } + goto out; + } + } else { + (void) d40_alloc_mask_free(phy, is_src, 0); + } + + /* Release physical channel */ + res = d40_channel_execute_command(d40c, D40_DMA_STOP); + if (res) { + chan_err(d40c, "Failed to stop channel\n"); + goto out; + } if (d40c->busy) { pm_runtime_mark_last_busy(d40c->base->dev); @@ -1899,6 +1852,7 @@ static int d40_free_dma(struct d40_chan *d40c) d40c->busy = false; d40c->phy_chan = NULL; d40c->configured = false; + d40c->base->lookup_phy_chans[phy->num] = NULL; out: pm_runtime_mark_last_busy(d40c->base->dev); @@ -2116,7 +2070,7 @@ d40_prep_sg(struct dma_chan *dchan, struct scatterlist *sg_src, if (sg_next(&sg_src[sg_len - 1]) == sg_src) desc->cyclic = true; - if (direction != DMA_TRANS_NONE) { + if (direction != DMA_NONE) { dma_addr_t dev_addr = d40_get_dev_addr(chan, direction); if (direction == DMA_DEV_TO_MEM) @@ -2417,31 +2371,6 @@ static void d40_issue_pending(struct dma_chan *chan) spin_unlock_irqrestore(&d40c->lock, flags); } -static void d40_terminate_all(struct dma_chan *chan) -{ - unsigned long flags; - struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); - int ret; - - spin_lock_irqsave(&d40c->lock, flags); - - pm_runtime_get_sync(d40c->base->dev); - ret = d40_channel_execute_command(d40c, D40_DMA_STOP); - if (ret) - chan_err(d40c, "Failed to stop channel\n"); - - d40_term_all(d40c); - pm_runtime_mark_last_busy(d40c->base->dev); - pm_runtime_put_autosuspend(d40c->base->dev); - if (d40c->busy) { - pm_runtime_mark_last_busy(d40c->base->dev); - pm_runtime_put_autosuspend(d40c->base->dev); - } - d40c->busy = false; - - spin_unlock_irqrestore(&d40c->lock, flags); -} - static int dma40_config_to_halfchannel(struct d40_chan *d40c, struct stedma40_half_channel_info *info, @@ -2622,8 +2551,7 @@ static int d40_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, switch (cmd) { case DMA_TERMINATE_ALL: - d40_terminate_all(chan); - return 0; + return d40_terminate_all(d40c); case DMA_PAUSE: return d40_pause(d40c); case DMA_RESUME: @@ -2980,12 +2908,6 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) dev_info(&pdev->dev, "hardware revision: %d @ 0x%x\n", rev, res->start); - if (rev < 2) { - d40_err(&pdev->dev, "hardware revision: %d is not supported", - rev); - goto failure; - } - plat_data = pdev->dev.platform_data; /* Count the number of logical channels in use */ @@ -3076,7 +2998,6 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) if (base) { kfree(base->lcla_pool.alloc_map); - kfree(base->reg_val_backup_chan); kfree(base->lookup_log_chans); kfree(base->lookup_phy_chans); kfree(base->phy_res); diff --git a/trunk/drivers/dma/ste_dma40_ll.h b/trunk/drivers/dma/ste_dma40_ll.h index 51e8e5396e9b..8d3d490968a3 100644 --- a/trunk/drivers/dma/ste_dma40_ll.h +++ b/trunk/drivers/dma/ste_dma40_ll.h @@ -62,6 +62,8 @@ #define D40_SREG_ELEM_LOG_LIDX_MASK (0xFF << D40_SREG_ELEM_LOG_LIDX_POS) /* Link register */ +#define D40_DEACTIVATE_EVENTLINE 0x0 +#define D40_ACTIVATE_EVENTLINE 0x1 #define D40_EVENTLINE_POS(i) (2 * i) #define D40_EVENTLINE_MASK(i) (0x3 << D40_EVENTLINE_POS(i)) diff --git a/trunk/drivers/edac/mce_amd.c b/trunk/drivers/edac/mce_amd.c index d0c372e30de4..36e1486eb9aa 100644 --- a/trunk/drivers/edac/mce_amd.c +++ b/trunk/drivers/edac/mce_amd.c @@ -754,7 +754,9 @@ static int __init mce_amd_init(void) if (c->x86_vendor != X86_VENDOR_AMD) return 0; - if (c->x86 < 0xf || c->x86 > 0x15) + if ((c->x86 < 0xf || c->x86 > 0x12) && + (c->x86 != 0x14 || c->x86_model > 0xf) && + (c->x86 != 0x15 || c->x86_model > 0xf)) return 0; fam_ops = kzalloc(sizeof(struct amd_decoder_ops), GFP_KERNEL); @@ -795,7 +797,7 @@ static int __init mce_amd_init(void) break; default: - printk(KERN_WARNING "Huh? What family is it: 0x%x?!\n", c->x86); + printk(KERN_WARNING "Huh? What family is that: %d?!\n", c->x86); kfree(fam_ops); return -EINVAL; } diff --git a/trunk/drivers/edac/tile_edac.c b/trunk/drivers/edac/tile_edac.c index e99d00976189..1d5cf06f6c6b 100644 --- a/trunk/drivers/edac/tile_edac.c +++ b/trunk/drivers/edac/tile_edac.c @@ -145,11 +145,7 @@ static int __devinit tile_edac_mc_probe(struct platform_device *pdev) mci->edac_ctl_cap = EDAC_FLAG_SECDED; mci->mod_name = DRV_NAME; -#ifdef __tilegx__ - mci->ctl_name = "TILEGx_Memory_Controller"; -#else mci->ctl_name = "TILEPro_Memory_Controller"; -#endif mci->dev_name = dev_name(&pdev->dev); mci->edac_check = tile_edac_check; diff --git a/trunk/drivers/firmware/efivars.c b/trunk/drivers/firmware/efivars.c index 47408e802ab6..d25599f2a3f8 100644 --- a/trunk/drivers/firmware/efivars.c +++ b/trunk/drivers/firmware/efivars.c @@ -191,190 +191,6 @@ utf16_strncmp(const efi_char16_t *a, const efi_char16_t *b, size_t len) } } -static bool -validate_device_path(struct efi_variable *var, int match, u8 *buffer, - unsigned long len) -{ - struct efi_generic_dev_path *node; - int offset = 0; - - node = (struct efi_generic_dev_path *)buffer; - - if (len < sizeof(*node)) - return false; - - while (offset <= len - sizeof(*node) && - node->length >= sizeof(*node) && - node->length <= len - offset) { - offset += node->length; - - if ((node->type == EFI_DEV_END_PATH || - node->type == EFI_DEV_END_PATH2) && - node->sub_type == EFI_DEV_END_ENTIRE) - return true; - - node = (struct efi_generic_dev_path *)(buffer + offset); - } - - /* - * If we're here then either node->length pointed past the end - * of the buffer or we reached the end of the buffer without - * finding a device path end node. - */ - return false; -} - -static bool -validate_boot_order(struct efi_variable *var, int match, u8 *buffer, - unsigned long len) -{ - /* An array of 16-bit integers */ - if ((len % 2) != 0) - return false; - - return true; -} - -static bool -validate_load_option(struct efi_variable *var, int match, u8 *buffer, - unsigned long len) -{ - u16 filepathlength; - int i, desclength = 0, namelen; - - namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName)); - - /* Either "Boot" or "Driver" followed by four digits of hex */ - for (i = match; i < match+4; i++) { - if (var->VariableName[i] > 127 || - hex_to_bin(var->VariableName[i] & 0xff) < 0) - return true; - } - - /* Reject it if there's 4 digits of hex and then further content */ - if (namelen > match + 4) - return false; - - /* A valid entry must be at least 8 bytes */ - if (len < 8) - return false; - - filepathlength = buffer[4] | buffer[5] << 8; - - /* - * There's no stored length for the description, so it has to be - * found by hand - */ - desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2; - - /* Each boot entry must have a descriptor */ - if (!desclength) - return false; - - /* - * If the sum of the length of the description, the claimed filepath - * length and the original header are greater than the length of the - * variable, it's malformed - */ - if ((desclength + filepathlength + 6) > len) - return false; - - /* - * And, finally, check the filepath - */ - return validate_device_path(var, match, buffer + desclength + 6, - filepathlength); -} - -static bool -validate_uint16(struct efi_variable *var, int match, u8 *buffer, - unsigned long len) -{ - /* A single 16-bit integer */ - if (len != 2) - return false; - - return true; -} - -static bool -validate_ascii_string(struct efi_variable *var, int match, u8 *buffer, - unsigned long len) -{ - int i; - - for (i = 0; i < len; i++) { - if (buffer[i] > 127) - return false; - - if (buffer[i] == 0) - return true; - } - - return false; -} - -struct variable_validate { - char *name; - bool (*validate)(struct efi_variable *var, int match, u8 *data, - unsigned long len); -}; - -static const struct variable_validate variable_validate[] = { - { "BootNext", validate_uint16 }, - { "BootOrder", validate_boot_order }, - { "DriverOrder", validate_boot_order }, - { "Boot*", validate_load_option }, - { "Driver*", validate_load_option }, - { "ConIn", validate_device_path }, - { "ConInDev", validate_device_path }, - { "ConOut", validate_device_path }, - { "ConOutDev", validate_device_path }, - { "ErrOut", validate_device_path }, - { "ErrOutDev", validate_device_path }, - { "Timeout", validate_uint16 }, - { "Lang", validate_ascii_string }, - { "PlatformLang", validate_ascii_string }, - { "", NULL }, -}; - -static bool -validate_var(struct efi_variable *var, u8 *data, unsigned long len) -{ - int i; - u16 *unicode_name = var->VariableName; - - for (i = 0; variable_validate[i].validate != NULL; i++) { - const char *name = variable_validate[i].name; - int match; - - for (match = 0; ; match++) { - char c = name[match]; - u16 u = unicode_name[match]; - - /* All special variables are plain ascii */ - if (u > 127) - return true; - - /* Wildcard in the matching name means we've matched */ - if (c == '*') - return variable_validate[i].validate(var, - match, data, len); - - /* Case sensitive match */ - if (c != u) - break; - - /* Reached the end of the string while matching */ - if (!c) - return variable_validate[i].validate(var, - match, data, len); - } - } - - return true; -} - static efi_status_t get_var_data_locked(struct efivars *efivars, struct efi_variable *var) { @@ -508,12 +324,6 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) return -EINVAL; } - if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 || - validate_var(new_var, new_var->Data, new_var->DataSize) == false) { - printk(KERN_ERR "efivars: Malformed variable content\n"); - return -EINVAL; - } - spin_lock(&efivars->lock); status = efivars->ops->set_variable(new_var->VariableName, &new_var->VendorGuid, @@ -816,12 +626,6 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 || - validate_var(new_var, new_var->Data, new_var->DataSize) == false) { - printk(KERN_ERR "efivars: Malformed variable content\n"); - return -EINVAL; - } - spin_lock(&efivars->lock); /* diff --git a/trunk/drivers/gpio/Kconfig b/trunk/drivers/gpio/Kconfig index e03653d69357..edadbdad31d0 100644 --- a/trunk/drivers/gpio/Kconfig +++ b/trunk/drivers/gpio/Kconfig @@ -430,7 +430,7 @@ config GPIO_ML_IOH config GPIO_SODAVILLE bool "Intel Sodaville GPIO support" - depends on X86 && PCI && OF + depends on X86 && PCI && OF && BROKEN select GPIO_GENERIC select GENERIC_IRQ_CHIP help diff --git a/trunk/drivers/gpio/gpio-adp5588.c b/trunk/drivers/gpio/gpio-adp5588.c index ae5d7f12ce66..9ad1703d1408 100644 --- a/trunk/drivers/gpio/gpio-adp5588.c +++ b/trunk/drivers/gpio/gpio-adp5588.c @@ -252,7 +252,7 @@ static irqreturn_t adp5588_irq_handler(int irq, void *devid) if (ret < 0) memset(dev->irq_stat, 0, ARRAY_SIZE(dev->irq_stat)); - for (bank = 0, bit = 0; bank <= ADP5588_BANK(ADP5588_MAXGPIO); + for (bank = 0; bank <= ADP5588_BANK(ADP5588_MAXGPIO); bank++, bit = 0) { pending = dev->irq_stat[bank] & dev->irq_mask[bank]; diff --git a/trunk/drivers/gpio/gpio-pxa.c b/trunk/drivers/gpio/gpio-pxa.c index fc3ace3fd4cb..5689ce62fd81 100644 --- a/trunk/drivers/gpio/gpio-pxa.c +++ b/trunk/drivers/gpio/gpio-pxa.c @@ -64,7 +64,6 @@ struct pxa_gpio_chip { unsigned long irq_mask; unsigned long irq_edge_rise; unsigned long irq_edge_fall; - int (*set_wake)(unsigned int gpio, unsigned int on); #ifdef CONFIG_PM unsigned long saved_gplr; @@ -270,8 +269,7 @@ static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) (value ? GPSR_OFFSET : GPCR_OFFSET)); } -static int __devinit pxa_init_gpio_chip(int gpio_end, - int (*set_wake)(unsigned int, unsigned int)) +static int __devinit pxa_init_gpio_chip(int gpio_end) { int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; struct pxa_gpio_chip *chips; @@ -287,7 +285,6 @@ static int __devinit pxa_init_gpio_chip(int gpio_end, sprintf(chips[i].label, "gpio-%d", i); chips[i].regbase = gpio_reg_base + BANK_OFF(i); - chips[i].set_wake = set_wake; c->base = gpio; c->label = chips[i].label; @@ -415,17 +412,6 @@ static void pxa_mask_muxed_gpio(struct irq_data *d) writel_relaxed(gfer, c->regbase + GFER_OFFSET); } -static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on) -{ - int gpio = pxa_irq_to_gpio(d->irq); - struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); - - if (c->set_wake) - return c->set_wake(gpio, on); - else - return 0; -} - static void pxa_unmask_muxed_gpio(struct irq_data *d) { int gpio = pxa_irq_to_gpio(d->irq); @@ -441,7 +427,6 @@ static struct irq_chip pxa_muxed_gpio_chip = { .irq_mask = pxa_mask_muxed_gpio, .irq_unmask = pxa_unmask_muxed_gpio, .irq_set_type = pxa_gpio_irq_type, - .irq_set_wake = pxa_gpio_set_wake, }; static int pxa_gpio_nums(void) @@ -486,7 +471,6 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev) struct pxa_gpio_chip *c; struct resource *res; struct clk *clk; - struct pxa_gpio_platform_data *info; int gpio, irq, ret; int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; @@ -532,8 +516,7 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev) } /* Initialize GPIO chips */ - info = dev_get_platdata(&pdev->dev); - pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL); + pxa_init_gpio_chip(pxa_last_gpio); /* clear all GPIO edge detects */ for_each_gpio_chip(gpio, c) { diff --git a/trunk/drivers/gpio/gpio-samsung.c b/trunk/drivers/gpio/gpio-samsung.c index 19d6fc0229c3..46277877b7ec 100644 --- a/trunk/drivers/gpio/gpio-samsung.c +++ b/trunk/drivers/gpio/gpio-samsung.c @@ -2382,8 +2382,8 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = { #endif }; -#ifdef CONFIG_ARCH_EXYNOS5 static struct samsung_gpio_chip exynos5_gpios_1[] = { +#ifdef CONFIG_ARCH_EXYNOS5 { .chip = { .base = EXYNOS5_GPA0(0), @@ -2541,11 +2541,11 @@ static struct samsung_gpio_chip exynos5_gpios_1[] = { .to_irq = samsung_gpiolib_to_irq, }, }, -}; #endif +}; -#ifdef CONFIG_ARCH_EXYNOS5 static struct samsung_gpio_chip exynos5_gpios_2[] = { +#ifdef CONFIG_ARCH_EXYNOS5 { .chip = { .base = EXYNOS5_GPE0(0), @@ -2602,11 +2602,11 @@ static struct samsung_gpio_chip exynos5_gpios_2[] = { }, }, -}; #endif +}; -#ifdef CONFIG_ARCH_EXYNOS5 static struct samsung_gpio_chip exynos5_gpios_3[] = { +#ifdef CONFIG_ARCH_EXYNOS5 { .chip = { .base = EXYNOS5_GPV0(0), @@ -2638,11 +2638,11 @@ static struct samsung_gpio_chip exynos5_gpios_3[] = { .label = "GPV4", }, }, -}; #endif +}; -#ifdef CONFIG_ARCH_EXYNOS5 static struct samsung_gpio_chip exynos5_gpios_4[] = { +#ifdef CONFIG_ARCH_EXYNOS5 { .chip = { .base = EXYNOS5_GPZ(0), @@ -2650,8 +2650,8 @@ static struct samsung_gpio_chip exynos5_gpios_4[] = { .label = "GPZ", }, }, -}; #endif +}; #if defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) diff --git a/trunk/drivers/gpio/gpio-sodaville.c b/trunk/drivers/gpio/gpio-sodaville.c index 031e5d24837d..9ba15d31d242 100644 --- a/trunk/drivers/gpio/gpio-sodaville.c +++ b/trunk/drivers/gpio/gpio-sodaville.c @@ -41,7 +41,7 @@ struct sdv_gpio_chip_data { int irq_base; void __iomem *gpio_pub_base; - struct irq_domain *id; + struct irq_domain id; struct irq_chip_generic *gc; struct bgpio_chip bgpio; }; @@ -51,9 +51,10 @@ static int sdv_gpio_pub_set_type(struct irq_data *d, unsigned int type) struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct sdv_gpio_chip_data *sd = gc->private; void __iomem *type_reg; + u32 irq_offs = d->irq - sd->irq_base; u32 reg; - if (d->hwirq < 8) + if (irq_offs < 8) type_reg = sd->gpio_pub_base + GPIT1R0; else type_reg = sd->gpio_pub_base + GPIT1R1; @@ -62,11 +63,11 @@ static int sdv_gpio_pub_set_type(struct irq_data *d, unsigned int type) switch (type) { case IRQ_TYPE_LEVEL_HIGH: - reg &= ~BIT(4 * (d->hwirq % 8)); + reg &= ~BIT(4 * (irq_offs % 8)); break; case IRQ_TYPE_LEVEL_LOW: - reg |= BIT(4 * (d->hwirq % 8)); + reg |= BIT(4 * (irq_offs % 8)); break; default: @@ -90,7 +91,7 @@ static irqreturn_t sdv_gpio_pub_irq_handler(int irq, void *data) u32 irq_bit = __fls(irq_stat); irq_stat &= ~BIT(irq_bit); - generic_handle_irq(irq_find_mapping(sd->id, irq_bit)); + generic_handle_irq(sd->irq_base + irq_bit); } return IRQ_HANDLED; @@ -126,7 +127,7 @@ static int sdv_xlate(struct irq_domain *h, struct device_node *node, } static struct irq_domain_ops irq_domain_sdv_ops = { - .xlate = sdv_xlate, + .dt_translate = sdv_xlate, }; static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, @@ -148,6 +149,10 @@ static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, if (ret) goto out_free_desc; + sd->id.irq_base = sd->irq_base; + sd->id.of_node = of_node_get(pdev->dev.of_node); + sd->id.ops = &irq_domain_sdv_ops; + /* * This gpio irq controller latches level irqs. Testing shows that if * we unmask & ACK the IRQ before the source of the interrupt is gone @@ -174,10 +179,7 @@ static __devinit int sdv_register_irqsupport(struct sdv_gpio_chip_data *sd, IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); - sd->id = irq_domain_add_legacy(pdev->dev.of_node, SDV_NUM_PUB_GPIOS, - sd->irq_base, 0, &irq_domain_sdv_ops, sd); - if (!sd->id) - goto out_free_irq; + irq_domain_add(&sd->id); return 0; out_free_irq: free_irq(pdev->irq, sd); @@ -258,6 +260,7 @@ static void sdv_gpio_remove(struct pci_dev *pdev) { struct sdv_gpio_chip_data *sd = pci_get_drvdata(pdev); + irq_domain_del(&sd->id); free_irq(pdev->irq, sd); irq_free_descs(sd->irq_base, SDV_NUM_PUB_GPIOS); diff --git a/trunk/drivers/gpio/gpio-tegra.c b/trunk/drivers/gpio/gpio-tegra.c index 12f349b3830d..32de6707e3c4 100644 --- a/trunk/drivers/gpio/gpio-tegra.c +++ b/trunk/drivers/gpio/gpio-tegra.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -37,8 +37,7 @@ #define GPIO_PORT(x) (((x) >> 3) & 0x3) #define GPIO_BIT(x) ((x) & 0x7) -#define GPIO_REG(x) (GPIO_BANK(x) * tegra_gpio_bank_stride + \ - GPIO_PORT(x) * 4) +#define GPIO_REG(x) (GPIO_BANK(x) * 0x80 + GPIO_PORT(x) * 4) #define GPIO_CNF(x) (GPIO_REG(x) + 0x00) #define GPIO_OE(x) (GPIO_REG(x) + 0x10) @@ -49,12 +48,12 @@ #define GPIO_INT_LVL(x) (GPIO_REG(x) + 0x60) #define GPIO_INT_CLR(x) (GPIO_REG(x) + 0x70) -#define GPIO_MSK_CNF(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x00) -#define GPIO_MSK_OE(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x10) -#define GPIO_MSK_OUT(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0X20) -#define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x40) -#define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x50) -#define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + tegra_gpio_upper_offset + 0x60) +#define GPIO_MSK_CNF(x) (GPIO_REG(x) + 0x800) +#define GPIO_MSK_OE(x) (GPIO_REG(x) + 0x810) +#define GPIO_MSK_OUT(x) (GPIO_REG(x) + 0X820) +#define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + 0x840) +#define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + 0x850) +#define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + 0x860) #define GPIO_INT_LVL_MASK 0x010101 #define GPIO_INT_LVL_EDGE_RISING 0x000101 @@ -79,8 +78,6 @@ struct tegra_gpio_bank { static struct irq_domain *irq_domain; static void __iomem *regs; static u32 tegra_gpio_bank_count; -static u32 tegra_gpio_bank_stride; -static u32 tegra_gpio_upper_offset; static struct tegra_gpio_bank *tegra_gpio_banks; static inline void tegra_gpio_writel(u32 val, u32 reg) @@ -336,26 +333,6 @@ static struct irq_chip tegra_gpio_irq_chip = { #endif }; -struct tegra_gpio_soc_config { - u32 bank_stride; - u32 upper_offset; -}; - -static struct tegra_gpio_soc_config tegra20_gpio_config = { - .bank_stride = 0x80, - .upper_offset = 0x800, -}; - -static struct tegra_gpio_soc_config tegra30_gpio_config = { - .bank_stride = 0x100, - .upper_offset = 0x80, -}; - -static struct of_device_id tegra_gpio_of_match[] __devinitdata = { - { .compatible = "nvidia,tegra30-gpio", .data = &tegra30_gpio_config }, - { .compatible = "nvidia,tegra20-gpio", .data = &tegra20_gpio_config }, - { }, -}; /* This lock class tells lockdep that GPIO irqs are in a different * category than their parents, so it won't report false recursion. @@ -364,8 +341,6 @@ static struct lock_class_key gpio_lock_class; static int __devinit tegra_gpio_probe(struct platform_device *pdev) { - const struct of_device_id *match; - struct tegra_gpio_soc_config *config; int irq_base; struct resource *res; struct tegra_gpio_bank *bank; @@ -373,15 +348,6 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) int i; int j; - match = of_match_device(tegra_gpio_of_match, &pdev->dev); - if (match) - config = (struct tegra_gpio_soc_config *)match->data; - else - config = &tegra20_gpio_config; - - tegra_gpio_bank_stride = config->bank_stride; - tegra_gpio_upper_offset = config->upper_offset; - for (;;) { res = platform_get_resource(pdev, IORESOURCE_IRQ, tegra_gpio_bank_count); if (!res) @@ -436,7 +402,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) return -ENODEV; } - for (i = 0; i < tegra_gpio_bank_count; i++) { + for (i = 0; i < 7; i++) { for (j = 0; j < 4; j++) { int gpio = tegra_gpio_compose(i, j, 0); tegra_gpio_writel(0x00, GPIO_INT_ENB(gpio)); @@ -475,6 +441,11 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) return 0; } +static struct of_device_id tegra_gpio_of_match[] __devinitdata = { + { .compatible = "nvidia,tegra20-gpio", }, + { }, +}; + static struct platform_driver tegra_gpio_driver = { .driver = { .name = "tegra-gpio", @@ -514,7 +485,7 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) int i; int j; - for (i = 0; i < tegra_gpio_bank_count; i++) { + for (i = 0; i < 7; i++) { for (j = 0; j < 4; j++) { int gpio = tegra_gpio_compose(i, j, 0); seq_printf(s, diff --git a/trunk/drivers/gpu/drm/Kconfig b/trunk/drivers/gpu/drm/Kconfig index e354bc0b052a..cc1148837e24 100644 --- a/trunk/drivers/gpu/drm/Kconfig +++ b/trunk/drivers/gpu/drm/Kconfig @@ -9,7 +9,6 @@ menuconfig DRM depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU select I2C select I2C_ALGOBIT - select DMA_SHARED_BUFFER help Kernel-level support for the Direct Rendering Infrastructure (DRI) introduced in XFree86 4.0. If you say Y here, you need to select diff --git a/trunk/drivers/gpu/drm/Makefile b/trunk/drivers/gpu/drm/Makefile index c20da5bda355..a858532806ae 100644 --- a/trunk/drivers/gpu/drm/Makefile +++ b/trunk/drivers/gpu/drm/Makefile @@ -12,7 +12,7 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \ drm_platform.o drm_sysfs.o drm_hashtab.o drm_mm.o \ drm_crtc.o drm_modes.o drm_edid.o \ drm_info.o drm_debugfs.o drm_encoder_slave.o \ - drm_trace_points.o drm_global.o drm_prime.o + drm_trace_points.o drm_global.o drm-$(CONFIG_COMPAT) += drm_ioc32.o diff --git a/trunk/drivers/gpu/drm/drm_bufs.c b/trunk/drivers/gpu/drm/drm_bufs.c index 348b367debeb..30372f7b2d45 100644 --- a/trunk/drivers/gpu/drm/drm_bufs.c +++ b/trunk/drivers/gpu/drm/drm_bufs.c @@ -1510,8 +1510,8 @@ int drm_freebufs(struct drm_device *dev, void *data, * \param arg pointer to a drm_buf_map structure. * \return zero on success or a negative number on failure. * - * Maps the AGP, SG or PCI buffer region with vm_mmap(), and copies information - * about each buffer into user space. For PCI buffers, it calls vm_mmap() with + * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information + * about each buffer into user space. For PCI buffers, it calls do_mmap() with * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls * drm_mmap_dma(). */ @@ -1553,14 +1553,18 @@ int drm_mapbufs(struct drm_device *dev, void *data, retcode = -EINVAL; goto done; } - virtual = vm_mmap(file_priv->filp, 0, map->size, + down_write(¤t->mm->mmap_sem); + virtual = do_mmap(file_priv->filp, 0, map->size, PROT_READ | PROT_WRITE, MAP_SHARED, token); + up_write(¤t->mm->mmap_sem); } else { - virtual = vm_mmap(file_priv->filp, 0, dma->byte_count, + down_write(¤t->mm->mmap_sem); + virtual = do_mmap(file_priv->filp, 0, dma->byte_count, PROT_READ | PROT_WRITE, MAP_SHARED, 0); + up_write(¤t->mm->mmap_sem); } if (virtual > -1024UL) { /* Real error */ diff --git a/trunk/drivers/gpu/drm/drm_crtc.c b/trunk/drivers/gpu/drm/drm_crtc.c index c79870a75c2f..d3aaeb6ae236 100644 --- a/trunk/drivers/gpu/drm/drm_crtc.c +++ b/trunk/drivers/gpu/drm/drm_crtc.c @@ -3335,12 +3335,10 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, ret = crtc->funcs->page_flip(crtc, fb, e); if (ret) { - if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { - spin_lock_irqsave(&dev->event_lock, flags); - file_priv->event_space += sizeof e->event; - spin_unlock_irqrestore(&dev->event_lock, flags); - kfree(e); - } + spin_lock_irqsave(&dev->event_lock, flags); + file_priv->event_space += sizeof e->event; + spin_unlock_irqrestore(&dev->event_lock, flags); + kfree(e); } out: diff --git a/trunk/drivers/gpu/drm/drm_drv.c b/trunk/drivers/gpu/drm/drm_drv.c index 6116e3b75393..0b65fbc8a630 100644 --- a/trunk/drivers/gpu/drm/drm_drv.c +++ b/trunk/drivers/gpu/drm/drm_drv.c @@ -136,10 +136,6 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED), - - DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), diff --git a/trunk/drivers/gpu/drm/drm_fb_helper.c b/trunk/drivers/gpu/drm/drm_fb_helper.c index a0d6e894d97c..7740dd26f007 100644 --- a/trunk/drivers/gpu/drm/drm_fb_helper.c +++ b/trunk/drivers/gpu/drm/drm_fb_helper.c @@ -559,13 +559,9 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, return -EINVAL; /* Need to resize the fb object !!! */ - if (var->bits_per_pixel > fb->bits_per_pixel || - var->xres > fb->width || var->yres > fb->height || - var->xres_virtual > fb->width || var->yres_virtual > fb->height) { + if (var->bits_per_pixel > fb->bits_per_pixel || var->xres > fb->width || var->yres > fb->height) { DRM_DEBUG("fb userspace requested width/height/bpp is greater than current fb " - "request %dx%d-%d (virtual %dx%d) > %dx%d-%d\n", - var->xres, var->yres, var->bits_per_pixel, - var->xres_virtual, var->yres_virtual, + "object %dx%d-%d > %dx%d-%d\n", var->xres, var->yres, var->bits_per_pixel, fb->width, fb->height, fb->bits_per_pixel); return -EINVAL; } diff --git a/trunk/drivers/gpu/drm/drm_fops.c b/trunk/drivers/gpu/drm/drm_fops.c index 123de28f94ef..7348a3dab250 100644 --- a/trunk/drivers/gpu/drm/drm_fops.c +++ b/trunk/drivers/gpu/drm/drm_fops.c @@ -271,9 +271,6 @@ static int drm_open_helper(struct inode *inode, struct file *filp, if (dev->driver->driver_features & DRIVER_GEM) drm_gem_open(dev, priv); - if (drm_core_check_feature(dev, DRIVER_PRIME)) - drm_prime_init_file_private(&priv->prime); - if (dev->driver->open) { ret = dev->driver->open(dev, priv); if (ret < 0) @@ -507,12 +504,12 @@ int drm_release(struct inode *inode, struct file *filp) drm_events_release(file_priv); - if (dev->driver->driver_features & DRIVER_MODESET) - drm_fb_release(file_priv); - if (dev->driver->driver_features & DRIVER_GEM) drm_gem_release(dev, file_priv); + if (dev->driver->driver_features & DRIVER_MODESET) + drm_fb_release(file_priv); + mutex_lock(&dev->ctxlist_mutex); if (!list_empty(&dev->ctxlist)) { struct drm_ctx_list *pos, *n; @@ -574,10 +571,6 @@ int drm_release(struct inode *inode, struct file *filp) if (dev->driver->postclose) dev->driver->postclose(dev, file_priv); - - if (drm_core_check_feature(dev, DRIVER_PRIME)) - drm_prime_destroy_file_private(&file_priv->prime); - kfree(file_priv); /* ======================================================== diff --git a/trunk/drivers/gpu/drm/drm_gem.c b/trunk/drivers/gpu/drm/drm_gem.c index 83114b5e3cee..0ef358e53245 100644 --- a/trunk/drivers/gpu/drm/drm_gem.c +++ b/trunk/drivers/gpu/drm/drm_gem.c @@ -35,7 +35,6 @@ #include #include #include -#include #include "drmP.h" /** @file drm_gem.c @@ -233,10 +232,6 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle) idr_remove(&filp->object_idr, handle); spin_unlock(&filp->table_lock); - if (obj->import_attach) - drm_prime_remove_imported_buf_handle(&filp->prime, - obj->import_attach->dmabuf); - if (dev->driver->gem_close_object) dev->driver->gem_close_object(obj, filp); drm_gem_object_handle_unreference_unlocked(obj); @@ -532,10 +527,6 @@ drm_gem_object_release_handle(int id, void *ptr, void *data) struct drm_gem_object *obj = ptr; struct drm_device *dev = obj->dev; - if (obj->import_attach) - drm_prime_remove_imported_buf_handle(&file_priv->prime, - obj->import_attach->dmabuf); - if (dev->driver->gem_close_object) dev->driver->gem_close_object(obj, file_priv); diff --git a/trunk/drivers/gpu/drm/drm_prime.c b/trunk/drivers/gpu/drm/drm_prime.c deleted file mode 100644 index 1bdf2b54eaf6..000000000000 --- a/trunk/drivers/gpu/drm/drm_prime.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright © 2012 Red Hat - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Dave Airlie - * Rob Clark - * - */ - -#include -#include -#include "drmP.h" - -/* - * DMA-BUF/GEM Object references and lifetime overview: - * - * On the export the dma_buf holds a reference to the exporting GEM - * object. It takes this reference in handle_to_fd_ioctl, when it - * first calls .prime_export and stores the exporting GEM object in - * the dma_buf priv. This reference is released when the dma_buf - * object goes away in the driver .release function. - * - * On the import the importing GEM object holds a reference to the - * dma_buf (which in turn holds a ref to the exporting GEM object). - * It takes that reference in the fd_to_handle ioctl. - * It calls dma_buf_get, creates an attachment to it and stores the - * attachment in the GEM object. When this attachment is destroyed - * when the imported object is destroyed, we remove the attachment - * and drop the reference to the dma_buf. - * - * Thus the chain of references always flows in one direction - * (avoiding loops): importing_gem -> dmabuf -> exporting_gem - * - * Self-importing: if userspace is using PRIME as a replacement for flink - * then it will get a fd->handle request for a GEM object that it created. - * Drivers should detect this situation and return back the gem object - * from the dma-buf private. - */ - -struct drm_prime_member { - struct list_head entry; - struct dma_buf *dma_buf; - uint32_t handle; -}; - -int drm_gem_prime_handle_to_fd(struct drm_device *dev, - struct drm_file *file_priv, uint32_t handle, uint32_t flags, - int *prime_fd) -{ - struct drm_gem_object *obj; - void *buf; - - obj = drm_gem_object_lookup(dev, file_priv, handle); - if (!obj) - return -ENOENT; - - mutex_lock(&file_priv->prime.lock); - /* re-export the original imported object */ - if (obj->import_attach) { - get_dma_buf(obj->import_attach->dmabuf); - *prime_fd = dma_buf_fd(obj->import_attach->dmabuf, flags); - drm_gem_object_unreference_unlocked(obj); - mutex_unlock(&file_priv->prime.lock); - return 0; - } - - if (obj->export_dma_buf) { - get_dma_buf(obj->export_dma_buf); - *prime_fd = dma_buf_fd(obj->export_dma_buf, flags); - drm_gem_object_unreference_unlocked(obj); - } else { - buf = dev->driver->gem_prime_export(dev, obj, flags); - if (IS_ERR(buf)) { - /* normally the created dma-buf takes ownership of the ref, - * but if that fails then drop the ref - */ - drm_gem_object_unreference_unlocked(obj); - mutex_unlock(&file_priv->prime.lock); - return PTR_ERR(buf); - } - obj->export_dma_buf = buf; - *prime_fd = dma_buf_fd(buf, flags); - } - mutex_unlock(&file_priv->prime.lock); - return 0; -} -EXPORT_SYMBOL(drm_gem_prime_handle_to_fd); - -int drm_gem_prime_fd_to_handle(struct drm_device *dev, - struct drm_file *file_priv, int prime_fd, uint32_t *handle) -{ - struct dma_buf *dma_buf; - struct drm_gem_object *obj; - int ret; - - dma_buf = dma_buf_get(prime_fd); - if (IS_ERR(dma_buf)) - return PTR_ERR(dma_buf); - - mutex_lock(&file_priv->prime.lock); - - ret = drm_prime_lookup_imported_buf_handle(&file_priv->prime, - dma_buf, handle); - if (!ret) { - ret = 0; - goto out_put; - } - - /* never seen this one, need to import */ - obj = dev->driver->gem_prime_import(dev, dma_buf); - if (IS_ERR(obj)) { - ret = PTR_ERR(obj); - goto out_put; - } - - ret = drm_gem_handle_create(file_priv, obj, handle); - drm_gem_object_unreference_unlocked(obj); - if (ret) - goto out_put; - - ret = drm_prime_add_imported_buf_handle(&file_priv->prime, - dma_buf, *handle); - if (ret) - goto fail; - - mutex_unlock(&file_priv->prime.lock); - return 0; - -fail: - /* hmm, if driver attached, we are relying on the free-object path - * to detach.. which seems ok.. - */ - drm_gem_object_handle_unreference_unlocked(obj); -out_put: - dma_buf_put(dma_buf); - mutex_unlock(&file_priv->prime.lock); - return ret; -} -EXPORT_SYMBOL(drm_gem_prime_fd_to_handle); - -int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_prime_handle *args = data; - uint32_t flags; - - if (!drm_core_check_feature(dev, DRIVER_PRIME)) - return -EINVAL; - - if (!dev->driver->prime_handle_to_fd) - return -ENOSYS; - - /* check flags are valid */ - if (args->flags & ~DRM_CLOEXEC) - return -EINVAL; - - /* we only want to pass DRM_CLOEXEC which is == O_CLOEXEC */ - flags = args->flags & DRM_CLOEXEC; - - return dev->driver->prime_handle_to_fd(dev, file_priv, - args->handle, flags, &args->fd); -} - -int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - struct drm_prime_handle *args = data; - - if (!drm_core_check_feature(dev, DRIVER_PRIME)) - return -EINVAL; - - if (!dev->driver->prime_fd_to_handle) - return -ENOSYS; - - return dev->driver->prime_fd_to_handle(dev, file_priv, - args->fd, &args->handle); -} - -/* - * drm_prime_pages_to_sg - * - * this helper creates an sg table object from a set of pages - * the driver is responsible for mapping the pages into the - * importers address space - */ -struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages) -{ - struct sg_table *sg = NULL; - struct scatterlist *iter; - int i; - int ret; - - sg = kmalloc(sizeof(struct sg_table), GFP_KERNEL); - if (!sg) - goto out; - - ret = sg_alloc_table(sg, nr_pages, GFP_KERNEL); - if (ret) - goto out; - - for_each_sg(sg->sgl, iter, nr_pages, i) - sg_set_page(iter, pages[i], PAGE_SIZE, 0); - - return sg; -out: - kfree(sg); - return NULL; -} -EXPORT_SYMBOL(drm_prime_pages_to_sg); - -/* helper function to cleanup a GEM/prime object */ -void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg) -{ - struct dma_buf_attachment *attach; - struct dma_buf *dma_buf; - attach = obj->import_attach; - if (sg) - dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL); - dma_buf = attach->dmabuf; - dma_buf_detach(attach->dmabuf, attach); - /* remove the reference */ - dma_buf_put(dma_buf); -} -EXPORT_SYMBOL(drm_prime_gem_destroy); - -void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv) -{ - INIT_LIST_HEAD(&prime_fpriv->head); - mutex_init(&prime_fpriv->lock); -} -EXPORT_SYMBOL(drm_prime_init_file_private); - -void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv) -{ - struct drm_prime_member *member, *safe; - list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) { - list_del(&member->entry); - kfree(member); - } -} -EXPORT_SYMBOL(drm_prime_destroy_file_private); - -int drm_prime_add_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle) -{ - struct drm_prime_member *member; - - member = kmalloc(sizeof(*member), GFP_KERNEL); - if (!member) - return -ENOMEM; - - member->dma_buf = dma_buf; - member->handle = handle; - list_add(&member->entry, &prime_fpriv->head); - return 0; -} -EXPORT_SYMBOL(drm_prime_add_imported_buf_handle); - -int drm_prime_lookup_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t *handle) -{ - struct drm_prime_member *member; - - list_for_each_entry(member, &prime_fpriv->head, entry) { - if (member->dma_buf == dma_buf) { - *handle = member->handle; - return 0; - } - } - return -ENOENT; -} -EXPORT_SYMBOL(drm_prime_lookup_imported_buf_handle); - -void drm_prime_remove_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf) -{ - struct drm_prime_member *member, *safe; - - mutex_lock(&prime_fpriv->lock); - list_for_each_entry_safe(member, safe, &prime_fpriv->head, entry) { - if (member->dma_buf == dma_buf) { - list_del(&member->entry); - kfree(member); - } - } - mutex_unlock(&prime_fpriv->lock); -} -EXPORT_SYMBOL(drm_prime_remove_imported_buf_handle); diff --git a/trunk/drivers/gpu/drm/drm_usb.c b/trunk/drivers/gpu/drm/drm_usb.c index 37c9a523dd1c..c8c83dad2ce1 100644 --- a/trunk/drivers/gpu/drm/drm_usb.c +++ b/trunk/drivers/gpu/drm/drm_usb.c @@ -1,6 +1,6 @@ #include "drmP.h" #include -#include +#include int drm_get_usb_dev(struct usb_interface *interface, const struct usb_device_id *id, @@ -114,7 +114,3 @@ void drm_usb_exit(struct drm_driver *driver, usb_deregister(udriver); } EXPORT_SYMBOL(drm_usb_exit); - -MODULE_AUTHOR("David Airlie"); -MODULE_DESCRIPTION("USB DRM support"); -MODULE_LICENSE("GPL and additional rights"); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_buf.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_buf.c index de8d2090bce3..4a3a5f72ed4a 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_buf.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_buf.c @@ -34,14 +34,14 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, unsigned int flags, struct exynos_drm_gem_buf *buf) { - dma_addr_t start_addr; + dma_addr_t start_addr, end_addr; unsigned int npages, page_size, i = 0; struct scatterlist *sgl; int ret = 0; DRM_DEBUG_KMS("%s\n", __FILE__); - if (IS_NONCONTIG_BUFFER(flags)) { + if (flags & EXYNOS_BO_NONCONTIG) { DRM_DEBUG_KMS("not support allocation type.\n"); return -EINVAL; } @@ -52,13 +52,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, } if (buf->size >= SZ_1M) { - npages = buf->size >> SECTION_SHIFT; + npages = (buf->size >> SECTION_SHIFT) + 1; page_size = SECTION_SIZE; } else if (buf->size >= SZ_64K) { - npages = buf->size >> 16; + npages = (buf->size >> 16) + 1; page_size = SZ_64K; } else { - npages = buf->size >> PAGE_SHIFT; + npages = (buf->size >> PAGE_SHIFT) + 1; page_size = PAGE_SIZE; } @@ -76,13 +76,26 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, return -ENOMEM; } - buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size, - &buf->dma_addr, GFP_KERNEL); - if (!buf->kvaddr) { - DRM_ERROR("failed to allocate buffer.\n"); - ret = -ENOMEM; - goto err1; - } + buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size, + &buf->dma_addr, GFP_KERNEL); + if (!buf->kvaddr) { + DRM_ERROR("failed to allocate buffer.\n"); + ret = -ENOMEM; + goto err1; + } + + start_addr = buf->dma_addr; + end_addr = buf->dma_addr + buf->size; + + buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL); + if (!buf->pages) { + DRM_ERROR("failed to allocate pages.\n"); + ret = -ENOMEM; + goto err2; + } + + start_addr = buf->dma_addr; + end_addr = buf->dma_addr + buf->size; buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL); if (!buf->pages) { @@ -92,17 +105,23 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, } sgl = buf->sgt->sgl; - start_addr = buf->dma_addr; while (i < npages) { buf->pages[i] = phys_to_page(start_addr); sg_set_page(sgl, buf->pages[i], page_size, 0); sg_dma_address(sgl) = start_addr; start_addr += page_size; + if (end_addr - start_addr < page_size) + break; sgl = sg_next(sgl); i++; } + buf->pages[i] = phys_to_page(start_addr); + + sgl = sg_next(sgl); + sg_set_page(sgl, buf->pages[i+1], end_addr - start_addr, 0); + DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", (unsigned long)buf->kvaddr, (unsigned long)buf->dma_addr, @@ -131,7 +150,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev, * non-continuous memory would be released by exynos * gem framework. */ - if (IS_NONCONTIG_BUFFER(flags)) { + if (flags & EXYNOS_BO_NONCONTIG) { DRM_DEBUG_KMS("not support allocation type.\n"); return; } diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_core.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_core.c index eaf630dc5dba..411832e8e17a 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_core.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_core.c @@ -54,18 +54,16 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev, * * P.S. note that this driver is considered for modularization. */ - ret = subdrv->probe(dev, subdrv->dev); + ret = subdrv->probe(dev, subdrv->manager.dev); if (ret) return ret; } - if (!subdrv->manager) + if (subdrv->is_local) return 0; - subdrv->manager->dev = subdrv->dev; - /* create and initialize a encoder for this sub driver. */ - encoder = exynos_drm_encoder_create(dev, subdrv->manager, + encoder = exynos_drm_encoder_create(dev, &subdrv->manager, (1 << MAX_CRTC) - 1); if (!encoder) { DRM_ERROR("failed to create encoder\n"); @@ -188,7 +186,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file) list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { if (subdrv->open) { - ret = subdrv->open(dev, subdrv->dev, file); + ret = subdrv->open(dev, subdrv->manager.dev, file); if (ret) goto err; } @@ -199,7 +197,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file) err: list_for_each_entry_reverse(subdrv, &subdrv->list, list) { if (subdrv->close) - subdrv->close(dev, subdrv->dev, file); + subdrv->close(dev, subdrv->manager.dev, file); } return ret; } @@ -211,7 +209,7 @@ void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file) list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) { if (subdrv->close) - subdrv->close(dev, subdrv->dev, file); + subdrv->close(dev, subdrv->manager.dev, file); } } EXPORT_SYMBOL_GPL(exynos_drm_subdrv_close); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h index 1d814175cd49..fbd0a232c93d 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -225,25 +225,24 @@ struct exynos_drm_private { * Exynos drm sub driver structure. * * @list: sub driver has its own list object to register to exynos drm driver. - * @dev: pointer to device object for subdrv device driver. * @drm_dev: pointer to drm_device and this pointer would be set * when sub driver calls exynos_drm_subdrv_register(). - * @manager: subdrv has its own manager to control a hardware appropriately - * and we can access a hardware drawing on this manager. + * @is_local: appear encoder and connector disrelated device. * @probe: this callback would be called by exynos drm driver after * subdrv is registered to it. * @remove: this callback is used to release resources created * by probe callback. * @open: this would be called with drm device file open. * @close: this would be called with drm device file close. + * @manager: subdrv has its own manager to control a hardware appropriately + * and we can access a hardware drawing on this manager. * @encoder: encoder object owned by this sub driver. * @connector: connector object owned by this sub driver. */ struct exynos_drm_subdrv { struct list_head list; - struct device *dev; struct drm_device *drm_dev; - struct exynos_drm_manager *manager; + bool is_local; int (*probe)(struct drm_device *drm_dev, struct device *dev); void (*remove)(struct drm_device *dev); @@ -252,6 +251,7 @@ struct exynos_drm_subdrv { void (*close)(struct drm_device *drm_dev, struct device *dev, struct drm_file *file); + struct exynos_drm_manager manager; struct drm_encoder *encoder; struct drm_connector *connector; }; diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 29fdbfeb43cb..ecb6db229700 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -172,7 +172,7 @@ static void fimd_dpms(struct device *subdrv_dev, int mode) static void fimd_apply(struct device *subdrv_dev) { struct fimd_context *ctx = get_fimd_context(subdrv_dev); - struct exynos_drm_manager *mgr = ctx->subdrv.manager; + struct exynos_drm_manager *mgr = &ctx->subdrv.manager; struct exynos_drm_manager_ops *mgr_ops = mgr->ops; struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; struct fimd_win_data *win_data; @@ -577,13 +577,6 @@ static struct exynos_drm_overlay_ops fimd_overlay_ops = { .disable = fimd_win_disable, }; -static struct exynos_drm_manager fimd_manager = { - .pipe = -1, - .ops = &fimd_manager_ops, - .overlay_ops = &fimd_overlay_ops, - .display_ops = &fimd_display_ops, -}; - static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc) { struct exynos_drm_private *dev_priv = drm_dev->dev_private; @@ -635,7 +628,7 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id) struct fimd_context *ctx = (struct fimd_context *)dev_id; struct exynos_drm_subdrv *subdrv = &ctx->subdrv; struct drm_device *drm_dev = subdrv->drm_dev; - struct exynos_drm_manager *manager = subdrv->manager; + struct exynos_drm_manager *manager = &subdrv->manager; u32 val; val = readl(ctx->regs + VIDINTCON1); @@ -751,7 +744,7 @@ static void fimd_clear_win(struct fimd_context *ctx, int win) static int fimd_power_on(struct fimd_context *ctx, bool enable) { struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct device *dev = subdrv->dev; + struct device *dev = subdrv->manager.dev; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -874,10 +867,13 @@ static int __devinit fimd_probe(struct platform_device *pdev) subdrv = &ctx->subdrv; - subdrv->dev = dev; - subdrv->manager = &fimd_manager; subdrv->probe = fimd_subdrv_probe; subdrv->remove = fimd_subdrv_remove; + subdrv->manager.pipe = -1; + subdrv->manager.ops = &fimd_manager_ops; + subdrv->manager.overlay_ops = &fimd_overlay_ops; + subdrv->manager.display_ops = &fimd_display_ops; + subdrv->manager.dev = dev; mutex_init(&ctx->lock); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c index 1dffa8359f88..fa1aa94a3d8e 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -56,28 +56,9 @@ static unsigned int convert_to_vm_err_msg(int msg) return out_msg; } -static int check_gem_flags(unsigned int flags) +static unsigned int mask_gem_flags(unsigned int flags) { - if (flags & ~(EXYNOS_BO_MASK)) { - DRM_ERROR("invalid flags.\n"); - return -EINVAL; - } - - return 0; -} - -static unsigned long roundup_gem_size(unsigned long size, unsigned int flags) -{ - if (!IS_NONCONTIG_BUFFER(flags)) { - if (size >= SZ_1M) - return roundup(size, SECTION_SIZE); - else if (size >= SZ_64K) - return roundup(size, SZ_64K); - else - goto out; - } -out: - return roundup(size, PAGE_SIZE); + return flags &= EXYNOS_BO_NONCONTIG; } static struct page **exynos_gem_get_pages(struct drm_gem_object *obj, @@ -149,12 +130,22 @@ static int exynos_drm_gem_map_pages(struct drm_gem_object *obj, unsigned long pfn; if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { + unsigned long usize = buf->size; + if (!buf->pages) return -EINTR; - pfn = page_to_pfn(buf->pages[page_offset++]); - } else - pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset; + while (usize > 0) { + pfn = page_to_pfn(buf->pages[page_offset++]); + vm_insert_mixed(vma, f_vaddr, pfn); + f_vaddr += PAGE_SIZE; + usize -= PAGE_SIZE; + } + + return 0; + } + + pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset; return vm_insert_mixed(vma, f_vaddr, pfn); } @@ -328,17 +319,10 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, struct exynos_drm_gem_buf *buf; int ret; - if (!size) { - DRM_ERROR("invalid size.\n"); - return ERR_PTR(-EINVAL); - } - - size = roundup_gem_size(size, flags); - DRM_DEBUG_KMS("%s\n", __FILE__); + size = roundup(size, PAGE_SIZE); + DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size); - ret = check_gem_flags(flags); - if (ret) - return ERR_PTR(ret); + flags = mask_gem_flags(flags); buf = exynos_drm_init_buf(dev, size); if (!buf) @@ -347,7 +331,7 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, exynos_gem_obj = exynos_drm_gem_init(dev, size); if (!exynos_gem_obj) { ret = -ENOMEM; - goto err_fini_buf; + goto err; } exynos_gem_obj->buffer = buf; @@ -363,19 +347,18 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base); if (ret < 0) { drm_gem_object_release(&exynos_gem_obj->base); - goto err_fini_buf; + goto err; } } else { ret = exynos_drm_alloc_buf(dev, buf, flags); if (ret < 0) { drm_gem_object_release(&exynos_gem_obj->base); - goto err_fini_buf; + goto err; } } return exynos_gem_obj; - -err_fini_buf: +err: exynos_drm_fini_buf(dev, buf); return ERR_PTR(ret); } @@ -514,8 +497,6 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp, if (!buffer->pages) return -EINVAL; - vma->vm_flags |= VM_MIXEDMAP; - do { ret = vm_insert_page(vma, uaddr, buffer->pages[i++]); if (ret) { @@ -573,8 +554,10 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, obj->filp->f_op = &exynos_drm_gem_fops; obj->filp->private_data = obj; - addr = vm_mmap(obj->filp, 0, args->size, + down_write(¤t->mm->mmap_sem); + addr = do_mmap(obj->filp, 0, args->size, PROT_READ | PROT_WRITE, MAP_SHARED, 0); + up_write(¤t->mm->mmap_sem); drm_gem_object_unreference_unlocked(obj); @@ -702,6 +685,7 @@ int exynos_drm_gem_dumb_destroy(struct drm_file *file_priv, int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct drm_gem_object *obj = vma->vm_private_data; + struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); struct drm_device *dev = obj->dev; unsigned long f_vaddr; pgoff_t page_offset; @@ -713,10 +697,21 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) mutex_lock(&dev->struct_mutex); + /* + * allocate all pages as desired size if user wants to allocate + * physically non-continuous memory. + */ + if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { + ret = exynos_drm_gem_get_pages(obj); + if (ret < 0) + goto err; + } + ret = exynos_drm_gem_map_pages(obj, vma, f_vaddr, page_offset); if (ret < 0) DRM_ERROR("failed to map pages.\n"); +err: mutex_unlock(&dev->struct_mutex); return convert_to_vm_err_msg(ret); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h index 4ed842039505..e40fbad8b705 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.h @@ -29,8 +29,6 @@ #define to_exynos_gem_obj(x) container_of(x,\ struct exynos_drm_gem_obj, base) -#define IS_NONCONTIG_BUFFER(f) (f & EXYNOS_BO_NONCONTIG) - /* * exynos drm gem buffer structure. * diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index 3424463676e0..14eb26b0ba1c 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.c @@ -30,8 +30,9 @@ struct drm_hdmi_context, subdrv); /* these callback points shoud be set by specific drivers. */ -static struct exynos_hdmi_ops *hdmi_ops; -static struct exynos_mixer_ops *mixer_ops; +static struct exynos_hdmi_display_ops *hdmi_display_ops; +static struct exynos_hdmi_manager_ops *hdmi_manager_ops; +static struct exynos_hdmi_overlay_ops *hdmi_overlay_ops; struct drm_hdmi_context { struct exynos_drm_subdrv subdrv; @@ -39,20 +40,31 @@ struct drm_hdmi_context { struct exynos_drm_hdmi_context *mixer_ctx; }; -void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops) +void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops + *display_ops) { DRM_DEBUG_KMS("%s\n", __FILE__); - if (ops) - hdmi_ops = ops; + if (display_ops) + hdmi_display_ops = display_ops; } -void exynos_mixer_ops_register(struct exynos_mixer_ops *ops) +void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops + *manager_ops) { DRM_DEBUG_KMS("%s\n", __FILE__); - if (ops) - mixer_ops = ops; + if (manager_ops) + hdmi_manager_ops = manager_ops; +} + +void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops + *overlay_ops) +{ + DRM_DEBUG_KMS("%s\n", __FILE__); + + if (overlay_ops) + hdmi_overlay_ops = overlay_ops; } static bool drm_hdmi_is_connected(struct device *dev) @@ -61,8 +73,8 @@ static bool drm_hdmi_is_connected(struct device *dev) DRM_DEBUG_KMS("%s\n", __FILE__); - if (hdmi_ops && hdmi_ops->is_connected) - return hdmi_ops->is_connected(ctx->hdmi_ctx->ctx); + if (hdmi_display_ops && hdmi_display_ops->is_connected) + return hdmi_display_ops->is_connected(ctx->hdmi_ctx->ctx); return false; } @@ -74,9 +86,9 @@ static int drm_hdmi_get_edid(struct device *dev, DRM_DEBUG_KMS("%s\n", __FILE__); - if (hdmi_ops && hdmi_ops->get_edid) - return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector, edid, - len); + if (hdmi_display_ops && hdmi_display_ops->get_edid) + return hdmi_display_ops->get_edid(ctx->hdmi_ctx->ctx, + connector, edid, len); return 0; } @@ -87,8 +99,9 @@ static int drm_hdmi_check_timing(struct device *dev, void *timing) DRM_DEBUG_KMS("%s\n", __FILE__); - if (hdmi_ops && hdmi_ops->check_timing) - return hdmi_ops->check_timing(ctx->hdmi_ctx->ctx, timing); + if (hdmi_display_ops && hdmi_display_ops->check_timing) + return hdmi_display_ops->check_timing(ctx->hdmi_ctx->ctx, + timing); return 0; } @@ -99,8 +112,8 @@ static int drm_hdmi_power_on(struct device *dev, int mode) DRM_DEBUG_KMS("%s\n", __FILE__); - if (hdmi_ops && hdmi_ops->power_on) - return hdmi_ops->power_on(ctx->hdmi_ctx->ctx, mode); + if (hdmi_display_ops && hdmi_display_ops->power_on) + return hdmi_display_ops->power_on(ctx->hdmi_ctx->ctx, mode); return 0; } @@ -117,13 +130,13 @@ static int drm_hdmi_enable_vblank(struct device *subdrv_dev) { struct drm_hdmi_context *ctx = to_context(subdrv_dev); struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct exynos_drm_manager *manager = subdrv->manager; + struct exynos_drm_manager *manager = &subdrv->manager; DRM_DEBUG_KMS("%s\n", __FILE__); - if (mixer_ops && mixer_ops->enable_vblank) - return mixer_ops->enable_vblank(ctx->mixer_ctx->ctx, - manager->pipe); + if (hdmi_overlay_ops && hdmi_overlay_ops->enable_vblank) + return hdmi_overlay_ops->enable_vblank(ctx->mixer_ctx->ctx, + manager->pipe); return 0; } @@ -134,8 +147,8 @@ static void drm_hdmi_disable_vblank(struct device *subdrv_dev) DRM_DEBUG_KMS("%s\n", __FILE__); - if (mixer_ops && mixer_ops->disable_vblank) - return mixer_ops->disable_vblank(ctx->mixer_ctx->ctx); + if (hdmi_overlay_ops && hdmi_overlay_ops->disable_vblank) + return hdmi_overlay_ops->disable_vblank(ctx->mixer_ctx->ctx); } static void drm_hdmi_mode_fixup(struct device *subdrv_dev, @@ -147,9 +160,9 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev, DRM_DEBUG_KMS("%s\n", __FILE__); - if (hdmi_ops && hdmi_ops->mode_fixup) - hdmi_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, mode, - adjusted_mode); + if (hdmi_manager_ops && hdmi_manager_ops->mode_fixup) + hdmi_manager_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, + mode, adjusted_mode); } static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode) @@ -158,8 +171,8 @@ static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode) DRM_DEBUG_KMS("%s\n", __FILE__); - if (hdmi_ops && hdmi_ops->mode_set) - hdmi_ops->mode_set(ctx->hdmi_ctx->ctx, mode); + if (hdmi_manager_ops && hdmi_manager_ops->mode_set) + hdmi_manager_ops->mode_set(ctx->hdmi_ctx->ctx, mode); } static void drm_hdmi_get_max_resol(struct device *subdrv_dev, @@ -169,8 +182,9 @@ static void drm_hdmi_get_max_resol(struct device *subdrv_dev, DRM_DEBUG_KMS("%s\n", __FILE__); - if (hdmi_ops && hdmi_ops->get_max_resol) - hdmi_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, height); + if (hdmi_manager_ops && hdmi_manager_ops->get_max_resol) + hdmi_manager_ops->get_max_resol(ctx->hdmi_ctx->ctx, width, + height); } static void drm_hdmi_commit(struct device *subdrv_dev) @@ -179,8 +193,8 @@ static void drm_hdmi_commit(struct device *subdrv_dev) DRM_DEBUG_KMS("%s\n", __FILE__); - if (hdmi_ops && hdmi_ops->commit) - hdmi_ops->commit(ctx->hdmi_ctx->ctx); + if (hdmi_manager_ops && hdmi_manager_ops->commit) + hdmi_manager_ops->commit(ctx->hdmi_ctx->ctx); } static void drm_hdmi_dpms(struct device *subdrv_dev, int mode) @@ -195,8 +209,8 @@ static void drm_hdmi_dpms(struct device *subdrv_dev, int mode) case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: - if (hdmi_ops && hdmi_ops->disable) - hdmi_ops->disable(ctx->hdmi_ctx->ctx); + if (hdmi_manager_ops && hdmi_manager_ops->disable) + hdmi_manager_ops->disable(ctx->hdmi_ctx->ctx); break; default: DRM_DEBUG_KMS("unkown dps mode: %d\n", mode); @@ -221,8 +235,8 @@ static void drm_mixer_mode_set(struct device *subdrv_dev, DRM_DEBUG_KMS("%s\n", __FILE__); - if (mixer_ops && mixer_ops->win_mode_set) - mixer_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay); + if (hdmi_overlay_ops && hdmi_overlay_ops->win_mode_set) + hdmi_overlay_ops->win_mode_set(ctx->mixer_ctx->ctx, overlay); } static void drm_mixer_commit(struct device *subdrv_dev, int zpos) @@ -231,8 +245,8 @@ static void drm_mixer_commit(struct device *subdrv_dev, int zpos) DRM_DEBUG_KMS("%s\n", __FILE__); - if (mixer_ops && mixer_ops->win_commit) - mixer_ops->win_commit(ctx->mixer_ctx->ctx, zpos); + if (hdmi_overlay_ops && hdmi_overlay_ops->win_commit) + hdmi_overlay_ops->win_commit(ctx->mixer_ctx->ctx, zpos); } static void drm_mixer_disable(struct device *subdrv_dev, int zpos) @@ -241,8 +255,8 @@ static void drm_mixer_disable(struct device *subdrv_dev, int zpos) DRM_DEBUG_KMS("%s\n", __FILE__); - if (mixer_ops && mixer_ops->win_disable) - mixer_ops->win_disable(ctx->mixer_ctx->ctx, zpos); + if (hdmi_overlay_ops && hdmi_overlay_ops->win_disable) + hdmi_overlay_ops->win_disable(ctx->mixer_ctx->ctx, zpos); } static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = { @@ -251,12 +265,6 @@ static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = { .disable = drm_mixer_disable, }; -static struct exynos_drm_manager hdmi_manager = { - .pipe = -1, - .ops = &drm_hdmi_manager_ops, - .overlay_ops = &drm_hdmi_overlay_ops, - .display_ops = &drm_hdmi_display_ops, -}; static int hdmi_subdrv_probe(struct drm_device *drm_dev, struct device *dev) @@ -324,9 +332,12 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev) subdrv = &ctx->subdrv; - subdrv->dev = dev; - subdrv->manager = &hdmi_manager; subdrv->probe = hdmi_subdrv_probe; + subdrv->manager.pipe = -1; + subdrv->manager.ops = &drm_hdmi_manager_ops; + subdrv->manager.overlay_ops = &drm_hdmi_overlay_ops; + subdrv->manager.display_ops = &drm_hdmi_display_ops; + subdrv->manager.dev = dev; platform_set_drvdata(pdev, subdrv); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.h index f3ae192c8dcf..44497cfb6c74 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.h +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_hdmi.h @@ -38,15 +38,15 @@ struct exynos_drm_hdmi_context { void *ctx; }; -struct exynos_hdmi_ops { - /* display */ +struct exynos_hdmi_display_ops { bool (*is_connected)(void *ctx); int (*get_edid)(void *ctx, struct drm_connector *connector, u8 *edid, int len); int (*check_timing)(void *ctx, void *timing); int (*power_on)(void *ctx, int mode); +}; - /* manager */ +struct exynos_hdmi_manager_ops { void (*mode_fixup)(void *ctx, struct drm_connector *connector, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); @@ -57,17 +57,22 @@ struct exynos_hdmi_ops { void (*disable)(void *ctx); }; -struct exynos_mixer_ops { - /* manager */ +struct exynos_hdmi_overlay_ops { int (*enable_vblank)(void *ctx, int pipe); void (*disable_vblank)(void *ctx); - - /* overlay */ void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay); void (*win_commit)(void *ctx, int zpos); void (*win_disable)(void *ctx, int zpos); }; -void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops); -void exynos_mixer_ops_register(struct exynos_mixer_ops *ops); +extern struct platform_driver hdmi_driver; +extern struct platform_driver mixer_driver; + +void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops + *display_ops); +void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops + *manager_ops); +void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops + *overlay_ops); + #endif diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c index f92fe4c6174a..c277a3a445f5 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -24,10 +24,6 @@ struct exynos_plane { static const uint32_t formats[] = { DRM_FORMAT_XRGB8888, - DRM_FORMAT_ARGB8888, - DRM_FORMAT_NV12, - DRM_FORMAT_NV12M, - DRM_FORMAT_NV12MT, }; static int diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 7b9c153dceb6..8e1339f9fe1f 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -199,7 +199,7 @@ static void vidi_dpms(struct device *subdrv_dev, int mode) static void vidi_apply(struct device *subdrv_dev) { struct vidi_context *ctx = get_vidi_context(subdrv_dev); - struct exynos_drm_manager *mgr = ctx->subdrv.manager; + struct exynos_drm_manager *mgr = &ctx->subdrv.manager; struct exynos_drm_manager_ops *mgr_ops = mgr->ops; struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; struct vidi_win_data *win_data; @@ -374,13 +374,6 @@ static struct exynos_drm_overlay_ops vidi_overlay_ops = { .disable = vidi_win_disable, }; -static struct exynos_drm_manager vidi_manager = { - .pipe = -1, - .ops = &vidi_manager_ops, - .overlay_ops = &vidi_overlay_ops, - .display_ops = &vidi_display_ops, -}; - static void vidi_finish_pageflip(struct drm_device *drm_dev, int crtc) { struct exynos_drm_private *dev_priv = drm_dev->dev_private; @@ -432,7 +425,7 @@ static void vidi_fake_vblank_handler(struct work_struct *work) struct vidi_context *ctx = container_of(work, struct vidi_context, work); struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct exynos_drm_manager *manager = subdrv->manager; + struct exynos_drm_manager *manager = &subdrv->manager; if (manager->pipe < 0) return; @@ -478,7 +471,7 @@ static void vidi_subdrv_remove(struct drm_device *drm_dev) static int vidi_power_on(struct vidi_context *ctx, bool enable) { struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct device *dev = subdrv->dev; + struct device *dev = subdrv->manager.dev; DRM_DEBUG_KMS("%s\n", __FILE__); @@ -618,10 +611,13 @@ static int __devinit vidi_probe(struct platform_device *pdev) ctx->raw_edid = (struct edid *)fake_edid_info; subdrv = &ctx->subdrv; - subdrv->dev = dev; - subdrv->manager = &vidi_manager; subdrv->probe = vidi_subdrv_probe; subdrv->remove = vidi_subdrv_remove; + subdrv->manager.pipe = -1; + subdrv->manager.ops = &vidi_manager_ops; + subdrv->manager.overlay_ops = &vidi_overlay_ops; + subdrv->manager.display_ops = &vidi_display_ops; + subdrv->manager.dev = dev; mutex_init(&ctx->lock); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c b/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c index b00353876458..575a8cbd3533 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -40,6 +40,7 @@ #include "exynos_hdmi.h" +#define HDMI_OVERLAY_NUMBER 3 #define MAX_WIDTH 1920 #define MAX_HEIGHT 1080 #define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev)) @@ -1193,7 +1194,7 @@ static int hdmi_conf_index(struct hdmi_context *hdata, static bool hdmi_is_connected(void *ctx) { - struct hdmi_context *hdata = ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx; u32 val = hdmi_reg_read(hdata, HDMI_HPD_STATUS); if (val) @@ -1206,7 +1207,7 @@ static int hdmi_get_edid(void *ctx, struct drm_connector *connector, u8 *edid, int len) { struct edid *raw_edid; - struct hdmi_context *hdata = ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx; DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); @@ -1274,7 +1275,7 @@ static int hdmi_v14_check_timing(struct fb_videomode *check_timing) static int hdmi_check_timing(void *ctx, void *timing) { - struct hdmi_context *hdata = ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx; struct fb_videomode *check_timing = timing; DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); @@ -1311,6 +1312,13 @@ static int hdmi_display_power_on(void *ctx, int mode) return 0; } +static struct exynos_hdmi_display_ops display_ops = { + .is_connected = hdmi_is_connected, + .get_edid = hdmi_get_edid, + .check_timing = hdmi_check_timing, + .power_on = hdmi_display_power_on, +}; + static void hdmi_set_acr(u32 freq, u8 *acr) { u32 n, cts; @@ -1906,7 +1914,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector, struct drm_display_mode *adjusted_mode) { struct drm_display_mode *m; - struct hdmi_context *hdata = ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx; int index; DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); @@ -1943,7 +1951,7 @@ static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector, static void hdmi_mode_set(void *ctx, void *mode) { - struct hdmi_context *hdata = ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx; int conf_idx; DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); @@ -1966,7 +1974,7 @@ static void hdmi_get_max_resol(void *ctx, unsigned int *width, static void hdmi_commit(void *ctx) { - struct hdmi_context *hdata = ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx; DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); @@ -1977,7 +1985,7 @@ static void hdmi_commit(void *ctx) static void hdmi_disable(void *ctx) { - struct hdmi_context *hdata = ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx; DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); @@ -1988,14 +1996,7 @@ static void hdmi_disable(void *ctx) } } -static struct exynos_hdmi_ops hdmi_ops = { - /* display */ - .is_connected = hdmi_is_connected, - .get_edid = hdmi_get_edid, - .check_timing = hdmi_check_timing, - .power_on = hdmi_display_power_on, - - /* manager */ +static struct exynos_hdmi_manager_ops manager_ops = { .mode_fixup = hdmi_mode_fixup, .mode_set = hdmi_mode_set, .get_max_resol = hdmi_get_max_resol, @@ -2019,7 +2020,7 @@ static void hdmi_hotplug_func(struct work_struct *work) static irqreturn_t hdmi_irq_handler(int irq, void *arg) { struct exynos_drm_hdmi_context *ctx = arg; - struct hdmi_context *hdata = ctx->ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx; u32 intc_flag; intc_flag = hdmi_reg_read(hdata, HDMI_INTC_FLAG); @@ -2172,7 +2173,7 @@ static int hdmi_runtime_suspend(struct device *dev) DRM_DEBUG_KMS("%s\n", __func__); - hdmi_resource_poweroff(ctx->ctx); + hdmi_resource_poweroff((struct hdmi_context *)ctx->ctx); return 0; } @@ -2183,7 +2184,7 @@ static int hdmi_runtime_resume(struct device *dev) DRM_DEBUG_KMS("%s\n", __func__); - hdmi_resource_poweron(ctx->ctx); + hdmi_resource_poweron((struct hdmi_context *)ctx->ctx); return 0; } @@ -2321,7 +2322,8 @@ static int __devinit hdmi_probe(struct platform_device *pdev) hdata->irq = res->start; /* register specific callbacks to common hdmi. */ - exynos_hdmi_ops_register(&hdmi_ops); + exynos_drm_display_ops_register(&display_ops); + exynos_drm_manager_ops_register(&manager_ops); hdmi_resource_poweron(hdata); @@ -2349,7 +2351,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev) static int __devexit hdmi_remove(struct platform_device *pdev) { struct exynos_drm_hdmi_context *ctx = platform_get_drvdata(pdev); - struct hdmi_context *hdata = ctx->ctx; + struct hdmi_context *hdata = (struct hdmi_context *)ctx->ctx; DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); diff --git a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c index e15438c01129..4d5f41e19527 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_mixer.c @@ -37,8 +37,7 @@ #include "exynos_drm_drv.h" #include "exynos_drm_hdmi.h" -#define MIXER_WIN_NR 3 -#define MIXER_DEFAULT_WIN 0 +#define HDMI_OVERLAY_NUMBER 3 #define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev)) @@ -76,12 +75,16 @@ struct mixer_resources { }; struct mixer_context { + struct fb_videomode *default_timing; + unsigned int default_win; + unsigned int default_bpp; unsigned int irq; int pipe; bool interlace; + bool vp_enabled; struct mixer_resources mixer_res; - struct hdmi_win_data win_data[MIXER_WIN_NR]; + struct hdmi_win_data win_data[HDMI_OVERLAY_NUMBER]; }; static const u8 filter_y_horiz_tap8[] = { @@ -640,9 +643,9 @@ static void mixer_win_mode_set(void *ctx, win = overlay->zpos; if (win == DEFAULT_ZPOS) - win = MIXER_DEFAULT_WIN; + win = mixer_ctx->default_win; - if (win < 0 || win > MIXER_WIN_NR) { + if (win < 0 || win > HDMI_OVERLAY_NUMBER) { DRM_ERROR("overlay plane[%d] is wrong\n", win); return; } @@ -680,9 +683,9 @@ static void mixer_win_commit(void *ctx, int zpos) DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); if (win == DEFAULT_ZPOS) - win = MIXER_DEFAULT_WIN; + win = mixer_ctx->default_win; - if (win < 0 || win > MIXER_WIN_NR) { + if (win < 0 || win > HDMI_OVERLAY_NUMBER) { DRM_ERROR("overlay plane[%d] is wrong\n", win); return; } @@ -703,9 +706,9 @@ static void mixer_win_disable(void *ctx, int zpos) DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win); if (win == DEFAULT_ZPOS) - win = MIXER_DEFAULT_WIN; + win = mixer_ctx->default_win; - if (win < 0 || win > MIXER_WIN_NR) { + if (win < 0 || win > HDMI_OVERLAY_NUMBER) { DRM_ERROR("overlay plane[%d] is wrong\n", win); return; } @@ -719,12 +722,9 @@ static void mixer_win_disable(void *ctx, int zpos) spin_unlock_irqrestore(&res->reg_slock, flags); } -static struct exynos_mixer_ops mixer_ops = { - /* manager */ +static struct exynos_hdmi_overlay_ops overlay_ops = { .enable_vblank = mixer_enable_vblank, .disable_vblank = mixer_disable_vblank, - - /* overlay */ .win_mode_set = mixer_win_mode_set, .win_commit = mixer_win_commit, .win_disable = mixer_win_disable, @@ -771,7 +771,8 @@ static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc) static irqreturn_t mixer_irq_handler(int irq, void *arg) { struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg; - struct mixer_context *ctx = drm_hdmi_ctx->ctx; + struct mixer_context *ctx = + (struct mixer_context *)drm_hdmi_ctx->ctx; struct mixer_resources *res = &ctx->mixer_res; u32 val, val_base; @@ -901,7 +902,7 @@ static int mixer_runtime_resume(struct device *dev) DRM_DEBUG_KMS("resume - start\n"); - mixer_resource_poweron(ctx->ctx); + mixer_resource_poweron((struct mixer_context *)ctx->ctx); return 0; } @@ -912,7 +913,7 @@ static int mixer_runtime_suspend(struct device *dev) DRM_DEBUG_KMS("suspend - start\n"); - mixer_resource_poweroff(ctx->ctx); + mixer_resource_poweroff((struct mixer_context *)ctx->ctx); return 0; } @@ -925,7 +926,8 @@ static const struct dev_pm_ops mixer_pm_ops = { static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx, struct platform_device *pdev) { - struct mixer_context *mixer_ctx = ctx->ctx; + struct mixer_context *mixer_ctx = + (struct mixer_context *)ctx->ctx; struct device *dev = &pdev->dev; struct mixer_resources *mixer_res = &mixer_ctx->mixer_res; struct resource *res; @@ -1074,7 +1076,7 @@ static int __devinit mixer_probe(struct platform_device *pdev) goto fail; /* register specific callback point to common hdmi. */ - exynos_mixer_ops_register(&mixer_ops); + exynos_drm_overlay_ops_register(&overlay_ops); mixer_resource_poweron(ctx); @@ -1091,7 +1093,7 @@ static int mixer_remove(struct platform_device *pdev) struct device *dev = &pdev->dev; struct exynos_drm_hdmi_context *drm_hdmi_ctx = platform_get_drvdata(pdev); - struct mixer_context *ctx = drm_hdmi_ctx->ctx; + struct mixer_context *ctx = (struct mixer_context *)drm_hdmi_ctx->ctx; dev_info(dev, "remove successful\n"); diff --git a/trunk/drivers/gpu/drm/gma500/mdfld_dsi_output.h b/trunk/drivers/gpu/drm/gma500/mdfld_dsi_output.h index 36eb0744841c..21071cef92a4 100644 --- a/trunk/drivers/gpu/drm/gma500/mdfld_dsi_output.h +++ b/trunk/drivers/gpu/drm/gma500/mdfld_dsi_output.h @@ -29,6 +29,7 @@ #define __MDFLD_DSI_OUTPUT_H__ #include +#include #include #include #include diff --git a/trunk/drivers/gpu/drm/i810/i810_dma.c b/trunk/drivers/gpu/drm/i810/i810_dma.c index f920fb5e42b6..2c8a60c3b98e 100644 --- a/trunk/drivers/gpu/drm/i810/i810_dma.c +++ b/trunk/drivers/gpu/drm/i810/i810_dma.c @@ -129,7 +129,6 @@ static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv) if (buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL; - /* This is all entirely broken */ down_write(¤t->mm->mmap_sem); old_fops = file_priv->filp->f_op; file_priv->filp->f_op = &i810_buffer_fops; @@ -158,8 +157,11 @@ static int i810_unmap_buffer(struct drm_buf *buf) if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EINVAL; - retcode = vm_munmap((unsigned long)buf_priv->virtual, + down_write(¤t->mm->mmap_sem); + retcode = do_munmap(current->mm, + (unsigned long)buf_priv->virtual, (size_t) buf->total); + up_write(¤t->mm->mmap_sem); buf_priv->currently_mapped = I810_BUF_UNMAPPED; buf_priv->virtual = NULL; diff --git a/trunk/drivers/gpu/drm/i915/i915_debugfs.c b/trunk/drivers/gpu/drm/i915/i915_debugfs.c index e6162a1681f0..fdb7ccefffbd 100644 --- a/trunk/drivers/gpu/drm/i915/i915_debugfs.c +++ b/trunk/drivers/gpu/drm/i915/i915_debugfs.c @@ -1224,9 +1224,6 @@ static int i915_emon_status(struct seq_file *m, void *unused) unsigned long temp, chipset, gfx; int ret; - if (!IS_GEN5(dev)) - return -ENODEV; - ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) return ret; @@ -1505,6 +1502,14 @@ static int i915_ppgtt_info(struct seq_file *m, void *data) return 0; } +static int +i915_debugfs_common_open(struct inode *inode, + struct file *filp) +{ + filp->private_data = inode->i_private; + return 0; +} + static ssize_t i915_wedged_read(struct file *filp, char __user *ubuf, @@ -1555,7 +1560,7 @@ i915_wedged_write(struct file *filp, static const struct file_operations i915_wedged_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = i915_debugfs_common_open, .read = i915_wedged_read, .write = i915_wedged_write, .llseek = default_llseek, @@ -1617,7 +1622,7 @@ i915_max_freq_write(struct file *filp, static const struct file_operations i915_max_freq_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = i915_debugfs_common_open, .read = i915_max_freq_read, .write = i915_max_freq_write, .llseek = default_llseek, @@ -1688,7 +1693,7 @@ i915_cache_sharing_write(struct file *filp, static const struct file_operations i915_cache_sharing_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = i915_debugfs_common_open, .read = i915_cache_sharing_read, .write = i915_cache_sharing_write, .llseek = default_llseek, diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index ba60f3c8f911..9341eb8ce93b 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -1183,21 +1183,6 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev) return can_switch; } -static bool -intel_enable_ppgtt(struct drm_device *dev) -{ - if (i915_enable_ppgtt >= 0) - return i915_enable_ppgtt; - -#ifdef CONFIG_INTEL_IOMMU - /* Disable ppgtt on SNB if VT-d is on. */ - if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) - return false; -#endif - - return true; -} - static int i915_load_gem_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -1212,7 +1197,7 @@ static int i915_load_gem_init(struct drm_device *dev) drm_mm_init(&dev_priv->mm.stolen, 0, prealloc_size); mutex_lock(&dev->struct_mutex); - if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) { + if (i915_enable_ppgtt && HAS_ALIASING_PPGTT(dev)) { /* PPGTT pdes are stolen from global gtt ptes, so shrink the * aperture accordingly when using aliasing ppgtt. */ gtt_size -= I915_PPGTT_PD_ENTRIES*PAGE_SIZE; @@ -1222,10 +1207,8 @@ static int i915_load_gem_init(struct drm_device *dev) i915_gem_do_init(dev, 0, mappable_size, gtt_size); ret = i915_gem_init_aliasing_ppgtt(dev); - if (ret) { - mutex_unlock(&dev->struct_mutex); + if (ret) return ret; - } } else { /* Let GEM Manage all of the aperture. * @@ -1701,9 +1684,6 @@ void i915_update_gfx_val(struct drm_i915_private *dev_priv) unsigned long diffms; u32 count; - if (dev_priv->info->gen != 5) - return; - getrawmonotonic(&now); diff1 = timespec_sub(now, dev_priv->last_time2); @@ -2124,14 +2104,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, (unsigned long) dev); - if (IS_GEN5(dev)) { - spin_lock(&mchdev_lock); - i915_mch_dev = dev_priv; - dev_priv->mchdev_lock = &mchdev_lock; - spin_unlock(&mchdev_lock); + spin_lock(&mchdev_lock); + i915_mch_dev = dev_priv; + dev_priv->mchdev_lock = &mchdev_lock; + spin_unlock(&mchdev_lock); - ips_ping_for_i915_load(); - } + ips_ping_for_i915_load(); return 0; diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index ae8a64f9f845..1a7559b59997 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -64,13 +64,9 @@ MODULE_PARM_DESC(semaphores, "Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))"); int i915_enable_rc6 __read_mostly = -1; -module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0400); +module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); MODULE_PARM_DESC(i915_enable_rc6, - "Enable power-saving render C-state 6. " - "Different stages can be selected via bitmask values " - "(0 = disable; 1 = enable rc6; 2 = enable deep rc6; 4 = enable deepest rc6). " - "For example, 3 would enable rc6 and deep rc6, and 7 would enable everything. " - "default: -1 (use per-chip default)"); + "Enable power-saving render C-state 6 (default: -1 (use per-chip default)"); int i915_enable_fbc __read_mostly = -1; module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600); @@ -107,8 +103,8 @@ MODULE_PARM_DESC(enable_hangcheck, "WARNING: Disabling this can cause system wide hangs. " "(default: true)"); -int i915_enable_ppgtt __read_mostly = -1; -module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, int, 0600); +bool i915_enable_ppgtt __read_mostly = 1; +module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, bool, 0600); MODULE_PARM_DESC(i915_enable_ppgtt, "Enable PPGTT (default: true)"); @@ -296,7 +292,6 @@ static const struct pci_device_id pciidlist[] = { /* aka */ INTEL_VGA_DEVICE(0x0152, &intel_ivybridge_d_info), /* GT1 desktop */ INTEL_VGA_DEVICE(0x0162, &intel_ivybridge_d_info), /* GT2 desktop */ INTEL_VGA_DEVICE(0x015a, &intel_ivybridge_d_info), /* GT1 server */ - INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */ {0, 0, 0} }; @@ -538,9 +533,7 @@ static int i915_drm_thaw(struct drm_device *dev) drm_irq_install(dev); /* Resume the modeset for every activated CRTC */ - mutex_lock(&dev->mode_config.mutex); drm_helper_resume_force_mode(dev); - mutex_unlock(&dev->mode_config.mutex); if (IS_IRONLAKE_M(dev)) ironlake_enable_rc6(dev); diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index 5fabc6c31fec..c0f19f572004 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -1053,27 +1053,6 @@ struct drm_i915_file_private { #include "i915_trace.h" -/** - * RC6 is a special power stage which allows the GPU to enter an very - * low-voltage mode when idle, using down to 0V while at this stage. This - * stage is entered automatically when the GPU is idle when RC6 support is - * enabled, and as soon as new workload arises GPU wakes up automatically as well. - * - * There are different RC6 modes available in Intel GPU, which differentiate - * among each other with the latency required to enter and leave RC6 and - * voltage consumed by the GPU in different states. - * - * The combination of the following flags define which states GPU is allowed - * to enter, while RC6 is the normal RC6 state, RC6p is the deep RC6, and - * RC6pp is deepest RC6. Their support by hardware varies according to the - * GPU, BIOS, chipset and platform. RC6 is usually the safest one and the one - * which brings the most power savings; deeper states save more power, but - * require higher latency to switch to and wake up. - */ -#define INTEL_RC6_ENABLE (1<<0) -#define INTEL_RC6p_ENABLE (1<<1) -#define INTEL_RC6pp_ENABLE (1<<2) - extern struct drm_ioctl_desc i915_ioctls[]; extern int i915_max_ioctl; extern unsigned int i915_fbpercrtc __always_unused; @@ -1086,7 +1065,7 @@ extern int i915_vbt_sdvo_panel_type __read_mostly; extern int i915_enable_rc6 __read_mostly; extern int i915_enable_fbc __read_mostly; extern bool i915_enable_hangcheck __read_mostly; -extern int i915_enable_ppgtt __read_mostly; +extern bool i915_enable_ppgtt __read_mostly; extern int i915_suspend(struct drm_device *dev, pm_message_t state); extern int i915_resume(struct drm_device *dev); diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index 0d1e4b7b4b99..1f441f5c2405 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -1087,9 +1087,11 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, if (obj == NULL) return -ENOENT; - addr = vm_mmap(obj->filp, 0, args->size, + down_write(¤t->mm->mmap_sem); + addr = do_mmap(obj->filp, 0, args->size, PROT_READ | PROT_WRITE, MAP_SHARED, args->offset); + up_write(¤t->mm->mmap_sem); drm_gem_object_unreference_unlocked(obj); if (IS_ERR((void *)addr)) return addr; @@ -1470,19 +1472,16 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, list_move_tail(&obj->ring_list, &ring->active_list); obj->last_rendering_seqno = seqno; - if (obj->fenced_gpu_access) { + struct drm_i915_fence_reg *reg; + + BUG_ON(obj->fence_reg == I915_FENCE_REG_NONE); + obj->last_fenced_seqno = seqno; obj->last_fenced_ring = ring; - /* Bump MRU to take account of the delayed flush */ - if (obj->fence_reg != I915_FENCE_REG_NONE) { - struct drm_i915_fence_reg *reg; - - reg = &dev_priv->fence_regs[obj->fence_reg]; - list_move_tail(®->lru_list, - &dev_priv->mm.fence_list); - } + reg = &dev_priv->fence_regs[obj->fence_reg]; + list_move_tail(®->lru_list, &dev_priv->mm.fence_list); } } @@ -1491,7 +1490,6 @@ i915_gem_object_move_off_active(struct drm_i915_gem_object *obj) { list_del_init(&obj->ring_list); obj->last_rendering_seqno = 0; - obj->last_fenced_seqno = 0; } static void @@ -1520,7 +1518,6 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) BUG_ON(!list_empty(&obj->gpu_write_list)); BUG_ON(!obj->active); obj->ring = NULL; - obj->last_fenced_ring = NULL; i915_gem_object_move_off_active(obj); obj->fenced_gpu_access = false; @@ -3757,32 +3754,12 @@ void i915_gem_init_ppgtt(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; uint32_t pd_offset; struct intel_ring_buffer *ring; - struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; - uint32_t __iomem *pd_addr; - uint32_t pd_entry; int i; if (!dev_priv->mm.aliasing_ppgtt) return; - - pd_addr = dev_priv->mm.gtt->gtt + ppgtt->pd_offset/sizeof(uint32_t); - for (i = 0; i < ppgtt->num_pd_entries; i++) { - dma_addr_t pt_addr; - - if (dev_priv->mm.gtt->needs_dmar) - pt_addr = ppgtt->pt_dma_addr[i]; - else - pt_addr = page_to_phys(ppgtt->pt_pages[i]); - - pd_entry = GEN6_PDE_ADDR_ENCODE(pt_addr); - pd_entry |= GEN6_PDE_VALID; - - writel(pd_entry, pd_addr + i); - } - readl(pd_addr); - - pd_offset = ppgtt->pd_offset; + pd_offset = dev_priv->mm.aliasing_ppgtt->pd_offset; pd_offset /= 64; /* in cachelines, */ pd_offset <<= 16; diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c index de431942ded4..81687af00893 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -498,8 +498,8 @@ pin_and_fence_object(struct drm_i915_gem_object *obj, if (ret) goto err_unpin; } - obj->pending_fenced_gpu_access = true; } + obj->pending_fenced_gpu_access = need_fence; } entry->offset = obj->gtt_offset; @@ -1133,11 +1133,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, return -EINVAL; } - if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) { - DRM_DEBUG("execbuf with %u cliprects\n", - args->num_cliprects); - return -EINVAL; - } cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects), GFP_KERNEL); if (cliprects == NULL) { @@ -1409,8 +1404,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, struct drm_i915_gem_exec_object2 *exec2_list = NULL; int ret; - if (args->buffer_count < 1 || - args->buffer_count > UINT_MAX / sizeof(*exec2_list)) { + if (args->buffer_count < 1) { DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count); return -EINVAL; } diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c b/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c index a135c61f4119..2eacd78bb93b 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -65,7 +65,9 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct i915_hw_ppgtt *ppgtt; + uint32_t pd_entry; unsigned first_pd_entry_in_global_pt; + uint32_t __iomem *pd_addr; int i; int ret = -ENOMEM; @@ -98,6 +100,7 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) goto err_pt_alloc; } + pd_addr = dev_priv->mm.gtt->gtt + first_pd_entry_in_global_pt; for (i = 0; i < ppgtt->num_pd_entries; i++) { dma_addr_t pt_addr; if (dev_priv->mm.gtt->needs_dmar) { @@ -114,7 +117,13 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) ppgtt->pt_dma_addr[i] = pt_addr; } else pt_addr = page_to_phys(ppgtt->pt_pages[i]); + + pd_entry = GEN6_PDE_ADDR_ENCODE(pt_addr); + pd_entry |= GEN6_PDE_VALID; + + writel(pd_entry, pd_addr + i); } + readl(pd_addr); ppgtt->scratch_page_dma_addr = dev_priv->mm.gtt->scratch_page_dma; diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index 9d24d65f0c3e..3886cf051bac 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -568,7 +568,6 @@ #define CM0_MASK_SHIFT 16 #define CM0_IZ_OPT_DISABLE (1<<6) #define CM0_ZR_OPT_DISABLE (1<<5) -#define CM0_STC_EVICT_DISABLE_LRA_SNB (1<<5) #define CM0_DEPTH_EVICT_DISABLE (1<<4) #define CM0_COLOR_EVICT_DISABLE (1<<3) #define CM0_DEPTH_WRITE_DISABLE (1<<1) @@ -2386,7 +2385,6 @@ #define PIPECONF_DISABLE 0 #define PIPECONF_DOUBLE_WIDE (1<<30) #define I965_PIPECONF_ACTIVE (1<<30) -#define PIPECONF_FRAME_START_DELAY_MASK (3<<27) #define PIPECONF_SINGLE_WIDE 0 #define PIPECONF_PIPE_UNLOCKED 0 #define PIPECONF_PIPE_LOCKED (1<<25) @@ -3729,9 +3727,6 @@ #define GT_FIFO_FREE_ENTRIES 0x120008 #define GT_FIFO_NUM_RESERVED_ENTRIES 20 -#define GEN6_UCGCTL1 0x9400 -# define GEN6_BLBUNIT_CLOCK_GATE_DISABLE (1 << 5) - #define GEN6_UCGCTL2 0x9404 # define GEN6_RCZUNIT_CLOCK_GATE_DISABLE (1 << 13) # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) diff --git a/trunk/drivers/gpu/drm/i915/intel_bios.c b/trunk/drivers/gpu/drm/i915/intel_bios.c index b48fc2a8410c..8168d8f8a634 100644 --- a/trunk/drivers/gpu/drm/i915/intel_bios.c +++ b/trunk/drivers/gpu/drm/i915/intel_bios.c @@ -24,7 +24,6 @@ * Eric Anholt * */ -#include #include #include "drmP.h" #include "drm.h" @@ -622,26 +621,6 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) dev_priv->edp.bpp = 18; } -static int __init intel_no_opregion_vbt_callback(const struct dmi_system_id *id) -{ - DRM_DEBUG_KMS("Falling back to manually reading VBT from " - "VBIOS ROM for %s\n", - id->ident); - return 1; -} - -static const struct dmi_system_id intel_no_opregion_vbt[] = { - { - .callback = intel_no_opregion_vbt_callback, - .ident = "ThinkCentre A57", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "97027RG"), - }, - }, - { } -}; - /** * intel_parse_bios - find VBT and initialize settings from the BIOS * @dev: DRM device @@ -662,7 +641,7 @@ intel_parse_bios(struct drm_device *dev) init_vbt_defaults(dev_priv); /* XXX Should this validation be moved to intel_opregion.c? */ - if (!dmi_check_system(intel_no_opregion_vbt) && dev_priv->opregion.vbt) { + if (dev_priv->opregion.vbt) { struct vbt_header *vbt = dev_priv->opregion.vbt; if (memcmp(vbt->signature, "$VBT", 4) == 0) { DRM_DEBUG_KMS("Using VBT from OpRegion: %20s\n", diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c index 90b9793fd5da..4d3d736a4f56 100644 --- a/trunk/drivers/gpu/drm/i915/intel_crt.c +++ b/trunk/drivers/gpu/drm/i915/intel_crt.c @@ -430,8 +430,8 @@ intel_crt_detect(struct drm_connector *connector, bool force) { struct drm_device *dev = connector->dev; struct intel_crt *crt = intel_attached_crt(connector); + struct drm_crtc *crtc; enum drm_connector_status status; - struct intel_load_detect_pipe tmp; if (I915_HAS_HOTPLUG(dev)) { if (intel_crt_detect_hotplug(connector)) { @@ -450,16 +450,23 @@ intel_crt_detect(struct drm_connector *connector, bool force) return connector->status; /* for pre-945g platforms use load detect */ - if (intel_get_load_detect_pipe(&crt->base, connector, NULL, - &tmp)) { - if (intel_crt_detect_ddc(connector)) - status = connector_status_connected; - else - status = intel_crt_load_detect(crt); - intel_release_load_detect_pipe(&crt->base, connector, - &tmp); - } else - status = connector_status_unknown; + crtc = crt->base.base.crtc; + if (crtc && crtc->enabled) { + status = intel_crt_load_detect(crt); + } else { + struct intel_load_detect_pipe tmp; + + if (intel_get_load_detect_pipe(&crt->base, connector, NULL, + &tmp)) { + if (intel_crt_detect_ddc(connector)) + status = connector_status_connected; + else + status = intel_crt_load_detect(crt); + intel_release_load_detect_pipe(&crt->base, connector, + &tmp); + } else + status = connector_status_unknown; + } return status; } diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 1b1cf3b3ff51..d514719f65e2 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -2244,33 +2244,6 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, return 0; } -static int -intel_finish_fb(struct drm_framebuffer *old_fb) -{ - struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj; - struct drm_i915_private *dev_priv = obj->base.dev->dev_private; - bool was_interruptible = dev_priv->mm.interruptible; - int ret; - - wait_event(dev_priv->pending_flip_queue, - atomic_read(&dev_priv->mm.wedged) || - atomic_read(&obj->pending_flip) == 0); - - /* Big Hammer, we also need to ensure that any pending - * MI_WAIT_FOR_EVENT inside a user batch buffer on the - * current scanout is retired before unpinning the old - * framebuffer. - * - * This should only fail upon a hung GPU, in which case we - * can safely continue. - */ - dev_priv->mm.interruptible = false; - ret = i915_gem_object_finish_gpu(obj); - dev_priv->mm.interruptible = was_interruptible; - - return ret; -} - static int intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) @@ -2309,8 +2282,25 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, return ret; } - if (old_fb) - intel_finish_fb(old_fb); + if (old_fb) { + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj; + + wait_event(dev_priv->pending_flip_queue, + atomic_read(&dev_priv->mm.wedged) || + atomic_read(&obj->pending_flip) == 0); + + /* Big Hammer, we also need to ensure that any pending + * MI_WAIT_FOR_EVENT inside a user batch buffer on the + * current scanout is retired before unpinning the old + * framebuffer. + * + * This should only fail upon a hung GPU, in which case we + * can safely continue. + */ + ret = i915_gem_object_finish_gpu(obj); + (void) ret; + } ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, LEAVE_ATOMIC_MODE_SET); @@ -3381,23 +3371,6 @@ static void intel_crtc_disable(struct drm_crtc *crtc) struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; struct drm_device *dev = crtc->dev; - /* Flush any pending WAITs before we disable the pipe. Note that - * we need to drop the struct_mutex in order to acquire it again - * during the lowlevel dpms routines around a couple of the - * operations. It does not look trivial nor desirable to move - * that locking higher. So instead we leave a window for the - * submission of further commands on the fb before we can actually - * disable it. This race with userspace exists anyway, and we can - * only rely on the pipe being disabled by userspace after it - * receives the hotplug notification and has flushed any pending - * batches. - */ - if (crtc->fb) { - mutex_lock(&dev->struct_mutex); - intel_finish_fb(crtc->fb); - mutex_unlock(&dev->struct_mutex); - } - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane); assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe); @@ -3478,11 +3451,8 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, return false; } - /* All interlaced capable intel hw wants timings in frames. Note though - * that intel_lvds_mode_fixup does some funny tricks with the crtc - * timings, so we need to be careful not to clobber these.*/ - if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET)) - drm_mode_set_crtcinfo(adjusted_mode, 0); + /* All interlaced capable intel hw wants timings in frames. */ + drm_mode_set_crtcinfo(adjusted_mode, 0); return true; } @@ -5569,8 +5539,7 @@ void ironlake_init_pch_refclk(struct drm_device *dev) if (intel_panel_use_ssc(dev_priv) && can_ssc) { DRM_DEBUG_KMS("Using SSC on panel\n"); temp |= DREF_SSC1_ENABLE; - } else - temp &= ~DREF_SSC1_ENABLE; + } /* Get SSC going before enabling the outputs */ I915_WRITE(PCH_DREF_CONTROL, temp); @@ -7072,6 +7041,9 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; drm_i915_private_t *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + int dpll_reg = DPLL(pipe); + int dpll = I915_READ(dpll_reg); if (HAS_PCH_SPLIT(dev)) return; @@ -7084,15 +7056,10 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) * the manual case. */ if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) { - int pipe = intel_crtc->pipe; - int dpll_reg = DPLL(pipe); - u32 dpll; - DRM_DEBUG_DRIVER("downclocking LVDS\n"); assert_panel_unlocked(dev_priv, pipe); - dpll = I915_READ(dpll_reg); dpll |= DISPLAY_RATE_SELECT_FPA1; I915_WRITE(dpll_reg, dpll); intel_wait_for_vblank(dev, pipe); @@ -7100,6 +7067,7 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); } + } /** @@ -7469,13 +7437,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev, OUT_RING(fb->pitches[0] | obj->tiling_mode); OUT_RING(obj->gtt_offset); - /* Contrary to the suggestions in the documentation, - * "Enable Panel Fitter" does not seem to be required when page - * flipping with a non-native mode, and worse causes a normal - * modeset to fail. - * pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; - */ - pf = 0; + pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; OUT_RING(pf | pipesrc); ADVANCE_LP_RING(); @@ -7618,12 +7580,6 @@ static void intel_sanitize_modesetting(struct drm_device *dev, struct drm_i915_private *dev_priv = dev->dev_private; u32 reg, val; - /* Clear any frame start delays used for debugging left by the BIOS */ - for_each_pipe(pipe) { - reg = PIPECONF(pipe); - I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); - } - if (HAS_PCH_SPLIT(dev)) return; @@ -8259,7 +8215,7 @@ void intel_init_emon(struct drm_device *dev) dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); } -static int intel_enable_rc6(struct drm_device *dev) +static bool intel_enable_rc6(struct drm_device *dev) { /* * Respect the kernel parameter if it is set @@ -8277,11 +8233,11 @@ static int intel_enable_rc6(struct drm_device *dev) * Disable rc6 on Sandybridge */ if (INTEL_INFO(dev)->gen == 6) { - DRM_DEBUG_DRIVER("Sandybridge: deep RC6 disabled\n"); - return INTEL_RC6_ENABLE; + DRM_DEBUG_DRIVER("Sandybridge: RC6 disabled\n"); + return 0; } - DRM_DEBUG_DRIVER("RC6 and deep RC6 enabled\n"); - return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE); + DRM_DEBUG_DRIVER("RC6 enabled\n"); + return 1; } void gen6_enable_rps(struct drm_i915_private *dev_priv) @@ -8291,7 +8247,6 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) u32 pcu_mbox, rc6_mask = 0; u32 gtfifodbg; int cur_freq, min_freq, max_freq; - int rc6_mode; int i; /* Here begins a magic sequence of register writes to enable @@ -8329,20 +8284,9 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RC6p_THRESHOLD, 100000); I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ - rc6_mode = intel_enable_rc6(dev_priv->dev); - if (rc6_mode & INTEL_RC6_ENABLE) - rc6_mask |= GEN6_RC_CTL_RC6_ENABLE; - - if (rc6_mode & INTEL_RC6p_ENABLE) - rc6_mask |= GEN6_RC_CTL_RC6p_ENABLE; - - if (rc6_mode & INTEL_RC6pp_ENABLE) - rc6_mask |= GEN6_RC_CTL_RC6pp_ENABLE; - - DRM_INFO("Enabling RC6 states: RC6 %s, RC6p %s, RC6pp %s\n", - (rc6_mode & INTEL_RC6_ENABLE) ? "on" : "off", - (rc6_mode & INTEL_RC6p_ENABLE) ? "on" : "off", - (rc6_mode & INTEL_RC6pp_ENABLE) ? "on" : "off"); + if (intel_enable_rc6(dev_priv->dev)) + rc6_mask = GEN6_RC_CTL_RC6_ENABLE | + ((IS_GEN7(dev_priv->dev)) ? GEN6_RC_CTL_RC6p_ENABLE : 0); I915_WRITE(GEN6_RC_CONTROL, rc6_mask | @@ -8566,10 +8510,6 @@ static void gen6_init_clock_gating(struct drm_device *dev) I915_WRITE(WM2_LP_ILK, 0); I915_WRITE(WM1_LP_ILK, 0); - I915_WRITE(GEN6_UCGCTL1, - I915_READ(GEN6_UCGCTL1) | - GEN6_BLBUNIT_CLOCK_GATE_DISABLE); - /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock * gating disable must be set. Failure to set it results in * flickering pixels due to Z write ordering failures after diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index 4b637919f74f..110552ff302c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -219,38 +219,14 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes) return (max_link_clock * max_lanes * 8) / 10; } -static bool -intel_dp_adjust_dithering(struct intel_dp *intel_dp, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); - int max_lanes = intel_dp_max_lane_count(intel_dp); - int max_rate, mode_rate; - - mode_rate = intel_dp_link_required(mode->clock, 24); - max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); - - if (mode_rate > max_rate) { - mode_rate = intel_dp_link_required(mode->clock, 18); - if (mode_rate > max_rate) - return false; - - if (adjusted_mode) - adjusted_mode->private_flags - |= INTEL_MODE_DP_FORCE_6BPC; - - return true; - } - - return true; -} - static int intel_dp_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct intel_dp *intel_dp = intel_attached_dp(connector); + int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); + int max_lanes = intel_dp_max_lane_count(intel_dp); + int max_rate, mode_rate; if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay) @@ -260,8 +236,16 @@ intel_dp_mode_valid(struct drm_connector *connector, return MODE_PANEL; } - if (!intel_dp_adjust_dithering(intel_dp, mode, NULL)) - return MODE_CLOCK_HIGH; + mode_rate = intel_dp_link_required(mode->clock, 24); + max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); + + if (mode_rate > max_rate) { + mode_rate = intel_dp_link_required(mode->clock, 18); + if (mode_rate > max_rate) + return MODE_CLOCK_HIGH; + else + mode->private_flags |= INTEL_MODE_DP_FORCE_6BPC; + } if (mode->clock < 10000) return MODE_CLOCK_LOW; @@ -688,7 +672,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, int lane_count, clock; int max_lane_count = intel_dp_max_lane_count(intel_dp); int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; - int bpp; + int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { @@ -702,11 +686,6 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, mode->clock = intel_dp->panel_fixed_mode->clock; } - if (!intel_dp_adjust_dithering(intel_dp, mode, adjusted_mode)) - return false; - - bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; - for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { for (clock = 0; clock <= max_clock; clock++) { int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index 715afa153025..5a14149b3794 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -105,10 +105,6 @@ #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) #define INTEL_MODE_DP_FORCE_6BPC (0x10) -/* This flag must be set by the encoder's mode_fixup if it changes the crtc - * timings in the mode to prevent the crtc fixup from overwriting them. - * Currently only lvds needs that. */ -#define INTEL_MODE_CRTC_TIMINGS_SET (0x20) static inline void intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, diff --git a/trunk/drivers/gpu/drm/i915/intel_fb.c b/trunk/drivers/gpu/drm/i915/intel_fb.c index 6e9ee33fd412..19ecd78b8a2c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_fb.c +++ b/trunk/drivers/gpu/drm/i915/intel_fb.c @@ -279,8 +279,6 @@ void intel_fb_restore_mode(struct drm_device *dev) struct drm_mode_config *config = &dev->mode_config; struct drm_plane *plane; - mutex_lock(&dev->mode_config.mutex); - ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); if (ret) DRM_DEBUG("failed to restore crtc mode\n"); @@ -288,6 +286,4 @@ void intel_fb_restore_mode(struct drm_device *dev) /* Be sure to shut off any planes that may be active */ list_for_each_entry(plane, &config->plane_list, head) plane->funcs->disable_plane(plane); - - mutex_unlock(&dev->mode_config.mutex); } diff --git a/trunk/drivers/gpu/drm/i915/intel_hdmi.c b/trunk/drivers/gpu/drm/i915/intel_hdmi.c index 2d7f47b56b6a..cae3e5f17a49 100644 --- a/trunk/drivers/gpu/drm/i915/intel_hdmi.c +++ b/trunk/drivers/gpu/drm/i915/intel_hdmi.c @@ -136,7 +136,7 @@ static void i9xx_write_infoframe(struct drm_encoder *encoder, val &= ~VIDEO_DIP_SELECT_MASK; - I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | val | port | flags); + I915_WRITE(VIDEO_DIP_CTL, val | port | flags); for (i = 0; i < len; i += 4) { I915_WRITE(VIDEO_DIP_DATA, *data); diff --git a/trunk/drivers/gpu/drm/i915/intel_i2c.c b/trunk/drivers/gpu/drm/i915/intel_i2c.c index 8fdc95700218..601c86e664af 100644 --- a/trunk/drivers/gpu/drm/i915/intel_i2c.c +++ b/trunk/drivers/gpu/drm/i915/intel_i2c.c @@ -390,7 +390,7 @@ int intel_setup_gmbus(struct drm_device *dev) bus->has_gpio = intel_gpio_setup(bus, i); /* XXX force bit banging until GMBUS is fully debugged */ - if (bus->has_gpio) + if (bus->has_gpio && IS_GEN2(dev)) bus->force_bit = true; } diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 9c71183629c2..c5c0973af8a1 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -187,8 +187,6 @@ centre_horizontally(struct drm_display_mode *mode, mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; - - mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; } static void @@ -210,8 +208,6 @@ centre_vertically(struct drm_display_mode *mode, mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; - - mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; } static inline u32 panel_fitter_scaling(u32 source, u32 target) @@ -287,8 +283,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, for_each_pipe(pipe) I915_WRITE(BCLRPAT(pipe), 0); - drm_mode_set_crtcinfo(adjusted_mode, 0); - switch (intel_lvds->fitting_mode) { case DRM_MODE_SCALE_CENTER: /* @@ -750,7 +744,7 @@ static const struct dmi_system_id intel_no_lvds[] = { .ident = "Hewlett-Packard t5745", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "hp t5745"), + DMI_MATCH(DMI_BOARD_NAME, "hp t5745"), }, }, { @@ -758,15 +752,7 @@ static const struct dmi_system_id intel_no_lvds[] = { .ident = "Hewlett-Packard st5747", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "hp st5747"), - }, - }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "MSI Wind Box DC500", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), - DMI_MATCH(DMI_BOARD_NAME, "MS-7469"), + DMI_MATCH(DMI_BOARD_NAME, "hp st5747"), }, }, diff --git a/trunk/drivers/gpu/drm/i915/intel_panel.c b/trunk/drivers/gpu/drm/i915/intel_panel.c index 48177ec4720e..230a141dbea3 100644 --- a/trunk/drivers/gpu/drm/i915/intel_panel.c +++ b/trunk/drivers/gpu/drm/i915/intel_panel.c @@ -47,6 +47,8 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, adjusted_mode->vtotal = fixed_mode->vtotal; adjusted_mode->clock = fixed_mode->clock; + + drm_mode_set_crtcinfo(adjusted_mode, 0); } /* adjusted_mode has been preset to be the panel's fixed mode */ diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c index 80fce51e2f43..fc66af6a9448 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -401,14 +401,6 @@ static int init_render_ring(struct intel_ring_buffer *ring) if (INTEL_INFO(dev)->gen >= 6) { I915_WRITE(INSTPM, INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING); - - /* From the Sandybridge PRM, volume 1 part 3, page 24: - * "If this bit is set, STCunit will have LRA as replacement - * policy. [...] This bit must be reset. LRA replacement - * policy is not supported." - */ - I915_WRITE(CACHE_MODE_0, - CM0_STC_EVICT_DISABLE_LRA_SNB << CM0_MASK_SHIFT); } return ret; @@ -634,7 +626,7 @@ gen6_ring_get_seqno(struct intel_ring_buffer *ring) /* Workaround to force correct ordering between irq and seqno writes on * ivb (and maybe also on snb) by reading from a CS register (like * ACTHD) before reading the status page. */ - if (IS_GEN6(dev) || IS_GEN7(dev)) + if (IS_GEN7(dev)) intel_ring_get_active_head(ring); return intel_read_status_page(ring, I915_GEM_HWS_INDEX); } @@ -1046,7 +1038,7 @@ int intel_init_ring_buffer(struct drm_device *dev, * of the buffer. */ ring->effective_size = ring->size; - if (IS_I830(ring->dev) || IS_845G(ring->dev)) + if (IS_I830(ring->dev)) ring->effective_size -= 128; return 0; diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c index 232d77d07d8b..e36b171c1e7d 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c @@ -731,7 +731,6 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, uint16_t width, height; uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; uint16_t h_sync_offset, v_sync_offset; - int mode_clock; width = mode->crtc_hdisplay; height = mode->crtc_vdisplay; @@ -746,11 +745,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; - mode_clock = mode->clock; - mode_clock /= intel_mode_get_pixel_multiplier(mode) ?: 1; - mode_clock /= 10; - dtd->part1.clock = mode_clock; - + dtd->part1.clock = mode->clock / 10; dtd->part1.h_active = width & 0xff; dtd->part1.h_blank = h_blank_len & 0xff; dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | @@ -1001,7 +996,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); u32 sdvox; struct intel_sdvo_in_out_map in_out; - struct intel_sdvo_dtd input_dtd, output_dtd; + struct intel_sdvo_dtd input_dtd; int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); int rate; @@ -1026,13 +1021,20 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, intel_sdvo->attached_output)) return; - /* lvds has a special fixed output timing. */ - if (intel_sdvo->is_lvds) - intel_sdvo_get_dtd_from_mode(&output_dtd, - intel_sdvo->sdvo_lvds_fixed_mode); - else - intel_sdvo_get_dtd_from_mode(&output_dtd, mode); - (void) intel_sdvo_set_output_timing(intel_sdvo, &output_dtd); + /* We have tried to get input timing in mode_fixup, and filled into + * adjusted_mode. + */ + if (intel_sdvo->is_tv || intel_sdvo->is_lvds) { + input_dtd = intel_sdvo->input_dtd; + } else { + /* Set the output timing to the screen */ + if (!intel_sdvo_set_target_output(intel_sdvo, + intel_sdvo->attached_output)) + return; + + intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); + (void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd); + } /* Set the input timing to the screen. Assume always input 0. */ if (!intel_sdvo_set_target_input(intel_sdvo)) @@ -1050,10 +1052,6 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, !intel_sdvo_set_tv_format(intel_sdvo)) return; - /* We have tried to get input timing in mode_fixup, and filled into - * adjusted_mode. - */ - intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); switch (pixel_multiplier) { diff --git a/trunk/drivers/gpu/drm/i915/intel_sprite.c b/trunk/drivers/gpu/drm/i915/intel_sprite.c index e90dfb625c42..7aa0450399a1 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sprite.c +++ b/trunk/drivers/gpu/drm/i915/intel_sprite.c @@ -95,6 +95,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, /* must disable */ sprctl |= SPRITE_TRICKLE_FEED_DISABLE; sprctl |= SPRITE_ENABLE; + sprctl |= SPRITE_DEST_KEY; /* Sizes are 0 based */ src_w--; @@ -410,9 +411,6 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, old_obj = intel_plane->obj; - src_w = src_w >> 16; - src_h = src_h >> 16; - /* Pipe must be running... */ if (!(I915_READ(PIPECONF(pipe)) & PIPECONF_ENABLE)) return -EINVAL; diff --git a/trunk/drivers/gpu/drm/nouveau/Kconfig b/trunk/drivers/gpu/drm/nouveau/Kconfig index 97a81260485a..ca1639918f57 100644 --- a/trunk/drivers/gpu/drm/nouveau/Kconfig +++ b/trunk/drivers/gpu/drm/nouveau/Kconfig @@ -13,7 +13,6 @@ config DRM_NOUVEAU select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL && INPUT select ACPI_WMI if ACPI select MXM_WMI if ACPI - select POWER_SUPPLY help Choose this option for open-source nVidia support. diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_acpi.c b/trunk/drivers/gpu/drm/nouveau/nouveau_acpi.c index 284bd25d5d21..7814a760c164 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -270,7 +270,7 @@ static bool nouveau_dsm_detect(void) struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name}; struct pci_dev *pdev = NULL; int has_dsm = 0; - int has_optimus = 0; + int has_optimus; int vga_count = 0; bool guid_valid; int retval; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c index 0be4a815e706..637afe71de56 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -177,15 +177,14 @@ bios_shadow_pci(struct nvbios *bios) if (!pci_enable_rom(pdev)) { void __iomem *rom = pci_map_rom(pdev, &length); - if (rom && length) { + if (rom) { bios->data = kmalloc(length, GFP_KERNEL); if (bios->data) { memcpy_fromio(bios->data, rom, length); bios->length = length; } - } - if (rom) pci_unmap_rom(pdev, rom); + } pci_disable_rom(pdev); } @@ -6156,14 +6155,10 @@ dcb_fake_connectors(struct nvbios *bios) /* heuristic: if we ever get a non-zero connector field, assume * that all the indices are valid and we don't need fake them. - * - * and, as usual, a blacklist of boards with bad bios data.. */ - if (!nv_match_device(bios->dev, 0x0392, 0x107d, 0x20a2)) { - for (i = 0; i < dcbt->entries; i++) { - if (dcbt->entry[i].connector) - return; - } + for (i = 0; i < dcbt->entries; i++) { + if (dcbt->entry[i].connector) + return; } /* no useful connector info available, we need to make it up diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_channel.c b/trunk/drivers/gpu/drm/nouveau/nouveau_channel.c index 846afb0bfef4..44e6416d4a33 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -436,11 +436,11 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, } if (dev_priv->card_type < NV_C0) { - init->subchan[0].handle = 0x00000000; - init->subchan[0].grclass = 0x0000; - init->subchan[1].handle = NvSw; - init->subchan[1].grclass = NV_SW; - init->nr_subchan = 2; + init->subchan[0].handle = NvSw; + init->subchan[0].grclass = NV_SW; + init->nr_subchan = 1; + } else { + init->nr_subchan = 0; } /* Named memory object area */ diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_dma.h b/trunk/drivers/gpu/drm/nouveau/nouveau_dma.h index 23d4edf992b7..bcf0fd9e313e 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_dma.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_dma.h @@ -48,8 +48,8 @@ void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *, /* Hardcoded object assignments to subchannels (subchannel id). */ enum { - NvSubM2MF = 0, - NvSubSw = 1, + NvSubSw = 0, + NvSubM2MF = 1, NvSub2D = 2, NvSubCtxSurf2D = 2, NvSubGdiRect = 3, diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_hdmi.c b/trunk/drivers/gpu/drm/nouveau/nouveau_hdmi.c index c3de36384522..59ea1c14eca0 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_hdmi.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_hdmi.c @@ -32,9 +32,7 @@ static bool hdmi_sor(struct drm_encoder *encoder) { struct drm_nouveau_private *dev_priv = encoder->dev->dev_private; - if (dev_priv->chipset < 0xa3 || - dev_priv->chipset == 0xaa || - dev_priv->chipset == 0xac) + if (dev_priv->chipset < 0xa3) return false; return true; } diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c index da3e7c3abab7..34d591b7d4ef 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c @@ -235,7 +235,6 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile) return -EPERM; strncpy(string, profile, sizeof(string)); - string[sizeof(string) - 1] = 0; if ((ptr = strchr(string, '\n'))) *ptr = '\0'; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_state.c b/trunk/drivers/gpu/drm/nouveau/nouveau_state.c index c2a8511e855a..a4886b36d0fa 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_state.c @@ -642,7 +642,7 @@ nouveau_card_channel_init(struct drm_device *dev) OUT_RING (chan, chan->vram_handle); OUT_RING (chan, chan->gart_handle); } else - if (dev_priv->card_type <= NV_D0) { + if (dev_priv->card_type <= NV_C0) { ret = nouveau_gpuobj_gr_new(chan, 0x9039, 0x9039); if (ret) goto error; diff --git a/trunk/drivers/gpu/drm/nouveau/nv10_gpio.c b/trunk/drivers/gpu/drm/nouveau/nv10_gpio.c index 9d79180069df..550ad3fcf0af 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv10_gpio.c +++ b/trunk/drivers/gpu/drm/nouveau/nv10_gpio.c @@ -65,7 +65,7 @@ nv10_gpio_drive(struct drm_device *dev, int line, int dir, int out) if (line < 10) { line = (line - 2) * 4; reg = NV_PCRTC_GPIO_EXT; - mask = 0x00000003; + mask = 0x00000003 << ((line - 2) * 4); data = (dir << 1) | out; } else if (line < 14) { diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_sor.c b/trunk/drivers/gpu/drm/nouveau/nv50_sor.c index 274640212475..a7844ab6a50c 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/trunk/drivers/gpu/drm/nouveau/nv50_sor.c @@ -42,7 +42,7 @@ nv50_sor_dp_lane_map(struct drm_device *dev, struct dcb_entry *dcb, u8 lane) struct drm_nouveau_private *dev_priv = dev->dev_private; static const u8 nvaf[] = { 24, 16, 8, 0 }; /* thanks, apple.. */ static const u8 nv50[] = { 16, 8, 0, 24 }; - if (dev_priv->chipset == 0xaf) + if (dev_priv->card_type == 0xaf) return nvaf[lane]; return nv50[lane]; } diff --git a/trunk/drivers/gpu/drm/nouveau/nvc0_fb.c b/trunk/drivers/gpu/drm/nouveau/nvc0_fb.c index f704e942372e..5bf55038fd92 100644 --- a/trunk/drivers/gpu/drm/nouveau/nvc0_fb.c +++ b/trunk/drivers/gpu/drm/nouveau/nvc0_fb.c @@ -54,11 +54,6 @@ nvc0_mfb_isr(struct drm_device *dev) nvc0_mfb_subp_isr(dev, unit, subp); units &= ~(1 << unit); } - - /* we do something horribly wrong and upset PMFB a lot, so mask off - * interrupts from it after the first one until it's fixed - */ - nv_mask(dev, 0x000640, 0x02000000, 0x00000000); } static void diff --git a/trunk/drivers/gpu/drm/radeon/atom.c b/trunk/drivers/gpu/drm/radeon/atom.c index 5ce9bf51a8de..d1bd239cd9e9 100644 --- a/trunk/drivers/gpu/drm/radeon/atom.c +++ b/trunk/drivers/gpu/drm/radeon/atom.c @@ -1306,11 +1306,8 @@ struct atom_context *atom_parse(struct card_info *card, void *bios) int atom_asic_init(struct atom_context *ctx) { - struct radeon_device *rdev = ctx->card->dev->dev_private; int hwi = CU16(ctx->data_table + ATOM_DATA_FWI_PTR); uint32_t ps[16]; - int ret; - memset(ps, 0, 64); ps[0] = cpu_to_le32(CU32(hwi + ATOM_FWI_DEFSCLK_PTR)); @@ -1320,17 +1317,7 @@ int atom_asic_init(struct atom_context *ctx) if (!CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_INIT)) return 1; - ret = atom_execute_table(ctx, ATOM_CMD_INIT, ps); - if (ret) - return ret; - - memset(ps, 0, 64); - - if (rdev->family < CHIP_R600) { - if (CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_SPDFANCNTL)) - atom_execute_table(ctx, ATOM_CMD_SPDFANCNTL, ps); - } - return ret; + return atom_execute_table(ctx, ATOM_CMD_INIT, ps); } void atom_destroy(struct atom_context *ctx) diff --git a/trunk/drivers/gpu/drm/radeon/atom.h b/trunk/drivers/gpu/drm/radeon/atom.h index 25fea631dad2..93cfe2086ba0 100644 --- a/trunk/drivers/gpu/drm/radeon/atom.h +++ b/trunk/drivers/gpu/drm/radeon/atom.h @@ -44,7 +44,6 @@ #define ATOM_CMD_SETSCLK 0x0A #define ATOM_CMD_SETMCLK 0x0B #define ATOM_CMD_SETPCLK 0x0C -#define ATOM_CMD_SPDFANCNTL 0x39 #define ATOM_DATA_FWI_PTR 0xC #define ATOM_DATA_IIO_PTR 0x32 diff --git a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c index af1054f8202a..b5ff1f7b6f7e 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c @@ -575,9 +575,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, if (rdev->family < CHIP_RV770) pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; - /* use frac fb div on APUs */ - if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) - pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; } else { pll->flags |= RADEON_PLL_LEGACY; @@ -958,8 +955,8 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode break; } - if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || - (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { + if (radeon_encoder->active_device & + (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) { struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); diff --git a/trunk/drivers/gpu/drm/radeon/atombios_encoders.c b/trunk/drivers/gpu/drm/radeon/atombios_encoders.c index 2d39f9977e00..e607c4d7dd98 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_encoders.c @@ -230,10 +230,6 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action) if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) return; - /* some R4xx chips have the wrong frev */ - if (rdev->family <= CHIP_RV410) - frev = 1; - switch (frev) { case 1: switch (crev) { diff --git a/trunk/drivers/gpu/drm/radeon/r100.c b/trunk/drivers/gpu/drm/radeon/r100.c index fe33d35dae8c..81801c176aa5 100644 --- a/trunk/drivers/gpu/drm/radeon/r100.c +++ b/trunk/drivers/gpu/drm/radeon/r100.c @@ -2553,7 +2553,7 @@ static void r100_pll_errata_after_data(struct radeon_device *rdev) * or the chip could hang on a subsequent access */ if (rdev->pll_errata & CHIP_ERRATA_PLL_DELAY) { - mdelay(5); + udelay(5000); } /* This function is required to workaround a hardware bug in some (all?) diff --git a/trunk/drivers/gpu/drm/radeon/r600.c b/trunk/drivers/gpu/drm/radeon/r600.c index c8187c4b6ae8..391bd2636a80 100644 --- a/trunk/drivers/gpu/drm/radeon/r600.c +++ b/trunk/drivers/gpu/drm/radeon/r600.c @@ -1135,7 +1135,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc } if (rdev->flags & RADEON_IS_AGP) { size_bf = mc->gtt_start; - size_af = 0xFFFFFFFF - mc->gtt_end; + size_af = 0xFFFFFFFF - mc->gtt_end + 1; if (size_bf > size_af) { if (mc->mc_vram_size > size_bf) { dev_warn(rdev->dev, "limiting VRAM\n"); @@ -1149,7 +1149,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc mc->real_vram_size = size_af; mc->mc_vram_size = size_af; } - mc->vram_start = mc->gtt_end + 1; + mc->vram_start = mc->gtt_end; } mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", @@ -2839,7 +2839,7 @@ void r600_rlc_stop(struct radeon_device *rdev) /* r7xx asics need to soft reset RLC before halting */ WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC); RREG32(SRBM_SOFT_RESET); - mdelay(15); + udelay(15000); WREG32(SRBM_SOFT_RESET, 0); RREG32(SRBM_SOFT_RESET); } diff --git a/trunk/drivers/gpu/drm/radeon/r600_cp.c b/trunk/drivers/gpu/drm/radeon/r600_cp.c index 75ed17c96115..84c546250955 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_cp.c +++ b/trunk/drivers/gpu/drm/radeon/r600_cp.c @@ -407,7 +407,7 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); RADEON_READ(R600_GRBM_SOFT_RESET); - mdelay(15); + DRM_UDELAY(15000); RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); fw_data = (const __be32 *)dev_priv->me_fw->data; @@ -500,7 +500,7 @@ static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv) RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); RADEON_READ(R600_GRBM_SOFT_RESET); - mdelay(15); + DRM_UDELAY(15000); RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); fw_data = (const __be32 *)dev_priv->pfp_fw->data; @@ -1797,7 +1797,7 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev, RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); RADEON_READ(R600_GRBM_SOFT_RESET); - mdelay(15); + DRM_UDELAY(15000); RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_clocks.c b/trunk/drivers/gpu/drm/radeon/radeon_clocks.c index 9c6b29a41927..6ae0c75f016a 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_clocks.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_clocks.c @@ -633,7 +633,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) tmp &= ~(R300_SCLK_FORCE_VAP); tmp |= RADEON_SCLK_FORCE_CP; WREG32_PLL(RADEON_SCLK_CNTL, tmp); - mdelay(15); + udelay(15000); tmp = RREG32_PLL(R300_SCLK_CNTL2); tmp &= ~(R300_SCLK_FORCE_TCL | @@ -651,12 +651,12 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) tmp |= (RADEON_ENGIN_DYNCLK_MODE | (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT)); WREG32_PLL(RADEON_CLK_PWRMGT_CNTL, tmp); - mdelay(15); + udelay(15000); tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL); tmp |= RADEON_SCLK_DYN_START_CNTL; WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp); - mdelay(15); + udelay(15000); /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200 to lockup randomly, leave them as set by BIOS. @@ -696,7 +696,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) tmp |= RADEON_SCLK_MORE_FORCEON; } WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); - mdelay(15); + udelay(15000); } /* RV200::A11 A12, RV250::A11 A12 */ @@ -709,7 +709,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) tmp |= RADEON_TCL_BYPASS_DISABLE; WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp); } - mdelay(15); + udelay(15000); /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK) */ tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); @@ -722,14 +722,14 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) RADEON_PIXCLK_TMDS_ALWAYS_ONb); WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); - mdelay(15); + udelay(15000); tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); tmp |= (RADEON_PIXCLK_ALWAYS_ONb | RADEON_PIXCLK_DAC_ALWAYS_ONb); WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); - mdelay(15); + udelay(15000); } } else { /* Turn everything OFF (ForceON to everything) */ @@ -861,7 +861,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) } WREG32_PLL(RADEON_SCLK_CNTL, tmp); - mdelay(16); + udelay(16000); if ((rdev->family == CHIP_R300) || (rdev->family == CHIP_R350)) { @@ -870,7 +870,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) R300_SCLK_FORCE_GA | R300_SCLK_FORCE_CBA); WREG32_PLL(R300_SCLK_CNTL2, tmp); - mdelay(16); + udelay(16000); } if (rdev->flags & RADEON_IS_IGP) { @@ -878,7 +878,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) tmp &= ~(RADEON_FORCEON_MCLKA | RADEON_FORCEON_YCLKA); WREG32_PLL(RADEON_MCLK_CNTL, tmp); - mdelay(16); + udelay(16000); } if ((rdev->family == CHIP_RV200) || @@ -887,7 +887,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); tmp |= RADEON_SCLK_MORE_FORCEON; WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); - mdelay(16); + udelay(16000); } tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); @@ -900,7 +900,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) RADEON_PIXCLK_TMDS_ALWAYS_ONb); WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); - mdelay(16); + udelay(16000); tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | diff --git a/trunk/drivers/gpu/drm/radeon/radeon_combios.c b/trunk/drivers/gpu/drm/radeon/radeon_combios.c index 2cad9fde92fc..81fc100be7e1 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_combios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_combios.c @@ -2845,7 +2845,7 @@ bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder) case 4: val = RBIOS16(index); index += 2; - mdelay(val); + udelay(val * 1000); break; case 6: slave_addr = id & 0xff; @@ -3044,7 +3044,7 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset) udelay(150); break; case 2: - mdelay(1); + udelay(1000); break; case 3: while (tmp--) { @@ -3075,13 +3075,13 @@ static void combios_parse_pll_table(struct drm_device *dev, uint16_t offset) /*mclk_cntl |= 0x00001111;*//* ??? */ WREG32_PLL(RADEON_MCLK_CNTL, mclk_cntl); - mdelay(10); + udelay(10000); #endif WREG32_PLL (RADEON_CLK_PWRMGT_CNTL, tmp & ~RADEON_CG_NO1_DEBUG_0); - mdelay(10); + udelay(10000); } break; default: diff --git a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c index 3c2e7a000a2a..bd05156edbdb 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c @@ -970,7 +970,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) encoder = obj_to_encoder(obj); - if (encoder->encoder_type != DRM_MODE_ENCODER_DAC && + if (encoder->encoder_type != DRM_MODE_ENCODER_DAC || encoder->encoder_type != DRM_MODE_ENCODER_TVDAC) continue; @@ -1000,7 +1000,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) * cases the DVI port is actually a virtual KVM port connected to the service * processor. */ -out: if ((!rdev->is_atom_bios) && (ret == connector_status_disconnected) && rdev->mode_info.bios_hardcoded_edid_size) { @@ -1008,6 +1007,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) ret = connector_status_connected; } +out: /* updated in get modes as well since we need to know if it's analog or digital */ radeon_connector_update_scratch_regs(connector, ret); return ret; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c index 5992502a3448..ea7df16e2f84 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_device.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c @@ -241,8 +241,8 @@ int radeon_wb_init(struct radeon_device *rdev) rdev->wb.use_event = true; } } - /* always use writeback/events on NI, APUs */ - if (rdev->family >= CHIP_PALM) { + /* always use writeback/events on NI */ + if (ASIC_IS_DCE5(rdev)) { rdev->wb.enabled = true; rdev->wb.use_event = true; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_display.c b/trunk/drivers/gpu/drm/radeon/radeon_display.c index 0a1d4bd65edc..8086c96e0b06 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_display.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_display.c @@ -533,7 +533,7 @@ static void radeon_crtc_init(struct drm_device *dev, int index) radeon_legacy_init_crtc(dev, radeon_crtc); } -static const char *encoder_names[37] = { +static const char *encoder_names[36] = { "NONE", "INTERNAL_LVDS", "INTERNAL_TMDS1", @@ -570,7 +570,6 @@ static const char *encoder_names[37] = { "INTERNAL_UNIPHY2", "NUTMEG", "TRAVIS", - "INTERNAL_VCE" }; static const char *connector_names[15] = { diff --git a/trunk/drivers/gpu/drm/radeon/radeon_i2c.c b/trunk/drivers/gpu/drm/radeon/radeon_i2c.c index 3edec1c198e3..85bcfc8923a7 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_i2c.c @@ -900,10 +900,6 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, struct radeon_i2c_chan *i2c; int ret; - /* don't add the mm_i2c bus unless hw_i2c is enabled */ - if (rec->mm_i2c && (radeon_hw_i2c == 0)) - return NULL; - i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); if (i2c == NULL) return NULL; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c b/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c index 65060b77c805..66d5fe1c8174 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -147,12 +147,6 @@ static bool radeon_msi_ok(struct radeon_device *rdev) (rdev->pdev->subsystem_device == 0x01fd)) return true; - /* RV515 seems to have MSI issues where it loses - * MSI rearms occasionally. This leads to lockups and freezes. - * disable it by default. - */ - if (rdev->family == CHIP_RV515) - return false; if (rdev->flags & RADEON_IS_IGP) { /* APUs work fine with MSIs */ if (rdev->family >= CHIP_PALM) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 42db254f6bb0..2f46e0c8df53 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -88,7 +88,7 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode) lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); lvds_pll_cntl |= RADEON_LVDS_PLL_EN; WREG32(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl); - mdelay(1); + udelay(1000); lvds_pll_cntl = RREG32(RADEON_LVDS_PLL_CNTL); lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET; @@ -101,7 +101,7 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode) (backlight_level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT)); if (is_mac) lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN; - mdelay(panel_pwr_delay); + udelay(panel_pwr_delay * 1000); WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); break; case DRM_MODE_DPMS_STANDBY: @@ -118,10 +118,10 @@ static void radeon_legacy_lvds_update(struct drm_encoder *encoder, int mode) WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON); } - mdelay(panel_pwr_delay); + udelay(panel_pwr_delay * 1000); WREG32(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); - mdelay(panel_pwr_delay); + udelay(panel_pwr_delay * 1000); break; } @@ -656,7 +656,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc WREG32(RADEON_DAC_MACRO_CNTL, tmp); - mdelay(2); + udelay(2000); if (RREG32(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) found = connector_status_connected; @@ -1499,7 +1499,7 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN; WREG32(RADEON_DAC_CNTL2, tmp); - mdelay(10); + udelay(10000); if (ASIC_IS_R300(rdev)) { if (RREG32(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_object.c b/trunk/drivers/gpu/drm/radeon/radeon_object.c index df6a4dbd93f8..6f70158d34e4 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_object.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_object.c @@ -241,8 +241,7 @@ int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset, domain_start = bo->rdev->mc.vram_start; else domain_start = bo->rdev->mc.gtt_start; - WARN_ON_ONCE(max_offset < - (radeon_bo_gpu_offset(bo) - domain_start)); + WARN_ON_ONCE((*gpu_addr - domain_start) > max_offset); } return 0; diff --git a/trunk/drivers/gpu/drm/radeon/rv770.c b/trunk/drivers/gpu/drm/radeon/rv770.c index cdab1aeaed6e..c62ae4be3845 100644 --- a/trunk/drivers/gpu/drm/radeon/rv770.c +++ b/trunk/drivers/gpu/drm/radeon/rv770.c @@ -969,7 +969,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) } if (rdev->flags & RADEON_IS_AGP) { size_bf = mc->gtt_start; - size_af = 0xFFFFFFFF - mc->gtt_end; + size_af = 0xFFFFFFFF - mc->gtt_end + 1; if (size_bf > size_af) { if (mc->mc_vram_size > size_bf) { dev_warn(rdev->dev, "limiting VRAM\n"); @@ -983,7 +983,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) mc->real_vram_size = size_af; mc->mc_vram_size = size_af; } - mc->vram_start = mc->gtt_end + 1; + mc->vram_start = mc->gtt_end; } mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", diff --git a/trunk/drivers/gpu/drm/radeon/si.c b/trunk/drivers/gpu/drm/radeon/si.c index 27bda986fc2b..ac7a199ffece 100644 --- a/trunk/drivers/gpu/drm/radeon/si.c +++ b/trunk/drivers/gpu/drm/radeon/si.c @@ -2999,8 +2999,8 @@ int si_rlc_init(struct radeon_device *rdev) } r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM, &rdev->rlc.save_restore_gpu_addr); - radeon_bo_unreserve(rdev->rlc.save_restore_obj); if (r) { + radeon_bo_unreserve(rdev->rlc.save_restore_obj); dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r); si_rlc_fini(rdev); return r; @@ -3023,8 +3023,9 @@ int si_rlc_init(struct radeon_device *rdev) } r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM, &rdev->rlc.clear_state_gpu_addr); - radeon_bo_unreserve(rdev->rlc.clear_state_obj); if (r) { + + radeon_bo_unreserve(rdev->rlc.clear_state_obj); dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r); si_rlc_fini(rdev); return r; diff --git a/trunk/drivers/gpu/drm/savage/savage_state.c b/trunk/drivers/gpu/drm/savage/savage_state.c index b6d8608375cd..031aaaf79ac2 100644 --- a/trunk/drivers/gpu/drm/savage/savage_state.c +++ b/trunk/drivers/gpu/drm/savage/savage_state.c @@ -988,7 +988,7 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_ * for locking on FreeBSD. */ if (cmdbuf->size) { - kcmd_addr = kmalloc_array(cmdbuf->size, 8, GFP_KERNEL); + kcmd_addr = kmalloc(cmdbuf->size * 8, GFP_KERNEL); if (kcmd_addr == NULL) return -ENOMEM; @@ -1015,8 +1015,8 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_ cmdbuf->vb_addr = kvb_addr; } if (cmdbuf->nbox) { - kbox_addr = kmalloc_array(cmdbuf->nbox, sizeof(struct drm_clip_rect), - GFP_KERNEL); + kbox_addr = kmalloc(cmdbuf->nbox * sizeof(struct drm_clip_rect), + GFP_KERNEL); if (kbox_addr == NULL) { ret = -ENOMEM; goto done; diff --git a/trunk/drivers/gpu/drm/udl/udl_drv.c b/trunk/drivers/gpu/drm/udl/udl_drv.c index 53673907a6a0..5340c5f3987b 100644 --- a/trunk/drivers/gpu/drm/udl/udl_drv.c +++ b/trunk/drivers/gpu/drm/udl/udl_drv.c @@ -47,7 +47,7 @@ static struct vm_operations_struct udl_gem_vm_ops = { static const struct file_operations udl_driver_fops = { .owner = THIS_MODULE, .open = drm_open, - .mmap = udl_drm_gem_mmap, + .mmap = drm_gem_mmap, .poll = drm_poll, .read = drm_read, .unlocked_ioctl = drm_ioctl, diff --git a/trunk/drivers/gpu/drm/udl/udl_drv.h b/trunk/drivers/gpu/drm/udl/udl_drv.h index 96820d03a303..1612954a5bc4 100644 --- a/trunk/drivers/gpu/drm/udl/udl_drv.h +++ b/trunk/drivers/gpu/drm/udl/udl_drv.h @@ -121,7 +121,6 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, int udl_gem_vmap(struct udl_gem_object *obj); void udl_gem_vunmap(struct udl_gem_object *obj); -int udl_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); int udl_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, diff --git a/trunk/drivers/gpu/drm/udl/udl_gem.c b/trunk/drivers/gpu/drm/udl/udl_gem.c index 92f19ef329b0..852642dc1187 100644 --- a/trunk/drivers/gpu/drm/udl/udl_gem.c +++ b/trunk/drivers/gpu/drm/udl/udl_gem.c @@ -71,20 +71,6 @@ int udl_dumb_destroy(struct drm_file *file, struct drm_device *dev, return drm_gem_handle_delete(file, handle); } -int udl_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) -{ - int ret; - - ret = drm_gem_mmap(filp, vma); - if (ret) - return ret; - - vma->vm_flags &= ~VM_PFNMAP; - vma->vm_flags |= VM_MIXEDMAP; - - return ret; -} - int udl_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct udl_gem_object *obj = to_udl_bo(vma->vm_private_data); diff --git a/trunk/drivers/hid/Kconfig b/trunk/drivers/hid/Kconfig index ffddcba32af6..a3d033252995 100644 --- a/trunk/drivers/hid/Kconfig +++ b/trunk/drivers/hid/Kconfig @@ -34,7 +34,7 @@ config HID config HID_BATTERY_STRENGTH bool depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY - default n + default y config HIDRAW bool "/dev/hidraw raw HID device support" diff --git a/trunk/drivers/hid/hid-picolcd.c b/trunk/drivers/hid/hid-picolcd.c index 45c3433f7986..12f9777c385d 100644 --- a/trunk/drivers/hid/hid-picolcd.c +++ b/trunk/drivers/hid/hid-picolcd.c @@ -1525,6 +1525,12 @@ static const struct file_operations picolcd_debug_reset_fops = { /* * The "eeprom" file */ +static int picolcd_debug_eeprom_open(struct inode *i, struct file *f) +{ + f->private_data = i->i_private; + return 0; +} + static ssize_t picolcd_debug_eeprom_read(struct file *f, char __user *u, size_t s, loff_t *off) { @@ -1612,7 +1618,7 @@ static ssize_t picolcd_debug_eeprom_write(struct file *f, const char __user *u, */ static const struct file_operations picolcd_debug_eeprom_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = picolcd_debug_eeprom_open, .read = picolcd_debug_eeprom_read, .write = picolcd_debug_eeprom_write, .llseek = generic_file_llseek, @@ -1621,6 +1627,12 @@ static const struct file_operations picolcd_debug_eeprom_fops = { /* * The "flash" file */ +static int picolcd_debug_flash_open(struct inode *i, struct file *f) +{ + f->private_data = i->i_private; + return 0; +} + /* record a flash address to buf (bounds check to be done by caller) */ static int _picolcd_flash_setaddr(struct picolcd_data *data, u8 *buf, long off) { @@ -1805,7 +1817,7 @@ static ssize_t picolcd_debug_flash_write(struct file *f, const char __user *u, */ static const struct file_operations picolcd_debug_flash_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = picolcd_debug_flash_open, .read = picolcd_debug_flash_read, .write = picolcd_debug_flash_write, .llseek = generic_file_llseek, diff --git a/trunk/drivers/hid/hid-tivo.c b/trunk/drivers/hid/hid-tivo.c index 9f85f827607f..de47039c708c 100644 --- a/trunk/drivers/hid/hid-tivo.c +++ b/trunk/drivers/hid/hid-tivo.c @@ -62,7 +62,7 @@ static int tivo_input_mapping(struct hid_device *hdev, struct hid_input *hi, static const struct hid_device_id tivo_devices[] = { /* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */ - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) }, + { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) }, { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) }, { } }; diff --git a/trunk/drivers/hid/hid-wiimote-debug.c b/trunk/drivers/hid/hid-wiimote-debug.c index eec329197c16..17dabc1f339e 100644 --- a/trunk/drivers/hid/hid-wiimote-debug.c +++ b/trunk/drivers/hid/hid-wiimote-debug.c @@ -23,6 +23,12 @@ struct wiimote_debug { struct dentry *drm; }; +static int wiidebug_eeprom_open(struct inode *i, struct file *f) +{ + f->private_data = i->i_private; + return 0; +} + static ssize_t wiidebug_eeprom_read(struct file *f, char __user *u, size_t s, loff_t *off) { @@ -77,7 +83,7 @@ static ssize_t wiidebug_eeprom_read(struct file *f, char __user *u, size_t s, static const struct file_operations wiidebug_eeprom_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = wiidebug_eeprom_open, .read = wiidebug_eeprom_read, .llseek = generic_file_llseek, }; diff --git a/trunk/drivers/hsi/Kconfig b/trunk/drivers/hsi/Kconfig deleted file mode 100644 index d94e38dd80c7..000000000000 --- a/trunk/drivers/hsi/Kconfig +++ /dev/null @@ -1,19 +0,0 @@ -# -# HSI driver configuration -# -menuconfig HSI - tristate "HSI support" - ---help--- - The "High speed synchronous Serial Interface" is - synchronous serial interface used mainly to connect - application engines and cellular modems. - -if HSI - -config HSI_BOARDINFO - bool - default y - -source "drivers/hsi/clients/Kconfig" - -endif # HSI diff --git a/trunk/drivers/hsi/Makefile b/trunk/drivers/hsi/Makefile deleted file mode 100644 index 9d5d33f90de2..000000000000 --- a/trunk/drivers/hsi/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# Makefile for HSI -# -obj-$(CONFIG_HSI_BOARDINFO) += hsi_boardinfo.o -obj-$(CONFIG_HSI) += hsi.o -obj-y += clients/ diff --git a/trunk/drivers/hsi/clients/Kconfig b/trunk/drivers/hsi/clients/Kconfig deleted file mode 100644 index 3bacd275f479..000000000000 --- a/trunk/drivers/hsi/clients/Kconfig +++ /dev/null @@ -1,13 +0,0 @@ -# -# HSI clients configuration -# - -comment "HSI clients" - -config HSI_CHAR - tristate "HSI/SSI character driver" - depends on HSI - ---help--- - If you say Y here, you will enable the HSI/SSI character driver. - This driver provides a simple character device interface for - serial communication with the cellular modem over HSI/SSI bus. diff --git a/trunk/drivers/hsi/clients/Makefile b/trunk/drivers/hsi/clients/Makefile deleted file mode 100644 index 327c0e27c8b0..000000000000 --- a/trunk/drivers/hsi/clients/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for HSI clients -# - -obj-$(CONFIG_HSI_CHAR) += hsi_char.o diff --git a/trunk/drivers/hsi/clients/hsi_char.c b/trunk/drivers/hsi/clients/hsi_char.c deleted file mode 100644 index 3ad91f6447d8..000000000000 --- a/trunk/drivers/hsi/clients/hsi_char.c +++ /dev/null @@ -1,802 +0,0 @@ -/* - * HSI character device driver, implements the character device - * interface. - * - * Copyright (C) 2010 Nokia Corporation. All rights reserved. - * - * Contact: Andras Domokos - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define HSC_DEVS 16 /* Num of channels */ -#define HSC_MSGS 4 - -#define HSC_RXBREAK 0 - -#define HSC_ID_BITS 6 -#define HSC_PORT_ID_BITS 4 -#define HSC_ID_MASK 3 -#define HSC_PORT_ID_MASK 3 -#define HSC_CH_MASK 0xf - -/* - * We support up to 4 controllers that can have up to 4 - * ports, which should currently be more than enough. - */ -#define HSC_BASEMINOR(id, port_id) \ - ((((id) & HSC_ID_MASK) << HSC_ID_BITS) | \ - (((port_id) & HSC_PORT_ID_MASK) << HSC_PORT_ID_BITS)) - -enum { - HSC_CH_OPEN, - HSC_CH_READ, - HSC_CH_WRITE, - HSC_CH_WLINE, -}; - -enum { - HSC_RX, - HSC_TX, -}; - -struct hsc_client_data; -/** - * struct hsc_channel - hsi_char internal channel data - * @ch: channel number - * @flags: Keeps state of the channel (open/close, reading, writing) - * @free_msgs_list: List of free HSI messages/requests - * @rx_msgs_queue: List of pending RX requests - * @tx_msgs_queue: List of pending TX requests - * @lock: Serialize access to the lists - * @cl: reference to the associated hsi_client - * @cl_data: reference to the client data that this channels belongs to - * @rx_wait: RX requests wait queue - * @tx_wait: TX requests wait queue - */ -struct hsc_channel { - unsigned int ch; - unsigned long flags; - struct list_head free_msgs_list; - struct list_head rx_msgs_queue; - struct list_head tx_msgs_queue; - spinlock_t lock; - struct hsi_client *cl; - struct hsc_client_data *cl_data; - wait_queue_head_t rx_wait; - wait_queue_head_t tx_wait; -}; - -/** - * struct hsc_client_data - hsi_char internal client data - * @cdev: Characther device associated to the hsi_client - * @lock: Lock to serialize open/close access - * @flags: Keeps track of port state (rx hwbreak armed) - * @usecnt: Use count for claiming the HSI port (mutex protected) - * @cl: Referece to the HSI client - * @channels: Array of channels accessible by the client - */ -struct hsc_client_data { - struct cdev cdev; - struct mutex lock; - unsigned long flags; - unsigned int usecnt; - struct hsi_client *cl; - struct hsc_channel channels[HSC_DEVS]; -}; - -/* Stores the major number dynamically allocated for hsi_char */ -static unsigned int hsc_major; -/* Maximum buffer size that hsi_char will accept from userspace */ -static unsigned int max_data_size = 0x1000; -module_param(max_data_size, uint, 0); -MODULE_PARM_DESC(max_data_size, "max read/write data size [4,8..65536] (^2)"); - -static void hsc_add_tail(struct hsc_channel *channel, struct hsi_msg *msg, - struct list_head *queue) -{ - unsigned long flags; - - spin_lock_irqsave(&channel->lock, flags); - list_add_tail(&msg->link, queue); - spin_unlock_irqrestore(&channel->lock, flags); -} - -static struct hsi_msg *hsc_get_first_msg(struct hsc_channel *channel, - struct list_head *queue) -{ - struct hsi_msg *msg = NULL; - unsigned long flags; - - spin_lock_irqsave(&channel->lock, flags); - - if (list_empty(queue)) - goto out; - - msg = list_first_entry(queue, struct hsi_msg, link); - list_del(&msg->link); -out: - spin_unlock_irqrestore(&channel->lock, flags); - - return msg; -} - -static inline void hsc_msg_free(struct hsi_msg *msg) -{ - kfree(sg_virt(msg->sgt.sgl)); - hsi_free_msg(msg); -} - -static void hsc_free_list(struct list_head *list) -{ - struct hsi_msg *msg, *tmp; - - list_for_each_entry_safe(msg, tmp, list, link) { - list_del(&msg->link); - hsc_msg_free(msg); - } -} - -static void hsc_reset_list(struct hsc_channel *channel, struct list_head *l) -{ - unsigned long flags; - LIST_HEAD(list); - - spin_lock_irqsave(&channel->lock, flags); - list_splice_init(l, &list); - spin_unlock_irqrestore(&channel->lock, flags); - - hsc_free_list(&list); -} - -static inline struct hsi_msg *hsc_msg_alloc(unsigned int alloc_size) -{ - struct hsi_msg *msg; - void *buf; - - msg = hsi_alloc_msg(1, GFP_KERNEL); - if (!msg) - goto out; - buf = kmalloc(alloc_size, GFP_KERNEL); - if (!buf) { - hsi_free_msg(msg); - goto out; - } - sg_init_one(msg->sgt.sgl, buf, alloc_size); - /* Ignore false positive, due to sg pointer handling */ - kmemleak_ignore(buf); - - return msg; -out: - return NULL; -} - -static inline int hsc_msgs_alloc(struct hsc_channel *channel) -{ - struct hsi_msg *msg; - int i; - - for (i = 0; i < HSC_MSGS; i++) { - msg = hsc_msg_alloc(max_data_size); - if (!msg) - goto out; - msg->channel = channel->ch; - list_add_tail(&msg->link, &channel->free_msgs_list); - } - - return 0; -out: - hsc_free_list(&channel->free_msgs_list); - - return -ENOMEM; -} - -static inline unsigned int hsc_msg_len_get(struct hsi_msg *msg) -{ - return msg->sgt.sgl->length; -} - -static inline void hsc_msg_len_set(struct hsi_msg *msg, unsigned int len) -{ - msg->sgt.sgl->length = len; -} - -static void hsc_rx_completed(struct hsi_msg *msg) -{ - struct hsc_client_data *cl_data = hsi_client_drvdata(msg->cl); - struct hsc_channel *channel = cl_data->channels + msg->channel; - - if (test_bit(HSC_CH_READ, &channel->flags)) { - hsc_add_tail(channel, msg, &channel->rx_msgs_queue); - wake_up(&channel->rx_wait); - } else { - hsc_add_tail(channel, msg, &channel->free_msgs_list); - } -} - -static void hsc_rx_msg_destructor(struct hsi_msg *msg) -{ - msg->status = HSI_STATUS_ERROR; - hsc_msg_len_set(msg, 0); - hsc_rx_completed(msg); -} - -static void hsc_tx_completed(struct hsi_msg *msg) -{ - struct hsc_client_data *cl_data = hsi_client_drvdata(msg->cl); - struct hsc_channel *channel = cl_data->channels + msg->channel; - - if (test_bit(HSC_CH_WRITE, &channel->flags)) { - hsc_add_tail(channel, msg, &channel->tx_msgs_queue); - wake_up(&channel->tx_wait); - } else { - hsc_add_tail(channel, msg, &channel->free_msgs_list); - } -} - -static void hsc_tx_msg_destructor(struct hsi_msg *msg) -{ - msg->status = HSI_STATUS_ERROR; - hsc_msg_len_set(msg, 0); - hsc_tx_completed(msg); -} - -static void hsc_break_req_destructor(struct hsi_msg *msg) -{ - struct hsc_client_data *cl_data = hsi_client_drvdata(msg->cl); - - hsi_free_msg(msg); - clear_bit(HSC_RXBREAK, &cl_data->flags); -} - -static void hsc_break_received(struct hsi_msg *msg) -{ - struct hsc_client_data *cl_data = hsi_client_drvdata(msg->cl); - struct hsc_channel *channel = cl_data->channels; - int i, ret; - - /* Broadcast HWBREAK on all channels */ - for (i = 0; i < HSC_DEVS; i++, channel++) { - struct hsi_msg *msg2; - - if (!test_bit(HSC_CH_READ, &channel->flags)) - continue; - msg2 = hsc_get_first_msg(channel, &channel->free_msgs_list); - if (!msg2) - continue; - clear_bit(HSC_CH_READ, &channel->flags); - hsc_msg_len_set(msg2, 0); - msg2->status = HSI_STATUS_COMPLETED; - hsc_add_tail(channel, msg2, &channel->rx_msgs_queue); - wake_up(&channel->rx_wait); - } - hsi_flush(msg->cl); - ret = hsi_async_read(msg->cl, msg); - if (ret < 0) - hsc_break_req_destructor(msg); -} - -static int hsc_break_request(struct hsi_client *cl) -{ - struct hsc_client_data *cl_data = hsi_client_drvdata(cl); - struct hsi_msg *msg; - int ret; - - if (test_and_set_bit(HSC_RXBREAK, &cl_data->flags)) - return -EBUSY; - - msg = hsi_alloc_msg(0, GFP_KERNEL); - if (!msg) { - clear_bit(HSC_RXBREAK, &cl_data->flags); - return -ENOMEM; - } - msg->break_frame = 1; - msg->complete = hsc_break_received; - msg->destructor = hsc_break_req_destructor; - ret = hsi_async_read(cl, msg); - if (ret < 0) - hsc_break_req_destructor(msg); - - return ret; -} - -static int hsc_break_send(struct hsi_client *cl) -{ - struct hsi_msg *msg; - int ret; - - msg = hsi_alloc_msg(0, GFP_ATOMIC); - if (!msg) - return -ENOMEM; - msg->break_frame = 1; - msg->complete = hsi_free_msg; - msg->destructor = hsi_free_msg; - ret = hsi_async_write(cl, msg); - if (ret < 0) - hsi_free_msg(msg); - - return ret; -} - -static int hsc_rx_set(struct hsi_client *cl, struct hsc_rx_config *rxc) -{ - struct hsi_config tmp; - int ret; - - if ((rxc->mode != HSI_MODE_STREAM) && (rxc->mode != HSI_MODE_FRAME)) - return -EINVAL; - if ((rxc->channels == 0) || (rxc->channels > HSC_DEVS)) - return -EINVAL; - if (rxc->channels & (rxc->channels - 1)) - return -EINVAL; - if ((rxc->flow != HSI_FLOW_SYNC) && (rxc->flow != HSI_FLOW_PIPE)) - return -EINVAL; - tmp = cl->rx_cfg; - cl->rx_cfg.mode = rxc->mode; - cl->rx_cfg.channels = rxc->channels; - cl->rx_cfg.flow = rxc->flow; - ret = hsi_setup(cl); - if (ret < 0) { - cl->rx_cfg = tmp; - return ret; - } - if (rxc->mode == HSI_MODE_FRAME) - hsc_break_request(cl); - - return ret; -} - -static inline void hsc_rx_get(struct hsi_client *cl, struct hsc_rx_config *rxc) -{ - rxc->mode = cl->rx_cfg.mode; - rxc->channels = cl->rx_cfg.channels; - rxc->flow = cl->rx_cfg.flow; -} - -static int hsc_tx_set(struct hsi_client *cl, struct hsc_tx_config *txc) -{ - struct hsi_config tmp; - int ret; - - if ((txc->mode != HSI_MODE_STREAM) && (txc->mode != HSI_MODE_FRAME)) - return -EINVAL; - if ((txc->channels == 0) || (txc->channels > HSC_DEVS)) - return -EINVAL; - if (txc->channels & (txc->channels - 1)) - return -EINVAL; - if ((txc->arb_mode != HSI_ARB_RR) && (txc->arb_mode != HSI_ARB_PRIO)) - return -EINVAL; - tmp = cl->tx_cfg; - cl->tx_cfg.mode = txc->mode; - cl->tx_cfg.channels = txc->channels; - cl->tx_cfg.speed = txc->speed; - cl->tx_cfg.arb_mode = txc->arb_mode; - ret = hsi_setup(cl); - if (ret < 0) { - cl->tx_cfg = tmp; - return ret; - } - - return ret; -} - -static inline void hsc_tx_get(struct hsi_client *cl, struct hsc_tx_config *txc) -{ - txc->mode = cl->tx_cfg.mode; - txc->channels = cl->tx_cfg.channels; - txc->speed = cl->tx_cfg.speed; - txc->arb_mode = cl->tx_cfg.arb_mode; -} - -static ssize_t hsc_read(struct file *file, char __user *buf, size_t len, - loff_t *ppos __maybe_unused) -{ - struct hsc_channel *channel = file->private_data; - struct hsi_msg *msg; - ssize_t ret; - - if (len == 0) - return 0; - if (!IS_ALIGNED(len, sizeof(u32))) - return -EINVAL; - if (len > max_data_size) - len = max_data_size; - if (channel->ch >= channel->cl->rx_cfg.channels) - return -ECHRNG; - if (test_and_set_bit(HSC_CH_READ, &channel->flags)) - return -EBUSY; - msg = hsc_get_first_msg(channel, &channel->free_msgs_list); - if (!msg) { - ret = -ENOSPC; - goto out; - } - hsc_msg_len_set(msg, len); - msg->complete = hsc_rx_completed; - msg->destructor = hsc_rx_msg_destructor; - ret = hsi_async_read(channel->cl, msg); - if (ret < 0) { - hsc_add_tail(channel, msg, &channel->free_msgs_list); - goto out; - } - - ret = wait_event_interruptible(channel->rx_wait, - !list_empty(&channel->rx_msgs_queue)); - if (ret < 0) { - clear_bit(HSC_CH_READ, &channel->flags); - hsi_flush(channel->cl); - return -EINTR; - } - - msg = hsc_get_first_msg(channel, &channel->rx_msgs_queue); - if (msg) { - if (msg->status != HSI_STATUS_ERROR) { - ret = copy_to_user((void __user *)buf, - sg_virt(msg->sgt.sgl), hsc_msg_len_get(msg)); - if (ret) - ret = -EFAULT; - else - ret = hsc_msg_len_get(msg); - } else { - ret = -EIO; - } - hsc_add_tail(channel, msg, &channel->free_msgs_list); - } -out: - clear_bit(HSC_CH_READ, &channel->flags); - - return ret; -} - -static ssize_t hsc_write(struct file *file, const char __user *buf, size_t len, - loff_t *ppos __maybe_unused) -{ - struct hsc_channel *channel = file->private_data; - struct hsi_msg *msg; - ssize_t ret; - - if ((len == 0) || !IS_ALIGNED(len, sizeof(u32))) - return -EINVAL; - if (len > max_data_size) - len = max_data_size; - if (channel->ch >= channel->cl->tx_cfg.channels) - return -ECHRNG; - if (test_and_set_bit(HSC_CH_WRITE, &channel->flags)) - return -EBUSY; - msg = hsc_get_first_msg(channel, &channel->free_msgs_list); - if (!msg) { - clear_bit(HSC_CH_WRITE, &channel->flags); - return -ENOSPC; - } - if (copy_from_user(sg_virt(msg->sgt.sgl), (void __user *)buf, len)) { - ret = -EFAULT; - goto out; - } - hsc_msg_len_set(msg, len); - msg->complete = hsc_tx_completed; - msg->destructor = hsc_tx_msg_destructor; - ret = hsi_async_write(channel->cl, msg); - if (ret < 0) - goto out; - - ret = wait_event_interruptible(channel->tx_wait, - !list_empty(&channel->tx_msgs_queue)); - if (ret < 0) { - clear_bit(HSC_CH_WRITE, &channel->flags); - hsi_flush(channel->cl); - return -EINTR; - } - - msg = hsc_get_first_msg(channel, &channel->tx_msgs_queue); - if (msg) { - if (msg->status == HSI_STATUS_ERROR) - ret = -EIO; - else - ret = hsc_msg_len_get(msg); - - hsc_add_tail(channel, msg, &channel->free_msgs_list); - } -out: - clear_bit(HSC_CH_WRITE, &channel->flags); - - return ret; -} - -static long hsc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct hsc_channel *channel = file->private_data; - unsigned int state; - struct hsc_rx_config rxc; - struct hsc_tx_config txc; - long ret = 0; - - switch (cmd) { - case HSC_RESET: - hsi_flush(channel->cl); - break; - case HSC_SET_PM: - if (copy_from_user(&state, (void __user *)arg, sizeof(state))) - return -EFAULT; - if (state == HSC_PM_DISABLE) { - if (test_and_set_bit(HSC_CH_WLINE, &channel->flags)) - return -EINVAL; - ret = hsi_start_tx(channel->cl); - } else if (state == HSC_PM_ENABLE) { - if (!test_and_clear_bit(HSC_CH_WLINE, &channel->flags)) - return -EINVAL; - ret = hsi_stop_tx(channel->cl); - } else { - ret = -EINVAL; - } - break; - case HSC_SEND_BREAK: - return hsc_break_send(channel->cl); - case HSC_SET_RX: - if (copy_from_user(&rxc, (void __user *)arg, sizeof(rxc))) - return -EFAULT; - return hsc_rx_set(channel->cl, &rxc); - case HSC_GET_RX: - hsc_rx_get(channel->cl, &rxc); - if (copy_to_user((void __user *)arg, &rxc, sizeof(rxc))) - return -EFAULT; - break; - case HSC_SET_TX: - if (copy_from_user(&txc, (void __user *)arg, sizeof(txc))) - return -EFAULT; - return hsc_tx_set(channel->cl, &txc); - case HSC_GET_TX: - hsc_tx_get(channel->cl, &txc); - if (copy_to_user((void __user *)arg, &txc, sizeof(txc))) - return -EFAULT; - break; - default: - return -ENOIOCTLCMD; - } - - return ret; -} - -static inline void __hsc_port_release(struct hsc_client_data *cl_data) -{ - BUG_ON(cl_data->usecnt == 0); - - if (--cl_data->usecnt == 0) { - hsi_flush(cl_data->cl); - hsi_release_port(cl_data->cl); - } -} - -static int hsc_open(struct inode *inode, struct file *file) -{ - struct hsc_client_data *cl_data; - struct hsc_channel *channel; - int ret = 0; - - pr_debug("open, minor = %d\n", iminor(inode)); - - cl_data = container_of(inode->i_cdev, struct hsc_client_data, cdev); - mutex_lock(&cl_data->lock); - channel = cl_data->channels + (iminor(inode) & HSC_CH_MASK); - - if (test_and_set_bit(HSC_CH_OPEN, &channel->flags)) { - ret = -EBUSY; - goto out; - } - /* - * Check if we have already claimed the port associated to the HSI - * client. If not then try to claim it, else increase its refcount - */ - if (cl_data->usecnt == 0) { - ret = hsi_claim_port(cl_data->cl, 0); - if (ret < 0) - goto out; - hsi_setup(cl_data->cl); - } - cl_data->usecnt++; - - ret = hsc_msgs_alloc(channel); - if (ret < 0) { - __hsc_port_release(cl_data); - goto out; - } - - file->private_data = channel; - mutex_unlock(&cl_data->lock); - - return ret; -out: - mutex_unlock(&cl_data->lock); - - return ret; -} - -static int hsc_release(struct inode *inode __maybe_unused, struct file *file) -{ - struct hsc_channel *channel = file->private_data; - struct hsc_client_data *cl_data = channel->cl_data; - - mutex_lock(&cl_data->lock); - file->private_data = NULL; - if (test_and_clear_bit(HSC_CH_WLINE, &channel->flags)) - hsi_stop_tx(channel->cl); - __hsc_port_release(cl_data); - hsc_reset_list(channel, &channel->rx_msgs_queue); - hsc_reset_list(channel, &channel->tx_msgs_queue); - hsc_reset_list(channel, &channel->free_msgs_list); - clear_bit(HSC_CH_READ, &channel->flags); - clear_bit(HSC_CH_WRITE, &channel->flags); - clear_bit(HSC_CH_OPEN, &channel->flags); - wake_up(&channel->rx_wait); - wake_up(&channel->tx_wait); - mutex_unlock(&cl_data->lock); - - return 0; -} - -static const struct file_operations hsc_fops = { - .owner = THIS_MODULE, - .read = hsc_read, - .write = hsc_write, - .unlocked_ioctl = hsc_ioctl, - .open = hsc_open, - .release = hsc_release, -}; - -static void __devinit hsc_channel_init(struct hsc_channel *channel) -{ - init_waitqueue_head(&channel->rx_wait); - init_waitqueue_head(&channel->tx_wait); - spin_lock_init(&channel->lock); - INIT_LIST_HEAD(&channel->free_msgs_list); - INIT_LIST_HEAD(&channel->rx_msgs_queue); - INIT_LIST_HEAD(&channel->tx_msgs_queue); -} - -static int __devinit hsc_probe(struct device *dev) -{ - const char devname[] = "hsi_char"; - struct hsc_client_data *cl_data; - struct hsc_channel *channel; - struct hsi_client *cl = to_hsi_client(dev); - unsigned int hsc_baseminor; - dev_t hsc_dev; - int ret; - int i; - - cl_data = kzalloc(sizeof(*cl_data), GFP_KERNEL); - if (!cl_data) { - dev_err(dev, "Could not allocate hsc_client_data\n"); - return -ENOMEM; - } - hsc_baseminor = HSC_BASEMINOR(hsi_id(cl), hsi_port_id(cl)); - if (!hsc_major) { - ret = alloc_chrdev_region(&hsc_dev, hsc_baseminor, - HSC_DEVS, devname); - if (ret > 0) - hsc_major = MAJOR(hsc_dev); - } else { - hsc_dev = MKDEV(hsc_major, hsc_baseminor); - ret = register_chrdev_region(hsc_dev, HSC_DEVS, devname); - } - if (ret < 0) { - dev_err(dev, "Device %s allocation failed %d\n", - hsc_major ? "minor" : "major", ret); - goto out1; - } - mutex_init(&cl_data->lock); - hsi_client_set_drvdata(cl, cl_data); - cdev_init(&cl_data->cdev, &hsc_fops); - cl_data->cdev.owner = THIS_MODULE; - cl_data->cl = cl; - for (i = 0, channel = cl_data->channels; i < HSC_DEVS; i++, channel++) { - hsc_channel_init(channel); - channel->ch = i; - channel->cl = cl; - channel->cl_data = cl_data; - } - - /* 1 hsi client -> N char devices (one for each channel) */ - ret = cdev_add(&cl_data->cdev, hsc_dev, HSC_DEVS); - if (ret) { - dev_err(dev, "Could not add char device %d\n", ret); - goto out2; - } - - return 0; -out2: - unregister_chrdev_region(hsc_dev, HSC_DEVS); -out1: - kfree(cl_data); - - return ret; -} - -static int __devexit hsc_remove(struct device *dev) -{ - struct hsi_client *cl = to_hsi_client(dev); - struct hsc_client_data *cl_data = hsi_client_drvdata(cl); - dev_t hsc_dev = cl_data->cdev.dev; - - cdev_del(&cl_data->cdev); - unregister_chrdev_region(hsc_dev, HSC_DEVS); - hsi_client_set_drvdata(cl, NULL); - kfree(cl_data); - - return 0; -} - -static struct hsi_client_driver hsc_driver = { - .driver = { - .name = "hsi_char", - .owner = THIS_MODULE, - .probe = hsc_probe, - .remove = __devexit_p(hsc_remove), - }, -}; - -static int __init hsc_init(void) -{ - int ret; - - if ((max_data_size < 4) || (max_data_size > 0x10000) || - (max_data_size & (max_data_size - 1))) { - pr_err("Invalid max read/write data size"); - return -EINVAL; - } - - ret = hsi_register_client_driver(&hsc_driver); - if (ret) { - pr_err("Error while registering HSI/SSI driver %d", ret); - return ret; - } - - pr_info("HSI/SSI char device loaded\n"); - - return 0; -} -module_init(hsc_init); - -static void __exit hsc_exit(void) -{ - hsi_unregister_client_driver(&hsc_driver); - pr_info("HSI char device removed\n"); -} -module_exit(hsc_exit); - -MODULE_AUTHOR("Andras Domokos "); -MODULE_ALIAS("hsi:hsi_char"); -MODULE_DESCRIPTION("HSI character device"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/hsi/hsi.c b/trunk/drivers/hsi/hsi.c deleted file mode 100644 index 2d58f939d27f..000000000000 --- a/trunk/drivers/hsi/hsi.c +++ /dev/null @@ -1,507 +0,0 @@ -/* - * HSI core. - * - * Copyright (C) 2010 Nokia Corporation. All rights reserved. - * - * Contact: Carlos Chinea - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include -#include -#include -#include -#include -#include -#include -#include "hsi_core.h" - -static ssize_t modalias_show(struct device *dev, - struct device_attribute *a __maybe_unused, char *buf) -{ - return sprintf(buf, "hsi:%s\n", dev_name(dev)); -} - -static struct device_attribute hsi_bus_dev_attrs[] = { - __ATTR_RO(modalias), - __ATTR_NULL, -}; - -static int hsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - add_uevent_var(env, "MODALIAS=hsi:%s", dev_name(dev)); - - return 0; -} - -static int hsi_bus_match(struct device *dev, struct device_driver *driver) -{ - return strcmp(dev_name(dev), driver->name) == 0; -} - -static struct bus_type hsi_bus_type = { - .name = "hsi", - .dev_attrs = hsi_bus_dev_attrs, - .match = hsi_bus_match, - .uevent = hsi_bus_uevent, -}; - -static void hsi_client_release(struct device *dev) -{ - kfree(to_hsi_client(dev)); -} - -static void hsi_new_client(struct hsi_port *port, struct hsi_board_info *info) -{ - struct hsi_client *cl; - - cl = kzalloc(sizeof(*cl), GFP_KERNEL); - if (!cl) - return; - cl->tx_cfg = info->tx_cfg; - cl->rx_cfg = info->rx_cfg; - cl->device.bus = &hsi_bus_type; - cl->device.parent = &port->device; - cl->device.release = hsi_client_release; - dev_set_name(&cl->device, info->name); - cl->device.platform_data = info->platform_data; - if (info->archdata) - cl->device.archdata = *info->archdata; - if (device_register(&cl->device) < 0) { - pr_err("hsi: failed to register client: %s\n", info->name); - put_device(&cl->device); - } -} - -static void hsi_scan_board_info(struct hsi_controller *hsi) -{ - struct hsi_cl_info *cl_info; - struct hsi_port *p; - - list_for_each_entry(cl_info, &hsi_board_list, list) - if (cl_info->info.hsi_id == hsi->id) { - p = hsi_find_port_num(hsi, cl_info->info.port); - if (!p) - continue; - hsi_new_client(p, &cl_info->info); - } -} - -static int hsi_remove_client(struct device *dev, void *data __maybe_unused) -{ - device_unregister(dev); - - return 0; -} - -static int hsi_remove_port(struct device *dev, void *data __maybe_unused) -{ - device_for_each_child(dev, NULL, hsi_remove_client); - device_unregister(dev); - - return 0; -} - -static void hsi_controller_release(struct device *dev) -{ - struct hsi_controller *hsi = to_hsi_controller(dev); - - kfree(hsi->port); - kfree(hsi); -} - -static void hsi_port_release(struct device *dev) -{ - kfree(to_hsi_port(dev)); -} - -/** - * hsi_unregister_controller - Unregister an HSI controller - * @hsi: The HSI controller to register - */ -void hsi_unregister_controller(struct hsi_controller *hsi) -{ - device_for_each_child(&hsi->device, NULL, hsi_remove_port); - device_unregister(&hsi->device); -} -EXPORT_SYMBOL_GPL(hsi_unregister_controller); - -/** - * hsi_register_controller - Register an HSI controller and its ports - * @hsi: The HSI controller to register - * - * Returns -errno on failure, 0 on success. - */ -int hsi_register_controller(struct hsi_controller *hsi) -{ - unsigned int i; - int err; - - err = device_add(&hsi->device); - if (err < 0) - return err; - for (i = 0; i < hsi->num_ports; i++) { - hsi->port[i]->device.parent = &hsi->device; - err = device_add(&hsi->port[i]->device); - if (err < 0) - goto out; - } - /* Populate HSI bus with HSI clients */ - hsi_scan_board_info(hsi); - - return 0; -out: - while (i-- > 0) - device_del(&hsi->port[i]->device); - device_del(&hsi->device); - - return err; -} -EXPORT_SYMBOL_GPL(hsi_register_controller); - -/** - * hsi_register_client_driver - Register an HSI client to the HSI bus - * @drv: HSI client driver to register - * - * Returns -errno on failure, 0 on success. - */ -int hsi_register_client_driver(struct hsi_client_driver *drv) -{ - drv->driver.bus = &hsi_bus_type; - - return driver_register(&drv->driver); -} -EXPORT_SYMBOL_GPL(hsi_register_client_driver); - -static inline int hsi_dummy_msg(struct hsi_msg *msg __maybe_unused) -{ - return 0; -} - -static inline int hsi_dummy_cl(struct hsi_client *cl __maybe_unused) -{ - return 0; -} - -/** - * hsi_put_controller - Free an HSI controller - * - * @hsi: Pointer to the HSI controller to freed - * - * HSI controller drivers should only use this function if they need - * to free their allocated hsi_controller structures before a successful - * call to hsi_register_controller. Other use is not allowed. - */ -void hsi_put_controller(struct hsi_controller *hsi) -{ - unsigned int i; - - if (!hsi) - return; - - for (i = 0; i < hsi->num_ports; i++) - if (hsi->port && hsi->port[i]) - put_device(&hsi->port[i]->device); - put_device(&hsi->device); -} -EXPORT_SYMBOL_GPL(hsi_put_controller); - -/** - * hsi_alloc_controller - Allocate an HSI controller and its ports - * @n_ports: Number of ports on the HSI controller - * @flags: Kernel allocation flags - * - * Return NULL on failure or a pointer to an hsi_controller on success. - */ -struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags) -{ - struct hsi_controller *hsi; - struct hsi_port **port; - unsigned int i; - - if (!n_ports) - return NULL; - - hsi = kzalloc(sizeof(*hsi), flags); - if (!hsi) - return NULL; - port = kzalloc(sizeof(*port)*n_ports, flags); - if (!port) { - kfree(hsi); - return NULL; - } - hsi->num_ports = n_ports; - hsi->port = port; - hsi->device.release = hsi_controller_release; - device_initialize(&hsi->device); - - for (i = 0; i < n_ports; i++) { - port[i] = kzalloc(sizeof(**port), flags); - if (port[i] == NULL) - goto out; - port[i]->num = i; - port[i]->async = hsi_dummy_msg; - port[i]->setup = hsi_dummy_cl; - port[i]->flush = hsi_dummy_cl; - port[i]->start_tx = hsi_dummy_cl; - port[i]->stop_tx = hsi_dummy_cl; - port[i]->release = hsi_dummy_cl; - mutex_init(&port[i]->lock); - ATOMIC_INIT_NOTIFIER_HEAD(&port[i]->n_head); - dev_set_name(&port[i]->device, "port%d", i); - hsi->port[i]->device.release = hsi_port_release; - device_initialize(&hsi->port[i]->device); - } - - return hsi; -out: - hsi_put_controller(hsi); - - return NULL; -} -EXPORT_SYMBOL_GPL(hsi_alloc_controller); - -/** - * hsi_free_msg - Free an HSI message - * @msg: Pointer to the HSI message - * - * Client is responsible to free the buffers pointed by the scatterlists. - */ -void hsi_free_msg(struct hsi_msg *msg) -{ - if (!msg) - return; - sg_free_table(&msg->sgt); - kfree(msg); -} -EXPORT_SYMBOL_GPL(hsi_free_msg); - -/** - * hsi_alloc_msg - Allocate an HSI message - * @nents: Number of memory entries - * @flags: Kernel allocation flags - * - * nents can be 0. This mainly makes sense for read transfer. - * In that case, HSI drivers will call the complete callback when - * there is data to be read without consuming it. - * - * Return NULL on failure or a pointer to an hsi_msg on success. - */ -struct hsi_msg *hsi_alloc_msg(unsigned int nents, gfp_t flags) -{ - struct hsi_msg *msg; - int err; - - msg = kzalloc(sizeof(*msg), flags); - if (!msg) - return NULL; - - if (!nents) - return msg; - - err = sg_alloc_table(&msg->sgt, nents, flags); - if (unlikely(err)) { - kfree(msg); - msg = NULL; - } - - return msg; -} -EXPORT_SYMBOL_GPL(hsi_alloc_msg); - -/** - * hsi_async - Submit an HSI transfer to the controller - * @cl: HSI client sending the transfer - * @msg: The HSI transfer passed to controller - * - * The HSI message must have the channel, ttype, complete and destructor - * fields set beforehand. If nents > 0 then the client has to initialize - * also the scatterlists to point to the buffers to write to or read from. - * - * HSI controllers relay on pre-allocated buffers from their clients and they - * do not allocate buffers on their own. - * - * Once the HSI message transfer finishes, the HSI controller calls the - * complete callback with the status and actual_len fields of the HSI message - * updated. The complete callback can be called before returning from - * hsi_async. - * - * Returns -errno on failure or 0 on success - */ -int hsi_async(struct hsi_client *cl, struct hsi_msg *msg) -{ - struct hsi_port *port = hsi_get_port(cl); - - if (!hsi_port_claimed(cl)) - return -EACCES; - - WARN_ON_ONCE(!msg->destructor || !msg->complete); - msg->cl = cl; - - return port->async(msg); -} -EXPORT_SYMBOL_GPL(hsi_async); - -/** - * hsi_claim_port - Claim the HSI client's port - * @cl: HSI client that wants to claim its port - * @share: Flag to indicate if the client wants to share the port or not. - * - * Returns -errno on failure, 0 on success. - */ -int hsi_claim_port(struct hsi_client *cl, unsigned int share) -{ - struct hsi_port *port = hsi_get_port(cl); - int err = 0; - - mutex_lock(&port->lock); - if ((port->claimed) && (!port->shared || !share)) { - err = -EBUSY; - goto out; - } - if (!try_module_get(to_hsi_controller(port->device.parent)->owner)) { - err = -ENODEV; - goto out; - } - port->claimed++; - port->shared = !!share; - cl->pclaimed = 1; -out: - mutex_unlock(&port->lock); - - return err; -} -EXPORT_SYMBOL_GPL(hsi_claim_port); - -/** - * hsi_release_port - Release the HSI client's port - * @cl: HSI client which previously claimed its port - */ -void hsi_release_port(struct hsi_client *cl) -{ - struct hsi_port *port = hsi_get_port(cl); - - mutex_lock(&port->lock); - /* Allow HW driver to do some cleanup */ - port->release(cl); - if (cl->pclaimed) - port->claimed--; - BUG_ON(port->claimed < 0); - cl->pclaimed = 0; - if (!port->claimed) - port->shared = 0; - module_put(to_hsi_controller(port->device.parent)->owner); - mutex_unlock(&port->lock); -} -EXPORT_SYMBOL_GPL(hsi_release_port); - -static int hsi_event_notifier_call(struct notifier_block *nb, - unsigned long event, void *data __maybe_unused) -{ - struct hsi_client *cl = container_of(nb, struct hsi_client, nb); - - (*cl->ehandler)(cl, event); - - return 0; -} - -/** - * hsi_register_port_event - Register a client to receive port events - * @cl: HSI client that wants to receive port events - * @cb: Event handler callback - * - * Clients should register a callback to be able to receive - * events from the ports. Registration should happen after - * claiming the port. - * The handler can be called in interrupt context. - * - * Returns -errno on error, or 0 on success. - */ -int hsi_register_port_event(struct hsi_client *cl, - void (*handler)(struct hsi_client *, unsigned long)) -{ - struct hsi_port *port = hsi_get_port(cl); - - if (!handler || cl->ehandler) - return -EINVAL; - if (!hsi_port_claimed(cl)) - return -EACCES; - cl->ehandler = handler; - cl->nb.notifier_call = hsi_event_notifier_call; - - return atomic_notifier_chain_register(&port->n_head, &cl->nb); -} -EXPORT_SYMBOL_GPL(hsi_register_port_event); - -/** - * hsi_unregister_port_event - Stop receiving port events for a client - * @cl: HSI client that wants to stop receiving port events - * - * Clients should call this function before releasing their associated - * port. - * - * Returns -errno on error, or 0 on success. - */ -int hsi_unregister_port_event(struct hsi_client *cl) -{ - struct hsi_port *port = hsi_get_port(cl); - int err; - - WARN_ON(!hsi_port_claimed(cl)); - - err = atomic_notifier_chain_unregister(&port->n_head, &cl->nb); - if (!err) - cl->ehandler = NULL; - - return err; -} -EXPORT_SYMBOL_GPL(hsi_unregister_port_event); - -/** - * hsi_event -Notifies clients about port events - * @port: Port where the event occurred - * @event: The event type - * - * Clients should not be concerned about wake line behavior. However, due - * to a race condition in HSI HW protocol, clients need to be notified - * about wake line changes, so they can implement a workaround for it. - * - * Events: - * HSI_EVENT_START_RX - Incoming wake line high - * HSI_EVENT_STOP_RX - Incoming wake line down - * - * Returns -errno on error, or 0 on success. - */ -int hsi_event(struct hsi_port *port, unsigned long event) -{ - return atomic_notifier_call_chain(&port->n_head, event, NULL); -} -EXPORT_SYMBOL_GPL(hsi_event); - -static int __init hsi_init(void) -{ - return bus_register(&hsi_bus_type); -} -postcore_initcall(hsi_init); - -static void __exit hsi_exit(void) -{ - bus_unregister(&hsi_bus_type); -} -module_exit(hsi_exit); - -MODULE_AUTHOR("Carlos Chinea "); -MODULE_DESCRIPTION("High-speed Synchronous Serial Interface (HSI) framework"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/hsi/hsi_boardinfo.c b/trunk/drivers/hsi/hsi_boardinfo.c deleted file mode 100644 index e56bc6da5f98..000000000000 --- a/trunk/drivers/hsi/hsi_boardinfo.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * HSI clients registration interface - * - * Copyright (C) 2010 Nokia Corporation. All rights reserved. - * - * Contact: Carlos Chinea - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include -#include -#include -#include "hsi_core.h" - -/* - * hsi_board_list is only used internally by the HSI framework. - * No one else is allowed to make use of it. - */ -LIST_HEAD(hsi_board_list); -EXPORT_SYMBOL_GPL(hsi_board_list); - -/** - * hsi_register_board_info - Register HSI clients information - * @info: Array of HSI clients on the board - * @len: Length of the array - * - * HSI clients are statically declared and registered on board files. - * - * HSI clients will be automatically registered to the HSI bus once the - * controller and the port where the clients wishes to attach are registered - * to it. - * - * Return -errno on failure, 0 on success. - */ -int __init hsi_register_board_info(struct hsi_board_info const *info, - unsigned int len) -{ - struct hsi_cl_info *cl_info; - - cl_info = kzalloc(sizeof(*cl_info) * len, GFP_KERNEL); - if (!cl_info) - return -ENOMEM; - - for (; len; len--, info++, cl_info++) { - cl_info->info = *info; - list_add_tail(&cl_info->list, &hsi_board_list); - } - - return 0; -} diff --git a/trunk/drivers/hsi/hsi_core.h b/trunk/drivers/hsi/hsi_core.h deleted file mode 100644 index ab5c2fb175fd..000000000000 --- a/trunk/drivers/hsi/hsi_core.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * HSI framework internal interfaces, - * - * Copyright (C) 2010 Nokia Corporation. All rights reserved. - * - * Contact: Carlos Chinea - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#ifndef __LINUX_HSI_CORE_H__ -#define __LINUX_HSI_CORE_H__ - -#include - -struct hsi_cl_info { - struct list_head list; - struct hsi_board_info info; -}; - -extern struct list_head hsi_board_list; - -#endif /* __LINUX_HSI_CORE_H__ */ diff --git a/trunk/drivers/hwmon/Kconfig b/trunk/drivers/hwmon/Kconfig index 8deedc1b9840..5b32d56dbb4d 100644 --- a/trunk/drivers/hwmon/Kconfig +++ b/trunk/drivers/hwmon/Kconfig @@ -253,8 +253,7 @@ config SENSORS_K10TEMP If you say yes here you get support for the temperature sensor(s) inside your CPU. Supported are later revisions of the AMD Family 10h and all revisions of the AMD Family 11h, - 12h (Llano), 14h (Brazos) and 15h (Bulldozer/Trinity) - microarchitectures. + 12h (Llano), 14h (Brazos) and 15h (Bulldozer) microarchitectures. This driver can also be built as a module. If so, the module will be called k10temp. @@ -426,7 +425,7 @@ config SENSORS_GL520SM config SENSORS_GPIO_FAN tristate "GPIO fan" - depends on GPIOLIB + depends on GENERIC_GPIO help If you say yes here you get support for fans connected to GPIO lines. @@ -884,7 +883,7 @@ source drivers/hwmon/pmbus/Kconfig config SENSORS_SHT15 tristate "Sensiron humidity and temperature sensors. SHT15 and compat." - depends on GPIOLIB + depends on GENERIC_GPIO help If you say yes here you get support for the Sensiron SHT10, SHT11, SHT15, SHT71, SHT75 humidity and temperature sensors. diff --git a/trunk/drivers/hwmon/acpi_power_meter.c b/trunk/drivers/hwmon/acpi_power_meter.c index 9140236a0182..554f046bcf20 100644 --- a/trunk/drivers/hwmon/acpi_power_meter.c +++ b/trunk/drivers/hwmon/acpi_power_meter.c @@ -391,7 +391,6 @@ static ssize_t show_str(struct device *dev, break; default: BUG(); - val = ""; } return sprintf(buf, "%s\n", val); @@ -633,7 +632,6 @@ static int register_ro_attrs(struct acpi_power_meter_resource *resource, sensors->dev_attr.show = ro->show; sensors->index = ro->index; - sysfs_attr_init(&sensors->dev_attr.attr); res = device_create_file(dev, &sensors->dev_attr); if (res) { sensors->dev_attr.attr.name = NULL; @@ -663,7 +661,6 @@ static int register_rw_attrs(struct acpi_power_meter_resource *resource, sensors->dev_attr.store = rw->set; sensors->index = rw->index; - sysfs_attr_init(&sensors->dev_attr.attr); res = device_create_file(dev, &sensors->dev_attr); if (res) { sensors->dev_attr.attr.name = NULL; diff --git a/trunk/drivers/hwmon/ad7314.c b/trunk/drivers/hwmon/ad7314.c index f85ce70d9677..0e0cfcc36f8d 100644 --- a/trunk/drivers/hwmon/ad7314.c +++ b/trunk/drivers/hwmon/ad7314.c @@ -47,7 +47,7 @@ struct ad7314_data { u16 rx ____cacheline_aligned; }; -static int ad7314_spi_read(struct ad7314_data *chip) +static int ad7314_spi_read(struct ad7314_data *chip, s16 *data) { int ret; @@ -57,7 +57,9 @@ static int ad7314_spi_read(struct ad7314_data *chip) return ret; } - return be16_to_cpu(chip->rx); + *data = be16_to_cpu(chip->rx); + + return ret; } static ssize_t ad7314_show_temperature(struct device *dev, @@ -68,12 +70,12 @@ static ssize_t ad7314_show_temperature(struct device *dev, s16 data; int ret; - ret = ad7314_spi_read(chip); + ret = ad7314_spi_read(chip, &data); if (ret < 0) return ret; switch (spi_get_device_id(chip->spi_dev)->driver_data) { case ad7314: - data = (ret & AD7314_TEMP_MASK) >> AD7314_TEMP_OFFSET; + data = (data & AD7314_TEMP_MASK) >> AD7314_TEMP_OFFSET; data = (data << 6) >> 6; return sprintf(buf, "%d\n", 250 * data); @@ -84,7 +86,7 @@ static ssize_t ad7314_show_temperature(struct device *dev, * with a sign bit - which is a 14 bit 2's complement * register. 1lsb - 31.25 milli degrees centigrade */ - data = ret & ADT7301_TEMP_MASK; + data &= ADT7301_TEMP_MASK; data = (data << 2) >> 2; return sprintf(buf, "%d\n", @@ -126,7 +128,6 @@ static int __devinit ad7314_probe(struct spi_device *spi_dev) ret = PTR_ERR(chip->hwmon_dev); goto error_remove_group; } - chip->spi_dev = spi_dev; return 0; error_remove_group: diff --git a/trunk/drivers/hwmon/adm1031.c b/trunk/drivers/hwmon/adm1031.c index 44e1fd7f3d81..ff37363ea5bc 100644 --- a/trunk/drivers/hwmon/adm1031.c +++ b/trunk/drivers/hwmon/adm1031.c @@ -233,15 +233,18 @@ static const auto_chan_table_t auto_channel_select_table_adm1030 = { * nearest match if no exact match where found. */ static int -get_fan_auto_nearest(struct adm1031_data *data, int chan, u8 val, u8 reg) +get_fan_auto_nearest(struct adm1031_data *data, + int chan, u8 val, u8 reg, u8 *new_reg) { int i; int first_match = -1, exact_match = -1; u8 other_reg_val = (*data->chan_select_table)[FAN_CHAN_FROM_REG(reg)][chan ? 0 : 1]; - if (val == 0) + if (val == 0) { + *new_reg = 0; return 0; + } for (i = 0; i < 8; i++) { if ((val == (*data->chan_select_table)[i][chan]) && @@ -261,11 +264,13 @@ get_fan_auto_nearest(struct adm1031_data *data, int chan, u8 val, u8 reg) } if (exact_match >= 0) - return exact_match; + *new_reg = exact_match; else if (first_match >= 0) - return first_match; + *new_reg = first_match; + else + return -EINVAL; - return -EINVAL; + return 0; } static ssize_t show_fan_auto_channel(struct device *dev, @@ -296,12 +301,11 @@ set_fan_auto_channel(struct device *dev, struct device_attribute *attr, mutex_lock(&data->update_lock); - ret = get_fan_auto_nearest(data, nr, val, data->conf1); - if (ret < 0) { + ret = get_fan_auto_nearest(data, nr, val, data->conf1, ®); + if (ret) { mutex_unlock(&data->update_lock); return ret; } - reg = ret; data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1); if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) ^ (old_fan_mode & ADM1031_CONF1_AUTO_MODE)) { diff --git a/trunk/drivers/hwmon/ads1015.c b/trunk/drivers/hwmon/ads1015.c index 1958f03efd7a..7765e4f74ec5 100644 --- a/trunk/drivers/hwmon/ads1015.c +++ b/trunk/drivers/hwmon/ads1015.c @@ -59,11 +59,14 @@ struct ads1015_data { struct ads1015_channel_data channel_data[ADS1015_CHANNELS]; }; -static int ads1015_read_adc(struct i2c_client *client, unsigned int channel) +static int ads1015_read_value(struct i2c_client *client, unsigned int channel, + int *value) { u16 config; + s16 conversion; struct ads1015_data *data = i2c_get_clientdata(client); unsigned int pga = data->channel_data[channel].pga; + int fullscale; unsigned int data_rate = data->channel_data[channel].data_rate; unsigned int conversion_time_ms; int res; @@ -75,6 +78,7 @@ static int ads1015_read_adc(struct i2c_client *client, unsigned int channel) if (res < 0) goto err_unlock; config = res; + fullscale = fullscale_table[pga]; conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]); /* setup and start single conversion */ @@ -101,20 +105,19 @@ static int ads1015_read_adc(struct i2c_client *client, unsigned int channel) } res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION); + if (res < 0) + goto err_unlock; + conversion = res; -err_unlock: mutex_unlock(&data->update_lock); - return res; -} -static int ads1015_reg_to_mv(struct i2c_client *client, unsigned int channel, - s16 reg) -{ - struct ads1015_data *data = i2c_get_clientdata(client); - unsigned int pga = data->channel_data[channel].pga; - int fullscale = fullscale_table[pga]; + *value = DIV_ROUND_CLOSEST(conversion * fullscale, 0x7ff0); + + return 0; - return DIV_ROUND_CLOSEST(reg * fullscale, 0x7ff0); +err_unlock: + mutex_unlock(&data->update_lock); + return res; } /* sysfs callback function */ @@ -123,14 +126,12 @@ static ssize_t show_in(struct device *dev, struct device_attribute *da, { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct i2c_client *client = to_i2c_client(dev); + int in; int res; - int index = attr->index; - res = ads1015_read_adc(client, index); - if (res < 0) - return res; + res = ads1015_read_value(client, attr->index, &in); - return sprintf(buf, "%d\n", ads1015_reg_to_mv(client, index, res)); + return (res < 0) ? res : sprintf(buf, "%d\n", in); } static const struct sensor_device_attribute ads1015_in[] = { diff --git a/trunk/drivers/hwmon/coretemp.c b/trunk/drivers/hwmon/coretemp.c index b9d512331ed4..0d3141fbbc20 100644 --- a/trunk/drivers/hwmon/coretemp.c +++ b/trunk/drivers/hwmon/coretemp.c @@ -52,7 +52,7 @@ module_param_named(tjmax, force_tjmax, int, 0444); MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ -#define NUM_REAL_CORES 32 /* Number of Real cores per cpu */ +#define NUM_REAL_CORES 16 /* Number of Real cores per cpu */ #define CORETEMP_NAME_LENGTH 17 /* String Length of attrs */ #define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */ #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1) @@ -709,10 +709,6 @@ static void __cpuinit put_core_offline(unsigned int cpu) indx = TO_ATTR_NO(cpu); - /* The core id is too big, just return */ - if (indx > MAX_CORE_DATA - 1) - return; - if (pdata->core_data[indx] && pdata->core_data[indx]->cpu == cpu) coretemp_remove_core(pdata, &pdev->dev, indx); diff --git a/trunk/drivers/hwmon/f75375s.c b/trunk/drivers/hwmon/f75375s.c index ece4159bd453..729499e75210 100644 --- a/trunk/drivers/hwmon/f75375s.c +++ b/trunk/drivers/hwmon/f75375s.c @@ -276,7 +276,6 @@ static bool duty_mode_enabled(u8 pwm_enable) return false; default: BUG(); - return true; } } @@ -292,7 +291,6 @@ static bool auto_mode_enabled(u8 pwm_enable) return true; default: BUG(); - return false; } } diff --git a/trunk/drivers/hwmon/fam15h_power.c b/trunk/drivers/hwmon/fam15h_power.c index e8e18cab1fb8..b7494af1e4a9 100644 --- a/trunk/drivers/hwmon/fam15h_power.c +++ b/trunk/drivers/hwmon/fam15h_power.c @@ -122,41 +122,6 @@ static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4) return true; } -/* - * Newer BKDG versions have an updated recommendation on how to properly - * initialize the running average range (was: 0xE, now: 0x9). This avoids - * counter saturations resulting in bogus power readings. - * We correct this value ourselves to cope with older BIOSes. - */ -static DEFINE_PCI_DEVICE_TABLE(affected_device) = { - { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }, - { 0 } -}; - -static void __devinit tweak_runavg_range(struct pci_dev *pdev) -{ - u32 val; - - /* - * let this quirk apply only to the current version of the - * northbridge, since future versions may change the behavior - */ - if (!pci_match_id(affected_device, pdev)) - return; - - pci_bus_read_config_dword(pdev->bus, - PCI_DEVFN(PCI_SLOT(pdev->devfn), 5), - REG_TDP_RUNNING_AVERAGE, &val); - if ((val & 0xf) != 0xe) - return; - - val &= ~0xf; - val |= 0x9; - pci_bus_write_config_dword(pdev->bus, - PCI_DEVFN(PCI_SLOT(pdev->devfn), 5), - REG_TDP_RUNNING_AVERAGE, val); -} - static void __devinit fam15h_power_init_data(struct pci_dev *f4, struct fam15h_power_data *data) { @@ -190,13 +155,6 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev, struct device *dev; int err; - /* - * though we ignore every other northbridge, we still have to - * do the tweaking on _each_ node in MCM processors as the counters - * are working hand-in-hand - */ - tweak_runavg_range(pdev); - if (!fam15h_power_is_internal_node0(pdev)) { err = -ENODEV; goto exit; diff --git a/trunk/drivers/hwmon/k10temp.c b/trunk/drivers/hwmon/k10temp.c index 307bb325dde9..aba29d63f195 100644 --- a/trunk/drivers/hwmon/k10temp.c +++ b/trunk/drivers/hwmon/k10temp.c @@ -33,9 +33,6 @@ static bool force; module_param(force, bool, 0444); MODULE_PARM_DESC(force, "force loading on processors with erratum 319"); -/* PCI-IDs for Northbridge devices not used anywhere else */ -#define PCI_DEVICE_ID_AMD_15H_M10H_NB_F3 0x1403 - /* CPUID function 0x80000001, ebx */ #define CPUID_PKGTYPE_MASK 0xf0000000 #define CPUID_PKGTYPE_F 0x00000000 @@ -213,7 +210,6 @@ static DEFINE_PCI_DEVICE_TABLE(k10temp_id_table) = { { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) }, - { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M10H_NB_F3) }, {} }; MODULE_DEVICE_TABLE(pci, k10temp_id_table); diff --git a/trunk/drivers/hwmon/max6639.c b/trunk/drivers/hwmon/max6639.c index de8f7adaccbd..193067e27b6f 100644 --- a/trunk/drivers/hwmon/max6639.c +++ b/trunk/drivers/hwmon/max6639.c @@ -596,10 +596,8 @@ static int max6639_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_PM_SLEEP -static int max6639_suspend(struct device *dev) +static int max6639_suspend(struct i2c_client *client, pm_message_t mesg) { - struct i2c_client *client = to_i2c_client(dev); int data = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG); if (data < 0) return data; @@ -608,9 +606,8 @@ static int max6639_suspend(struct device *dev) MAX6639_REG_GCONFIG, data | MAX6639_GCONFIG_STANDBY); } -static int max6639_resume(struct device *dev) +static int max6639_resume(struct i2c_client *client) { - struct i2c_client *client = to_i2c_client(dev); int data = i2c_smbus_read_byte_data(client, MAX6639_REG_GCONFIG); if (data < 0) return data; @@ -618,7 +615,6 @@ static int max6639_resume(struct device *dev) return i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG, data & ~MAX6639_GCONFIG_STANDBY); } -#endif /* CONFIG_PM_SLEEP */ static const struct i2c_device_id max6639_id[] = { {"max6639", 0}, @@ -627,18 +623,15 @@ static const struct i2c_device_id max6639_id[] = { MODULE_DEVICE_TABLE(i2c, max6639_id); -static const struct dev_pm_ops max6639_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(max6639_suspend, max6639_resume) -}; - static struct i2c_driver max6639_driver = { .class = I2C_CLASS_HWMON, .driver = { .name = "max6639", - .pm = &max6639_pm_ops, }, .probe = max6639_probe, .remove = max6639_remove, + .suspend = max6639_suspend, + .resume = max6639_resume, .id_table = max6639_id, .detect = max6639_detect, .address_list = normal_i2c, diff --git a/trunk/drivers/hwmon/pmbus/pmbus_core.c b/trunk/drivers/hwmon/pmbus/pmbus_core.c index 29b319db573e..be51037363c8 100644 --- a/trunk/drivers/hwmon/pmbus/pmbus_core.c +++ b/trunk/drivers/hwmon/pmbus/pmbus_core.c @@ -710,13 +710,13 @@ static u16 pmbus_data2reg(struct pmbus_data *data, * If a negative value is stored in any of the referenced registers, this value * reflects an error code which will be returned. */ -static int pmbus_get_boolean(struct pmbus_data *data, int index) +static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val) { u8 s1 = (index >> 24) & 0xff; u8 s2 = (index >> 16) & 0xff; u8 reg = (index >> 8) & 0xff; u8 mask = index & 0xff; - int ret, status; + int status; u8 regval; status = data->status[reg]; @@ -725,7 +725,7 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index) regval = status & mask; if (!s1 && !s2) - ret = !!regval; + *val = !!regval; else { long v1, v2; struct pmbus_sensor *sensor1, *sensor2; @@ -739,9 +739,9 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index) v1 = pmbus_reg2data(data, sensor1); v2 = pmbus_reg2data(data, sensor2); - ret = !!(regval && v1 >= v2); + *val = !!(regval && v1 >= v2); } - return ret; + return 0; } static ssize_t pmbus_show_boolean(struct device *dev, @@ -750,10 +750,11 @@ static ssize_t pmbus_show_boolean(struct device *dev, struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct pmbus_data *data = pmbus_update_device(dev); int val; + int err; - val = pmbus_get_boolean(data, attr->index); - if (val < 0) - return val; + err = pmbus_get_boolean(data, attr->index, &val); + if (err) + return err; return snprintf(buf, PAGE_SIZE, "%d\n", val); } diff --git a/trunk/drivers/hwmon/smsc47b397.c b/trunk/drivers/hwmon/smsc47b397.c index c5f6be478bad..d3b778da3f86 100644 --- a/trunk/drivers/hwmon/smsc47b397.c +++ b/trunk/drivers/hwmon/smsc47b397.c @@ -343,11 +343,10 @@ static int __init smsc47b397_device_add(unsigned short address) return err; } -static int __init smsc47b397_find(void) +static int __init smsc47b397_find(unsigned short *addr) { u8 id, rev; char *name; - unsigned short addr; superio_enter(); id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID); @@ -371,14 +370,14 @@ static int __init smsc47b397_find(void) rev = superio_inb(SUPERIO_REG_DEVREV); superio_select(SUPERIO_REG_LD8); - addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8) + *addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8) | superio_inb(SUPERIO_REG_BASE_LSB); pr_info("found SMSC %s (base address 0x%04x, revision %u)\n", - name, addr, rev); + name, *addr, rev); superio_exit(); - return addr; + return 0; } static int __init smsc47b397_init(void) @@ -386,10 +385,9 @@ static int __init smsc47b397_init(void) unsigned short address; int ret; - ret = smsc47b397_find(); - if (ret < 0) + ret = smsc47b397_find(&address); + if (ret) return ret; - address = ret; ret = platform_driver_register(&smsc47b397_driver); if (ret) diff --git a/trunk/drivers/hwmon/smsc47m1.c b/trunk/drivers/hwmon/smsc47m1.c index b5aa38dd7ab9..c590c1469793 100644 --- a/trunk/drivers/hwmon/smsc47m1.c +++ b/trunk/drivers/hwmon/smsc47m1.c @@ -491,10 +491,10 @@ static const struct attribute_group smsc47m1_group = { .attrs = smsc47m1_attributes, }; -static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data) +static int __init smsc47m1_find(unsigned short *addr, + struct smsc47m1_sio_data *sio_data) { u8 val; - unsigned short addr; superio_enter(); val = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID); @@ -546,9 +546,9 @@ static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data) } superio_select(); - addr = (superio_inb(SUPERIO_REG_BASE) << 8) + *addr = (superio_inb(SUPERIO_REG_BASE) << 8) | superio_inb(SUPERIO_REG_BASE + 1); - if (addr == 0) { + if (*addr == 0) { pr_info("Device address not set, will not use\n"); superio_exit(); return -ENODEV; @@ -565,7 +565,7 @@ static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data) } superio_exit(); - return addr; + return 0; } /* Restore device to its initial state */ @@ -938,15 +938,13 @@ static int __init sm_smsc47m1_init(void) unsigned short address; struct smsc47m1_sio_data sio_data; - err = smsc47m1_find(&sio_data); - if (err < 0) - return err; - address = err; + if (smsc47m1_find(&address, &sio_data)) + return -ENODEV; /* Sets global pdev as a side effect */ err = smsc47m1_device_add(address, &sio_data); if (err) - return err; + goto exit; err = platform_driver_probe(&smsc47m1_driver, smsc47m1_probe); if (err) @@ -957,6 +955,7 @@ static int __init sm_smsc47m1_init(void) exit_device: platform_device_unregister(pdev); smsc47m1_restore(&sio_data); +exit: return err; } diff --git a/trunk/drivers/hwmon/w83627ehf.c b/trunk/drivers/hwmon/w83627ehf.c index 54922ed12978..a25350cf9554 100644 --- a/trunk/drivers/hwmon/w83627ehf.c +++ b/trunk/drivers/hwmon/w83627ehf.c @@ -2619,15 +2619,15 @@ static struct platform_driver w83627ehf_driver = { static int __init w83627ehf_find(int sioaddr, unsigned short *addr, struct w83627ehf_sio_data *sio_data) { - static const char sio_name_W83627EHF[] __initconst = "W83627EHF"; - static const char sio_name_W83627EHG[] __initconst = "W83627EHG"; - static const char sio_name_W83627DHG[] __initconst = "W83627DHG"; - static const char sio_name_W83627DHG_P[] __initconst = "W83627DHG-P"; - static const char sio_name_W83627UHG[] __initconst = "W83627UHG"; - static const char sio_name_W83667HG[] __initconst = "W83667HG"; - static const char sio_name_W83667HG_B[] __initconst = "W83667HG-B"; - static const char sio_name_NCT6775[] __initconst = "NCT6775F"; - static const char sio_name_NCT6776[] __initconst = "NCT6776F"; + static const char __initdata sio_name_W83627EHF[] = "W83627EHF"; + static const char __initdata sio_name_W83627EHG[] = "W83627EHG"; + static const char __initdata sio_name_W83627DHG[] = "W83627DHG"; + static const char __initdata sio_name_W83627DHG_P[] = "W83627DHG-P"; + static const char __initdata sio_name_W83627UHG[] = "W83627UHG"; + static const char __initdata sio_name_W83667HG[] = "W83667HG"; + static const char __initdata sio_name_W83667HG_B[] = "W83667HG-B"; + static const char __initdata sio_name_NCT6775[] = "NCT6775F"; + static const char __initdata sio_name_NCT6776[] = "NCT6776F"; u16 val; const char *sio_name; diff --git a/trunk/drivers/i2c/busses/i2c-designware-pcidrv.c b/trunk/drivers/i2c/busses/i2c-designware-pcidrv.c index 00e8f213f56e..37f42113af31 100644 --- a/trunk/drivers/i2c/busses/i2c-designware-pcidrv.c +++ b/trunk/drivers/i2c/busses/i2c-designware-pcidrv.c @@ -182,6 +182,7 @@ static int i2c_dw_pci_resume(struct device *dev) pci_restore_state(pdev); i2c_dw_init(i2c); + i2c_dw_enable(i2c); return 0; } diff --git a/trunk/drivers/i2c/busses/i2c-eg20t.c b/trunk/drivers/i2c/busses/i2c-eg20t.c index c811289b61e2..f086131cb1c7 100644 --- a/trunk/drivers/i2c/busses/i2c-eg20t.c +++ b/trunk/drivers/i2c/busses/i2c-eg20t.c @@ -324,7 +324,7 @@ static s32 pch_i2c_wait_for_xfer_complete(struct i2c_algo_pch_data *adap) { long ret; ret = wait_event_timeout(pch_event, - (adap->pch_event_flag != 0), msecs_to_jiffies(1000)); + (adap->pch_event_flag != 0), msecs_to_jiffies(50)); if (ret == 0) { pch_err(adap, "timeout: %x\n", adap->pch_event_flag); @@ -1063,6 +1063,6 @@ module_exit(pch_pci_exit); MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semico ML7213/ML7223/ML7831 IOH I2C"); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Tomoya MORINAGA. "); +MODULE_AUTHOR("Tomoya MORINAGA. "); module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR)); module_param(pch_clk, int, (S_IRUSR | S_IWUSR)); diff --git a/trunk/drivers/i2c/busses/i2c-mxs.c b/trunk/drivers/i2c/busses/i2c-mxs.c index 76b8af44f634..3d471d56bf15 100644 --- a/trunk/drivers/i2c/busses/i2c-mxs.c +++ b/trunk/drivers/i2c/busses/i2c-mxs.c @@ -227,7 +227,6 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, return -EINVAL; init_completion(&i2c->cmd_complete); - i2c->cmd_err = 0; flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0; @@ -253,9 +252,6 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, if (i2c->cmd_err == -ENXIO) mxs_i2c_reset(i2c); - else - writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, - i2c->regs + MXS_I2C_QUEUECTRL_CLR); dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err); @@ -303,6 +299,8 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) MXS_I2C_CTRL1_SLAVE_STOP_IRQ | MXS_I2C_CTRL1_SLAVE_IRQ)) /* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */ i2c->cmd_err = -EIO; + else + i2c->cmd_err = 0; is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) & MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0; @@ -386,6 +384,8 @@ static int __devexit mxs_i2c_remove(struct platform_device *pdev) if (ret) return -EBUSY; + writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, + i2c->regs + MXS_I2C_QUEUECTRL_CLR); writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET); platform_set_drvdata(pdev, NULL); diff --git a/trunk/drivers/i2c/busses/i2c-pnx.c b/trunk/drivers/i2c/busses/i2c-pnx.c index eb8ad538c79f..04be9f82e14b 100644 --- a/trunk/drivers/i2c/busses/i2c-pnx.c +++ b/trunk/drivers/i2c/busses/i2c-pnx.c @@ -546,7 +546,8 @@ static int i2c_pnx_controller_suspend(struct platform_device *pdev, { struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); - clk_disable(alg_data->clk); + /* FIXME: shouldn't this be clk_disable? */ + clk_enable(alg_data->clk); return 0; } diff --git a/trunk/drivers/i2c/busses/i2c-tegra.c b/trunk/drivers/i2c/busses/i2c-tegra.c index 55e5ea62ccee..e978635e60f0 100644 --- a/trunk/drivers/i2c/busses/i2c-tegra.c +++ b/trunk/drivers/i2c/busses/i2c-tegra.c @@ -516,14 +516,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, if (likely(i2c_dev->msg_err == I2C_ERR_NONE)) return 0; - /* - * NACK interrupt is generated before the I2C controller generates the - * STOP condition on the bus. So wait for 2 clock periods before resetting - * the controller so that STOP condition has been delivered properly. - */ - if (i2c_dev->msg_err == I2C_ERR_NO_ACK) - udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->bus_clk_rate)); - tegra_i2c_init(i2c_dev); if (i2c_dev->msg_err == I2C_ERR_NO_ACK) { if (msg->flags & I2C_M_IGNORE_NAK) diff --git a/trunk/drivers/idle/i7300_idle.c b/trunk/drivers/idle/i7300_idle.c index fa080ebd568f..c976285d313e 100644 --- a/trunk/drivers/idle/i7300_idle.c +++ b/trunk/drivers/idle/i7300_idle.c @@ -516,6 +516,12 @@ static struct notifier_block i7300_idle_nb = { MODULE_DEVICE_TABLE(pci, pci_tbl); +int stats_open_generic(struct inode *inode, struct file *fp) +{ + fp->private_data = inode->i_private; + return 0; +} + static ssize_t stats_read_ul(struct file *fp, char __user *ubuf, size_t count, loff_t *off) { @@ -528,7 +534,7 @@ static ssize_t stats_read_ul(struct file *fp, char __user *ubuf, size_t count, } static const struct file_operations idle_fops = { - .open = simple_open, + .open = stats_open_generic, .read = stats_read_ul, .llseek = default_llseek, }; diff --git a/trunk/drivers/infiniband/core/mad.c b/trunk/drivers/infiniband/core/mad.c index b0d0bc8a6fb6..426bb7617ec6 100644 --- a/trunk/drivers/infiniband/core/mad.c +++ b/trunk/drivers/infiniband/core/mad.c @@ -1854,8 +1854,6 @@ static bool generate_unmatched_resp(struct ib_mad_private *recv, response->mad.mad.mad_hdr.method = IB_MGMT_METHOD_GET_RESP; response->mad.mad.mad_hdr.status = cpu_to_be16(IB_MGMT_MAD_STATUS_UNSUPPORTED_METHOD_ATTRIB); - if (recv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) - response->mad.mad.mad_hdr.status |= IB_SMP_DIRECTION; return true; } else { @@ -1871,7 +1869,6 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, struct ib_mad_list_head *mad_list; struct ib_mad_agent_private *mad_agent; int port_num; - int ret = IB_MAD_RESULT_SUCCESS; mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id; qp_info = mad_list->mad_queue->qp_info; @@ -1955,6 +1952,8 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, local: /* Give driver "right of first refusal" on incoming MAD */ if (port_priv->device->process_mad) { + int ret; + ret = port_priv->device->process_mad(port_priv->device, 0, port_priv->port_num, wc, &recv->grh, @@ -1982,8 +1981,7 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, * or via recv_handler in ib_mad_complete_recv() */ recv = NULL; - } else if ((ret & IB_MAD_RESULT_SUCCESS) && - generate_unmatched_resp(recv, response)) { + } else if (generate_unmatched_resp(recv, response)) { agent_send_response(&response->mad.mad, &recv->grh, wc, port_priv->device, port_num, qp_info->qp->qp_num); } diff --git a/trunk/drivers/infiniband/core/sysfs.c b/trunk/drivers/infiniband/core/sysfs.c index 246fdc151652..83b720ef6c34 100644 --- a/trunk/drivers/infiniband/core/sysfs.c +++ b/trunk/drivers/infiniband/core/sysfs.c @@ -179,7 +179,7 @@ static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused, { struct ib_port_attr attr; char *speed = ""; - int rate; /* in deci-Gb/sec */ + int rate = -1; /* in deci-Gb/sec */ ssize_t ret; ret = ib_query_port(p->ibdev, p->port_num, &attr); @@ -187,6 +187,9 @@ static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused, return ret; switch (attr.active_speed) { + case IB_SPEED_SDR: + rate = 25; + break; case IB_SPEED_DDR: speed = " DDR"; rate = 50; @@ -207,10 +210,6 @@ static ssize_t rate_show(struct ib_port *p, struct port_attribute *unused, speed = " EDR"; rate = 250; break; - case IB_SPEED_SDR: - default: /* default to SDR for invalid rates */ - rate = 25; - break; } rate *= ib_width_enum_to_int(attr.active_width); diff --git a/trunk/drivers/infiniband/hw/mlx4/main.c b/trunk/drivers/infiniband/hw/mlx4/main.c index b948b6dd5d55..75d305629300 100644 --- a/trunk/drivers/infiniband/hw/mlx4/main.c +++ b/trunk/drivers/infiniband/hw/mlx4/main.c @@ -247,17 +247,12 @@ static int ib_link_query_port(struct ib_device *ibdev, u8 port, err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, out_mad); if (err) - goto out; + return err; /* Checking LinkSpeedActive for FDR-10 */ if (out_mad->data[15] & 0x1) props->active_speed = IB_SPEED_FDR10; } - - /* Avoid wrong speed value returned by FW if the IB link is down. */ - if (props->state == IB_PORT_DOWN) - props->active_speed = IB_SPEED_SDR; - out: kfree(in_mad); kfree(out_mad); diff --git a/trunk/drivers/infiniband/ulp/srpt/ib_srpt.c b/trunk/drivers/infiniband/ulp/srpt/ib_srpt.c index daf21b899999..69e2ad06e515 100644 --- a/trunk/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/trunk/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -3232,7 +3232,6 @@ static void srpt_add_one(struct ib_device *device) srq_attr.attr.max_wr = sdev->srq_size; srq_attr.attr.max_sge = 1; srq_attr.attr.srq_limit = 0; - srq_attr.srq_type = IB_SRQT_BASIC; sdev->srq = ib_create_srq(sdev->pd, &srq_attr); if (IS_ERR(sdev->srq)) diff --git a/trunk/drivers/input/misc/Kconfig b/trunk/drivers/input/misc/Kconfig index 7faf4a7fcaa9..2d787796bf50 100644 --- a/trunk/drivers/input/misc/Kconfig +++ b/trunk/drivers/input/misc/Kconfig @@ -380,7 +380,8 @@ config INPUT_TWL4030_VIBRA config INPUT_TWL6040_VIBRA tristate "Support for TWL6040 Vibrator" - depends on TWL6040_CORE + depends on TWL4030_CORE + select TWL6040_CORE select INPUT_FF_MEMLESS help This option enables support for TWL6040 Vibrator Driver. diff --git a/trunk/drivers/input/misc/da9052_onkey.c b/trunk/drivers/input/misc/da9052_onkey.c index 3c843cd725fa..34aebb8cd080 100644 --- a/trunk/drivers/input/misc/da9052_onkey.c +++ b/trunk/drivers/input/misc/da9052_onkey.c @@ -95,8 +95,7 @@ static int __devinit da9052_onkey_probe(struct platform_device *pdev) input_dev = input_allocate_device(); if (!onkey || !input_dev) { dev_err(&pdev->dev, "Failed to allocate memory\n"); - error = -ENOMEM; - goto err_free_mem; + return -ENOMEM; } onkey->input = input_dev; diff --git a/trunk/drivers/input/misc/twl6040-vibra.c b/trunk/drivers/input/misc/twl6040-vibra.c index 14e94f56cb7d..45874fed523a 100644 --- a/trunk/drivers/input/misc/twl6040-vibra.c +++ b/trunk/drivers/input/misc/twl6040-vibra.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -257,7 +257,7 @@ static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL); static int __devinit twl6040_vibra_probe(struct platform_device *pdev) { - struct twl6040_vibra_data *pdata = pdev->dev.platform_data; + struct twl4030_vibra_data *pdata = pdev->dev.platform_data; struct vibra_info *info; int ret; diff --git a/trunk/drivers/input/mouse/elantech.c b/trunk/drivers/input/mouse/elantech.c index 479011004a11..d2c0db159b18 100644 --- a/trunk/drivers/input/mouse/elantech.c +++ b/trunk/drivers/input/mouse/elantech.c @@ -486,6 +486,7 @@ static void elantech_input_sync_v4(struct psmouse *psmouse) unsigned char *packet = psmouse->packet; input_report_key(dev, BTN_LEFT, packet[0] & 0x01); + input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); input_mt_report_pointer_emulation(dev, true); input_sync(dev); } @@ -966,7 +967,6 @@ static int elantech_set_input_params(struct psmouse *psmouse) if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width)) return -1; - __set_bit(INPUT_PROP_POINTER, dev->propbit); __set_bit(EV_KEY, dev->evbit); __set_bit(EV_ABS, dev->evbit); __clear_bit(EV_REL, dev->evbit); @@ -1017,9 +1017,7 @@ static int elantech_set_input_params(struct psmouse *psmouse) */ psmouse_warn(psmouse, "couldn't query resolution data.\n"); } - /* v4 is clickpad, with only one button. */ - __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); - __clear_bit(BTN_RIGHT, dev->keybit); + __set_bit(BTN_TOOL_QUADTAP, dev->keybit); /* For X to recognize me as touchpad. */ input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0); @@ -1247,8 +1245,6 @@ static void elantech_disconnect(struct psmouse *psmouse) */ static int elantech_reconnect(struct psmouse *psmouse) { - psmouse_reset(psmouse); - if (elantech_detect(psmouse, 0)) return -1; @@ -1328,8 +1324,6 @@ int elantech_init(struct psmouse *psmouse) if (!etd) return -ENOMEM; - psmouse_reset(psmouse); - etd->parity[0] = 1; for (i = 1; i < 256; i++) etd->parity[i] = etd->parity[i & (i - 1)] ^ 1; diff --git a/trunk/drivers/input/mouse/gpio_mouse.c b/trunk/drivers/input/mouse/gpio_mouse.c index 39fe9b737cae..a9ad8e1402be 100644 --- a/trunk/drivers/input/mouse/gpio_mouse.c +++ b/trunk/drivers/input/mouse/gpio_mouse.c @@ -12,9 +12,9 @@ #include #include #include -#include #include +#include /* * Timer function which is run every scan_ms ms when the device is opened. diff --git a/trunk/drivers/input/mouse/sentelic.c b/trunk/drivers/input/mouse/sentelic.c index 661a0ca3b3d6..a977bfaa6821 100644 --- a/trunk/drivers/input/mouse/sentelic.c +++ b/trunk/drivers/input/mouse/sentelic.c @@ -741,14 +741,6 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) } } else { /* SFAC packet */ - if ((packet[0] & (FSP_PB0_LBTN|FSP_PB0_PHY_BTN)) == - FSP_PB0_LBTN) { - /* On-pad click in SFAC mode should be handled - * by userspace. On-pad clicks in MFMC mode - * are real clickpad clicks, and not ignored. - */ - packet[0] &= ~FSP_PB0_LBTN; - } /* no multi-finger information */ ad->last_mt_fgr = 0; diff --git a/trunk/drivers/input/mouse/synaptics.c b/trunk/drivers/input/mouse/synaptics.c index a4b14a41cbf4..8081a0a5d602 100644 --- a/trunk/drivers/input/mouse/synaptics.c +++ b/trunk/drivers/input/mouse/synaptics.c @@ -274,8 +274,7 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse) static unsigned char param = 0xc8; struct synaptics_data *priv = psmouse->private; - if (!(SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) || - SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c))) + if (!SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) return 0; if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL)) diff --git a/trunk/drivers/input/mouse/trackpoint.c b/trunk/drivers/input/mouse/trackpoint.c index f3102494237d..22b218018137 100644 --- a/trunk/drivers/input/mouse/trackpoint.c +++ b/trunk/drivers/input/mouse/trackpoint.c @@ -304,7 +304,7 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) return 0; if (trackpoint_read(&psmouse->ps2dev, TP_EXT_BTN, &button_info)) { - psmouse_warn(psmouse, "failed to get extended button data\n"); + printk(KERN_WARNING "trackpoint.c: failed to get extended button data\n"); button_info = 0; } @@ -326,18 +326,16 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group); if (error) { - psmouse_err(psmouse, - "failed to create sysfs attributes, error: %d\n", - error); + printk(KERN_ERR + "trackpoint.c: failed to create sysfs attributes, error: %d\n", + error); kfree(psmouse->private); psmouse->private = NULL; return -1; } - psmouse_info(psmouse, - "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n", - firmware_id, - (button_info & 0xf0) >> 4, button_info & 0x0f); + printk(KERN_INFO "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n", + firmware_id, (button_info & 0xf0) >> 4, button_info & 0x0f); return 0; } diff --git a/trunk/drivers/input/touchscreen/tps6507x-ts.c b/trunk/drivers/input/touchscreen/tps6507x-ts.c index f7eda3d00fad..6c6f6d8ea9b4 100644 --- a/trunk/drivers/input/touchscreen/tps6507x-ts.c +++ b/trunk/drivers/input/touchscreen/tps6507x-ts.c @@ -1,4 +1,6 @@ /* + * drivers/input/touchscreen/tps6507x_ts.c + * * Touchscreen driver for the tps6507x chip. * * Copyright (c) 2009 RidgeRun (todd.fischer@ridgerun.com) @@ -374,4 +376,4 @@ module_platform_driver(tps6507x_ts_driver); MODULE_AUTHOR("Todd Fischer "); MODULE_DESCRIPTION("TPS6507x - TouchScreen driver"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:tps6507x-ts"); +MODULE_ALIAS("platform:tps6507x-tsc"); diff --git a/trunk/drivers/iommu/amd_iommu.c b/trunk/drivers/iommu/amd_iommu.c index a5bee8e2dfce..ae2ec929e52f 100644 --- a/trunk/drivers/iommu/amd_iommu.c +++ b/trunk/drivers/iommu/amd_iommu.c @@ -2707,8 +2707,7 @@ static void unmap_sg(struct device *dev, struct scatterlist *sglist, * The exported alloc_coherent function for dma_ops. */ static void *alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_addr, gfp_t flag, - struct dma_attrs *attrs) + dma_addr_t *dma_addr, gfp_t flag) { unsigned long flags; void *virt_addr; @@ -2766,8 +2765,7 @@ static void *alloc_coherent(struct device *dev, size_t size, * The exported free_coherent function for dma_ops. */ static void free_coherent(struct device *dev, size_t size, - void *virt_addr, dma_addr_t dma_addr, - struct dma_attrs *attrs) + void *virt_addr, dma_addr_t dma_addr) { unsigned long flags; struct protection_domain *domain; @@ -2848,8 +2846,8 @@ static void __init prealloc_protection_domains(void) } static struct dma_map_ops amd_iommu_dma_ops = { - .alloc = alloc_coherent, - .free = free_coherent, + .alloc_coherent = alloc_coherent, + .free_coherent = free_coherent, .map_page = map_page, .unmap_page = unmap_page, .map_sg = map_sg, diff --git a/trunk/drivers/iommu/intel-iommu.c b/trunk/drivers/iommu/intel-iommu.c index f93d5ac8f81c..132f93b05154 100644 --- a/trunk/drivers/iommu/intel-iommu.c +++ b/trunk/drivers/iommu/intel-iommu.c @@ -2949,8 +2949,7 @@ static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr, } static void *intel_alloc_coherent(struct device *hwdev, size_t size, - dma_addr_t *dma_handle, gfp_t flags, - struct dma_attrs *attrs) + dma_addr_t *dma_handle, gfp_t flags) { void *vaddr; int order; @@ -2982,7 +2981,7 @@ static void *intel_alloc_coherent(struct device *hwdev, size_t size, } static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr, - dma_addr_t dma_handle, struct dma_attrs *attrs) + dma_addr_t dma_handle) { int order; @@ -3127,8 +3126,8 @@ static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr) } struct dma_map_ops intel_dma_ops = { - .alloc = intel_alloc_coherent, - .free = intel_free_coherent, + .alloc_coherent = intel_alloc_coherent, + .free_coherent = intel_free_coherent, .map_sg = intel_map_sg, .unmap_sg = intel_unmap_sg, .map_page = intel_map_page, diff --git a/trunk/drivers/iommu/omap-iommu-debug.c b/trunk/drivers/iommu/omap-iommu-debug.c index f55fc5dfbadc..103dbd92e256 100644 --- a/trunk/drivers/iommu/omap-iommu-debug.c +++ b/trunk/drivers/iommu/omap-iommu-debug.c @@ -323,9 +323,15 @@ static ssize_t debug_write_mem(struct file *file, const char __user *userbuf, return count; } +static int debug_open_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + #define DEBUG_FOPS(name) \ static const struct file_operations debug_##name##_fops = { \ - .open = simple_open, \ + .open = debug_open_generic, \ .read = debug_read_##name, \ .write = debug_write_##name, \ .llseek = generic_file_llseek, \ @@ -333,7 +339,7 @@ static ssize_t debug_write_mem(struct file *file, const char __user *userbuf, #define DEBUG_FOPS_RO(name) \ static const struct file_operations debug_##name##_fops = { \ - .open = simple_open, \ + .open = debug_open_generic, \ .read = debug_read_##name, \ .llseek = generic_file_llseek, \ }; diff --git a/trunk/drivers/isdn/gigaset/interface.c b/trunk/drivers/isdn/gigaset/interface.c index a6d9fd2858f7..b3d6ac17272d 100644 --- a/trunk/drivers/isdn/gigaset/interface.c +++ b/trunk/drivers/isdn/gigaset/interface.c @@ -176,7 +176,7 @@ static void if_close(struct tty_struct *tty, struct file *filp) struct cardstate *cs = tty->driver_data; if (!cs) { /* happens if we didn't find cs in open */ - gig_dbg(DEBUG_IF, "%s: no cardstate", __func__); + printk(KERN_DEBUG "%s: no cardstate\n", __func__); return; } diff --git a/trunk/drivers/isdn/hardware/mISDN/avmfritz.c b/trunk/drivers/isdn/hardware/mISDN/avmfritz.c index c0b8c960ee3f..05ed4d0cb18b 100644 --- a/trunk/drivers/isdn/hardware/mISDN/avmfritz.c +++ b/trunk/drivers/isdn/hardware/mISDN/avmfritz.c @@ -891,7 +891,7 @@ open_bchannel(struct fritzcard *fc, struct channel_req *rq) { struct bchannel *bch; - if (rq->adr.channel == 0 || rq->adr.channel > 2) + if (rq->adr.channel > 2) return -EINVAL; if (rq->protocol == ISDN_P_NONE) return -EINVAL; diff --git a/trunk/drivers/isdn/hardware/mISDN/hfcpci.c b/trunk/drivers/isdn/hardware/mISDN/hfcpci.c index e2c83a2d7691..d055ae7fa040 100644 --- a/trunk/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/trunk/drivers/isdn/hardware/mISDN/hfcpci.c @@ -1962,7 +1962,7 @@ open_bchannel(struct hfc_pci *hc, struct channel_req *rq) { struct bchannel *bch; - if (rq->adr.channel == 0 || rq->adr.channel > 2) + if (rq->adr.channel > 2) return -EINVAL; if (rq->protocol == ISDN_P_NONE) return -EINVAL; diff --git a/trunk/drivers/isdn/hardware/mISDN/hfcsusb.c b/trunk/drivers/isdn/hardware/mISDN/hfcsusb.c index 8cde2a0538ab..602338734634 100644 --- a/trunk/drivers/isdn/hardware/mISDN/hfcsusb.c +++ b/trunk/drivers/isdn/hardware/mISDN/hfcsusb.c @@ -486,7 +486,7 @@ open_bchannel(struct hfcsusb *hw, struct channel_req *rq) { struct bchannel *bch; - if (rq->adr.channel == 0 || rq->adr.channel > 2) + if (rq->adr.channel > 2) return -EINVAL; if (rq->protocol == ISDN_P_NONE) return -EINVAL; diff --git a/trunk/drivers/isdn/hardware/mISDN/mISDNipac.c b/trunk/drivers/isdn/hardware/mISDN/mISDNipac.c index 884369f09cad..b47e9bed2185 100644 --- a/trunk/drivers/isdn/hardware/mISDN/mISDNipac.c +++ b/trunk/drivers/isdn/hardware/mISDN/mISDNipac.c @@ -1506,7 +1506,7 @@ open_bchannel(struct ipac_hw *ipac, struct channel_req *rq) { struct bchannel *bch; - if (rq->adr.channel == 0 || rq->adr.channel > 2) + if (rq->adr.channel > 2) return -EINVAL; if (rq->protocol == ISDN_P_NONE) return -EINVAL; diff --git a/trunk/drivers/isdn/hardware/mISDN/mISDNisar.c b/trunk/drivers/isdn/hardware/mISDN/mISDNisar.c index 9a6da6edcfa8..10446ab404b5 100644 --- a/trunk/drivers/isdn/hardware/mISDN/mISDNisar.c +++ b/trunk/drivers/isdn/hardware/mISDN/mISDNisar.c @@ -1670,7 +1670,7 @@ isar_open(struct isar_hw *isar, struct channel_req *rq) { struct bchannel *bch; - if (rq->adr.channel == 0 || rq->adr.channel > 2) + if (rq->adr.channel > 2) return -EINVAL; if (rq->protocol == ISDN_P_NONE) return -EINVAL; diff --git a/trunk/drivers/isdn/hardware/mISDN/netjet.c b/trunk/drivers/isdn/hardware/mISDN/netjet.c index c726e09d0981..dd6de9f7a8a3 100644 --- a/trunk/drivers/isdn/hardware/mISDN/netjet.c +++ b/trunk/drivers/isdn/hardware/mISDN/netjet.c @@ -860,7 +860,7 @@ open_bchannel(struct tiger_hw *card, struct channel_req *rq) { struct bchannel *bch; - if (rq->adr.channel == 0 || rq->adr.channel > 2) + if (rq->adr.channel > 2) return -EINVAL; if (rq->protocol == ISDN_P_NONE) return -EINVAL; diff --git a/trunk/drivers/isdn/hardware/mISDN/w6692.c b/trunk/drivers/isdn/hardware/mISDN/w6692.c index 2183357f0799..7f1e7ba75cd1 100644 --- a/trunk/drivers/isdn/hardware/mISDN/w6692.c +++ b/trunk/drivers/isdn/hardware/mISDN/w6692.c @@ -1015,7 +1015,7 @@ open_bchannel(struct w6692_hw *card, struct channel_req *rq) { struct bchannel *bch; - if (rq->adr.channel == 0 || rq->adr.channel > 2) + if (rq->adr.channel > 2) return -EINVAL; if (rq->protocol == ISDN_P_NONE) return -EINVAL; diff --git a/trunk/drivers/leds/leds-atmel-pwm.c b/trunk/drivers/leds/leds-atmel-pwm.c index 64ad702a2ecc..800243b6037e 100644 --- a/trunk/drivers/leds/leds-atmel-pwm.c +++ b/trunk/drivers/leds/leds-atmel-pwm.c @@ -35,7 +35,7 @@ static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b) * NOTE: we reuse the platform_data structure of GPIO leds, * but repurpose its "gpio" number as a PWM channel number. */ -static int __devinit pwmled_probe(struct platform_device *pdev) +static int __init pwmled_probe(struct platform_device *pdev) { const struct gpio_led_platform_data *pdata; struct pwmled *leds; diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c index 17e2b472e16d..3d0dfa7a89a2 100644 --- a/trunk/drivers/md/bitmap.c +++ b/trunk/drivers/md/bitmap.c @@ -539,6 +539,9 @@ static int bitmap_new_disk_sb(struct bitmap *bitmap) bitmap->events_cleared = bitmap->mddev->events; sb->events_cleared = cpu_to_le64(bitmap->mddev->events); + bitmap->flags |= BITMAP_HOSTENDIAN; + sb->version = cpu_to_le32(BITMAP_MAJOR_HOSTENDIAN); + kunmap_atomic(sb); return 0; @@ -1727,7 +1730,8 @@ int bitmap_create(struct mddev *mddev) bitmap->chunkshift = (ffz(~mddev->bitmap_info.chunksize) - BITMAP_BLOCK_SHIFT); - chunks = (blocks + (1 << bitmap->chunkshift) - 1) >> + /* now that chunksize and chunkshift are set, we can use these macros */ + chunks = (blocks + bitmap->chunkshift - 1) >> bitmap->chunkshift; pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO; @@ -1784,9 +1788,7 @@ int bitmap_load(struct mddev *mddev) * re-add of a missing device */ start = mddev->recovery_cp; - mutex_lock(&mddev->bitmap_info.mutex); err = bitmap_init_from_disk(bitmap, start); - mutex_unlock(&mddev->bitmap_info.mutex); if (err) goto out; diff --git a/trunk/drivers/md/bitmap.h b/trunk/drivers/md/bitmap.h index b44b0aba2d47..55ca5aec84e4 100644 --- a/trunk/drivers/md/bitmap.h +++ b/trunk/drivers/md/bitmap.h @@ -101,6 +101,9 @@ typedef __u16 bitmap_counter_t; #define BITMAP_BLOCK_SHIFT 9 +/* how many blocks per chunk? (this is variable) */ +#define CHUNK_BLOCK_RATIO(bitmap) ((bitmap)->mddev->bitmap_info.chunksize >> BITMAP_BLOCK_SHIFT) + #endif /* diff --git a/trunk/drivers/md/dm-raid.c b/trunk/drivers/md/dm-raid.c index 68965e663248..b0ba52459ed7 100644 --- a/trunk/drivers/md/dm-raid.c +++ b/trunk/drivers/md/dm-raid.c @@ -859,7 +859,7 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) int ret; unsigned redundancy = 0; struct raid_dev *dev; - struct md_rdev *rdev, *tmp, *freshest; + struct md_rdev *rdev, *freshest; struct mddev *mddev = &rs->md; switch (rs->raid_type->level) { @@ -877,7 +877,7 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) } freshest = NULL; - rdev_for_each_safe(rdev, tmp, mddev) { + rdev_for_each(rdev, mddev) { if (!rdev->meta_bdev) continue; diff --git a/trunk/drivers/md/linear.c b/trunk/drivers/md/linear.c index fa211d80fc0a..b0fcc7d02adb 100644 --- a/trunk/drivers/md/linear.c +++ b/trunk/drivers/md/linear.c @@ -198,7 +198,6 @@ static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks) static int linear_run (struct mddev *mddev) { struct linear_conf *conf; - int ret; if (md_check_no_bitmap(mddev)) return -EINVAL; @@ -212,13 +211,7 @@ static int linear_run (struct mddev *mddev) blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec); mddev->queue->backing_dev_info.congested_fn = linear_congested; mddev->queue->backing_dev_info.congested_data = mddev; - - ret = md_integrity_register(mddev); - if (ret) { - kfree(conf); - mddev->private = NULL; - } - return ret; + return md_integrity_register(mddev); } static int linear_add(struct mddev *mddev, struct md_rdev *rdev) diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 477eb2e180c0..b572e1e386ce 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -7560,14 +7560,14 @@ void md_check_recovery(struct mddev *mddev) * any transients in the value of "sync_action". */ set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); + clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); /* Clear some bits that don't mean anything, but * might be left set */ clear_bit(MD_RECOVERY_INTR, &mddev->recovery); clear_bit(MD_RECOVERY_DONE, &mddev->recovery); - if (!test_and_clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || - test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) + if (test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) goto unlock; /* no recovery is running. * remove any failed drives, then @@ -8140,8 +8140,7 @@ static int md_notify_reboot(struct notifier_block *this, for_each_mddev(mddev, tmp) { if (mddev_trylock(mddev)) { - if (mddev->pers) - __md_stop_writes(mddev); + __md_stop_writes(mddev); mddev->safemode = 2; mddev_unlock(mddev); } diff --git a/trunk/drivers/md/raid0.c b/trunk/drivers/md/raid0.c index de63a1fc3737..6f31f5596e01 100644 --- a/trunk/drivers/md/raid0.c +++ b/trunk/drivers/md/raid0.c @@ -407,8 +407,6 @@ static sector_t raid0_size(struct mddev *mddev, sector_t sectors, int raid_disks return array_sectors; } -static int raid0_stop(struct mddev *mddev); - static int raid0_run(struct mddev *mddev) { struct r0conf *conf; @@ -456,12 +454,7 @@ static int raid0_run(struct mddev *mddev) blk_queue_merge_bvec(mddev->queue, raid0_mergeable_bvec); dump_zones(mddev); - - ret = md_integrity_register(mddev); - if (ret) - raid0_stop(mddev); - - return ret; + return md_integrity_register(mddev); } static int raid0_stop(struct mddev *mddev) @@ -632,7 +625,6 @@ static void *raid0_takeover_raid10(struct mddev *mddev) static void *raid0_takeover_raid1(struct mddev *mddev) { struct r0conf *priv_conf; - int chunksect; /* Check layout: * - (N - 1) mirror drives must be already faulty @@ -643,25 +635,10 @@ static void *raid0_takeover_raid1(struct mddev *mddev) return ERR_PTR(-EINVAL); } - /* - * a raid1 doesn't have the notion of chunk size, so - * figure out the largest suitable size we can use. - */ - chunksect = 64 * 2; /* 64K by default */ - - /* The array must be an exact multiple of chunksize */ - while (chunksect && (mddev->array_sectors & (chunksect - 1))) - chunksect >>= 1; - - if ((chunksect << 9) < PAGE_SIZE) - /* array size does not allow a suitable chunk size */ - return ERR_PTR(-EINVAL); - /* Set new parameters */ mddev->new_level = 0; mddev->new_layout = 0; - mddev->new_chunk_sectors = chunksect; - mddev->chunk_sectors = chunksect; + mddev->new_chunk_sectors = 128; /* by default set chunk size to 64k */ mddev->delta_disks = 1 - mddev->raid_disks; mddev->raid_disks = 1; /* make sure it will be not marked as dirty */ diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index 15dd59b84e94..4a40a200d769 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -1712,7 +1712,6 @@ static int process_checks(struct r1bio *r1_bio) struct r1conf *conf = mddev->private; int primary; int i; - int vcnt; for (primary = 0; primary < conf->raid_disks * 2; primary++) if (r1_bio->bios[primary]->bi_end_io == end_sync_read && @@ -1722,9 +1721,9 @@ static int process_checks(struct r1bio *r1_bio) break; } r1_bio->read_disk = primary; - vcnt = (r1_bio->sectors + PAGE_SIZE / 512 - 1) >> (PAGE_SHIFT - 9); for (i = 0; i < conf->raid_disks * 2; i++) { int j; + int vcnt = r1_bio->sectors >> (PAGE_SHIFT- 9); struct bio *pbio = r1_bio->bios[primary]; struct bio *sbio = r1_bio->bios[i]; int size; @@ -1739,7 +1738,7 @@ static int process_checks(struct r1bio *r1_bio) s = sbio->bi_io_vec[j].bv_page; if (memcmp(page_address(p), page_address(s), - sbio->bi_io_vec[j].bv_len)) + PAGE_SIZE)) break; } } else @@ -2387,7 +2386,8 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipp int ok = 1; for (i = 0 ; i < conf->raid_disks * 2 ; i++) if (r1_bio->bios[i]->bi_end_io == end_sync_write) { - struct md_rdev *rdev = conf->mirrors[i].rdev; + struct md_rdev *rdev = + rcu_dereference(conf->mirrors[i].rdev); ok = rdev_set_badblocks(rdev, sector_nr, min_bad, 0 ) && ok; @@ -2636,13 +2636,11 @@ static struct r1conf *setup_conf(struct mddev *mddev) return ERR_PTR(err); } -static int stop(struct mddev *mddev); static int run(struct mddev *mddev) { struct r1conf *conf; int i; struct md_rdev *rdev; - int ret; if (mddev->level != 1) { printk(KERN_ERR "md/raid1:%s: raid level not set to mirroring (%d)\n", @@ -2707,11 +2705,7 @@ static int run(struct mddev *mddev) mddev->queue->backing_dev_info.congested_data = mddev; blk_queue_merge_bvec(mddev->queue, raid1_mergeable_bvec); } - - ret = md_integrity_register(mddev); - if (ret) - stop(mddev); - return ret; + return md_integrity_register(mddev); } static int stop(struct mddev *mddev) diff --git a/trunk/drivers/md/raid10.c b/trunk/drivers/md/raid10.c index c8dbb84d5357..3540316886f2 100644 --- a/trunk/drivers/md/raid10.c +++ b/trunk/drivers/md/raid10.c @@ -1788,7 +1788,6 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio) struct r10conf *conf = mddev->private; int i, first; struct bio *tbio, *fbio; - int vcnt; atomic_set(&r10_bio->remaining, 1); @@ -1803,10 +1802,10 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio) first = i; fbio = r10_bio->devs[i].bio; - vcnt = (r10_bio->sectors + (PAGE_SIZE >> 9) - 1) >> (PAGE_SHIFT - 9); /* now find blocks with errors */ for (i=0 ; i < conf->copies ; i++) { int j, d; + int vcnt = r10_bio->sectors >> (PAGE_SHIFT-9); tbio = r10_bio->devs[i].bio; @@ -1822,7 +1821,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio) for (j = 0; j < vcnt; j++) if (memcmp(page_address(fbio->bi_io_vec[j].bv_page), page_address(tbio->bi_io_vec[j].bv_page), - fbio->bi_io_vec[j].bv_len)) + PAGE_SIZE)) break; if (j == vcnt) continue; @@ -1872,6 +1871,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio) */ for (i = 0; i < conf->copies; i++) { int j, d; + int vcnt = r10_bio->sectors >> (PAGE_SHIFT-9); tbio = r10_bio->devs[i].repl_bio; if (!tbio || !tbio->bi_end_io) diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index f351422938e0..23ac880bba9a 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -2471,41 +2471,39 @@ handle_failed_sync(struct r5conf *conf, struct stripe_head *sh, int abort = 0; int i; + md_done_sync(conf->mddev, STRIPE_SECTORS, 0); clear_bit(STRIPE_SYNCING, &sh->state); s->syncing = 0; s->replacing = 0; /* There is nothing more to do for sync/check/repair. - * Don't even need to abort as that is handled elsewhere - * if needed, and not always wanted e.g. if there is a known - * bad block here. * For recover/replace we need to record a bad block on all * non-sync devices, or abort the recovery */ - if (test_bit(MD_RECOVERY_RECOVER, &conf->mddev->recovery)) { - /* During recovery devices cannot be removed, so - * locking and refcounting of rdevs is not needed - */ - for (i = 0; i < conf->raid_disks; i++) { - struct md_rdev *rdev = conf->disks[i].rdev; - if (rdev - && !test_bit(Faulty, &rdev->flags) - && !test_bit(In_sync, &rdev->flags) - && !rdev_set_badblocks(rdev, sh->sector, - STRIPE_SECTORS, 0)) - abort = 1; - rdev = conf->disks[i].replacement; - if (rdev - && !test_bit(Faulty, &rdev->flags) - && !test_bit(In_sync, &rdev->flags) - && !rdev_set_badblocks(rdev, sh->sector, - STRIPE_SECTORS, 0)) - abort = 1; - } - if (abort) - conf->recovery_disabled = - conf->mddev->recovery_disabled; + if (!test_bit(MD_RECOVERY_RECOVER, &conf->mddev->recovery)) + return; + /* During recovery devices cannot be removed, so locking and + * refcounting of rdevs is not needed + */ + for (i = 0; i < conf->raid_disks; i++) { + struct md_rdev *rdev = conf->disks[i].rdev; + if (rdev + && !test_bit(Faulty, &rdev->flags) + && !test_bit(In_sync, &rdev->flags) + && !rdev_set_badblocks(rdev, sh->sector, + STRIPE_SECTORS, 0)) + abort = 1; + rdev = conf->disks[i].replacement; + if (rdev + && !test_bit(Faulty, &rdev->flags) + && !test_bit(In_sync, &rdev->flags) + && !rdev_set_badblocks(rdev, sh->sector, + STRIPE_SECTORS, 0)) + abort = 1; + } + if (abort) { + conf->recovery_disabled = conf->mddev->recovery_disabled; + set_bit(MD_RECOVERY_INTR, &conf->mddev->recovery); } - md_done_sync(conf->mddev, STRIPE_SECTORS, !abort); } static int want_replace(struct stripe_head *sh, int disk_idx) @@ -3205,8 +3203,7 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) /* Not in-sync */; else if (is_bad) { /* also not in-sync */ - if (!test_bit(WriteErrorSeen, &rdev->flags) && - test_bit(R5_UPTODATE, &dev->flags)) { + if (!test_bit(WriteErrorSeen, &rdev->flags)) { /* treat as in-sync, but with a read error * which we can now try to correct */ @@ -3279,14 +3276,12 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) /* If there is a failed device being replaced, * we must be recovering. * else if we are after recovery_cp, we must be syncing - * else if MD_RECOVERY_REQUESTED is set, we also are syncing. * else we can only be replacing * sync and recovery both need to read all devices, and so * use the same flag. */ if (do_recovery || - sh->sector >= conf->mddev->recovery_cp || - test_bit(MD_RECOVERY_REQUESTED, &(conf->mddev->recovery))) + sh->sector >= conf->mddev->recovery_cp) s->syncing = 1; else s->replacing = 1; diff --git a/trunk/drivers/media/common/tuners/xc5000.c b/trunk/drivers/media/common/tuners/xc5000.c index eab2ea424200..7f98984e4fad 100644 --- a/trunk/drivers/media/common/tuners/xc5000.c +++ b/trunk/drivers/media/common/tuners/xc5000.c @@ -54,7 +54,6 @@ struct xc5000_priv { struct list_head hybrid_tuner_instance_list; u32 if_khz; - u32 xtal_khz; u32 freq_hz; u32 bandwidth; u8 video_standard; @@ -215,9 +214,9 @@ static const struct xc5000_fw_cfg xc5000a_1_6_114 = { .size = 12401, }; -static const struct xc5000_fw_cfg xc5000c_41_024_5 = { - .name = "dvb-fe-xc5000c-41.024.5.fw", - .size = 16497, +static const struct xc5000_fw_cfg xc5000c_41_024_5_31875 = { + .name = "dvb-fe-xc5000c-41.024.5-31875.fw", + .size = 16503, }; static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id) @@ -227,7 +226,7 @@ static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id) case XC5000A: return &xc5000a_1_6_114; case XC5000C: - return &xc5000c_41_024_5; + return &xc5000c_41_024_5_31875; } } @@ -573,31 +572,6 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode) return found; } -static int xc_set_xtal(struct dvb_frontend *fe) -{ - struct xc5000_priv *priv = fe->tuner_priv; - int ret = XC_RESULT_SUCCESS; - - switch (priv->chip_id) { - default: - case XC5000A: - /* 32.000 MHz xtal is default */ - break; - case XC5000C: - switch (priv->xtal_khz) { - default: - case 32000: - /* 32.000 MHz xtal is default */ - break; - case 31875: - /* 31.875 MHz xtal configuration */ - ret = xc_write_reg(priv, 0x000f, 0x8081); - break; - } - break; - } - return ret; -} static int xc5000_fwupload(struct dvb_frontend *fe) { @@ -629,8 +603,6 @@ static int xc5000_fwupload(struct dvb_frontend *fe) } else { printk(KERN_INFO "xc5000: firmware uploading...\n"); ret = xc_load_i2c_sequence(fe, fw->data); - if (XC_RESULT_SUCCESS == ret) - ret = xc_set_xtal(fe); printk(KERN_INFO "xc5000: firmware upload complete...\n"); } @@ -1192,9 +1164,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, priv->if_khz = cfg->if_khz; } - if (priv->xtal_khz == 0) - priv->xtal_khz = cfg->xtal_khz; - if (priv->radio_input == 0) priv->radio_input = cfg->radio_input; diff --git a/trunk/drivers/media/common/tuners/xc5000.h b/trunk/drivers/media/common/tuners/xc5000.h index 39a73bf01406..3396f8e02b40 100644 --- a/trunk/drivers/media/common/tuners/xc5000.h +++ b/trunk/drivers/media/common/tuners/xc5000.h @@ -34,7 +34,6 @@ struct xc5000_config { u8 i2c_address; u32 if_khz; u8 radio_input; - u32 xtal_khz; int chip_id; }; diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c index 0f64d7182657..4555baa383b2 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -143,12 +143,10 @@ struct dvb_frontend_private { static void dvb_frontend_wakeup(struct dvb_frontend *fe); static int dtv_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p_out); -static int dtv_property_legacy_params_sync(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p); static bool has_get_frontend(struct dvb_frontend *fe) { - return fe->ops.get_frontend != NULL; + return fe->ops.get_frontend; } /* @@ -699,7 +697,6 @@ static int dvb_frontend_thread(void *data) fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; fepriv->delay = HZ / 2; } - dtv_property_legacy_params_sync(fe, &fepriv->parameters_out); fe->ops.read_status(fe, &s); if (s != fepriv->status) { dvb_frontend_add_event(fe, s); /* update event list */ @@ -1446,28 +1443,6 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system) __func__); return -EINVAL; } - /* - * Get a delivery system that is compatible with DVBv3 - * NOTE: in order for this to work with softwares like Kaffeine that - * uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to - * DVB-S, drivers that support both should put the SYS_DVBS entry - * before the SYS_DVBS2, otherwise it won't switch back to DVB-S. - * The real fix is that userspace applications should not use DVBv3 - * and not trust on calling FE_SET_FRONTEND to switch the delivery - * system. - */ - ncaps = 0; - while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { - if (fe->ops.delsys[ncaps] == desired_system) { - delsys = desired_system; - break; - } - ncaps++; - } - if (delsys == SYS_UNDEFINED) { - dprintk("%s() Couldn't find a delivery system that matches %d\n", - __func__, desired_system); - } } else { /* * This is a DVBv5 call. So, it likely knows the supported @@ -1516,10 +1491,9 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system) __func__); return -EINVAL; } + c->delivery_system = delsys; } - c->delivery_system = delsys; - /* * The DVBv3 or DVBv5 call is requesting a different system. So, * emulation is needed. @@ -1858,13 +1832,6 @@ static int dtv_set_frontend(struct dvb_frontend *fe) if (dvb_frontend_check_parameters(fe) < 0) return -EINVAL; - /* - * Initialize output parameters to match the values given by - * the user. FE_SET_FRONTEND triggers an initial frontend event - * with status = 0, which copies output parameters to userspace. - */ - dtv_property_legacy_params_sync(fe, &fepriv->parameters_out); - /* * Be sure that the bandwidth will be filled for all * non-satellite systems, as tuners need to know what diff --git a/trunk/drivers/media/dvb/dvb-usb/it913x.c b/trunk/drivers/media/dvb/dvb-usb/it913x.c index 482d249ca7f3..3b7b102f20ae 100644 --- a/trunk/drivers/media/dvb/dvb-usb/it913x.c +++ b/trunk/drivers/media/dvb/dvb-usb/it913x.c @@ -238,27 +238,12 @@ static int it913x_read_reg(struct usb_device *udev, u32 reg) static u32 it913x_query(struct usb_device *udev, u8 pro) { - int ret, i; + int ret; u8 data[4]; - u8 ver; - - for (i = 0; i < 5; i++) { - ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ, - 0x1222, 0, &data[0], 3); - ver = data[0]; - if (ver > 0 && ver < 3) - break; - msleep(100); - } + ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ, + 0x1222, 0, &data[0], 3); - if (ver < 1 || ver > 2) { - info("Failed to identify chip version applying 1"); - it913x_config.chip_ver = 0x1; - it913x_config.chip_type = 0x9135; - return 0; - } - - it913x_config.chip_ver = ver; + it913x_config.chip_ver = data[0]; it913x_config.chip_type = (u16)(data[2] << 8) + data[1]; info("Chip Version=%02x Chip Type=%04x", it913x_config.chip_ver, @@ -675,41 +660,30 @@ static int it913x_download_firmware(struct usb_device *udev, if ((packet_size > min_pkt) || (i == fw->size)) { fw_data = (u8 *)(fw->data + pos); pos += packet_size; - if (packet_size > 0) { - ret = it913x_io(udev, WRITE_DATA, + if (packet_size > 0) + ret |= it913x_io(udev, WRITE_DATA, DEV_0, CMD_SCATTER_WRITE, 0, 0, fw_data, packet_size); - if (ret < 0) - break; - } udelay(1000); } } i++; } - if (ret < 0) - info("FRM Firmware Download Failed (%d)" , ret); - else - info("FRM Firmware Download Completed - Resetting Device"); + ret |= it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0); - msleep(30); + msleep(100); - ret = it913x_io(udev, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0); if (ret < 0) - info("FRM Device not responding to reboot"); + info("FRM Firmware Download Failed (%04x)" , ret); + else + info("FRM Firmware Download Completed - Resetting Device"); - ret = it913x_return_status(udev); - if (ret == 0) { - info("FRM Failed to reboot device"); - return -ENODEV; - } + ret |= it913x_return_status(udev); msleep(30); - ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400); - - msleep(30); + ret |= it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400); /* Tuner function */ if (it913x_config.dual_mode) @@ -927,5 +901,5 @@ module_usb_driver(it913x_driver); MODULE_AUTHOR("Malcolm Priestley "); MODULE_DESCRIPTION("it913x USB 2 Driver"); -MODULE_VERSION("1.28"); +MODULE_VERSION("1.27"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/dvb/frontends/drxk_hard.c b/trunk/drivers/media/dvb/frontends/drxk_hard.c index a414b1f2b6a5..36d11756492f 100644 --- a/trunk/drivers/media/dvb/frontends/drxk_hard.c +++ b/trunk/drivers/media/dvb/frontends/drxk_hard.c @@ -1520,10 +1520,8 @@ static int scu_command(struct drxk_state *state, dprintk(1, "\n"); if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) || - ((resultLen > 0) && (result == NULL))) { - printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); - return status; - } + ((resultLen > 0) && (result == NULL))) + goto error; mutex_lock(&state->mutex); diff --git a/trunk/drivers/media/rc/winbond-cir.c b/trunk/drivers/media/rc/winbond-cir.c index af526586fa26..b09c5fae489b 100644 --- a/trunk/drivers/media/rc/winbond-cir.c +++ b/trunk/drivers/media/rc/winbond-cir.c @@ -1046,7 +1046,6 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) goto exit_unregister_led; } - data->dev->driver_type = RC_DRIVER_IR_RAW; data->dev->driver_name = WBCIR_NAME; data->dev->input_name = WBCIR_NAME; data->dev->input_phys = "wbcir/cir0"; diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig index ce1e7ba940f6..f2479c5c0eb2 100644 --- a/trunk/drivers/media/video/Kconfig +++ b/trunk/drivers/media/video/Kconfig @@ -492,7 +492,7 @@ config VIDEO_VS6624 config VIDEO_MT9M032 tristate "MT9M032 camera sensor support" - depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + depends on I2C && VIDEO_V4L2 select VIDEO_APTINA_PLL ---help--- This driver supports MT9M032 camera sensors from Aptina, monochrome diff --git a/trunk/drivers/media/video/ivtv/ivtv-ioctl.c b/trunk/drivers/media/video/ivtv/ivtv-ioctl.c index 989e556913ed..5452beef8e11 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/trunk/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1763,13 +1763,13 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n"); if (iarg > AUDIO_STEREO_SWAPPED) return -EINVAL; - return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg + 1); + return v4l2_ctrl_s_ctrl(itv->ctrl_audio_playback, iarg); case AUDIO_BILINGUAL_CHANNEL_SELECT: IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n"); if (iarg > AUDIO_STEREO_SWAPPED) return -EINVAL; - return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg + 1); + return v4l2_ctrl_s_ctrl(itv->ctrl_audio_multilingual_playback, iarg); default: return -EINVAL; diff --git a/trunk/drivers/media/video/mt9m032.c b/trunk/drivers/media/video/mt9m032.c index 645973c5feb0..7636672c3548 100644 --- a/trunk/drivers/media/video/mt9m032.c +++ b/trunk/drivers/media/video/mt9m032.c @@ -392,11 +392,10 @@ static int mt9m032_set_pad_format(struct v4l2_subdev *subdev, } /* Scaling is not supported, the format is thus fixed. */ - fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which); - ret = 0; + ret = mt9m032_get_pad_format(subdev, fh, fmt); done: - mutex_unlock(&sensor->lock); + mutex_lock(&sensor->lock); return ret; } diff --git a/trunk/drivers/media/video/uvc/uvc_video.c b/trunk/drivers/media/video/uvc/uvc_video.c index b76b0ac0958f..4a44f9a1bae0 100644 --- a/trunk/drivers/media/video/uvc/uvc_video.c +++ b/trunk/drivers/media/video/uvc/uvc_video.c @@ -468,30 +468,22 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf, spin_unlock_irqrestore(&stream->clock.lock, flags); } -static void uvc_video_clock_reset(struct uvc_streaming *stream) +static int uvc_video_clock_init(struct uvc_streaming *stream) { struct uvc_clock *clock = &stream->clock; + spin_lock_init(&clock->lock); clock->head = 0; clock->count = 0; + clock->size = 32; clock->last_sof = -1; clock->sof_offset = -1; -} - -static int uvc_video_clock_init(struct uvc_streaming *stream) -{ - struct uvc_clock *clock = &stream->clock; - - spin_lock_init(&clock->lock); - clock->size = 32; clock->samples = kmalloc(clock->size * sizeof(*clock->samples), GFP_KERNEL); if (clock->samples == NULL) return -ENOMEM; - uvc_video_clock_reset(stream); - return 0; } @@ -1432,6 +1424,8 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers) if (free_buffers) uvc_free_urb_buffers(stream); + + uvc_video_clock_cleanup(stream); } /* @@ -1561,6 +1555,10 @@ static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags) uvc_video_stats_start(stream); + ret = uvc_video_clock_init(stream); + if (ret < 0) + return ret; + if (intf->num_altsetting > 1) { struct usb_host_endpoint *best_ep = NULL; unsigned int best_psize = 3 * 1024; @@ -1685,8 +1683,6 @@ int uvc_video_resume(struct uvc_streaming *stream, int reset) stream->frozen = 0; - uvc_video_clock_reset(stream); - ret = uvc_commit_video(stream, &stream->ctrl); if (ret < 0) { uvc_queue_enable(&stream->queue, 0); @@ -1823,35 +1819,25 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable) uvc_uninit_video(stream, 1); usb_set_interface(stream->dev->udev, stream->intfnum, 0); uvc_queue_enable(&stream->queue, 0); - uvc_video_clock_cleanup(stream); return 0; } - ret = uvc_video_clock_init(stream); - if (ret < 0) - return ret; - ret = uvc_queue_enable(&stream->queue, 1); if (ret < 0) - goto error_queue; + return ret; /* Commit the streaming parameters. */ ret = uvc_commit_video(stream, &stream->ctrl); - if (ret < 0) - goto error_commit; + if (ret < 0) { + uvc_queue_enable(&stream->queue, 0); + return ret; + } ret = uvc_init_video(stream, GFP_KERNEL); - if (ret < 0) - goto error_video; - - return 0; - -error_video: - usb_set_interface(stream->dev->udev, stream->intfnum, 0); -error_commit: - uvc_queue_enable(&stream->queue, 0); -error_queue: - uvc_video_clock_cleanup(stream); + if (ret < 0) { + usb_set_interface(stream->dev->udev, stream->intfnum, 0); + uvc_queue_enable(&stream->queue, 0); + } return ret; } diff --git a/trunk/drivers/mfd/Kconfig b/trunk/drivers/mfd/Kconfig index 11e44386fa9b..29f463cc09cb 100644 --- a/trunk/drivers/mfd/Kconfig +++ b/trunk/drivers/mfd/Kconfig @@ -268,17 +268,10 @@ config TWL6030_PWM This is used to control charging LED brightness. config TWL6040_CORE - bool "Support for TWL6040 audio codec" - depends on I2C=y && GENERIC_HARDIRQS + bool + depends on TWL4030_CORE && GENERIC_HARDIRQS select MFD_CORE - select REGMAP_I2C default n - help - Say yes here if you want support for Texas Instruments TWL6040 audio - codec. - This driver provides common support for accessing the device, - additional drivers must be enabled in order to use the - functionality of the device (audio, vibra). config MFD_STMPE bool "Support STMicroelectronics STMPE" diff --git a/trunk/drivers/mfd/aat2870-core.c b/trunk/drivers/mfd/aat2870-core.c index 44a3fdbadef4..3aa36eb5c79b 100644 --- a/trunk/drivers/mfd/aat2870-core.c +++ b/trunk/drivers/mfd/aat2870-core.c @@ -262,6 +262,13 @@ static ssize_t aat2870_dump_reg(struct aat2870_data *aat2870, char *buf) return count; } +static int aat2870_reg_open_file(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + + return 0; +} + static ssize_t aat2870_reg_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -323,7 +330,7 @@ static ssize_t aat2870_reg_write_file(struct file *file, } static const struct file_operations aat2870_reg_fops = { - .open = simple_open, + .open = aat2870_reg_open_file, .read = aat2870_reg_read_file, .write = aat2870_reg_write_file, }; diff --git a/trunk/drivers/mfd/ab3100-core.c b/trunk/drivers/mfd/ab3100-core.c index 1efad20fb175..60107ee166fc 100644 --- a/trunk/drivers/mfd/ab3100-core.c +++ b/trunk/drivers/mfd/ab3100-core.c @@ -483,6 +483,12 @@ struct ab3100_get_set_reg_priv { bool mode; }; +static int ab3100_get_set_reg_open_file(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static ssize_t ab3100_get_set_reg(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) @@ -577,7 +583,7 @@ static ssize_t ab3100_get_set_reg(struct file *file, } static const struct file_operations ab3100_get_set_reg_fops = { - .open = simple_open, + .open = ab3100_get_set_reg_open_file, .write = ab3100_get_set_reg, .llseek = noop_llseek, }; diff --git a/trunk/drivers/mfd/asic3.c b/trunk/drivers/mfd/asic3.c index 1582c3d95257..1895cf9fab8c 100644 --- a/trunk/drivers/mfd/asic3.c +++ b/trunk/drivers/mfd/asic3.c @@ -527,9 +527,7 @@ static void asic3_gpio_set(struct gpio_chip *chip, static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset) { - struct asic3 *asic = container_of(chip, struct asic3, gpio); - - return (offset < ASIC3_NUM_GPIOS) ? asic->irq_base + offset : -ENXIO; + return (offset < ASIC3_NUM_GPIOS) ? IRQ_BOARD_START + offset : -ENXIO; } static __init int asic3_gpio_probe(struct platform_device *pdev, diff --git a/trunk/drivers/mfd/db8500-prcmu.c b/trunk/drivers/mfd/db8500-prcmu.c index 5be32489714f..ebc1e8658226 100644 --- a/trunk/drivers/mfd/db8500-prcmu.c +++ b/trunk/drivers/mfd/db8500-prcmu.c @@ -2788,7 +2788,6 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { .constraints = { .name = "db8500-vape", .valid_ops_mask = REGULATOR_CHANGE_STATUS, - .always_on = true, }, .consumer_supplies = db8500_vape_consumers, .num_consumer_supplies = ARRAY_SIZE(db8500_vape_consumers), diff --git a/trunk/drivers/mfd/omap-usb-host.c b/trunk/drivers/mfd/omap-usb-host.c index 7e96bb229724..95a2e546a489 100644 --- a/trunk/drivers/mfd/omap-usb-host.c +++ b/trunk/drivers/mfd/omap-usb-host.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -502,6 +502,19 @@ static void omap_usbhs_init(struct device *dev) pm_runtime_get_sync(dev); spin_lock_irqsave(&omap->lock, flags); + if (pdata->ehci_data->phy_reset) { + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) + gpio_request_one(pdata->ehci_data->reset_gpio_port[0], + GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) + gpio_request_one(pdata->ehci_data->reset_gpio_port[1], + GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); + + /* Hold the PHY in RESET for enough time till DIR is high */ + udelay(10); + } + omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); @@ -580,10 +593,39 @@ static void omap_usbhs_init(struct device *dev) usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT); } + if (pdata->ehci_data->phy_reset) { + /* Hold the PHY in RESET for enough time till + * PHY is settled and ready + */ + udelay(10); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) + gpio_set_value + (pdata->ehci_data->reset_gpio_port[0], 1); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) + gpio_set_value + (pdata->ehci_data->reset_gpio_port[1], 1); + } + spin_unlock_irqrestore(&omap->lock, flags); pm_runtime_put_sync(dev); } +static void omap_usbhs_deinit(struct device *dev) +{ + struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); + struct usbhs_omap_platform_data *pdata = &omap->platdata; + + if (pdata->ehci_data->phy_reset) { + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) + gpio_free(pdata->ehci_data->reset_gpio_port[0]); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) + gpio_free(pdata->ehci_data->reset_gpio_port[1]); + } +} + /** * usbhs_omap_probe - initialize TI-based HCDs @@ -818,6 +860,7 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev) { struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); + omap_usbhs_deinit(&pdev->dev); iounmap(omap->tll_base); iounmap(omap->uhh_base); clk_put(omap->init_60m_fclk); diff --git a/trunk/drivers/mfd/rc5t583.c b/trunk/drivers/mfd/rc5t583.c index 44afae0a69ce..99ef944c621d 100644 --- a/trunk/drivers/mfd/rc5t583.c +++ b/trunk/drivers/mfd/rc5t583.c @@ -80,6 +80,44 @@ static struct mfd_cell rc5t583_subdevs[] = { {.name = "rc5t583-key", } }; +int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + return regmap_write(rc5t583->regmap, reg, val); +} + +int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + unsigned int ival; + int ret; + ret = regmap_read(rc5t583->regmap, reg, &ival); + if (!ret) + *val = (uint8_t)ival; + return ret; +} + +int rc5t583_set_bits(struct device *dev, unsigned int reg, + unsigned int bit_mask) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask); +} + +int rc5t583_clear_bits(struct device *dev, unsigned int reg, + unsigned int bit_mask) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0); +} + +int rc5t583_update(struct device *dev, unsigned int reg, + unsigned int val, unsigned int mask) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + return regmap_update_bits(rc5t583->regmap, reg, mask, val); +} + static int __rc5t583_set_ext_pwrreq1_control(struct device *dev, int id, int ext_pwr, int slots) { @@ -159,7 +197,6 @@ int rc5t583_ext_power_req_config(struct device *dev, int ds_id, ds_id, ext_pwr_req); return 0; } -EXPORT_SYMBOL(rc5t583_ext_power_req_config); static int rc5t583_clear_ext_power_req(struct rc5t583 *rc5t583, struct rc5t583_platform_data *pdata) diff --git a/trunk/drivers/mfd/twl6040-core.c b/trunk/drivers/mfd/twl6040-core.c index 2d6bedadca09..b2d8e512d3cb 100644 --- a/trunk/drivers/mfd/twl6040-core.c +++ b/trunk/drivers/mfd/twl6040-core.c @@ -30,9 +30,7 @@ #include #include #include -#include -#include -#include +#include #include #include @@ -41,7 +39,7 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg) { int ret; - unsigned int val; + u8 val = 0; mutex_lock(&twl6040->io_mutex); /* Vibra control registers from cache */ @@ -49,7 +47,7 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg) reg == TWL6040_REG_VIBCTLR)) { val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)]; } else { - ret = regmap_read(twl6040->regmap, reg, &val); + ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); if (ret < 0) { mutex_unlock(&twl6040->io_mutex); return ret; @@ -66,7 +64,7 @@ int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, u8 val) int ret; mutex_lock(&twl6040->io_mutex); - ret = regmap_write(twl6040->regmap, reg, val); + ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); /* Cache the vibra control registers */ if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR) twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val; @@ -79,9 +77,16 @@ EXPORT_SYMBOL(twl6040_reg_write); int twl6040_set_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask) { int ret; + u8 val; mutex_lock(&twl6040->io_mutex); - ret = regmap_update_bits(twl6040->regmap, reg, mask, mask); + ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); + if (ret) + goto out; + + val |= mask; + ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); +out: mutex_unlock(&twl6040->io_mutex); return ret; } @@ -90,9 +95,16 @@ EXPORT_SYMBOL(twl6040_set_bits); int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask) { int ret; + u8 val; mutex_lock(&twl6040->io_mutex); - ret = regmap_update_bits(twl6040->regmap, reg, mask, 0); + ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); + if (ret) + goto out; + + val &= ~mask; + ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); +out: mutex_unlock(&twl6040->io_mutex); return ret; } @@ -482,58 +494,32 @@ static struct resource twl6040_codec_rsrc[] = { }, }; -static bool twl6040_readable_reg(struct device *dev, unsigned int reg) +static int __devinit twl6040_probe(struct platform_device *pdev) { - /* Register 0 is not readable */ - if (!reg) - return false; - return true; -} - -static struct regmap_config twl6040_regmap_config = { - .reg_bits = 8, - .val_bits = 8, - .max_register = TWL6040_REG_STATUS, /* 0x2e */ - - .readable_reg = twl6040_readable_reg, -}; - -static int __devinit twl6040_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct twl6040_platform_data *pdata = client->dev.platform_data; + struct twl4030_audio_data *pdata = pdev->dev.platform_data; struct twl6040 *twl6040; struct mfd_cell *cell = NULL; int ret, children = 0; if (!pdata) { - dev_err(&client->dev, "Platform data is missing\n"); + dev_err(&pdev->dev, "Platform data is missing\n"); return -EINVAL; } /* In order to operate correctly we need valid interrupt config */ - if (!client->irq || !pdata->irq_base) { - dev_err(&client->dev, "Invalid IRQ configuration\n"); + if (!pdata->naudint_irq || !pdata->irq_base) { + dev_err(&pdev->dev, "Invalid IRQ configuration\n"); return -EINVAL; } - twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040), - GFP_KERNEL); - if (!twl6040) { - ret = -ENOMEM; - goto err; - } - - twl6040->regmap = regmap_init_i2c(client, &twl6040_regmap_config); - if (IS_ERR(twl6040->regmap)) { - ret = PTR_ERR(twl6040->regmap); - goto err; - } + twl6040 = kzalloc(sizeof(struct twl6040), GFP_KERNEL); + if (!twl6040) + return -ENOMEM; - i2c_set_clientdata(client, twl6040); + platform_set_drvdata(pdev, twl6040); - twl6040->dev = &client->dev; - twl6040->irq = client->irq; + twl6040->dev = &pdev->dev; + twl6040->irq = pdata->naudint_irq; twl6040->irq_base = pdata->irq_base; mutex_init(&twl6040->mutex); @@ -602,12 +588,12 @@ static int __devinit twl6040_probe(struct i2c_client *client, } if (children) { - ret = mfd_add_devices(&client->dev, -1, twl6040->cells, + ret = mfd_add_devices(&pdev->dev, pdev->id, twl6040->cells, children, NULL, 0); if (ret) goto mfd_err; } else { - dev_err(&client->dev, "No platform data found for children\n"); + dev_err(&pdev->dev, "No platform data found for children\n"); ret = -ENODEV; goto mfd_err; } @@ -622,15 +608,14 @@ static int __devinit twl6040_probe(struct i2c_client *client, if (gpio_is_valid(twl6040->audpwron)) gpio_free(twl6040->audpwron); gpio1_err: - i2c_set_clientdata(client, NULL); - regmap_exit(twl6040->regmap); -err: + platform_set_drvdata(pdev, NULL); + kfree(twl6040); return ret; } -static int __devexit twl6040_remove(struct i2c_client *client) +static int __devexit twl6040_remove(struct platform_device *pdev) { - struct twl6040 *twl6040 = i2c_get_clientdata(client); + struct twl6040 *twl6040 = platform_get_drvdata(pdev); if (twl6040->power_count) twl6040_power(twl6040, 0); @@ -641,30 +626,23 @@ static int __devexit twl6040_remove(struct i2c_client *client) free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040); twl6040_irq_exit(twl6040); - mfd_remove_devices(&client->dev); - i2c_set_clientdata(client, NULL); - regmap_exit(twl6040->regmap); + mfd_remove_devices(&pdev->dev); + platform_set_drvdata(pdev, NULL); + kfree(twl6040); return 0; } -static const struct i2c_device_id twl6040_i2c_id[] = { - { "twl6040", 0, }, - { }, -}; -MODULE_DEVICE_TABLE(i2c, twl6040_i2c_id); - -static struct i2c_driver twl6040_driver = { - .driver = { - .name = "twl6040", - .owner = THIS_MODULE, - }, +static struct platform_driver twl6040_driver = { .probe = twl6040_probe, .remove = __devexit_p(twl6040_remove), - .id_table = twl6040_i2c_id, + .driver = { + .owner = THIS_MODULE, + .name = "twl6040", + }, }; -module_i2c_driver(twl6040_driver); +module_platform_driver(twl6040_driver); MODULE_DESCRIPTION("TWL6040 MFD"); MODULE_AUTHOR("Misael Lopez Cruz "); diff --git a/trunk/drivers/misc/ibmasm/ibmasmfs.c b/trunk/drivers/misc/ibmasm/ibmasmfs.c index 6673e578b3e9..1c034b80d408 100644 --- a/trunk/drivers/misc/ibmasm/ibmasmfs.c +++ b/trunk/drivers/misc/ibmasm/ibmasmfs.c @@ -500,6 +500,12 @@ static ssize_t r_heartbeat_file_write(struct file *file, const char __user *buf, return 1; } +static int remote_settings_file_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static int remote_settings_file_close(struct inode *inode, struct file *file) { return 0; @@ -594,7 +600,7 @@ static const struct file_operations r_heartbeat_fops = { }; static const struct file_operations remote_settings_fops = { - .open = simple_open, + .open = remote_settings_file_open, .release = remote_settings_file_close, .read = remote_settings_file_read, .write = remote_settings_file_write, diff --git a/trunk/drivers/misc/kgdbts.c b/trunk/drivers/misc/kgdbts.c index 3aa9a969b373..3f7ad83ed740 100644 --- a/trunk/drivers/misc/kgdbts.c +++ b/trunk/drivers/misc/kgdbts.c @@ -134,17 +134,12 @@ static int force_hwbrks; static int hwbreaks_ok; static int hw_break_val; static int hw_break_val2; -static int cont_instead_of_sstep; -static unsigned long cont_thread_id; -static unsigned long sstep_thread_id; #if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || defined(CONFIG_SPARC) static int arch_needs_sstep_emulation = 1; #else static int arch_needs_sstep_emulation; #endif -static unsigned long cont_addr; static unsigned long sstep_addr; -static int restart_from_top_after_write; static int sstep_state; /* Storage for the registers, in GDB format. */ @@ -192,8 +187,7 @@ static int kgdbts_unreg_thread(void *ptr) */ while (!final_ack) msleep_interruptible(1500); - /* Pause for any other threads to exit after final ack. */ - msleep_interruptible(1000); + if (configured) kgdb_unregister_io_module(&kgdbts_io_ops); configured = 0; @@ -217,7 +211,7 @@ static unsigned long lookup_addr(char *arg) if (!strcmp(arg, "kgdbts_break_test")) addr = (unsigned long)kgdbts_break_test; else if (!strcmp(arg, "sys_open")) - addr = (unsigned long)do_sys_open; + addr = (unsigned long)sys_open; else if (!strcmp(arg, "do_fork")) addr = (unsigned long)do_fork; else if (!strcmp(arg, "hw_break_val")) @@ -289,16 +283,6 @@ static void hw_break_val_write(void) hw_break_val++; } -static int get_thread_id_continue(char *put_str, char *arg) -{ - char *ptr = &put_str[11]; - - if (put_str[1] != 'T' || put_str[2] != '0') - return 1; - kgdb_hex2long(&ptr, &cont_thread_id); - return 0; -} - static int check_and_rewind_pc(char *put_str, char *arg) { unsigned long addr = lookup_addr(arg); @@ -315,21 +299,13 @@ static int check_and_rewind_pc(char *put_str, char *arg) if (addr + BREAK_INSTR_SIZE == ip) offset = -BREAK_INSTR_SIZE; #endif - - if (arch_needs_sstep_emulation && sstep_addr && - ip + offset == sstep_addr && - ((!strcmp(arg, "sys_open") || !strcmp(arg, "do_fork")))) { - /* This is special case for emulated single step */ - v2printk("Emul: rewind hit single step bp\n"); - restart_from_top_after_write = 1; - } else if (strcmp(arg, "silent") && ip + offset != addr) { + if (strcmp(arg, "silent") && ip + offset != addr) { eprintk("kgdbts: BP mismatch %lx expected %lx\n", ip + offset, addr); return 1; } /* Readjust the instruction pointer if needed */ ip += offset; - cont_addr = ip; #ifdef GDB_ADJUSTS_BREAK_OFFSET instruction_pointer_set(&kgdbts_regs, ip); #endif @@ -339,8 +315,6 @@ static int check_and_rewind_pc(char *put_str, char *arg) static int check_single_step(char *put_str, char *arg) { unsigned long addr = lookup_addr(arg); - static int matched_id; - /* * From an arch indepent point of view the instruction pointer * should be on a different instruction @@ -350,29 +324,6 @@ static int check_single_step(char *put_str, char *arg) gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs); v2printk("Singlestep stopped at IP: %lx\n", instruction_pointer(&kgdbts_regs)); - - if (sstep_thread_id != cont_thread_id) { - /* - * Ensure we stopped in the same thread id as before, else the - * debugger should continue until the original thread that was - * single stepped is scheduled again, emulating gdb's behavior. - */ - v2printk("ThrID does not match: %lx\n", cont_thread_id); - if (arch_needs_sstep_emulation) { - if (matched_id && - instruction_pointer(&kgdbts_regs) != addr) - goto continue_test; - matched_id++; - ts.idx -= 2; - sstep_state = 0; - return 0; - } - cont_instead_of_sstep = 1; - ts.idx -= 4; - return 0; - } -continue_test: - matched_id = 0; if (instruction_pointer(&kgdbts_regs) == addr) { eprintk("kgdbts: SingleStep failed at %lx\n", instruction_pointer(&kgdbts_regs)); @@ -414,40 +365,10 @@ static int got_break(char *put_str, char *arg) return 1; } -static void get_cont_catch(char *arg) -{ - /* Always send detach because the test is completed at this point */ - fill_get_buf("D"); -} - -static int put_cont_catch(char *put_str, char *arg) -{ - /* This is at the end of the test and we catch any and all input */ - v2printk("kgdbts: cleanup task: %lx\n", sstep_thread_id); - ts.idx--; - return 0; -} - -static int emul_reset(char *put_str, char *arg) -{ - if (strncmp(put_str, "$OK", 3)) - return 1; - if (restart_from_top_after_write) { - restart_from_top_after_write = 0; - ts.idx = -1; - } - return 0; -} - static void emul_sstep_get(char *arg) { if (!arch_needs_sstep_emulation) { - if (cont_instead_of_sstep) { - cont_instead_of_sstep = 0; - fill_get_buf("c"); - } else { - fill_get_buf(arg); - } + fill_get_buf(arg); return; } switch (sstep_state) { @@ -477,11 +398,9 @@ static void emul_sstep_get(char *arg) static int emul_sstep_put(char *put_str, char *arg) { if (!arch_needs_sstep_emulation) { - char *ptr = &put_str[11]; - if (put_str[1] != 'T' || put_str[2] != '0') - return 1; - kgdb_hex2long(&ptr, &sstep_thread_id); - return 0; + if (!strncmp(put_str+1, arg, 2)) + return 0; + return 1; } switch (sstep_state) { case 1: @@ -492,7 +411,8 @@ static int emul_sstep_put(char *put_str, char *arg) v2printk("Stopped at IP: %lx\n", instruction_pointer(&kgdbts_regs)); /* Want to stop at IP + break instruction size by default */ - sstep_addr = cont_addr + BREAK_INSTR_SIZE; + sstep_addr = instruction_pointer(&kgdbts_regs) + + BREAK_INSTR_SIZE; break; case 2: if (strncmp(put_str, "$OK", 3)) { @@ -504,9 +424,6 @@ static int emul_sstep_put(char *put_str, char *arg) if (strncmp(put_str, "$T0", 3)) { eprintk("kgdbts: failed continue sstep\n"); return 1; - } else { - char *ptr = &put_str[11]; - kgdb_hex2long(&ptr, &sstep_thread_id); } break; case 4: @@ -585,10 +502,10 @@ static struct test_struct bad_read_test[] = { static struct test_struct singlestep_break_test[] = { { "?", "S0*" }, /* Clear break points */ { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ - { "c", "T0*", NULL, get_thread_id_continue }, /* Continue */ - { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */ + { "c", "T0*", }, /* Continue */ { "g", "kgdbts_break_test", NULL, check_and_rewind_pc }, { "write", "OK", write_regs }, /* Write registers */ + { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */ { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ { "g", "kgdbts_break_test", NULL, check_single_step }, { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */ @@ -606,16 +523,16 @@ static struct test_struct singlestep_break_test[] = { static struct test_struct do_fork_test[] = { { "?", "S0*" }, /* Clear break points */ { "do_fork", "OK", sw_break, }, /* set sw breakpoint */ - { "c", "T0*", NULL, get_thread_id_continue }, /* Continue */ - { "do_fork", "OK", sw_rem_break }, /*remove breakpoint */ + { "c", "T0*", }, /* Continue */ { "g", "do_fork", NULL, check_and_rewind_pc }, /* check location */ - { "write", "OK", write_regs, emul_reset }, /* Write registers */ + { "write", "OK", write_regs }, /* Write registers */ + { "do_fork", "OK", sw_rem_break }, /*remove breakpoint */ { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ { "g", "do_fork", NULL, check_single_step }, { "do_fork", "OK", sw_break, }, /* set sw breakpoint */ { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */ { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */ - { "", "", get_cont_catch, put_cont_catch }, + { "", "" }, }; /* Test for hitting a breakpoint at sys_open for what ever the number @@ -624,16 +541,16 @@ static struct test_struct do_fork_test[] = { static struct test_struct sys_open_test[] = { { "?", "S0*" }, /* Clear break points */ { "sys_open", "OK", sw_break, }, /* set sw breakpoint */ - { "c", "T0*", NULL, get_thread_id_continue }, /* Continue */ - { "sys_open", "OK", sw_rem_break }, /*remove breakpoint */ + { "c", "T0*", }, /* Continue */ { "g", "sys_open", NULL, check_and_rewind_pc }, /* check location */ - { "write", "OK", write_regs, emul_reset }, /* Write registers */ + { "write", "OK", write_regs }, /* Write registers */ + { "sys_open", "OK", sw_rem_break }, /*remove breakpoint */ { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */ { "g", "sys_open", NULL, check_single_step }, { "sys_open", "OK", sw_break, }, /* set sw breakpoint */ { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */ { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */ - { "", "", get_cont_catch, put_cont_catch }, + { "", "" }, }; /* @@ -776,8 +693,8 @@ static int run_simple_test(int is_get_char, int chr) /* This callback is a put char which is when kgdb sends data to * this I/O module. */ - if (ts.tst[ts.idx].get[0] == '\0' && ts.tst[ts.idx].put[0] == '\0' && - !ts.tst[ts.idx].get_handler) { + if (ts.tst[ts.idx].get[0] == '\0' && + ts.tst[ts.idx].put[0] == '\0') { eprintk("kgdbts: ERROR: beyond end of test on" " '%s' line %i\n", ts.name, ts.idx); return 0; @@ -990,17 +907,6 @@ static void kgdbts_run_tests(void) if (ptr) sstep_test = simple_strtol(ptr+1, NULL, 10); - /* All HW break point tests */ - if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) { - hwbreaks_ok = 1; - v1printk("kgdbts:RUN hw breakpoint test\n"); - run_breakpoint_test(1); - v1printk("kgdbts:RUN hw write breakpoint test\n"); - run_hw_break_test(1); - v1printk("kgdbts:RUN access write breakpoint test\n"); - run_hw_break_test(0); - } - /* required internal KGDB tests */ v1printk("kgdbts:RUN plant and detach test\n"); run_plant_and_detach_test(0); @@ -1018,11 +924,35 @@ static void kgdbts_run_tests(void) /* ===Optional tests=== */ + /* All HW break point tests */ + if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) { + hwbreaks_ok = 1; + v1printk("kgdbts:RUN hw breakpoint test\n"); + run_breakpoint_test(1); + v1printk("kgdbts:RUN hw write breakpoint test\n"); + run_hw_break_test(1); + v1printk("kgdbts:RUN access write breakpoint test\n"); + run_hw_break_test(0); + } + if (nmi_sleep) { v1printk("kgdbts:RUN NMI sleep %i seconds test\n", nmi_sleep); run_nmi_sleep_test(nmi_sleep); } +#ifdef CONFIG_DEBUG_RODATA + /* Until there is an api to write to read-only text segments, use + * HW breakpoints for the remainder of any tests, else print a + * failure message if hw breakpoints do not work. + */ + if (!(arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT && hwbreaks_ok)) { + eprintk("kgdbts: HW breakpoints do not work," + "skipping remaining tests\n"); + return; + } + force_hwbrks = 1; +#endif /* CONFIG_DEBUG_RODATA */ + /* If the do_fork test is run it will be the last test that is * executed because a kernel thread will be spawned at the very * end to unregister the debug hooks. diff --git a/trunk/drivers/mmc/card/block.c b/trunk/drivers/mmc/card/block.c index dabec556ebb8..eed213a5c8cb 100644 --- a/trunk/drivers/mmc/card/block.c +++ b/trunk/drivers/mmc/card/block.c @@ -873,7 +873,7 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, { struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; - unsigned int from, nr, arg, trim_arg, erase_arg; + unsigned int from, nr, arg; int err = 0, type = MMC_BLK_SECDISCARD; if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) { @@ -881,26 +881,20 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, goto out; } - from = blk_rq_pos(req); - nr = blk_rq_sectors(req); - /* The sanitize operation is supported at v4.5 only */ if (mmc_can_sanitize(card)) { - erase_arg = MMC_ERASE_ARG; - trim_arg = MMC_TRIM_ARG; - } else { - erase_arg = MMC_SECURE_ERASE_ARG; - trim_arg = MMC_SECURE_TRIM1_ARG; - } - - if (mmc_erase_group_aligned(card, from, nr)) - arg = erase_arg; - else if (mmc_can_trim(card)) - arg = trim_arg; - else { - err = -EINVAL; + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_SANITIZE_START, 1, 0); goto out; } + + from = blk_rq_pos(req); + nr = blk_rq_sectors(req); + + if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr)) + arg = MMC_SECURE_TRIM1_ARG; + else + arg = MMC_SECURE_ERASE_ARG; retry: if (card->quirks & MMC_QUIRK_INAND_CMD38) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, @@ -910,41 +904,25 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, INAND_CMD38_ARG_SECERASE, 0); if (err) - goto out_retry; + goto out; } - err = mmc_erase(card, from, nr, arg); - if (err == -EIO) - goto out_retry; - if (err) - goto out; - - if (arg == MMC_SECURE_TRIM1_ARG) { + if (!err && arg == MMC_SECURE_TRIM1_ARG) { if (card->quirks & MMC_QUIRK_INAND_CMD38) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, INAND_CMD38_ARG_EXT_CSD, INAND_CMD38_ARG_SECTRIM2, 0); if (err) - goto out_retry; + goto out; } - err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG); - if (err == -EIO) - goto out_retry; - if (err) - goto out; } - - if (mmc_can_sanitize(card)) - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_SANITIZE_START, 1, 0); -out_retry: - if (err && !mmc_blk_reset(md, card->host, type)) +out: + if (err == -EIO && !mmc_blk_reset(md, card->host, type)) goto retry; if (!err) mmc_blk_reset_success(md, type); -out: spin_lock_irq(&md->lock); __blk_end_request(req, err, blk_rq_bytes(req)); spin_unlock_irq(&md->lock); @@ -1645,6 +1623,24 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) return ret; } +static int +mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) +{ + int err; + + mmc_claim_host(card->host); + err = mmc_set_blocklen(card, 512); + mmc_release_host(card->host); + + if (err) { + pr_err("%s: unable to set block size to 512: %d\n", + md->disk->disk_name, err); + return -EINVAL; + } + + return 0; +} + static void mmc_blk_remove_req(struct mmc_blk_data *md) { struct mmc_card *card; @@ -1772,6 +1768,7 @@ static const struct mmc_fixup blk_fixups[] = static int mmc_blk_probe(struct mmc_card *card) { struct mmc_blk_data *md, *part_md; + int err; char cap_str[10]; /* @@ -1784,6 +1781,10 @@ static int mmc_blk_probe(struct mmc_card *card) if (IS_ERR(md)) return PTR_ERR(md); + err = mmc_blk_set_blksize(md, card); + if (err) + goto out; + string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2, cap_str, sizeof(cap_str)); pr_info("%s: %s %s %s %s\n", @@ -1808,7 +1809,7 @@ static int mmc_blk_probe(struct mmc_card *card) out: mmc_blk_remove_parts(card, md); mmc_blk_remove_req(md); - return 0; + return err; } static void mmc_blk_remove(struct mmc_card *card) @@ -1824,7 +1825,7 @@ static void mmc_blk_remove(struct mmc_card *card) } #ifdef CONFIG_PM -static int mmc_blk_suspend(struct mmc_card *card) +static int mmc_blk_suspend(struct mmc_card *card, pm_message_t state) { struct mmc_blk_data *part_md; struct mmc_blk_data *md = mmc_get_drvdata(card); @@ -1844,6 +1845,8 @@ static int mmc_blk_resume(struct mmc_card *card) struct mmc_blk_data *md = mmc_get_drvdata(card); if (md) { + mmc_blk_set_blksize(md, card); + /* * Resume involves the card going into idle state, * so current partition is always the main one. diff --git a/trunk/drivers/mmc/card/queue.c b/trunk/drivers/mmc/card/queue.c index 996f8e36e23d..2517547b4366 100644 --- a/trunk/drivers/mmc/card/queue.c +++ b/trunk/drivers/mmc/card/queue.c @@ -139,7 +139,7 @@ static void mmc_queue_setup_discard(struct request_queue *q, queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); q->limits.max_discard_sectors = max_discard; - if (card->erased_byte == 0 && !mmc_can_discard(card)) + if (card->erased_byte == 0) q->limits.discard_zeroes_data = 1; q->limits.discard_granularity = card->pref_erase << 9; /* granularity must not be greater than max. discard */ diff --git a/trunk/drivers/mmc/core/bus.c b/trunk/drivers/mmc/core/bus.c index c60cee92a2b2..5d011a39dfff 100644 --- a/trunk/drivers/mmc/core/bus.c +++ b/trunk/drivers/mmc/core/bus.c @@ -122,14 +122,14 @@ static int mmc_bus_remove(struct device *dev) return 0; } -static int mmc_bus_suspend(struct device *dev) +static int mmc_bus_suspend(struct device *dev, pm_message_t state) { struct mmc_driver *drv = to_mmc_driver(dev->driver); struct mmc_card *card = mmc_dev_to_card(dev); int ret = 0; if (dev->driver && drv->suspend) - ret = drv->suspend(card); + ret = drv->suspend(card, state); return ret; } @@ -165,14 +165,20 @@ static int mmc_runtime_idle(struct device *dev) return pm_runtime_suspend(dev); } -#endif /* !CONFIG_PM_RUNTIME */ - static const struct dev_pm_ops mmc_bus_pm_ops = { - SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume, - mmc_runtime_idle) - SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_suspend, mmc_bus_resume) + .runtime_suspend = mmc_runtime_suspend, + .runtime_resume = mmc_runtime_resume, + .runtime_idle = mmc_runtime_idle, }; +#define MMC_PM_OPS_PTR (&mmc_bus_pm_ops) + +#else /* !CONFIG_PM_RUNTIME */ + +#define MMC_PM_OPS_PTR NULL + +#endif /* !CONFIG_PM_RUNTIME */ + static struct bus_type mmc_bus_type = { .name = "mmc", .dev_attrs = mmc_dev_attrs, @@ -180,7 +186,9 @@ static struct bus_type mmc_bus_type = { .uevent = mmc_bus_uevent, .probe = mmc_bus_probe, .remove = mmc_bus_remove, - .pm = &mmc_bus_pm_ops, + .suspend = mmc_bus_suspend, + .resume = mmc_bus_resume, + .pm = MMC_PM_OPS_PTR, }; int mmc_register_bus(void) @@ -259,15 +267,6 @@ int mmc_add_card(struct mmc_card *card) { int ret; const char *type; - const char *uhs_bus_speed_mode = ""; - static const char *const uhs_speeds[] = { - [UHS_SDR12_BUS_SPEED] = "SDR12 ", - [UHS_SDR25_BUS_SPEED] = "SDR25 ", - [UHS_SDR50_BUS_SPEED] = "SDR50 ", - [UHS_SDR104_BUS_SPEED] = "SDR104 ", - [UHS_DDR50_BUS_SPEED] = "DDR50 ", - }; - dev_set_name(&card->dev, "%s:%04x", mmc_hostname(card->host), card->rca); @@ -297,10 +296,6 @@ int mmc_add_card(struct mmc_card *card) break; } - if (mmc_sd_card_uhs(card) && - (card->sd_bus_speed < ARRAY_SIZE(uhs_speeds))) - uhs_bus_speed_mode = uhs_speeds[card->sd_bus_speed]; - if (mmc_host_is_spi(card->host)) { pr_info("%s: new %s%s%s card on SPI\n", mmc_hostname(card->host), @@ -308,13 +303,13 @@ int mmc_add_card(struct mmc_card *card) mmc_card_ddr_mode(card) ? "DDR " : "", type); } else { - pr_info("%s: new %s%s%s%s%s card at address %04x\n", + pr_info("%s: new %s%s%s%s card at address %04x\n", mmc_hostname(card->host), mmc_card_uhs(card) ? "ultra high speed " : (mmc_card_highspeed(card) ? "high speed " : ""), (mmc_card_hs200(card) ? "HS200 " : ""), mmc_card_ddr_mode(card) ? "DDR " : "", - uhs_bus_speed_mode, type, card->rca); + type, card->rca); } #ifdef CONFIG_DEBUG_FS diff --git a/trunk/drivers/mmc/core/cd-gpio.c b/trunk/drivers/mmc/core/cd-gpio.c index 2c14be73254c..29de31e260dd 100644 --- a/trunk/drivers/mmc/core/cd-gpio.c +++ b/trunk/drivers/mmc/core/cd-gpio.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/mmc/core/core.c b/trunk/drivers/mmc/core/core.c index ba821fe70bca..14f262e9246d 100644 --- a/trunk/drivers/mmc/core/core.c +++ b/trunk/drivers/mmc/core/core.c @@ -527,14 +527,10 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) if (data->flags & MMC_DATA_WRITE) /* - * The MMC spec "It is strongly recommended - * for hosts to implement more than 500ms - * timeout value even if the card indicates - * the 250ms maximum busy length." Even the - * previous value of 300ms is known to be - * insufficient for some cards. + * The limit is really 250 ms, but that is + * insufficient for some crappy cards. */ - limit_us = 3000000; + limit_us = 300000; else limit_us = 100000; @@ -1409,10 +1405,7 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card, { unsigned int erase_timeout; - if (arg == MMC_DISCARD_ARG || - (arg == MMC_TRIM_ARG && card->ext_csd.rev >= 6)) { - erase_timeout = card->ext_csd.trim_timeout; - } else if (card->ext_csd.erase_group_def & 1) { + if (card->ext_csd.erase_group_def & 1) { /* High Capacity Erase Group Size uses HC timeouts */ if (arg == MMC_TRIM_ARG) erase_timeout = card->ext_csd.trim_timeout; @@ -1684,6 +1677,8 @@ int mmc_can_trim(struct mmc_card *card) { if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN) return 1; + if (mmc_can_discard(card)) + return 1; return 0; } EXPORT_SYMBOL(mmc_can_trim); @@ -1702,8 +1697,6 @@ EXPORT_SYMBOL(mmc_can_discard); int mmc_can_sanitize(struct mmc_card *card) { - if (!mmc_can_trim(card) && !mmc_can_erase(card)) - return 0; if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE) return 1; return 0; @@ -2238,7 +2231,6 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable) mmc_card_is_removable(host)) return err; - mmc_claim_host(host); if (card && mmc_card_mmc(card) && (card->ext_csd.cache_size > 0)) { enable = !!enable; @@ -2256,7 +2248,6 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable) card->ext_csd.cache_ctrl = enable; } } - mmc_release_host(host); return err; } @@ -2274,32 +2265,49 @@ int mmc_suspend_host(struct mmc_host *host) cancel_delayed_work(&host->detect); mmc_flush_scheduled_work(); + if (mmc_try_claim_host(host)) { + err = mmc_cache_ctrl(host, 0); + mmc_release_host(host); + } else { + err = -EBUSY; + } - err = mmc_cache_ctrl(host, 0); if (err) goto out; mmc_bus_get(host); if (host->bus_ops && !host->bus_dead) { - if (host->bus_ops->suspend) - err = host->bus_ops->suspend(host); - - if (err == -ENOSYS || !host->bus_ops->resume) { - /* - * We simply "remove" the card in this case. - * It will be redetected on resume. (Calling - * bus_ops->remove() with a claimed host can - * deadlock.) - */ - if (host->bus_ops->remove) - host->bus_ops->remove(host); - mmc_claim_host(host); - mmc_detach_bus(host); - mmc_power_off(host); + /* + * A long response time is not acceptable for device drivers + * when doing suspend. Prevent mmc_claim_host in the suspend + * sequence, to potentially wait "forever" by trying to + * pre-claim the host. + */ + if (mmc_try_claim_host(host)) { + if (host->bus_ops->suspend) { + err = host->bus_ops->suspend(host); + } mmc_release_host(host); - host->pm_flags = 0; - err = 0; + + if (err == -ENOSYS || !host->bus_ops->resume) { + /* + * We simply "remove" the card in this case. + * It will be redetected on resume. (Calling + * bus_ops->remove() with a claimed host can + * deadlock.) + */ + if (host->bus_ops->remove) + host->bus_ops->remove(host); + mmc_claim_host(host); + mmc_detach_bus(host); + mmc_power_off(host); + mmc_release_host(host); + host->pm_flags = 0; + err = 0; + } + } else { + err = -EBUSY; } } mmc_bus_put(host); diff --git a/trunk/drivers/mmc/core/mmc.c b/trunk/drivers/mmc/core/mmc.c index 54df5adc0413..02914d609a91 100644 --- a/trunk/drivers/mmc/core/mmc.c +++ b/trunk/drivers/mmc/core/mmc.c @@ -695,11 +695,6 @@ static int mmc_select_powerclass(struct mmc_card *card, else if (host->ios.clock <= 200000000) index = EXT_CSD_PWR_CL_200_195; break; - case MMC_VDD_27_28: - case MMC_VDD_28_29: - case MMC_VDD_29_30: - case MMC_VDD_30_31: - case MMC_VDD_31_32: case MMC_VDD_32_33: case MMC_VDD_33_34: case MMC_VDD_34_35: @@ -1116,10 +1111,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4; err = mmc_select_powerclass(card, ext_csd_bits, ext_csd); - if (err) - pr_warning("%s: power class selection to bus width %d" - " failed\n", mmc_hostname(card->host), - 1 << bus_width); + if (err) { + pr_err("%s: power class selection to bus width %d failed\n", + mmc_hostname(card->host), 1 << bus_width); + goto err; + } } /* @@ -1151,10 +1147,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, err = mmc_select_powerclass(card, ext_csd_bits[idx][0], ext_csd); if (err) - pr_warning("%s: power class selection to " - "bus width %d failed\n", - mmc_hostname(card->host), - 1 << bus_width); + pr_err("%s: power class selection to " + "bus width %d failed\n", + mmc_hostname(card->host), + 1 << bus_width); err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, @@ -1182,10 +1178,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, err = mmc_select_powerclass(card, ext_csd_bits[idx][1], ext_csd); if (err) - pr_warning("%s: power class selection to " - "bus width %d ddr %d failed\n", - mmc_hostname(card->host), - 1 << bus_width, ddr); + pr_err("%s: power class selection to " + "bus width %d ddr %d failed\n", + mmc_hostname(card->host), + 1 << bus_width, ddr); err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, diff --git a/trunk/drivers/mmc/core/sdio_bus.c b/trunk/drivers/mmc/core/sdio_bus.c index 236842ec955a..40989e6bb53a 100644 --- a/trunk/drivers/mmc/core/sdio_bus.c +++ b/trunk/drivers/mmc/core/sdio_bus.c @@ -192,15 +192,9 @@ static int sdio_bus_remove(struct device *dev) return ret; } -#ifdef CONFIG_PM - -static int pm_no_operation(struct device *dev) -{ - return 0; -} +#ifdef CONFIG_PM_RUNTIME static const struct dev_pm_ops sdio_bus_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(pm_no_operation, pm_no_operation) SET_RUNTIME_PM_OPS( pm_generic_runtime_suspend, pm_generic_runtime_resume, @@ -210,11 +204,11 @@ static const struct dev_pm_ops sdio_bus_pm_ops = { #define SDIO_PM_OPS_PTR (&sdio_bus_pm_ops) -#else /* !CONFIG_PM */ +#else /* !CONFIG_PM_RUNTIME */ #define SDIO_PM_OPS_PTR NULL -#endif /* !CONFIG_PM */ +#endif /* !CONFIG_PM_RUNTIME */ static struct bus_type sdio_bus_type = { .name = "sdio", diff --git a/trunk/drivers/mmc/host/atmel-mci-regs.h b/trunk/drivers/mmc/host/atmel-mci-regs.h index 787aba1682bb..000b3ad0f5ca 100644 --- a/trunk/drivers/mmc/host/atmel-mci-regs.h +++ b/trunk/drivers/mmc/host/atmel-mci-regs.h @@ -31,7 +31,6 @@ # define ATMCI_MR_PDCFBYTE ( 1 << 13) /* Force Byte Transfer */ # define ATMCI_MR_PDCPADV ( 1 << 14) /* Padding Value */ # define ATMCI_MR_PDCMODE ( 1 << 15) /* PDC-oriented Mode */ -# define ATMCI_MR_CLKODD(x) ((x) << 16) /* LSB of Clock Divider */ #define ATMCI_DTOR 0x0008 /* Data Timeout */ # define ATMCI_DTOCYC(x) ((x) << 0) /* Data Timeout Cycles */ # define ATMCI_DTOMUL(x) ((x) << 4) /* Data Timeout Multiplier */ diff --git a/trunk/drivers/mmc/host/atmel-mci.c b/trunk/drivers/mmc/host/atmel-mci.c index e94476beca18..9819dc09ce08 100644 --- a/trunk/drivers/mmc/host/atmel-mci.c +++ b/trunk/drivers/mmc/host/atmel-mci.c @@ -77,7 +77,6 @@ struct atmel_mci_caps { bool has_cstor_reg; bool has_highspeed; bool has_rwproof; - bool has_odd_clk_div; }; struct atmel_mci_dma { @@ -483,14 +482,7 @@ static void atmci_init_debugfs(struct atmel_mci_slot *slot) static inline unsigned int atmci_ns_to_clocks(struct atmel_mci *host, unsigned int ns) { - /* - * It is easier here to use us instead of ns for the timeout, - * it prevents from overflows during calculation. - */ - unsigned int us = DIV_ROUND_UP(ns, 1000); - - /* Maximum clock frequency is host->bus_hz/2 */ - return us * (DIV_ROUND_UP(host->bus_hz, 2000000)); + return (ns * (host->bus_hz / 1000000) + 999) / 1000; } static void atmci_set_timeout(struct atmel_mci *host, @@ -1135,27 +1127,16 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) } /* Calculate clock divider */ - if (host->caps.has_odd_clk_div) { - clkdiv = DIV_ROUND_UP(host->bus_hz, clock_min) - 2; - if (clkdiv > 511) { - dev_warn(&mmc->class_dev, - "clock %u too slow; using %lu\n", - clock_min, host->bus_hz / (511 + 2)); - clkdiv = 511; - } - host->mode_reg = ATMCI_MR_CLKDIV(clkdiv >> 1) - | ATMCI_MR_CLKODD(clkdiv & 1); - } else { - clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * clock_min) - 1; - if (clkdiv > 255) { - dev_warn(&mmc->class_dev, - "clock %u too slow; using %lu\n", - clock_min, host->bus_hz / (2 * 256)); - clkdiv = 255; - } - host->mode_reg = ATMCI_MR_CLKDIV(clkdiv); + clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * clock_min) - 1; + if (clkdiv > 255) { + dev_warn(&mmc->class_dev, + "clock %u too slow; using %lu\n", + clock_min, host->bus_hz / (2 * 256)); + clkdiv = 255; } + host->mode_reg = ATMCI_MR_CLKDIV(clkdiv); + /* * WRPROOF and RDPROOF prevent overruns/underruns by * stopping the clock when the FIFO is full/empty. @@ -2026,35 +2007,35 @@ static void __init atmci_get_cap(struct atmel_mci *host) "version: 0x%x\n", version); host->caps.has_dma = 0; - host->caps.has_pdc = 1; + host->caps.has_pdc = 0; host->caps.has_cfg_reg = 0; host->caps.has_cstor_reg = 0; host->caps.has_highspeed = 0; host->caps.has_rwproof = 0; - host->caps.has_odd_clk_div = 0; /* keep only major version number */ switch (version & 0xf00) { - case 0x500: - host->caps.has_odd_clk_div = 1; - case 0x400: + case 0x100: + case 0x200: + host->caps.has_pdc = 1; + host->caps.has_rwproof = 1; + break; case 0x300: + case 0x400: + case 0x500: #ifdef CONFIG_AT_HDMAC host->caps.has_dma = 1; #else + host->caps.has_dma = 0; dev_info(&host->pdev->dev, "has dma capability but dma engine is not selected, then use pio\n"); #endif - host->caps.has_pdc = 0; host->caps.has_cfg_reg = 1; host->caps.has_cstor_reg = 1; host->caps.has_highspeed = 1; - case 0x200: host->caps.has_rwproof = 1; - case 0x100: break; default: - host->caps.has_pdc = 0; dev_warn(&host->pdev->dev, "Unmanaged mci version, set minimum capabilities\n"); break; diff --git a/trunk/drivers/mmc/host/dw_mmc.c b/trunk/drivers/mmc/host/dw_mmc.c index ab3fc4617107..bf3c9b456aaf 100644 --- a/trunk/drivers/mmc/host/dw_mmc.c +++ b/trunk/drivers/mmc/host/dw_mmc.c @@ -526,10 +526,8 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data) return -ENODEV; sg_len = dw_mci_pre_dma_transfer(host, data, 0); - if (sg_len < 0) { - host->dma_ops->stop(host); + if (sg_len < 0) return sg_len; - } host->using_dma = 1; @@ -1881,8 +1879,7 @@ static void dw_mci_init_dma(struct dw_mci *host) if (!host->dma_ops) goto no_dma; - if (host->dma_ops->init && host->dma_ops->start && - host->dma_ops->stop && host->dma_ops->cleanup) { + if (host->dma_ops->init) { if (host->dma_ops->init(host)) { dev_err(&host->dev, "%s: Unable to initialize " "DMA Controller.\n", __func__); diff --git a/trunk/drivers/mmc/host/mxs-mmc.c b/trunk/drivers/mmc/host/mxs-mmc.c index e3f5af96ab87..65f36cf2ff33 100644 --- a/trunk/drivers/mmc/host/mxs-mmc.c +++ b/trunk/drivers/mmc/host/mxs-mmc.c @@ -38,10 +38,10 @@ #include #include #include -#include #include #include +#include #include #define DRIVER_NAME "mxs-mmc" @@ -305,7 +305,7 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id) } static struct dma_async_tx_descriptor *mxs_mmc_prep_dma( - struct mxs_mmc_host *host, unsigned long flags) + struct mxs_mmc_host *host, unsigned int append) { struct dma_async_tx_descriptor *desc; struct mmc_data *data = host->data; @@ -325,7 +325,7 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma( } desc = dmaengine_prep_slave_sg(host->dmach, - sgl, sg_len, host->slave_dirn, flags); + sgl, sg_len, host->slave_dirn, append); if (desc) { desc->callback = mxs_mmc_dma_irq_callback; desc->callback_param = host; @@ -358,12 +358,11 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host) host->ssp_pio_words[2] = cmd1; host->dma_dir = DMA_NONE; host->slave_dirn = DMA_TRANS_NONE; - desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK); + desc = mxs_mmc_prep_dma(host, 0); if (!desc) goto out; dmaengine_submit(desc); - dma_async_issue_pending(host->dmach); return; out: @@ -399,12 +398,11 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host) host->ssp_pio_words[2] = cmd1; host->dma_dir = DMA_NONE; host->slave_dirn = DMA_TRANS_NONE; - desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK); + desc = mxs_mmc_prep_dma(host, 0); if (!desc) goto out; dmaengine_submit(desc); - dma_async_issue_pending(host->dmach); return; out: @@ -528,12 +526,11 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host) host->data = data; host->dma_dir = dma_data_dir; host->slave_dirn = slave_dirn; - desc = mxs_mmc_prep_dma(host, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + desc = mxs_mmc_prep_dma(host, 1); if (!desc) goto out; dmaengine_submit(desc); - dma_async_issue_pending(host->dmach); return; out: dev_warn(mmc_dev(host->mmc), diff --git a/trunk/drivers/mmc/host/omap_hsmmc.c b/trunk/drivers/mmc/host/omap_hsmmc.c index 56d4499d4388..47adb161d3ad 100644 --- a/trunk/drivers/mmc/host/omap_hsmmc.c +++ b/trunk/drivers/mmc/host/omap_hsmmc.c @@ -249,7 +249,7 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, * the pbias cell programming support is still missing when * booting with Device tree */ - if (dev->of_node && !vdd) + if (of_have_populated_dt() && !vdd) return 0; if (mmc_slot(host).before_set_reg) @@ -1549,7 +1549,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * can't be allowed when booting with device * tree. */ - !host->dev->of_node) { + (!of_have_populated_dt())) { /* * The mmc_select_voltage fn of the core does * not seem to set the power_mode to @@ -1741,7 +1741,7 @@ static const struct of_device_id omap_mmc_of_match[] = { .data = &omap4_reg_offset, }, {}, -}; +} MODULE_DEVICE_TABLE(of, omap_mmc_of_match); static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) @@ -1785,7 +1785,7 @@ static inline struct omap_mmc_platform_data } #endif -static int __devinit omap_hsmmc_probe(struct platform_device *pdev) +static int __init omap_hsmmc_probe(struct platform_device *pdev) { struct omap_mmc_platform_data *pdata = pdev->dev.platform_data; struct mmc_host *mmc; @@ -1818,6 +1818,8 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) if (res == NULL || irq < 0) return -ENXIO; + res->start += pdata->reg_offset; + res->end += pdata->reg_offset; res = request_mem_region(res->start, resource_size(res), pdev->name); if (res == NULL) return -EBUSY; @@ -1841,7 +1843,7 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) host->dma_ch = -1; host->irq = irq; host->slot_id = 0; - host->mapbase = res->start + pdata->reg_offset; + host->mapbase = res->start; host->base = ioremap(host->mapbase, SZ_4K); host->power_mode = MMC_POWER_OFF; host->next_data.cookie = 1; @@ -1873,6 +1875,8 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) goto err1; } + omap_hsmmc_context_save(host); + if (host->pdata->controller_flags & OMAP_HSMMC_BROKEN_MULTIBLOCK_READ) { dev_info(&pdev->dev, "multiblock reads disabled due to 35xx erratum 2.1.1.128; MMC read performance may suffer\n"); mmc->caps2 |= MMC_CAP2_NO_MULTI_READ; @@ -1883,8 +1887,6 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) pm_runtime_set_autosuspend_delay(host->dev, MMC_AUTOSUSPEND_DELAY); pm_runtime_use_autosuspend(host->dev); - omap_hsmmc_context_save(host); - if (cpu_is_omap2430()) { host->dbclk = clk_get(&pdev->dev, "mmchsdb_fck"); /* @@ -2016,7 +2018,8 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) err_irq_cd_init: free_irq(host->irq, host); err_irq: - pm_runtime_put_sync(host->dev); + pm_runtime_mark_last_busy(host->dev); + pm_runtime_put_autosuspend(host->dev); pm_runtime_disable(host->dev); clk_put(host->fclk); if (host->got_dbclk) { @@ -2034,33 +2037,35 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) return ret; } -static int __devexit omap_hsmmc_remove(struct platform_device *pdev) +static int omap_hsmmc_remove(struct platform_device *pdev) { struct omap_hsmmc_host *host = platform_get_drvdata(pdev); struct resource *res; - pm_runtime_get_sync(host->dev); - mmc_remove_host(host->mmc); - if (host->use_reg) - omap_hsmmc_reg_put(host); - if (host->pdata->cleanup) - host->pdata->cleanup(&pdev->dev); - free_irq(host->irq, host); - if (mmc_slot(host).card_detect_irq) - free_irq(mmc_slot(host).card_detect_irq, host); + if (host) { + pm_runtime_get_sync(host->dev); + mmc_remove_host(host->mmc); + if (host->use_reg) + omap_hsmmc_reg_put(host); + if (host->pdata->cleanup) + host->pdata->cleanup(&pdev->dev); + free_irq(host->irq, host); + if (mmc_slot(host).card_detect_irq) + free_irq(mmc_slot(host).card_detect_irq, host); + + pm_runtime_put_sync(host->dev); + pm_runtime_disable(host->dev); + clk_put(host->fclk); + if (host->got_dbclk) { + clk_disable(host->dbclk); + clk_put(host->dbclk); + } - pm_runtime_put_sync(host->dev); - pm_runtime_disable(host->dev); - clk_put(host->fclk); - if (host->got_dbclk) { - clk_disable(host->dbclk); - clk_put(host->dbclk); + mmc_free_host(host->mmc); + iounmap(host->base); + omap_hsmmc_gpio_free(pdev->dev.platform_data); } - mmc_free_host(host->mmc); - iounmap(host->base); - omap_hsmmc_gpio_free(pdev->dev.platform_data); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res) release_mem_region(res->start, resource_size(res)); @@ -2073,45 +2078,49 @@ static int __devexit omap_hsmmc_remove(struct platform_device *pdev) static int omap_hsmmc_suspend(struct device *dev) { int ret = 0; - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - - if (!host) - return 0; + struct platform_device *pdev = to_platform_device(dev); + struct omap_hsmmc_host *host = platform_get_drvdata(pdev); if (host && host->suspended) return 0; - pm_runtime_get_sync(host->dev); - host->suspended = 1; - if (host->pdata->suspend) { - ret = host->pdata->suspend(dev, host->slot_id); - if (ret) { - dev_dbg(dev, "Unable to handle MMC board" + if (host) { + pm_runtime_get_sync(host->dev); + host->suspended = 1; + if (host->pdata->suspend) { + ret = host->pdata->suspend(&pdev->dev, + host->slot_id); + if (ret) { + dev_dbg(mmc_dev(host->mmc), + "Unable to handle MMC board" " level suspend\n"); - host->suspended = 0; - return ret; + host->suspended = 0; + return ret; + } } - } - ret = mmc_suspend_host(host->mmc); + ret = mmc_suspend_host(host->mmc); - if (ret) { - host->suspended = 0; - if (host->pdata->resume) { - ret = host->pdata->resume(dev, host->slot_id); - if (ret) - dev_dbg(dev, "Unmask interrupt failed\n"); + if (ret) { + host->suspended = 0; + if (host->pdata->resume) { + ret = host->pdata->resume(&pdev->dev, + host->slot_id); + if (ret) + dev_dbg(mmc_dev(host->mmc), + "Unmask interrupt failed\n"); + } + goto err; } - goto err; - } - if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) { - omap_hsmmc_disable_irq(host); - OMAP_HSMMC_WRITE(host->base, HCTL, + if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) { + omap_hsmmc_disable_irq(host); + OMAP_HSMMC_WRITE(host->base, HCTL, OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP); - } + } + if (host->got_dbclk) + clk_disable(host->dbclk); - if (host->got_dbclk) - clk_disable(host->dbclk); + } err: pm_runtime_put_sync(host->dev); return ret; @@ -2121,37 +2130,38 @@ static int omap_hsmmc_suspend(struct device *dev) static int omap_hsmmc_resume(struct device *dev) { int ret = 0; - struct omap_hsmmc_host *host = dev_get_drvdata(dev); - - if (!host) - return 0; + struct platform_device *pdev = to_platform_device(dev); + struct omap_hsmmc_host *host = platform_get_drvdata(pdev); if (host && !host->suspended) return 0; - pm_runtime_get_sync(host->dev); + if (host) { + pm_runtime_get_sync(host->dev); - if (host->got_dbclk) - clk_enable(host->dbclk); + if (host->got_dbclk) + clk_enable(host->dbclk); - if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) - omap_hsmmc_conf_bus_power(host); + if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) + omap_hsmmc_conf_bus_power(host); - if (host->pdata->resume) { - ret = host->pdata->resume(dev, host->slot_id); - if (ret) - dev_dbg(dev, "Unmask interrupt failed\n"); - } + if (host->pdata->resume) { + ret = host->pdata->resume(&pdev->dev, host->slot_id); + if (ret) + dev_dbg(mmc_dev(host->mmc), + "Unmask interrupt failed\n"); + } - omap_hsmmc_protect_card(host); + omap_hsmmc_protect_card(host); - /* Notify the core to resume the host */ - ret = mmc_resume_host(host->mmc); - if (ret == 0) - host->suspended = 0; + /* Notify the core to resume the host */ + ret = mmc_resume_host(host->mmc); + if (ret == 0) + host->suspended = 0; - pm_runtime_mark_last_busy(host->dev); - pm_runtime_put_autosuspend(host->dev); + pm_runtime_mark_last_busy(host->dev); + pm_runtime_put_autosuspend(host->dev); + } return ret; @@ -2168,7 +2178,7 @@ static int omap_hsmmc_runtime_suspend(struct device *dev) host = platform_get_drvdata(to_platform_device(dev)); omap_hsmmc_context_save(host); - dev_dbg(dev, "disabled\n"); + dev_dbg(mmc_dev(host->mmc), "disabled\n"); return 0; } @@ -2179,7 +2189,7 @@ static int omap_hsmmc_runtime_resume(struct device *dev) host = platform_get_drvdata(to_platform_device(dev)); omap_hsmmc_context_restore(host); - dev_dbg(dev, "enabled\n"); + dev_dbg(mmc_dev(host->mmc), "enabled\n"); return 0; } @@ -2192,8 +2202,7 @@ static struct dev_pm_ops omap_hsmmc_dev_pm_ops = { }; static struct platform_driver omap_hsmmc_driver = { - .probe = omap_hsmmc_probe, - .remove = __devexit_p(omap_hsmmc_remove), + .remove = omap_hsmmc_remove, .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, @@ -2202,7 +2211,21 @@ static struct platform_driver omap_hsmmc_driver = { }, }; -module_platform_driver(omap_hsmmc_driver); +static int __init omap_hsmmc_init(void) +{ + /* Register the MMC driver */ + return platform_driver_probe(&omap_hsmmc_driver, omap_hsmmc_probe); +} + +static void __exit omap_hsmmc_cleanup(void) +{ + /* Unregister MMC driver */ + platform_driver_unregister(&omap_hsmmc_driver); +} + +module_init(omap_hsmmc_init); +module_exit(omap_hsmmc_cleanup); + MODULE_DESCRIPTION("OMAP High Speed Multimedia Card driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/trunk/drivers/mmc/host/sdhci-dove.c b/trunk/drivers/mmc/host/sdhci-dove.c index 177f697b5835..46fd1fd1b605 100644 --- a/trunk/drivers/mmc/host/sdhci-dove.c +++ b/trunk/drivers/mmc/host/sdhci-dove.c @@ -20,7 +20,6 @@ */ #include -#include #include #include "sdhci-pltfm.h" diff --git a/trunk/drivers/mmc/host/sdhci-esdhc-imx.c b/trunk/drivers/mmc/host/sdhci-esdhc-imx.c index 8abdaf6697a8..6193a0d7bde5 100644 --- a/trunk/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/trunk/drivers/mmc/host/sdhci-esdhc-imx.c @@ -467,7 +467,8 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev) clk_prepare_enable(clk); pltfm_host->clk = clk; - host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; + if (!is_imx25_esdhc(imx_data)) + host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data)) /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */ diff --git a/trunk/drivers/mmc/host/sdhci-pci.c b/trunk/drivers/mmc/host/sdhci-pci.c index 69ef0beae104..fbbebe251e01 100644 --- a/trunk/drivers/mmc/host/sdhci-pci.c +++ b/trunk/drivers/mmc/host/sdhci-pci.c @@ -1418,6 +1418,8 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev, slots = chip->num_slots; /* Quirk may have changed this */ + pci_enable_msi(pdev); + for (i = 0; i < slots; i++) { slot = sdhci_pci_probe_slot(pdev, chip, first_bar, i); if (IS_ERR(slot)) { @@ -1436,6 +1438,8 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev, return 0; free: + pci_disable_msi(pdev); + pci_set_drvdata(pdev, NULL); kfree(chip); @@ -1458,6 +1462,8 @@ static void __devexit sdhci_pci_remove(struct pci_dev *pdev) for (i = 0; i < chip->num_slots; i++) sdhci_pci_remove_slot(chip->slots[i]); + pci_disable_msi(pdev); + pci_set_drvdata(pdev, NULL); kfree(chip); } diff --git a/trunk/drivers/mmc/host/sdhci-s3c.c b/trunk/drivers/mmc/host/sdhci-s3c.c index 55a164fcaa15..b19e7d435f8d 100644 --- a/trunk/drivers/mmc/host/sdhci-s3c.c +++ b/trunk/drivers/mmc/host/sdhci-s3c.c @@ -20,10 +20,6 @@ #include #include #include -#include -#include -#include -#include #include @@ -57,18 +53,6 @@ struct sdhci_s3c { struct clk *clk_bus[MAX_BUS_CLK]; }; -/** - * struct sdhci_s3c_driver_data - S3C SDHCI platform specific driver data - * @sdhci_quirks: sdhci host specific quirks. - * - * Specifies platform specific configuration of sdhci controller. - * Note: A structure for driver specific platform data is used for future - * expansion of its usage. - */ -struct sdhci_s3c_drv_data { - unsigned int sdhci_quirks; -}; - static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host) { return sdhci_priv(host); @@ -148,10 +132,10 @@ static unsigned int sdhci_s3c_consider_clock(struct sdhci_s3c *ourhost, return UINT_MAX; /* - * If controller uses a non-standard clock division, find the best clock - * speed possible with selected clock source and skip the division. + * Clock divider's step is different as 1 from that of host controller + * when 'clk_type' is S3C_SDHCI_CLK_DIV_EXTERNAL. */ - if (ourhost->host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) { + if (ourhost->pdata->clk_type) { rate = clk_round_rate(clksrc, wanted); return wanted - rate; } @@ -288,8 +272,6 @@ static unsigned int sdhci_cmu_get_min_clock(struct sdhci_host *host) static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock) { struct sdhci_s3c *ourhost = to_s3c(host); - unsigned long timeout; - u16 clk = 0; /* don't bother if the clock is going off */ if (clock == 0) @@ -300,25 +282,6 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock) clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock); host->clock = clock; - - clk = SDHCI_CLOCK_INT_EN; - sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); - - /* Wait max 20 ms */ - timeout = 20; - while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) - & SDHCI_CLOCK_INT_STABLE)) { - if (timeout == 0) { - printk(KERN_ERR "%s: Internal clock never " - "stabilised.\n", mmc_hostname(host->mmc)); - return; - } - timeout--; - mdelay(1); - } - - clk |= SDHCI_CLOCK_CARD_EN; - sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); } /** @@ -419,24 +382,16 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc) } } -static inline struct sdhci_s3c_drv_data *sdhci_s3c_get_driver_data( - struct platform_device *pdev) -{ - return (struct sdhci_s3c_drv_data *) - platform_get_device_id(pdev)->driver_data; -} - static int __devinit sdhci_s3c_probe(struct platform_device *pdev) { - struct s3c_sdhci_platdata *pdata; - struct sdhci_s3c_drv_data *drv_data; + struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data; struct device *dev = &pdev->dev; struct sdhci_host *host; struct sdhci_s3c *sc; struct resource *res; int ret, irq, ptr, clks; - if (!pdev->dev.platform_data) { + if (!pdata) { dev_err(dev, "no device data specified\n"); return -ENOENT; } @@ -447,20 +402,18 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) return irq; } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "no memory specified\n"); + return -ENOENT; + } + host = sdhci_alloc_host(dev, sizeof(struct sdhci_s3c)); if (IS_ERR(host)) { dev_err(dev, "sdhci_alloc_host() failed\n"); return PTR_ERR(host); } - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - ret = -ENOMEM; - goto err_io_clk; - } - memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata)); - - drv_data = sdhci_s3c_get_driver_data(pdev); sc = sdhci_priv(host); sc->host = host; @@ -511,8 +464,15 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) goto err_no_busclks; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - host->ioaddr = devm_request_and_ioremap(&pdev->dev, res); + sc->ioarea = request_mem_region(res->start, resource_size(res), + mmc_hostname(host->mmc)); + if (!sc->ioarea) { + dev_err(dev, "failed to reserve register area\n"); + ret = -ENXIO; + goto err_req_regs; + } + + host->ioaddr = ioremap_nocache(res->start, resource_size(res)); if (!host->ioaddr) { dev_err(dev, "failed to map registers\n"); ret = -ENXIO; @@ -531,8 +491,6 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) /* Setup quirks for the controller */ host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC; host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT; - if (drv_data) - host->quirks |= drv_data->sdhci_quirks; #ifndef CONFIG_MMC_SDHCI_S3C_DMA @@ -560,14 +518,6 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) if (pdata->cd_type == S3C_SDHCI_CD_PERMANENT) host->mmc->caps = MMC_CAP_NONREMOVABLE; - switch (pdata->max_width) { - case 8: - host->mmc->caps |= MMC_CAP_8_BIT_DATA; - case 4: - host->mmc->caps |= MMC_CAP_4_BIT_DATA; - break; - } - if (pdata->pm_caps) host->mmc->pm_caps |= pdata->pm_caps; @@ -581,7 +531,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) * If controller does not have internal clock divider, * we can use overriding functions instead of default. */ - if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) { + if (pdata->clk_type) { sdhci_s3c_ops.set_clock = sdhci_cmu_set_clock; sdhci_s3c_ops.get_min_clock = sdhci_cmu_get_min_clock; sdhci_s3c_ops.get_max_clock = sdhci_cmu_get_max_clock; @@ -594,17 +544,10 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) if (pdata->host_caps2) host->mmc->caps2 |= pdata->host_caps2; - pm_runtime_enable(&pdev->dev); - pm_runtime_set_autosuspend_delay(&pdev->dev, 50); - pm_runtime_use_autosuspend(&pdev->dev); - pm_suspend_ignore_children(&pdev->dev, 1); - ret = sdhci_add_host(host); if (ret) { dev_err(dev, "sdhci_add_host() failed\n"); - pm_runtime_forbid(&pdev->dev); - pm_runtime_get_noresume(&pdev->dev); - goto err_req_regs; + goto err_add_host; } /* The following two methods of card detection might call @@ -618,6 +561,10 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) return 0; + err_add_host: + release_resource(sc->ioarea); + kfree(sc->ioarea); + err_req_regs: for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { if (sc->clk_bus[ptr]) { @@ -654,8 +601,6 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) sdhci_remove_host(host, 1); - pm_runtime_disable(&pdev->dev); - for (ptr = 0; ptr < 3; ptr++) { if (sc->clk_bus[ptr]) { clk_disable(sc->clk_bus[ptr]); @@ -665,13 +610,18 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) clk_disable(sc->clk_io); clk_put(sc->clk_io); + iounmap(host->ioaddr); + release_resource(sc->ioarea); + kfree(sc->ioarea); + sdhci_free_host(host); platform_set_drvdata(pdev, NULL); return 0; } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM + static int sdhci_s3c_suspend(struct device *dev) { struct sdhci_host *host = dev_get_drvdata(dev); @@ -685,29 +635,10 @@ static int sdhci_s3c_resume(struct device *dev) return sdhci_resume_host(host); } -#endif - -#ifdef CONFIG_PM_RUNTIME -static int sdhci_s3c_runtime_suspend(struct device *dev) -{ - struct sdhci_host *host = dev_get_drvdata(dev); - - return sdhci_runtime_suspend_host(host); -} -static int sdhci_s3c_runtime_resume(struct device *dev) -{ - struct sdhci_host *host = dev_get_drvdata(dev); - - return sdhci_runtime_resume_host(host); -} -#endif - -#ifdef CONFIG_PM static const struct dev_pm_ops sdhci_s3c_pmops = { - SET_SYSTEM_SLEEP_PM_OPS(sdhci_s3c_suspend, sdhci_s3c_resume) - SET_RUNTIME_PM_OPS(sdhci_s3c_runtime_suspend, sdhci_s3c_runtime_resume, - NULL) + .suspend = sdhci_s3c_suspend, + .resume = sdhci_s3c_resume, }; #define SDHCI_S3C_PMOPS (&sdhci_s3c_pmops) @@ -716,31 +647,9 @@ static const struct dev_pm_ops sdhci_s3c_pmops = { #define SDHCI_S3C_PMOPS NULL #endif -#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212) -static struct sdhci_s3c_drv_data exynos4_sdhci_drv_data = { - .sdhci_quirks = SDHCI_QUIRK_NONSTANDARD_CLOCK, -}; -#define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)&exynos4_sdhci_drv_data) -#else -#define EXYNOS4_SDHCI_DRV_DATA ((kernel_ulong_t)NULL) -#endif - -static struct platform_device_id sdhci_s3c_driver_ids[] = { - { - .name = "s3c-sdhci", - .driver_data = (kernel_ulong_t)NULL, - }, { - .name = "exynos4-sdhci", - .driver_data = EXYNOS4_SDHCI_DRV_DATA, - }, - { } -}; -MODULE_DEVICE_TABLE(platform, sdhci_s3c_driver_ids); - static struct platform_driver sdhci_s3c_driver = { .probe = sdhci_s3c_probe, .remove = __devexit_p(sdhci_s3c_remove), - .id_table = sdhci_s3c_driver_ids, .driver = { .owner = THIS_MODULE, .name = "s3c-sdhci", diff --git a/trunk/drivers/mmc/host/sdhci.c b/trunk/drivers/mmc/host/sdhci.c index ccefdebeff14..8262cadfdab7 100644 --- a/trunk/drivers/mmc/host/sdhci.c +++ b/trunk/drivers/mmc/host/sdhci.c @@ -147,7 +147,7 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable) u32 present, irqs; if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) || - (host->mmc->caps & MMC_CAP_NONREMOVABLE)) + !mmc_card_is_removable(host->mmc)) return; present = sdhci_readl(host, SDHCI_PRESENT_STATE) & @@ -2782,9 +2782,8 @@ int sdhci_add_host(struct sdhci_host *host) mmc_card_is_removable(mmc)) mmc->caps |= MMC_CAP_NEEDS_POLL; - /* Any UHS-I mode in caps implies SDR12 and SDR25 support. */ - if (caps[1] & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | - SDHCI_SUPPORT_DDR50)) + /* UHS-I mode(s) supported by the host controller. */ + if (host->version >= SDHCI_SPEC_300) mmc->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25; /* SDR104 supports also implies SDR50 support */ diff --git a/trunk/drivers/mmc/host/sh_mmcif.c b/trunk/drivers/mmc/host/sh_mmcif.c index 724b35e85a26..aafaf0b6eb1c 100644 --- a/trunk/drivers/mmc/host/sh_mmcif.c +++ b/trunk/drivers/mmc/host/sh_mmcif.c @@ -454,8 +454,7 @@ static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk) sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK); else sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR & - ((fls(DIV_ROUND_UP(host->clk, - clk) - 1) - 1) << 16)); + ((fls(host->clk / clk) - 1) << 16)); sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE); } @@ -1298,8 +1297,14 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) spin_lock_init(&host->lock); mmc->ops = &sh_mmcif_ops; - mmc->f_max = host->clk / 2; - mmc->f_min = host->clk / 512; + mmc->f_max = host->clk; + /* close to 400KHz */ + if (mmc->f_max < 51200000) + mmc->f_min = mmc->f_max / 128; + else if (mmc->f_max < 102400000) + mmc->f_min = mmc->f_max / 256; + else + mmc->f_min = mmc->f_max / 512; if (pd->ocr) mmc->ocr_avail = pd->ocr; mmc->caps = MMC_CAP_MMC_HIGHSPEED; diff --git a/trunk/drivers/mtd/Kconfig b/trunk/drivers/mtd/Kconfig index 5760c1a4b3f6..284cf3433720 100644 --- a/trunk/drivers/mtd/Kconfig +++ b/trunk/drivers/mtd/Kconfig @@ -304,6 +304,9 @@ config MTD_OOPS buffer in a flash partition where it can be read back at some later point. + To use, add console=ttyMTDx to the kernel command line, + where x is the MTD device number to use. + config MTD_SWAP tristate "Swap on MTD device support" depends on MTD && SWAP diff --git a/trunk/drivers/mtd/chips/cfi_cmdset_0001.c b/trunk/drivers/mtd/chips/cfi_cmdset_0001.c index dbbd2edfb812..9bcd1f415f43 100644 --- a/trunk/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/trunk/drivers/mtd/chips/cfi_cmdset_0001.c @@ -87,7 +87,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *, struct cfi_private ** static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys); -static int cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len); +static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len); static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode); static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode); @@ -262,9 +262,9 @@ static void fixup_st_m28w320cb(struct mtd_info *mtd) static void fixup_use_point(struct mtd_info *mtd) { struct map_info *map = mtd->priv; - if (!mtd->_point && map_is_linear(map)) { - mtd->_point = cfi_intelext_point; - mtd->_unpoint = cfi_intelext_unpoint; + if (!mtd->point && map_is_linear(map)) { + mtd->point = cfi_intelext_point; + mtd->unpoint = cfi_intelext_unpoint; } } @@ -274,8 +274,8 @@ static void fixup_use_write_buffers(struct mtd_info *mtd) struct cfi_private *cfi = map->fldrv_priv; if (cfi->cfiq->BufWriteTimeoutTyp) { printk(KERN_INFO "Using buffer write method\n" ); - mtd->_write = cfi_intelext_write_buffers; - mtd->_writev = cfi_intelext_writev; + mtd->write = cfi_intelext_write_buffers; + mtd->writev = cfi_intelext_writev; } } @@ -443,15 +443,15 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary) mtd->type = MTD_NORFLASH; /* Fill in the default mtd operations */ - mtd->_erase = cfi_intelext_erase_varsize; - mtd->_read = cfi_intelext_read; - mtd->_write = cfi_intelext_write_words; - mtd->_sync = cfi_intelext_sync; - mtd->_lock = cfi_intelext_lock; - mtd->_unlock = cfi_intelext_unlock; - mtd->_is_locked = cfi_intelext_is_locked; - mtd->_suspend = cfi_intelext_suspend; - mtd->_resume = cfi_intelext_resume; + mtd->erase = cfi_intelext_erase_varsize; + mtd->read = cfi_intelext_read; + mtd->write = cfi_intelext_write_words; + mtd->sync = cfi_intelext_sync; + mtd->lock = cfi_intelext_lock; + mtd->unlock = cfi_intelext_unlock; + mtd->is_locked = cfi_intelext_is_locked; + mtd->suspend = cfi_intelext_suspend; + mtd->resume = cfi_intelext_resume; mtd->flags = MTD_CAP_NORFLASH; mtd->name = map->name; mtd->writesize = 1; @@ -600,12 +600,12 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd) } #ifdef CONFIG_MTD_OTP - mtd->_read_fact_prot_reg = cfi_intelext_read_fact_prot_reg; - mtd->_read_user_prot_reg = cfi_intelext_read_user_prot_reg; - mtd->_write_user_prot_reg = cfi_intelext_write_user_prot_reg; - mtd->_lock_user_prot_reg = cfi_intelext_lock_user_prot_reg; - mtd->_get_fact_prot_info = cfi_intelext_get_fact_prot_info; - mtd->_get_user_prot_info = cfi_intelext_get_user_prot_info; + mtd->read_fact_prot_reg = cfi_intelext_read_fact_prot_reg; + mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg; + mtd->write_user_prot_reg = cfi_intelext_write_user_prot_reg; + mtd->lock_user_prot_reg = cfi_intelext_lock_user_prot_reg; + mtd->get_fact_prot_info = cfi_intelext_get_fact_prot_info; + mtd->get_user_prot_info = cfi_intelext_get_user_prot_info; #endif /* This function has the potential to distort the reality @@ -1017,6 +1017,8 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad case FL_READY: case FL_STATUS: case FL_JEDEC_QUERY: + /* We should really make set_vpp() count, rather than doing this */ + DISABLE_VPP(map); break; default: printk(KERN_ERR "%s: put_chip() called with oldstate %d!!\n", map->name, chip->oldstate); @@ -1322,7 +1324,7 @@ static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len, int chipnum; int ret = 0; - if (!map->virt) + if (!map->virt || (from + len > mtd->size)) return -EINVAL; /* Now lock the chip(s) to POINT state */ @@ -1332,6 +1334,7 @@ static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len, ofs = from - (chipnum << cfi->chipshift); *virt = map->virt + cfi->chips[chipnum].start + ofs; + *retlen = 0; if (phys) *phys = map->phys + cfi->chips[chipnum].start + ofs; @@ -1366,12 +1369,12 @@ static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len, return 0; } -static int cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; unsigned long ofs; - int chipnum, err = 0; + int chipnum; /* Now unlock the chip(s) POINT state */ @@ -1379,7 +1382,7 @@ static int cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len) chipnum = (from >> cfi->chipshift); ofs = from - (chipnum << cfi->chipshift); - while (len && !err) { + while (len) { unsigned long thislen; struct flchip *chip; @@ -1397,10 +1400,8 @@ static int cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len) chip->ref_point_counter--; if(chip->ref_point_counter == 0) chip->state = FL_READY; - } else { - printk(KERN_ERR "%s: Error: unpoint called on non pointed region\n", map->name); - err = -EINVAL; - } + } else + printk(KERN_ERR "%s: Warning: unpoint called on non pointed region\n", map->name); /* Should this give an error? */ put_chip(map, chip, chip->start); mutex_unlock(&chip->mutex); @@ -1409,8 +1410,6 @@ static int cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len) ofs = 0; chipnum++; } - - return err; } static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) @@ -1457,6 +1456,8 @@ static int cfi_intelext_read (struct mtd_info *mtd, loff_t from, size_t len, siz chipnum = (from >> cfi->chipshift); ofs = from - (chipnum << cfi->chipshift); + *retlen = 0; + while (len) { unsigned long thislen; @@ -1550,8 +1551,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, } xip_enable(map, chip, adr); - out: DISABLE_VPP(map); - put_chip(map, chip, adr); + out: put_chip(map, chip, adr); mutex_unlock(&chip->mutex); return ret; } @@ -1565,6 +1565,10 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le int chipnum; unsigned long ofs; + *retlen = 0; + if (!len) + return 0; + chipnum = to >> cfi->chipshift; ofs = to - (chipnum << cfi->chipshift); @@ -1790,8 +1794,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, } xip_enable(map, chip, cmd_adr); - out: DISABLE_VPP(map); - put_chip(map, chip, cmd_adr); + out: put_chip(map, chip, cmd_adr); mutex_unlock(&chip->mutex); return ret; } @@ -1810,6 +1813,7 @@ static int cfi_intelext_writev (struct mtd_info *mtd, const struct kvec *vecs, for (i = 0; i < count; i++) len += vecs[i].iov_len; + *retlen = 0; if (!len) return 0; @@ -1928,7 +1932,6 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, ret = -EIO; } else if (chipstatus & 0x20 && retries--) { printk(KERN_DEBUG "block erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus); - DISABLE_VPP(map); put_chip(map, chip, adr); mutex_unlock(&chip->mutex); goto retry; @@ -1941,8 +1944,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, } xip_enable(map, chip, adr); - out: DISABLE_VPP(map); - put_chip(map, chip, adr); + out: put_chip(map, chip, adr); mutex_unlock(&chip->mutex); return ret; } @@ -2084,8 +2086,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip } xip_enable(map, chip, adr); - out: DISABLE_VPP(map); - put_chip(map, chip, adr); +out: put_chip(map, chip, adr); mutex_unlock(&chip->mutex); return ret; } @@ -2482,7 +2483,7 @@ static int cfi_intelext_suspend(struct mtd_info *mtd) allowed to. Or should we return -EAGAIN, because the upper layers ought to have already shut down anything which was using the device anyway? The latter for now. */ - printk(KERN_NOTICE "Flash device refused suspend due to active operation (state %d)\n", chip->state); + printk(KERN_NOTICE "Flash device refused suspend due to active operation (state %d)\n", chip->oldstate); ret = -EAGAIN; case FL_PM_SUSPENDED: break; diff --git a/trunk/drivers/mtd/chips/cfi_cmdset_0002.c b/trunk/drivers/mtd/chips/cfi_cmdset_0002.c index d02592e6a0f0..8d70895a58d6 100644 --- a/trunk/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/trunk/drivers/mtd/chips/cfi_cmdset_0002.c @@ -59,9 +59,6 @@ static void cfi_amdstd_resume (struct mtd_info *); static int cfi_amdstd_reboot(struct notifier_block *, unsigned long, void *); static int cfi_amdstd_secsi_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); -static int cfi_amdstd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf); - static void cfi_amdstd_destroy(struct mtd_info *); struct mtd_info *cfi_cmdset_0002(struct map_info *, int); @@ -192,7 +189,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd) struct cfi_private *cfi = map->fldrv_priv; if (cfi->cfiq->BufWriteTimeoutTyp) { pr_debug("Using buffer write method\n" ); - mtd->_write = cfi_amdstd_write_buffers; + mtd->write = cfi_amdstd_write_buffers; } } @@ -231,8 +228,8 @@ static void fixup_convert_atmel_pri(struct mtd_info *mtd) static void fixup_use_secsi(struct mtd_info *mtd) { /* Setup for chips with a secsi area */ - mtd->_read_user_prot_reg = cfi_amdstd_secsi_read; - mtd->_read_fact_prot_reg = cfi_amdstd_secsi_read; + mtd->read_user_prot_reg = cfi_amdstd_secsi_read; + mtd->read_fact_prot_reg = cfi_amdstd_secsi_read; } static void fixup_use_erase_chip(struct mtd_info *mtd) @@ -241,7 +238,7 @@ static void fixup_use_erase_chip(struct mtd_info *mtd) struct cfi_private *cfi = map->fldrv_priv; if ((cfi->cfiq->NumEraseRegions == 1) && ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) == 0)) { - mtd->_erase = cfi_amdstd_erase_chip; + mtd->erase = cfi_amdstd_erase_chip; } } @@ -252,8 +249,8 @@ static void fixup_use_erase_chip(struct mtd_info *mtd) */ static void fixup_use_atmel_lock(struct mtd_info *mtd) { - mtd->_lock = cfi_atmel_lock; - mtd->_unlock = cfi_atmel_unlock; + mtd->lock = cfi_atmel_lock; + mtd->unlock = cfi_atmel_unlock; mtd->flags |= MTD_POWERUP_LOCK; } @@ -432,12 +429,12 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) mtd->type = MTD_NORFLASH; /* Fill in the default mtd operations */ - mtd->_erase = cfi_amdstd_erase_varsize; - mtd->_write = cfi_amdstd_write_words; - mtd->_read = cfi_amdstd_read; - mtd->_sync = cfi_amdstd_sync; - mtd->_suspend = cfi_amdstd_suspend; - mtd->_resume = cfi_amdstd_resume; + mtd->erase = cfi_amdstd_erase_varsize; + mtd->write = cfi_amdstd_write_words; + mtd->read = cfi_amdstd_read; + mtd->sync = cfi_amdstd_sync; + mtd->suspend = cfi_amdstd_suspend; + mtd->resume = cfi_amdstd_resume; mtd->flags = MTD_CAP_NORFLASH; mtd->name = map->name; mtd->writesize = 1; @@ -446,7 +443,6 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) pr_debug("MTD %s(): write buffer size %d\n", __func__, mtd->writebufsize); - mtd->_panic_write = cfi_amdstd_panic_write; mtd->reboot_notifier.notifier_call = cfi_amdstd_reboot; if (cfi->cfi_mode==CFI_MODE_CFI){ @@ -774,6 +770,8 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad case FL_READY: case FL_STATUS: + /* We should really make set_vpp() count, rather than doing this */ + DISABLE_VPP(map); break; default: printk(KERN_ERR "MTD: put_chip() called with oldstate %d!!\n", chip->oldstate); @@ -1015,9 +1013,13 @@ static int cfi_amdstd_read (struct mtd_info *mtd, loff_t from, size_t len, size_ int ret = 0; /* ofs: offset within the first chip that the first read should start */ + chipnum = (from >> cfi->chipshift); ofs = from - (chipnum << cfi->chipshift); + + *retlen = 0; + while (len) { unsigned long thislen; @@ -1095,11 +1097,16 @@ static int cfi_amdstd_secsi_read (struct mtd_info *mtd, loff_t from, size_t len, int chipnum; int ret = 0; + /* ofs: offset within the first chip that the first read should start */ + /* 8 secsi bytes per chip */ chipnum=from>>3; ofs=from & 7; + + *retlen = 0; + while (len) { unsigned long thislen; @@ -1227,7 +1234,6 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, xip_enable(map, chip, adr); op_done: chip->state = FL_READY; - DISABLE_VPP(map); put_chip(map, chip, adr); mutex_unlock(&chip->mutex); @@ -1245,6 +1251,10 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len, unsigned long ofs, chipstart; DECLARE_WAITQUEUE(wait, current); + *retlen = 0; + if (!len) + return 0; + chipnum = to >> cfi->chipshift; ofs = to - (chipnum << cfi->chipshift); chipstart = cfi->chips[chipnum].start; @@ -1466,7 +1476,6 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, ret = -EIO; op_done: chip->state = FL_READY; - DISABLE_VPP(map); put_chip(map, chip, adr); mutex_unlock(&chip->mutex); @@ -1484,6 +1493,10 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len, int chipnum; unsigned long ofs; + *retlen = 0; + if (!len) + return 0; + chipnum = to >> cfi->chipshift; ofs = to - (chipnum << cfi->chipshift); @@ -1549,238 +1562,6 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len, return 0; } -/* - * Wait for the flash chip to become ready to write data - * - * This is only called during the panic_write() path. When panic_write() - * is called, the kernel is in the process of a panic, and will soon be - * dead. Therefore we don't take any locks, and attempt to get access - * to the chip as soon as possible. - */ -static int cfi_amdstd_panic_wait(struct map_info *map, struct flchip *chip, - unsigned long adr) -{ - struct cfi_private *cfi = map->fldrv_priv; - int retries = 10; - int i; - - /* - * If the driver thinks the chip is idle, and no toggle bits - * are changing, then the chip is actually idle for sure. - */ - if (chip->state == FL_READY && chip_ready(map, adr)) - return 0; - - /* - * Try several times to reset the chip and then wait for it - * to become idle. The upper limit of a few milliseconds of - * delay isn't a big problem: the kernel is dying anyway. It - * is more important to save the messages. - */ - while (retries > 0) { - const unsigned long timeo = (HZ / 1000) + 1; - - /* send the reset command */ - map_write(map, CMD(0xF0), chip->start); - - /* wait for the chip to become ready */ - for (i = 0; i < jiffies_to_usecs(timeo); i++) { - if (chip_ready(map, adr)) - return 0; - - udelay(1); - } - } - - /* the chip never became ready */ - return -EBUSY; -} - -/* - * Write out one word of data to a single flash chip during a kernel panic - * - * This is only called during the panic_write() path. When panic_write() - * is called, the kernel is in the process of a panic, and will soon be - * dead. Therefore we don't take any locks, and attempt to get access - * to the chip as soon as possible. - * - * The implementation of this routine is intentionally similar to - * do_write_oneword(), in order to ease code maintenance. - */ -static int do_panic_write_oneword(struct map_info *map, struct flchip *chip, - unsigned long adr, map_word datum) -{ - const unsigned long uWriteTimeout = (HZ / 1000) + 1; - struct cfi_private *cfi = map->fldrv_priv; - int retry_cnt = 0; - map_word oldd; - int ret = 0; - int i; - - adr += chip->start; - - ret = cfi_amdstd_panic_wait(map, chip, adr); - if (ret) - return ret; - - pr_debug("MTD %s(): PANIC WRITE 0x%.8lx(0x%.8lx)\n", - __func__, adr, datum.x[0]); - - /* - * Check for a NOP for the case when the datum to write is already - * present - it saves time and works around buggy chips that corrupt - * data at other locations when 0xff is written to a location that - * already contains 0xff. - */ - oldd = map_read(map, adr); - if (map_word_equal(map, oldd, datum)) { - pr_debug("MTD %s(): NOP\n", __func__); - goto op_done; - } - - ENABLE_VPP(map); - -retry: - cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); - cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); - cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); - map_write(map, datum, adr); - - for (i = 0; i < jiffies_to_usecs(uWriteTimeout); i++) { - if (chip_ready(map, adr)) - break; - - udelay(1); - } - - if (!chip_good(map, adr, datum)) { - /* reset on all failures. */ - map_write(map, CMD(0xF0), chip->start); - /* FIXME - should have reset delay before continuing */ - - if (++retry_cnt <= MAX_WORD_RETRIES) - goto retry; - - ret = -EIO; - } - -op_done: - DISABLE_VPP(map); - return ret; -} - -/* - * Write out some data during a kernel panic - * - * This is used by the mtdoops driver to save the dying messages from a - * kernel which has panic'd. - * - * This routine ignores all of the locking used throughout the rest of the - * driver, in order to ensure that the data gets written out no matter what - * state this driver (and the flash chip itself) was in when the kernel crashed. - * - * The implementation of this routine is intentionally similar to - * cfi_amdstd_write_words(), in order to ease code maintenance. - */ -static int cfi_amdstd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) -{ - struct map_info *map = mtd->priv; - struct cfi_private *cfi = map->fldrv_priv; - unsigned long ofs, chipstart; - int ret = 0; - int chipnum; - - chipnum = to >> cfi->chipshift; - ofs = to - (chipnum << cfi->chipshift); - chipstart = cfi->chips[chipnum].start; - - /* If it's not bus aligned, do the first byte write */ - if (ofs & (map_bankwidth(map) - 1)) { - unsigned long bus_ofs = ofs & ~(map_bankwidth(map) - 1); - int i = ofs - bus_ofs; - int n = 0; - map_word tmp_buf; - - ret = cfi_amdstd_panic_wait(map, &cfi->chips[chipnum], bus_ofs); - if (ret) - return ret; - - /* Load 'tmp_buf' with old contents of flash */ - tmp_buf = map_read(map, bus_ofs + chipstart); - - /* Number of bytes to copy from buffer */ - n = min_t(int, len, map_bankwidth(map) - i); - - tmp_buf = map_word_load_partial(map, tmp_buf, buf, i, n); - - ret = do_panic_write_oneword(map, &cfi->chips[chipnum], - bus_ofs, tmp_buf); - if (ret) - return ret; - - ofs += n; - buf += n; - (*retlen) += n; - len -= n; - - if (ofs >> cfi->chipshift) { - chipnum++; - ofs = 0; - if (chipnum == cfi->numchips) - return 0; - } - } - - /* We are now aligned, write as much as possible */ - while (len >= map_bankwidth(map)) { - map_word datum; - - datum = map_word_load(map, buf); - - ret = do_panic_write_oneword(map, &cfi->chips[chipnum], - ofs, datum); - if (ret) - return ret; - - ofs += map_bankwidth(map); - buf += map_bankwidth(map); - (*retlen) += map_bankwidth(map); - len -= map_bankwidth(map); - - if (ofs >> cfi->chipshift) { - chipnum++; - ofs = 0; - if (chipnum == cfi->numchips) - return 0; - - chipstart = cfi->chips[chipnum].start; - } - } - - /* Write the trailing bytes if any */ - if (len & (map_bankwidth(map) - 1)) { - map_word tmp_buf; - - ret = cfi_amdstd_panic_wait(map, &cfi->chips[chipnum], ofs); - if (ret) - return ret; - - tmp_buf = map_read(map, ofs + chipstart); - - tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len); - - ret = do_panic_write_oneword(map, &cfi->chips[chipnum], - ofs, tmp_buf); - if (ret) - return ret; - - (*retlen) += len; - } - - return 0; -} - /* * Handle devices with one erase region, that only implement @@ -1868,7 +1649,6 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip) chip->state = FL_READY; xip_enable(map, chip, adr); - DISABLE_VPP(map); put_chip(map, chip, adr); mutex_unlock(&chip->mutex); @@ -1959,7 +1739,6 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, } chip->state = FL_READY; - DISABLE_VPP(map); put_chip(map, chip, adr); mutex_unlock(&chip->mutex); return ret; diff --git a/trunk/drivers/mtd/chips/cfi_cmdset_0020.c b/trunk/drivers/mtd/chips/cfi_cmdset_0020.c index 096993f9711e..85e80180b65b 100644 --- a/trunk/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/trunk/drivers/mtd/chips/cfi_cmdset_0020.c @@ -228,15 +228,15 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map) } /* Also select the correct geometry setup too */ - mtd->_erase = cfi_staa_erase_varsize; - mtd->_read = cfi_staa_read; - mtd->_write = cfi_staa_write_buffers; - mtd->_writev = cfi_staa_writev; - mtd->_sync = cfi_staa_sync; - mtd->_lock = cfi_staa_lock; - mtd->_unlock = cfi_staa_unlock; - mtd->_suspend = cfi_staa_suspend; - mtd->_resume = cfi_staa_resume; + mtd->erase = cfi_staa_erase_varsize; + mtd->read = cfi_staa_read; + mtd->write = cfi_staa_write_buffers; + mtd->writev = cfi_staa_writev; + mtd->sync = cfi_staa_sync; + mtd->lock = cfi_staa_lock; + mtd->unlock = cfi_staa_unlock; + mtd->suspend = cfi_staa_suspend; + mtd->resume = cfi_staa_resume; mtd->flags = MTD_CAP_NORFLASH & ~MTD_BIT_WRITEABLE; mtd->writesize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */ mtd->writebufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; @@ -394,6 +394,8 @@ static int cfi_staa_read (struct mtd_info *mtd, loff_t from, size_t len, size_t chipnum = (from >> cfi->chipshift); ofs = from - (chipnum << cfi->chipshift); + *retlen = 0; + while (len) { unsigned long thislen; @@ -615,6 +617,10 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, int chipnum; unsigned long ofs; + *retlen = 0; + if (!len) + return 0; + chipnum = to >> cfi->chipshift; ofs = to - (chipnum << cfi->chipshift); @@ -898,6 +904,12 @@ static int cfi_staa_erase_varsize(struct mtd_info *mtd, int i, first; struct mtd_erase_region_info *regions = mtd->eraseregions; + if (instr->addr > mtd->size) + return -EINVAL; + + if ((instr->len + instr->addr) > mtd->size) + return -EINVAL; + /* Check that both start and end of the requested erase are * aligned with the erasesize at the appropriate addresses. */ @@ -1143,6 +1155,9 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) if (len & (mtd->erasesize -1)) return -EINVAL; + if ((len + ofs) > mtd->size) + return -EINVAL; + chipnum = ofs >> cfi->chipshift; adr = ofs - (chipnum << cfi->chipshift); diff --git a/trunk/drivers/mtd/chips/cfi_util.c b/trunk/drivers/mtd/chips/cfi_util.c index f992418f40a8..8e464054a631 100644 --- a/trunk/drivers/mtd/chips/cfi_util.c +++ b/trunk/drivers/mtd/chips/cfi_util.c @@ -173,6 +173,12 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob, int i, first; struct mtd_erase_region_info *regions = mtd->eraseregions; + if (ofs > mtd->size) + return -EINVAL; + + if ((len + ofs) > mtd->size) + return -EINVAL; + /* Check that both start and end of the requested erase are * aligned with the erasesize at the appropriate addresses. */ diff --git a/trunk/drivers/mtd/chips/fwh_lock.h b/trunk/drivers/mtd/chips/fwh_lock.h index 800b0e853e86..89c6595454a5 100644 --- a/trunk/drivers/mtd/chips/fwh_lock.h +++ b/trunk/drivers/mtd/chips/fwh_lock.h @@ -101,7 +101,7 @@ static void fixup_use_fwh_lock(struct mtd_info *mtd) { printk(KERN_NOTICE "using fwh lock/unlock method\n"); /* Setup for the chips with the fwh lock method */ - mtd->_lock = fwh_lock_varsize; - mtd->_unlock = fwh_unlock_varsize; + mtd->lock = fwh_lock_varsize; + mtd->unlock = fwh_unlock_varsize; } #endif /* FWH_LOCK_H */ diff --git a/trunk/drivers/mtd/chips/map_absent.c b/trunk/drivers/mtd/chips/map_absent.c index f7a5bca92aef..f2b872946871 100644 --- a/trunk/drivers/mtd/chips/map_absent.c +++ b/trunk/drivers/mtd/chips/map_absent.c @@ -55,10 +55,10 @@ static struct mtd_info *map_absent_probe(struct map_info *map) mtd->name = map->name; mtd->type = MTD_ABSENT; mtd->size = map->size; - mtd->_erase = map_absent_erase; - mtd->_read = map_absent_read; - mtd->_write = map_absent_write; - mtd->_sync = map_absent_sync; + mtd->erase = map_absent_erase; + mtd->read = map_absent_read; + mtd->write = map_absent_write; + mtd->sync = map_absent_sync; mtd->flags = 0; mtd->erasesize = PAGE_SIZE; mtd->writesize = 1; @@ -70,11 +70,13 @@ static struct mtd_info *map_absent_probe(struct map_info *map) static int map_absent_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { + *retlen = 0; return -ENODEV; } static int map_absent_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { + *retlen = 0; return -ENODEV; } diff --git a/trunk/drivers/mtd/chips/map_ram.c b/trunk/drivers/mtd/chips/map_ram.c index 991c2a1c05d3..67640ccb2d41 100644 --- a/trunk/drivers/mtd/chips/map_ram.c +++ b/trunk/drivers/mtd/chips/map_ram.c @@ -64,11 +64,11 @@ static struct mtd_info *map_ram_probe(struct map_info *map) mtd->name = map->name; mtd->type = MTD_RAM; mtd->size = map->size; - mtd->_erase = mapram_erase; - mtd->_get_unmapped_area = mapram_unmapped_area; - mtd->_read = mapram_read; - mtd->_write = mapram_write; - mtd->_sync = mapram_nop; + mtd->erase = mapram_erase; + mtd->get_unmapped_area = mapram_unmapped_area; + mtd->read = mapram_read; + mtd->write = mapram_write; + mtd->sync = mapram_nop; mtd->flags = MTD_CAP_RAM; mtd->writesize = 1; @@ -122,10 +122,14 @@ static int mapram_erase (struct mtd_info *mtd, struct erase_info *instr) unsigned long i; allff = map_word_ff(map); + for (i=0; ilen; i += map_bankwidth(map)) map_write(map, allff, instr->addr + i); + instr->state = MTD_ERASE_DONE; + mtd_erase_callback(instr); + return 0; } diff --git a/trunk/drivers/mtd/chips/map_rom.c b/trunk/drivers/mtd/chips/map_rom.c index 47a43cf7e5c6..593f73d480d2 100644 --- a/trunk/drivers/mtd/chips/map_rom.c +++ b/trunk/drivers/mtd/chips/map_rom.c @@ -41,11 +41,11 @@ static struct mtd_info *map_rom_probe(struct map_info *map) mtd->name = map->name; mtd->type = MTD_ROM; mtd->size = map->size; - mtd->_get_unmapped_area = maprom_unmapped_area; - mtd->_read = maprom_read; - mtd->_write = maprom_write; - mtd->_sync = maprom_nop; - mtd->_erase = maprom_erase; + mtd->get_unmapped_area = maprom_unmapped_area; + mtd->read = maprom_read; + mtd->write = maprom_write; + mtd->sync = maprom_nop; + mtd->erase = maprom_erase; mtd->flags = MTD_CAP_ROM; mtd->erasesize = map->size; mtd->writesize = 1; @@ -85,7 +85,8 @@ static void maprom_nop(struct mtd_info *mtd) static int maprom_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { - return -EROFS; + printk(KERN_NOTICE "maprom_write called\n"); + return -EIO; } static int maprom_erase (struct mtd_info *mtd, struct erase_info *info) diff --git a/trunk/drivers/mtd/devices/Kconfig b/trunk/drivers/mtd/devices/Kconfig index 4cdb2af7bf44..8d3dac40d7e6 100644 --- a/trunk/drivers/mtd/devices/Kconfig +++ b/trunk/drivers/mtd/devices/Kconfig @@ -103,13 +103,6 @@ config M25PXX_USE_FAST_READ help This option enables FAST_READ access supported by ST M25Pxx. -config MTD_SPEAR_SMI - tristate "SPEAR MTD NOR Support through SMI controller" - depends on PLAT_SPEAR - default y - help - This enable SNOR support on SPEAR platforms using SMI controller - config MTD_SST25L tristate "Support SST25L (non JEDEC) SPI Flash chips" depends on SPI_MASTER diff --git a/trunk/drivers/mtd/devices/Makefile b/trunk/drivers/mtd/devices/Makefile index a4dd1d822b6c..56c7cd462f11 100644 --- a/trunk/drivers/mtd/devices/Makefile +++ b/trunk/drivers/mtd/devices/Makefile @@ -17,7 +17,6 @@ obj-$(CONFIG_MTD_LART) += lart.o obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o obj-$(CONFIG_MTD_M25P80) += m25p80.o -obj-$(CONFIG_MTD_SPEAR_SMI) += spear_smi.o obj-$(CONFIG_MTD_SST25L) += sst25l.o CFLAGS_docg3.o += -I$(src) \ No newline at end of file diff --git a/trunk/drivers/mtd/devices/block2mtd.c b/trunk/drivers/mtd/devices/block2mtd.c index a4a80b742e65..e7e46d1e7463 100644 --- a/trunk/drivers/mtd/devices/block2mtd.c +++ b/trunk/drivers/mtd/devices/block2mtd.c @@ -104,6 +104,14 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len, int offset = from & (PAGE_SIZE-1); int cpylen; + if (from > mtd->size) + return -EINVAL; + if (from + len > mtd->size) + len = mtd->size - from; + + if (retlen) + *retlen = 0; + while (len) { if ((offset + len) > PAGE_SIZE) cpylen = PAGE_SIZE - offset; // multiple pages @@ -140,6 +148,8 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf, int offset = to & ~PAGE_MASK; // page offset int cpylen; + if (retlen) + *retlen = 0; while (len) { if ((offset+len) > PAGE_SIZE) cpylen = PAGE_SIZE - offset; // multiple pages @@ -178,6 +188,13 @@ static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len, struct block2mtd_dev *dev = mtd->priv; int err; + if (!len) + return 0; + if (to >= mtd->size) + return -ENOSPC; + if (to + len > mtd->size) + len = mtd->size - to; + mutex_lock(&dev->write_mutex); err = _block2mtd_write(dev, buf, to, len, retlen); mutex_unlock(&dev->write_mutex); @@ -266,14 +283,13 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; dev->mtd.erasesize = erase_size; dev->mtd.writesize = 1; - dev->mtd.writebufsize = PAGE_SIZE; dev->mtd.type = MTD_RAM; dev->mtd.flags = MTD_CAP_RAM; - dev->mtd._erase = block2mtd_erase; - dev->mtd._write = block2mtd_write; - dev->mtd._writev = mtd_writev; - dev->mtd._sync = block2mtd_sync; - dev->mtd._read = block2mtd_read; + dev->mtd.erase = block2mtd_erase; + dev->mtd.write = block2mtd_write; + dev->mtd.writev = mtd_writev; + dev->mtd.sync = block2mtd_sync; + dev->mtd.read = block2mtd_read; dev->mtd.priv = dev; dev->mtd.owner = THIS_MODULE; diff --git a/trunk/drivers/mtd/devices/doc2000.c b/trunk/drivers/mtd/devices/doc2000.c index a4eb8b5b85ec..b1cdf6479019 100644 --- a/trunk/drivers/mtd/devices/doc2000.c +++ b/trunk/drivers/mtd/devices/doc2000.c @@ -562,15 +562,14 @@ void DoC2k_init(struct mtd_info *mtd) mtd->type = MTD_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH; - mtd->writebufsize = mtd->writesize = 512; + mtd->writesize = 512; mtd->oobsize = 16; - mtd->ecc_strength = 2; mtd->owner = THIS_MODULE; - mtd->_erase = doc_erase; - mtd->_read = doc_read; - mtd->_write = doc_write; - mtd->_read_oob = doc_read_oob; - mtd->_write_oob = doc_write_oob; + mtd->erase = doc_erase; + mtd->read = doc_read; + mtd->write = doc_write; + mtd->read_oob = doc_read_oob; + mtd->write_oob = doc_write_oob; this->curfloor = -1; this->curchip = -1; mutex_init(&this->lock); @@ -603,7 +602,13 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, int i, len256 = 0, ret=0; size_t left = len; + /* Don't allow read past end of device */ + if (from >= this->totlen) + return -EINVAL; + mutex_lock(&this->lock); + + *retlen = 0; while (left) { len = left; @@ -743,7 +748,13 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, size_t left = len; int status; + /* Don't allow write past end of device */ + if (to >= this->totlen) + return -EINVAL; + mutex_lock(&this->lock); + + *retlen = 0; while (left) { len = left; diff --git a/trunk/drivers/mtd/devices/doc2001.c b/trunk/drivers/mtd/devices/doc2001.c index f6927955dab0..7543b98f46c4 100644 --- a/trunk/drivers/mtd/devices/doc2001.c +++ b/trunk/drivers/mtd/devices/doc2001.c @@ -346,15 +346,14 @@ void DoCMil_init(struct mtd_info *mtd) /* FIXME: erase size is not always 8KiB */ mtd->erasesize = 0x2000; - mtd->writebufsize = mtd->writesize = 512; + mtd->writesize = 512; mtd->oobsize = 16; - mtd->ecc_strength = 2; mtd->owner = THIS_MODULE; - mtd->_erase = doc_erase; - mtd->_read = doc_read; - mtd->_write = doc_write; - mtd->_read_oob = doc_read_oob; - mtd->_write_oob = doc_write_oob; + mtd->erase = doc_erase; + mtd->read = doc_read; + mtd->write = doc_write; + mtd->read_oob = doc_read_oob; + mtd->write_oob = doc_write_oob; this->curfloor = -1; this->curchip = -1; @@ -384,6 +383,10 @@ static int doc_read (struct mtd_info *mtd, loff_t from, size_t len, void __iomem *docptr = this->virtadr; struct Nand *mychip = &this->chips[from >> (this->chipshift)]; + /* Don't allow read past end of device */ + if (from >= this->totlen) + return -EINVAL; + /* Don't allow a single read to cross a 512-byte block boundary */ if (from + len > ((from | 0x1ff) + 1)) len = ((from | 0x1ff) + 1) - from; @@ -491,6 +494,10 @@ static int doc_write (struct mtd_info *mtd, loff_t to, size_t len, void __iomem *docptr = this->virtadr; struct Nand *mychip = &this->chips[to >> (this->chipshift)]; + /* Don't allow write past end of device */ + if (to >= this->totlen) + return -EINVAL; + #if 0 /* Don't allow a single write to cross a 512-byte block boundary */ if (to + len > ( (to | 0x1ff) + 1)) @@ -592,6 +599,7 @@ static int doc_write (struct mtd_info *mtd, loff_t to, size_t len, printk("Error programming flash\n"); /* Error in programming FIXME: implement Bad Block Replacement (in nftl.c ??) */ + *retlen = 0; ret = -EIO; } dummy = ReadDOC(docptr, LastDataRead); diff --git a/trunk/drivers/mtd/devices/doc2001plus.c b/trunk/drivers/mtd/devices/doc2001plus.c index 04eb2e4aa50f..177510d0e7ee 100644 --- a/trunk/drivers/mtd/devices/doc2001plus.c +++ b/trunk/drivers/mtd/devices/doc2001plus.c @@ -467,15 +467,14 @@ void DoCMilPlus_init(struct mtd_info *mtd) mtd->type = MTD_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH; - mtd->writebufsize = mtd->writesize = 512; + mtd->writesize = 512; mtd->oobsize = 16; - mtd->ecc_strength = 2; mtd->owner = THIS_MODULE; - mtd->_erase = doc_erase; - mtd->_read = doc_read; - mtd->_write = doc_write; - mtd->_read_oob = doc_read_oob; - mtd->_write_oob = doc_write_oob; + mtd->erase = doc_erase; + mtd->read = doc_read; + mtd->write = doc_write; + mtd->read_oob = doc_read_oob; + mtd->write_oob = doc_write_oob; this->curfloor = -1; this->curchip = -1; @@ -582,6 +581,10 @@ static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, void __iomem * docptr = this->virtadr; struct Nand *mychip = &this->chips[from >> (this->chipshift)]; + /* Don't allow read past end of device */ + if (from >= this->totlen) + return -EINVAL; + /* Don't allow a single read to cross a 512-byte block boundary */ if (from + len > ((from | 0x1ff) + 1)) len = ((from | 0x1ff) + 1) - from; @@ -697,6 +700,10 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, void __iomem * docptr = this->virtadr; struct Nand *mychip = &this->chips[to >> (this->chipshift)]; + /* Don't allow write past end of device */ + if (to >= this->totlen) + return -EINVAL; + /* Don't allow writes which aren't exactly one block (512 bytes) */ if ((to & 0x1ff) || (len != 0x200)) return -EINVAL; @@ -793,6 +800,7 @@ static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, printk("MTD: Error 0x%x programming at 0x%x\n", dummy, (int)to); /* Error in programming FIXME: implement Bad Block Replacement (in nftl.c ??) */ + *retlen = 0; ret = -EIO; } dummy = ReadDOC(docptr, Mplus_LastDataRead); diff --git a/trunk/drivers/mtd/devices/docg3.c b/trunk/drivers/mtd/devices/docg3.c index 8272c02668d6..ad11ef0a81f4 100644 --- a/trunk/drivers/mtd/devices/docg3.c +++ b/trunk/drivers/mtd/devices/docg3.c @@ -80,9 +80,14 @@ static struct nand_ecclayout docg3_oobinfo = { .oobavail = 8, }; +/** + * struct docg3_bch - BCH engine + */ +static struct bch_control *docg3_bch; + static inline u8 doc_readb(struct docg3 *docg3, u16 reg) { - u8 val = readb(docg3->cascade->base + reg); + u8 val = readb(docg3->base + reg); trace_docg3_io(0, 8, reg, (int)val); return val; @@ -90,7 +95,7 @@ static inline u8 doc_readb(struct docg3 *docg3, u16 reg) static inline u16 doc_readw(struct docg3 *docg3, u16 reg) { - u16 val = readw(docg3->cascade->base + reg); + u16 val = readw(docg3->base + reg); trace_docg3_io(0, 16, reg, (int)val); return val; @@ -98,13 +103,13 @@ static inline u16 doc_readw(struct docg3 *docg3, u16 reg) static inline void doc_writeb(struct docg3 *docg3, u8 val, u16 reg) { - writeb(val, docg3->cascade->base + reg); + writeb(val, docg3->base + reg); trace_docg3_io(1, 8, reg, val); } static inline void doc_writew(struct docg3 *docg3, u16 val, u16 reg) { - writew(val, docg3->cascade->base + reg); + writew(val, docg3->base + reg); trace_docg3_io(1, 16, reg, val); } @@ -638,8 +643,7 @@ static int doc_ecc_bch_fix_data(struct docg3 *docg3, void *buf, u8 *hwecc) for (i = 0; i < DOC_ECC_BCH_SIZE; i++) ecc[i] = bitrev8(hwecc[i]); - numerrs = decode_bch(docg3->cascade->bch, NULL, - DOC_ECC_BCH_COVERED_BYTES, + numerrs = decode_bch(docg3_bch, NULL, DOC_ECC_BCH_COVERED_BYTES, NULL, ecc, NULL, errorpos); BUG_ON(numerrs == -EINVAL); if (numerrs < 0) @@ -730,7 +734,7 @@ static int doc_read_page_prepare(struct docg3 *docg3, int block0, int block1, * doc_read_page_getbytes - Reads bytes from a prepared page * @docg3: the device * @len: the number of bytes to be read (must be a multiple of 4) - * @buf: the buffer to be filled in (or NULL is forget bytes) + * @buf: the buffer to be filled in * @first: 1 if first time read, DOC_READADDRESS should be set * */ @@ -845,7 +849,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) { struct docg3 *docg3 = mtd->priv; - int block0, block1, page, ret, skip, ofs = 0; + int block0, block1, page, ret, ofs = 0; u8 *oobbuf = ops->oobbuf; u8 *buf = ops->datbuf; size_t len, ooblen, nbdata, nboob; @@ -865,36 +869,34 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, doc_dbg("doc_read_oob(from=%lld, mode=%d, data=(%p:%zu), oob=(%p:%zu))\n", from, ops->mode, buf, len, oobbuf, ooblen); - if (ooblen % DOC_LAYOUT_OOB_SIZE) + if ((len % DOC_LAYOUT_PAGE_SIZE) || (ooblen % DOC_LAYOUT_OOB_SIZE) || + (from % DOC_LAYOUT_PAGE_SIZE)) return -EINVAL; - if (from + len > mtd->size) - return -EINVAL; + ret = -EINVAL; + calc_block_sector(from + len, &block0, &block1, &page, &ofs, + docg3->reliable); + if (block1 > docg3->max_block) + goto err; ops->oobretlen = 0; ops->retlen = 0; ret = 0; - skip = from % DOC_LAYOUT_PAGE_SIZE; - mutex_lock(&docg3->cascade->lock); while (!ret && (len > 0 || ooblen > 0)) { - calc_block_sector(from - skip, &block0, &block1, &page, &ofs, + calc_block_sector(from, &block0, &block1, &page, &ofs, docg3->reliable); - nbdata = min_t(size_t, len, DOC_LAYOUT_PAGE_SIZE - skip); + nbdata = min_t(size_t, len, (size_t)DOC_LAYOUT_PAGE_SIZE); nboob = min_t(size_t, ooblen, (size_t)DOC_LAYOUT_OOB_SIZE); ret = doc_read_page_prepare(docg3, block0, block1, page, ofs); if (ret < 0) - goto out; + goto err; ret = doc_read_page_ecc_init(docg3, DOC_ECC_BCH_TOTAL_BYTES); if (ret < 0) goto err_in_read; - ret = doc_read_page_getbytes(docg3, skip, NULL, 1); - if (ret < skip) - goto err_in_read; - ret = doc_read_page_getbytes(docg3, nbdata, buf, 0); + ret = doc_read_page_getbytes(docg3, nbdata, buf, 1); if (ret < nbdata) goto err_in_read; - doc_read_page_getbytes(docg3, - DOC_LAYOUT_PAGE_SIZE - nbdata - skip, + doc_read_page_getbytes(docg3, DOC_LAYOUT_PAGE_SIZE - nbdata, NULL, 0); ret = doc_read_page_getbytes(docg3, nboob, oobbuf, 0); if (ret < nboob) @@ -948,15 +950,13 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t from, len -= nbdata; ooblen -= nboob; from += DOC_LAYOUT_PAGE_SIZE; - skip = 0; } -out: - mutex_unlock(&docg3->cascade->lock); return ret; err_in_read: doc_read_page_finish(docg3); - goto out; +err: + return ret; } /** @@ -1114,10 +1114,10 @@ static int doc_get_op_status(struct docg3 *docg3) */ static int doc_write_erase_wait_status(struct docg3 *docg3) { - int i, status, ret = 0; + int status, ret = 0; - for (i = 0; !doc_is_ready(docg3) && i < 5; i++) - msleep(20); + if (!doc_is_ready(docg3)) + usleep_range(3000, 3000); if (!doc_is_ready(docg3)) { doc_dbg("Timeout reached and the chip is still not ready\n"); ret = -EAGAIN; @@ -1196,19 +1196,18 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *info) int block0, block1, page, ret, ofs = 0; doc_dbg("doc_erase(from=%lld, len=%lld\n", info->addr, info->len); + doc_set_device_id(docg3, docg3->device_id); info->state = MTD_ERASE_PENDING; calc_block_sector(info->addr + info->len, &block0, &block1, &page, &ofs, docg3->reliable); ret = -EINVAL; - if (info->addr + info->len > mtd->size || page || ofs) + if (block1 > docg3->max_block || page || ofs) goto reset_err; ret = 0; calc_block_sector(info->addr, &block0, &block1, &page, &ofs, docg3->reliable); - mutex_lock(&docg3->cascade->lock); - doc_set_device_id(docg3, docg3->device_id); doc_set_reliable_mode(docg3); for (len = info->len; !ret && len > 0; len -= mtd->erasesize) { info->state = MTD_ERASING; @@ -1216,7 +1215,6 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *info) block0 += 2; block1 += 2; } - mutex_unlock(&docg3->cascade->lock); if (ret) goto reset_err; @@ -1403,7 +1401,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, struct mtd_oob_ops *ops) { struct docg3 *docg3 = mtd->priv; - int ret, autoecc, oobdelta; + int block0, block1, page, ret, pofs = 0, autoecc, oobdelta; u8 *oobbuf = ops->oobbuf; u8 *buf = ops->datbuf; size_t len, ooblen; @@ -1440,8 +1438,12 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, if (len && ooblen && (len / DOC_LAYOUT_PAGE_SIZE) != (ooblen / oobdelta)) return -EINVAL; - if (ofs + len > mtd->size) - return -EINVAL; + + ret = -EINVAL; + calc_block_sector(ofs + len, &block0, &block1, &page, &pofs, + docg3->reliable); + if (block1 > docg3->max_block) + goto err; ops->oobretlen = 0; ops->retlen = 0; @@ -1455,7 +1457,6 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, if (autoecc < 0) return autoecc; - mutex_lock(&docg3->cascade->lock); while (!ret && len > 0) { memset(oob, 0, sizeof(oob)); if (ofs == docg3->oob_write_ofs) @@ -1476,9 +1477,8 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, } ops->retlen += DOC_LAYOUT_PAGE_SIZE; } - +err: doc_set_device_id(docg3, 0); - mutex_unlock(&docg3->cascade->lock); return ret; } @@ -1535,11 +1535,9 @@ static ssize_t dps0_is_key_locked(struct device *dev, struct docg3 *docg3 = sysfs_dev2docg3(dev, attr); int dps0; - mutex_lock(&docg3->cascade->lock); doc_set_device_id(docg3, docg3->device_id); dps0 = doc_register_readb(docg3, DOC_DPS0_STATUS); doc_set_device_id(docg3, 0); - mutex_unlock(&docg3->cascade->lock); return sprintf(buf, "%d\n", !(dps0 & DOC_DPS_KEY_OK)); } @@ -1550,11 +1548,9 @@ static ssize_t dps1_is_key_locked(struct device *dev, struct docg3 *docg3 = sysfs_dev2docg3(dev, attr); int dps1; - mutex_lock(&docg3->cascade->lock); doc_set_device_id(docg3, docg3->device_id); dps1 = doc_register_readb(docg3, DOC_DPS1_STATUS); doc_set_device_id(docg3, 0); - mutex_unlock(&docg3->cascade->lock); return sprintf(buf, "%d\n", !(dps1 & DOC_DPS_KEY_OK)); } @@ -1569,12 +1565,10 @@ static ssize_t dps0_insert_key(struct device *dev, if (count != DOC_LAYOUT_DPS_KEY_LENGTH) return -EINVAL; - mutex_lock(&docg3->cascade->lock); doc_set_device_id(docg3, docg3->device_id); for (i = 0; i < DOC_LAYOUT_DPS_KEY_LENGTH; i++) doc_writeb(docg3, buf[i], DOC_DPS0_KEY); doc_set_device_id(docg3, 0); - mutex_unlock(&docg3->cascade->lock); return count; } @@ -1588,12 +1582,10 @@ static ssize_t dps1_insert_key(struct device *dev, if (count != DOC_LAYOUT_DPS_KEY_LENGTH) return -EINVAL; - mutex_lock(&docg3->cascade->lock); doc_set_device_id(docg3, docg3->device_id); for (i = 0; i < DOC_LAYOUT_DPS_KEY_LENGTH; i++) doc_writeb(docg3, buf[i], DOC_DPS1_KEY); doc_set_device_id(docg3, 0); - mutex_unlock(&docg3->cascade->lock); return count; } @@ -1609,13 +1601,13 @@ static struct device_attribute doc_sys_attrs[DOC_MAX_NBFLOORS][4] = { }; static int doc_register_sysfs(struct platform_device *pdev, - struct docg3_cascade *cascade) + struct mtd_info **floors) { int ret = 0, floor, i = 0; struct device *dev = &pdev->dev; - for (floor = 0; !ret && floor < DOC_MAX_NBFLOORS && - cascade->floors[floor]; floor++) + for (floor = 0; !ret && floor < DOC_MAX_NBFLOORS && floors[floor]; + floor++) for (i = 0; !ret && i < 4; i++) ret = device_create_file(dev, &doc_sys_attrs[floor][i]); if (!ret) @@ -1629,12 +1621,12 @@ static int doc_register_sysfs(struct platform_device *pdev, } static void doc_unregister_sysfs(struct platform_device *pdev, - struct docg3_cascade *cascade) + struct mtd_info **floors) { struct device *dev = &pdev->dev; int floor, i; - for (floor = 0; floor < DOC_MAX_NBFLOORS && cascade->floors[floor]; + for (floor = 0; floor < DOC_MAX_NBFLOORS && floors[floor]; floor++) for (i = 0; i < 4; i++) device_remove_file(dev, &doc_sys_attrs[floor][i]); @@ -1648,11 +1640,7 @@ static int dbg_flashctrl_show(struct seq_file *s, void *p) struct docg3 *docg3 = (struct docg3 *)s->private; int pos = 0; - u8 fctrl; - - mutex_lock(&docg3->cascade->lock); - fctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); - mutex_unlock(&docg3->cascade->lock); + u8 fctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); pos += seq_printf(s, "FlashControl : 0x%02x (%s,CE# %s,%s,%s,flash %s)\n", @@ -1670,12 +1658,9 @@ static int dbg_asicmode_show(struct seq_file *s, void *p) { struct docg3 *docg3 = (struct docg3 *)s->private; - int pos = 0, pctrl, mode; - - mutex_lock(&docg3->cascade->lock); - pctrl = doc_register_readb(docg3, DOC_ASICMODE); - mode = pctrl & 0x03; - mutex_unlock(&docg3->cascade->lock); + int pos = 0; + int pctrl = doc_register_readb(docg3, DOC_ASICMODE); + int mode = pctrl & 0x03; pos += seq_printf(s, "%04x : RAM_WE=%d,RSTIN_RESET=%d,BDETCT_RESET=%d,WRITE_ENABLE=%d,POWERDOWN=%d,MODE=%d%d (", @@ -1707,11 +1692,7 @@ static int dbg_device_id_show(struct seq_file *s, void *p) { struct docg3 *docg3 = (struct docg3 *)s->private; int pos = 0; - int id; - - mutex_lock(&docg3->cascade->lock); - id = doc_register_readb(docg3, DOC_DEVICESELECT); - mutex_unlock(&docg3->cascade->lock); + int id = doc_register_readb(docg3, DOC_DEVICESELECT); pos += seq_printf(s, "DeviceId = %d\n", id); return pos; @@ -1724,7 +1705,6 @@ static int dbg_protection_show(struct seq_file *s, void *p) int pos = 0; int protect, dps0, dps0_low, dps0_high, dps1, dps1_low, dps1_high; - mutex_lock(&docg3->cascade->lock); protect = doc_register_readb(docg3, DOC_PROTECTION); dps0 = doc_register_readb(docg3, DOC_DPS0_STATUS); dps0_low = doc_register_readw(docg3, DOC_DPS0_ADDRLOW); @@ -1732,7 +1712,6 @@ static int dbg_protection_show(struct seq_file *s, void *p) dps1 = doc_register_readb(docg3, DOC_DPS1_STATUS); dps1_low = doc_register_readw(docg3, DOC_DPS1_ADDRLOW); dps1_high = doc_register_readw(docg3, DOC_DPS1_ADDRHIGH); - mutex_unlock(&docg3->cascade->lock); pos += seq_printf(s, "Protection = 0x%02x (", protect); @@ -1825,7 +1804,7 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd) switch (chip_id) { case DOC_CHIPID_G3: - mtd->name = kasprintf(GFP_KERNEL, "docg3.%d", + mtd->name = kasprintf(GFP_KERNEL, "DiskOnChip G3 floor %d", docg3->device_id); docg3->max_block = 2047; break; @@ -1838,17 +1817,16 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd) mtd->erasesize = DOC_LAYOUT_BLOCK_SIZE * DOC_LAYOUT_NBPLANES; if (docg3->reliable == 2) mtd->erasesize /= 2; - mtd->writebufsize = mtd->writesize = DOC_LAYOUT_PAGE_SIZE; + mtd->writesize = DOC_LAYOUT_PAGE_SIZE; mtd->oobsize = DOC_LAYOUT_OOB_SIZE; mtd->owner = THIS_MODULE; - mtd->_erase = doc_erase; - mtd->_read = doc_read; - mtd->_write = doc_write; - mtd->_read_oob = doc_read_oob; - mtd->_write_oob = doc_write_oob; - mtd->_block_isbad = doc_block_isbad; + mtd->erase = doc_erase; + mtd->read = doc_read; + mtd->write = doc_write; + mtd->read_oob = doc_read_oob; + mtd->write_oob = doc_write_oob; + mtd->block_isbad = doc_block_isbad; mtd->ecclayout = &docg3_oobinfo; - mtd->ecc_strength = DOC_ECC_BCH_T; } /** @@ -1856,7 +1834,6 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd) * @base: the io space where the device is probed * @floor: the floor of the probed device * @dev: the device - * @cascade: the cascade of chips this devices will belong to * * Checks whether a device at the specified IO range, and floor is available. * @@ -1864,8 +1841,8 @@ static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd) * if a memory allocation failed. If floor 0 is checked, a reset of the ASIC is * launched. */ -static struct mtd_info * __init -doc_probe_device(struct docg3_cascade *cascade, int floor, struct device *dev) +static struct mtd_info *doc_probe_device(void __iomem *base, int floor, + struct device *dev) { int ret, bbt_nbpages; u16 chip_id, chip_id_inv; @@ -1888,7 +1865,7 @@ doc_probe_device(struct docg3_cascade *cascade, int floor, struct device *dev) docg3->dev = dev; docg3->device_id = floor; - docg3->cascade = cascade; + docg3->base = base; doc_set_device_id(docg3, docg3->device_id); if (!floor) doc_set_asic_mode(docg3, DOC_ASICMODE_RESET); @@ -1905,7 +1882,7 @@ doc_probe_device(struct docg3_cascade *cascade, int floor, struct device *dev) switch (chip_id) { case DOC_CHIPID_G3: doc_info("Found a G3 DiskOnChip at addr %p, floor %d\n", - docg3->cascade->base, floor); + base, floor); break; default: doc_err("Chip id %04x is not a DiskOnChip G3 chip\n", chip_id); @@ -1950,12 +1927,10 @@ static void doc_release_device(struct mtd_info *mtd) static int docg3_resume(struct platform_device *pdev) { int i; - struct docg3_cascade *cascade; struct mtd_info **docg3_floors, *mtd; struct docg3 *docg3; - cascade = platform_get_drvdata(pdev); - docg3_floors = cascade->floors; + docg3_floors = platform_get_drvdata(pdev); mtd = docg3_floors[0]; docg3 = mtd->priv; @@ -1977,13 +1952,11 @@ static int docg3_resume(struct platform_device *pdev) static int docg3_suspend(struct platform_device *pdev, pm_message_t state) { int floor, i; - struct docg3_cascade *cascade; struct mtd_info **docg3_floors, *mtd; struct docg3 *docg3; u8 ctrl, pwr_down; - cascade = platform_get_drvdata(pdev); - docg3_floors = cascade->floors; + docg3_floors = platform_get_drvdata(pdev); for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) { mtd = docg3_floors[floor]; if (!mtd) @@ -2033,7 +2006,7 @@ static int __init docg3_probe(struct platform_device *pdev) struct resource *ress; void __iomem *base; int ret, floor, found = 0; - struct docg3_cascade *cascade; + struct mtd_info **docg3_floors; ret = -ENXIO; ress = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -2044,19 +2017,17 @@ static int __init docg3_probe(struct platform_device *pdev) base = ioremap(ress->start, DOC_IOSPACE_SIZE); ret = -ENOMEM; - cascade = kzalloc(sizeof(*cascade) * DOC_MAX_NBFLOORS, - GFP_KERNEL); - if (!cascade) + docg3_floors = kzalloc(sizeof(*docg3_floors) * DOC_MAX_NBFLOORS, + GFP_KERNEL); + if (!docg3_floors) goto nomem1; - cascade->base = base; - mutex_init(&cascade->lock); - cascade->bch = init_bch(DOC_ECC_BCH_M, DOC_ECC_BCH_T, + docg3_bch = init_bch(DOC_ECC_BCH_M, DOC_ECC_BCH_T, DOC_ECC_BCH_PRIMPOLY); - if (!cascade->bch) + if (!docg3_bch) goto nomem2; for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) { - mtd = doc_probe_device(cascade, floor, dev); + mtd = doc_probe_device(base, floor, dev); if (IS_ERR(mtd)) { ret = PTR_ERR(mtd); goto err_probe; @@ -2067,7 +2038,7 @@ static int __init docg3_probe(struct platform_device *pdev) else continue; } - cascade->floors[floor] = mtd; + docg3_floors[floor] = mtd; ret = mtd_device_parse_register(mtd, part_probes, NULL, NULL, 0); if (ret) @@ -2075,26 +2046,26 @@ static int __init docg3_probe(struct platform_device *pdev) found++; } - ret = doc_register_sysfs(pdev, cascade); + ret = doc_register_sysfs(pdev, docg3_floors); if (ret) goto err_probe; if (!found) goto notfound; - platform_set_drvdata(pdev, cascade); - doc_dbg_register(cascade->floors[0]->priv); + platform_set_drvdata(pdev, docg3_floors); + doc_dbg_register(docg3_floors[0]->priv); return 0; notfound: ret = -ENODEV; dev_info(dev, "No supported DiskOnChip found\n"); err_probe: - kfree(cascade->bch); + free_bch(docg3_bch); for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) - if (cascade->floors[floor]) - doc_release_device(cascade->floors[floor]); + if (docg3_floors[floor]) + doc_release_device(docg3_floors[floor]); nomem2: - kfree(cascade); + kfree(docg3_floors); nomem1: iounmap(base); noress: @@ -2109,19 +2080,19 @@ static int __init docg3_probe(struct platform_device *pdev) */ static int __exit docg3_release(struct platform_device *pdev) { - struct docg3_cascade *cascade = platform_get_drvdata(pdev); - struct docg3 *docg3 = cascade->floors[0]->priv; - void __iomem *base = cascade->base; + struct mtd_info **docg3_floors = platform_get_drvdata(pdev); + struct docg3 *docg3 = docg3_floors[0]->priv; + void __iomem *base = docg3->base; int floor; - doc_unregister_sysfs(pdev, cascade); + doc_unregister_sysfs(pdev, docg3_floors); doc_dbg_unregister(docg3); for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) - if (cascade->floors[floor]) - doc_release_device(cascade->floors[floor]); + if (docg3_floors[floor]) + doc_release_device(docg3_floors[floor]); - free_bch(docg3->cascade->bch); - kfree(cascade); + kfree(docg3_floors); + free_bch(docg3_bch); iounmap(base); return 0; } diff --git a/trunk/drivers/mtd/devices/docg3.h b/trunk/drivers/mtd/devices/docg3.h index 19fb93f96a3a..db0da436b493 100644 --- a/trunk/drivers/mtd/devices/docg3.h +++ b/trunk/drivers/mtd/devices/docg3.h @@ -22,8 +22,6 @@ #ifndef _MTD_DOCG3_H #define _MTD_DOCG3_H -#include - /* * Flash memory areas : * - 0x0000 .. 0x07ff : IPL @@ -268,24 +266,10 @@ */ #define DOC_LAYOUT_DPS_KEY_LENGTH 8 -/** - * struct docg3_cascade - Cascade of 1 to 4 docg3 chips - * @floors: floors (ie. one physical docg3 chip is one floor) - * @base: IO space to access all chips in the cascade - * @bch: the BCH correcting control structure - * @lock: lock to protect docg3 IO space from concurrent accesses - */ -struct docg3_cascade { - struct mtd_info *floors[DOC_MAX_NBFLOORS]; - void __iomem *base; - struct bch_control *bch; - struct mutex lock; -}; - /** * struct docg3 - DiskOnChip driver private data * @dev: the device currently under control - * @cascade: the cascade this device belongs to + * @base: mapped IO space * @device_id: number of the cascaded DoCG3 device (0, 1, 2 or 3) * @if_cfg: if true, reads are on 16bits, else reads are on 8bits @@ -303,7 +287,7 @@ struct docg3_cascade { */ struct docg3 { struct device *dev; - struct docg3_cascade *cascade; + void __iomem *base; unsigned int device_id:4; unsigned int if_cfg:1; unsigned int reliable:2; diff --git a/trunk/drivers/mtd/devices/lart.c b/trunk/drivers/mtd/devices/lart.c index 82bd00af5cc3..3a11ea628e58 100644 --- a/trunk/drivers/mtd/devices/lart.c +++ b/trunk/drivers/mtd/devices/lart.c @@ -367,6 +367,9 @@ static int flash_erase (struct mtd_info *mtd,struct erase_info *instr) printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n", __func__, instr->addr, instr->len); #endif + /* sanity checks */ + if (instr->addr + instr->len > mtd->size) return (-EINVAL); + /* * check that both start and end of the requested erase are * aligned with the erasesize at the appropriate addresses. @@ -437,6 +440,10 @@ static int flash_read (struct mtd_info *mtd,loff_t from,size_t len,size_t *retle printk (KERN_DEBUG "%s(from = 0x%.8x, len = %d)\n", __func__, (__u32)from, len); #endif + /* sanity checks */ + if (!len) return (0); + if (from + len > mtd->size) return (-EINVAL); + /* we always read len bytes */ *retlen = len; @@ -515,8 +522,11 @@ static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen printk (KERN_DEBUG "%s(to = 0x%.8x, len = %d)\n", __func__, (__u32)to, len); #endif + *retlen = 0; + /* sanity checks */ if (!len) return (0); + if (to + len > mtd->size) return (-EINVAL); /* first, we write a 0xFF.... padded byte until we reach a dword boundary */ if (to & (BUSWIDTH - 1)) @@ -620,15 +630,14 @@ static int __init lart_flash_init (void) mtd.name = module_name; mtd.type = MTD_NORFLASH; mtd.writesize = 1; - mtd.writebufsize = 4; mtd.flags = MTD_CAP_NORFLASH; mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN; mtd.erasesize = FLASH_BLOCKSIZE_MAIN; mtd.numeraseregions = ARRAY_SIZE(erase_regions); mtd.eraseregions = erase_regions; - mtd._erase = flash_erase; - mtd._read = flash_read; - mtd._write = flash_write; + mtd.erase = flash_erase; + mtd.read = flash_read; + mtd.write = flash_write; mtd.owner = THIS_MODULE; #ifdef LART_DEBUG diff --git a/trunk/drivers/mtd/devices/m25p80.c b/trunk/drivers/mtd/devices/m25p80.c index 1924d247c1cb..7c60dddbefc0 100644 --- a/trunk/drivers/mtd/devices/m25p80.c +++ b/trunk/drivers/mtd/devices/m25p80.c @@ -288,6 +288,9 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr) __func__, (long long)instr->addr, (long long)instr->len); + /* sanity checks */ + if (instr->addr + instr->len > flash->mtd.size) + return -EINVAL; div_u64_rem(instr->len, mtd->erasesize, &rem); if (rem) return -EINVAL; @@ -346,6 +349,13 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), __func__, (u32)from, len); + /* sanity checks */ + if (!len) + return 0; + + if (from + len > flash->mtd.size) + return -EINVAL; + spi_message_init(&m); memset(t, 0, (sizeof t)); @@ -361,6 +371,9 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, t[1].len = len; spi_message_add_tail(&t[1], &m); + /* Byte count starts at zero. */ + *retlen = 0; + mutex_lock(&flash->lock); /* Wait till previous write/erase is done. */ @@ -404,6 +417,15 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev), __func__, (u32)to, len); + *retlen = 0; + + /* sanity checks */ + if (!len) + return(0); + + if (to + len > flash->mtd.size) + return -EINVAL; + spi_message_init(&m); memset(t, 0, (sizeof t)); @@ -487,6 +509,15 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len, pr_debug("%s: %s to 0x%08x, len %zd\n", dev_name(&flash->spi->dev), __func__, (u32)to, len); + *retlen = 0; + + /* sanity checks */ + if (!len) + return 0; + + if (to + len > flash->mtd.size) + return -EINVAL; + spi_message_init(&m); memset(t, 0, (sizeof t)); @@ -877,14 +908,14 @@ static int __devinit m25p_probe(struct spi_device *spi) flash->mtd.writesize = 1; flash->mtd.flags = MTD_CAP_NORFLASH; flash->mtd.size = info->sector_size * info->n_sectors; - flash->mtd._erase = m25p80_erase; - flash->mtd._read = m25p80_read; + flash->mtd.erase = m25p80_erase; + flash->mtd.read = m25p80_read; /* sst flash chips use AAI word program */ if (JEDEC_MFR(info->jedec_id) == CFI_MFR_SST) - flash->mtd._write = sst_write; + flash->mtd.write = sst_write; else - flash->mtd._write = m25p80_write; + flash->mtd.write = m25p80_write; /* prefer "small sector" erase if possible */ if (info->flags & SECT_4K) { @@ -901,7 +932,6 @@ static int __devinit m25p_probe(struct spi_device *spi) ppdata.of_node = spi->dev.of_node; flash->mtd.dev.parent = &spi->dev; flash->page_size = info->page_size; - flash->mtd.writebufsize = flash->page_size; if (info->addr_width) flash->addr_width = info->addr_width; @@ -974,7 +1004,21 @@ static struct spi_driver m25p80_driver = { */ }; -module_spi_driver(m25p80_driver); + +static int __init m25p80_init(void) +{ + return spi_register_driver(&m25p80_driver); +} + + +static void __exit m25p80_exit(void) +{ + spi_unregister_driver(&m25p80_driver); +} + + +module_init(m25p80_init); +module_exit(m25p80_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Mike Lavender"); diff --git a/trunk/drivers/mtd/devices/ms02-nv.c b/trunk/drivers/mtd/devices/ms02-nv.c index 182849d39c61..8423fb6d4f26 100644 --- a/trunk/drivers/mtd/devices/ms02-nv.c +++ b/trunk/drivers/mtd/devices/ms02-nv.c @@ -59,8 +59,12 @@ static int ms02nv_read(struct mtd_info *mtd, loff_t from, { struct ms02nv_private *mp = mtd->priv; + if (from + len > mtd->size) + return -EINVAL; + memcpy(buf, mp->uaddr + from, len); *retlen = len; + return 0; } @@ -69,8 +73,12 @@ static int ms02nv_write(struct mtd_info *mtd, loff_t to, { struct ms02nv_private *mp = mtd->priv; + if (to + len > mtd->size) + return -EINVAL; + memcpy(mp->uaddr + to, buf, len); *retlen = len; + return 0; } @@ -207,8 +215,8 @@ static int __init ms02nv_init_one(ulong addr) mtd->size = fixsize; mtd->name = (char *)ms02nv_name; mtd->owner = THIS_MODULE; - mtd->_read = ms02nv_read; - mtd->_write = ms02nv_write; + mtd->read = ms02nv_read; + mtd->write = ms02nv_write; mtd->writesize = 1; ret = -EIO; diff --git a/trunk/drivers/mtd/devices/mtd_dataflash.c b/trunk/drivers/mtd/devices/mtd_dataflash.c index 928fb0e6d73a..236057ead0d2 100644 --- a/trunk/drivers/mtd/devices/mtd_dataflash.c +++ b/trunk/drivers/mtd/devices/mtd_dataflash.c @@ -164,6 +164,9 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) dev_name(&spi->dev), (long long)instr->addr, (long long)instr->len); + /* Sanity checks */ + if (instr->addr + instr->len > mtd->size) + return -EINVAL; div_u64_rem(instr->len, priv->page_size, &rem); if (rem) return -EINVAL; @@ -249,6 +252,14 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, pr_debug("%s: read 0x%x..0x%x\n", dev_name(&priv->spi->dev), (unsigned)from, (unsigned)(from + len)); + *retlen = 0; + + /* Sanity checks */ + if (!len) + return 0; + if (from + len > mtd->size) + return -EINVAL; + /* Calculate flash page/byte address */ addr = (((unsigned)from / priv->page_size) << priv->page_offset) + ((unsigned)from % priv->page_size); @@ -317,6 +328,14 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, pr_debug("%s: write 0x%x..0x%x\n", dev_name(&spi->dev), (unsigned)to, (unsigned)(to + len)); + *retlen = 0; + + /* Sanity checks */ + if (!len) + return 0; + if ((to + len) > mtd->size) + return -EINVAL; + spi_message_init(&msg); x[0].tx_buf = command = priv->command; @@ -471,6 +490,8 @@ static ssize_t otp_read(struct spi_device *spi, unsigned base, if ((off + len) > 64) len = 64 - off; + if (len == 0) + return len; spi_message_init(&m); @@ -590,16 +611,16 @@ static int dataflash_write_user_otp(struct mtd_info *mtd, static char *otp_setup(struct mtd_info *device, char revision) { - device->_get_fact_prot_info = dataflash_get_otp_info; - device->_read_fact_prot_reg = dataflash_read_fact_otp; - device->_get_user_prot_info = dataflash_get_otp_info; - device->_read_user_prot_reg = dataflash_read_user_otp; + device->get_fact_prot_info = dataflash_get_otp_info; + device->read_fact_prot_reg = dataflash_read_fact_otp; + device->get_user_prot_info = dataflash_get_otp_info; + device->read_user_prot_reg = dataflash_read_user_otp; /* rev c parts (at45db321c and at45db1281 only!) use a * different write procedure; not (yet?) implemented. */ if (revision > 'c') - device->_write_user_prot_reg = dataflash_write_user_otp; + device->write_user_prot_reg = dataflash_write_user_otp; return ", OTP"; } @@ -651,9 +672,9 @@ add_dataflash_otp(struct spi_device *spi, char *name, device->owner = THIS_MODULE; device->type = MTD_DATAFLASH; device->flags = MTD_WRITEABLE; - device->_erase = dataflash_erase; - device->_read = dataflash_read; - device->_write = dataflash_write; + device->erase = dataflash_erase; + device->read = dataflash_read; + device->write = dataflash_write; device->priv = priv; device->dev.parent = &spi->dev; @@ -925,7 +946,18 @@ static struct spi_driver dataflash_driver = { /* FIXME: investigate suspend and resume... */ }; -module_spi_driver(dataflash_driver); +static int __init dataflash_init(void) +{ + return spi_register_driver(&dataflash_driver); +} +module_init(dataflash_init); + +static void __exit dataflash_exit(void) +{ + spi_unregister_driver(&dataflash_driver); +} +module_exit(dataflash_exit); + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Andrew Victor, David Brownell"); diff --git a/trunk/drivers/mtd/devices/mtdram.c b/trunk/drivers/mtd/devices/mtdram.c index ec59d65897fb..2562689ba6b4 100644 --- a/trunk/drivers/mtd/devices/mtdram.c +++ b/trunk/drivers/mtd/devices/mtdram.c @@ -34,23 +34,34 @@ static struct mtd_info *mtd_info; static int ram_erase(struct mtd_info *mtd, struct erase_info *instr) { + if (instr->addr + instr->len > mtd->size) + return -EINVAL; + memset((char *)mtd->priv + instr->addr, 0xff, instr->len); + instr->state = MTD_ERASE_DONE; mtd_erase_callback(instr); + return 0; } static int ram_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys) { + if (from + len > mtd->size) + return -EINVAL; + + /* can we return a physical address with this driver? */ + if (phys) + return -EINVAL; + *virt = mtd->priv + from; *retlen = len; return 0; } -static int ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static void ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) { - return 0; } /* @@ -69,7 +80,11 @@ static unsigned long ram_get_unmapped_area(struct mtd_info *mtd, static int ram_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { + if (from + len > mtd->size) + return -EINVAL; + memcpy(buf, mtd->priv + from, len); + *retlen = len; return 0; } @@ -77,7 +92,11 @@ static int ram_read(struct mtd_info *mtd, loff_t from, size_t len, static int ram_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { + if (to + len > mtd->size) + return -EINVAL; + memcpy((char *)mtd->priv + to, buf, len); + *retlen = len; return 0; } @@ -107,12 +126,12 @@ int mtdram_init_device(struct mtd_info *mtd, void *mapped_address, mtd->priv = mapped_address; mtd->owner = THIS_MODULE; - mtd->_erase = ram_erase; - mtd->_point = ram_point; - mtd->_unpoint = ram_unpoint; - mtd->_get_unmapped_area = ram_get_unmapped_area; - mtd->_read = ram_read; - mtd->_write = ram_write; + mtd->erase = ram_erase; + mtd->point = ram_point; + mtd->unpoint = ram_unpoint; + mtd->get_unmapped_area = ram_get_unmapped_area; + mtd->read = ram_read; + mtd->write = ram_write; if (mtd_device_register(mtd, NULL, 0)) return -EIO; diff --git a/trunk/drivers/mtd/devices/phram.c b/trunk/drivers/mtd/devices/phram.c index 67823de68db6..23423bd00b06 100644 --- a/trunk/drivers/mtd/devices/phram.c +++ b/trunk/drivers/mtd/devices/phram.c @@ -33,33 +33,45 @@ struct phram_mtd_list { static LIST_HEAD(phram_list); + static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) { u_char *start = mtd->priv; + if (instr->addr + instr->len > mtd->size) + return -EINVAL; + memset(start + instr->addr, 0xff, instr->len); - /* - * This'll catch a few races. Free the thing before returning :) + /* This'll catch a few races. Free the thing before returning :) * I don't feel at all ashamed. This kind of thing is possible anyway * with flash, but unlikely. */ + instr->state = MTD_ERASE_DONE; + mtd_erase_callback(instr); + return 0; } static int phram_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys) { + if (from + len > mtd->size) + return -EINVAL; + + /* can we return a physical address with this driver? */ + if (phys) + return -EINVAL; + *virt = mtd->priv + from; *retlen = len; return 0; } -static int phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static void phram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) { - return 0; } static int phram_read(struct mtd_info *mtd, loff_t from, size_t len, @@ -67,7 +79,14 @@ static int phram_read(struct mtd_info *mtd, loff_t from, size_t len, { u_char *start = mtd->priv; + if (from >= mtd->size) + return -EINVAL; + + if (len > mtd->size - from) + len = mtd->size - from; + memcpy(buf, start + from, len); + *retlen = len; return 0; } @@ -77,11 +96,20 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len, { u_char *start = mtd->priv; + if (to >= mtd->size) + return -EINVAL; + + if (len > mtd->size - to) + len = mtd->size - to; + memcpy(start + to, buf, len); + *retlen = len; return 0; } + + static void unregister_devices(void) { struct phram_mtd_list *this, *safe; @@ -114,11 +142,11 @@ static int register_device(char *name, unsigned long start, unsigned long len) new->mtd.name = name; new->mtd.size = len; new->mtd.flags = MTD_CAP_RAM; - new->mtd._erase = phram_erase; - new->mtd._point = phram_point; - new->mtd._unpoint = phram_unpoint; - new->mtd._read = phram_read; - new->mtd._write = phram_write; + new->mtd.erase = phram_erase; + new->mtd.point = phram_point; + new->mtd.unpoint = phram_unpoint; + new->mtd.read = phram_read; + new->mtd.write = phram_write; new->mtd.owner = THIS_MODULE; new->mtd.type = MTD_RAM; new->mtd.erasesize = PAGE_SIZE; @@ -205,17 +233,7 @@ static inline void kill_final_newline(char *str) return 1; \ } while (0) -/* - * This shall contain the module parameter if any. It is of the form: - * - phram=,
, for module case - * - phram.phram=,
, for built-in case - * We leave 64 bytes for the device name, 12 for the address and 12 for the - * size. - * Example: phram.phram=rootfs,0xa0000000,512Mi - */ -static __initdata char phram_paramline[64+12+12]; - -static int __init phram_setup(const char *val) +static int phram_setup(const char *val, struct kernel_param *kp) { char buf[64+12+12], *str = buf; char *token[3]; @@ -264,28 +282,12 @@ static int __init phram_setup(const char *val) return ret; } -static int __init phram_param_call(const char *val, struct kernel_param *kp) -{ - /* - * This function is always called before 'init_phram()', whether - * built-in or module. - */ - if (strlen(val) >= sizeof(phram_paramline)) - return -ENOSPC; - strcpy(phram_paramline, val); - - return 0; -} - -module_param_call(phram, phram_param_call, NULL, NULL, 000); +module_param_call(phram, phram_setup, NULL, NULL, 000); MODULE_PARM_DESC(phram, "Memory region to map. \"phram=,,\""); static int __init init_phram(void) { - if (phram_paramline[0]) - return phram_setup(phram_paramline); - return 0; } diff --git a/trunk/drivers/mtd/devices/pmc551.c b/trunk/drivers/mtd/devices/pmc551.c index 0c51b988e1f8..5d53c5760a6c 100644 --- a/trunk/drivers/mtd/devices/pmc551.c +++ b/trunk/drivers/mtd/devices/pmc551.c @@ -94,48 +94,12 @@ #include #include #include -#include -#define PMC551_VERSION \ - "Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n" - -#define PCI_VENDOR_ID_V3_SEMI 0x11b0 -#define PCI_DEVICE_ID_V3_SEMI_V370PDC 0x0200 - -#define PMC551_PCI_MEM_MAP0 0x50 -#define PMC551_PCI_MEM_MAP1 0x54 -#define PMC551_PCI_MEM_MAP_MAP_ADDR_MASK 0x3ff00000 -#define PMC551_PCI_MEM_MAP_APERTURE_MASK 0x000000f0 -#define PMC551_PCI_MEM_MAP_REG_EN 0x00000002 -#define PMC551_PCI_MEM_MAP_ENABLE 0x00000001 - -#define PMC551_SDRAM_MA 0x60 -#define PMC551_SDRAM_CMD 0x62 -#define PMC551_DRAM_CFG 0x64 -#define PMC551_SYS_CTRL_REG 0x78 - -#define PMC551_DRAM_BLK0 0x68 -#define PMC551_DRAM_BLK1 0x6c -#define PMC551_DRAM_BLK2 0x70 -#define PMC551_DRAM_BLK3 0x74 -#define PMC551_DRAM_BLK_GET_SIZE(x) (524288 << ((x >> 4) & 0x0f)) -#define PMC551_DRAM_BLK_SET_COL_MUX(x, v) (((x) & ~0x00007000) | (((v) & 0x7) << 12)) -#define PMC551_DRAM_BLK_SET_ROW_MUX(x, v) (((x) & ~0x00000f00) | (((v) & 0xf) << 8)) - -struct mypriv { - struct pci_dev *dev; - u_char *start; - u32 base_map0; - u32 curr_map0; - u32 asize; - struct mtd_info *nextpmc551; -}; +#include +#include static struct mtd_info *pmc551list; -static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys); - static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr) { struct mypriv *priv = mtd->priv; @@ -151,6 +115,16 @@ static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr) #endif end = instr->addr + instr->len - 1; + + /* Is it past the end? */ + if (end > mtd->size) { +#ifdef CONFIG_MTD_PMC551_DEBUG + printk(KERN_DEBUG "pmc551_erase() out of bounds (%ld > %ld)\n", + (long)end, (long)mtd->size); +#endif + return -EINVAL; + } + eoff_hi = end & ~(priv->asize - 1); soff_hi = instr->addr & ~(priv->asize - 1); eoff_lo = end & (priv->asize - 1); @@ -204,6 +178,18 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, printk(KERN_DEBUG "pmc551_point(%ld, %ld)\n", (long)from, (long)len); #endif + if (from + len > mtd->size) { +#ifdef CONFIG_MTD_PMC551_DEBUG + printk(KERN_DEBUG "pmc551_point() out of bounds (%ld > %ld)\n", + (long)from + len, (long)mtd->size); +#endif + return -EINVAL; + } + + /* can we return a physical address with this driver? */ + if (phys) + return -EINVAL; + soff_hi = from & ~(priv->asize - 1); soff_lo = from & (priv->asize - 1); @@ -219,12 +205,11 @@ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, return 0; } -static int pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static void pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len) { #ifdef CONFIG_MTD_PMC551_DEBUG printk(KERN_DEBUG "pmc551_unpoint()\n"); #endif - return 0; } static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len, @@ -243,6 +228,16 @@ static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len, #endif end = from + len - 1; + + /* Is it past the end? */ + if (end > mtd->size) { +#ifdef CONFIG_MTD_PMC551_DEBUG + printk(KERN_DEBUG "pmc551_read() out of bounds (%ld > %ld)\n", + (long)end, (long)mtd->size); +#endif + return -EINVAL; + } + soff_hi = from & ~(priv->asize - 1); eoff_hi = end & ~(priv->asize - 1); soff_lo = from & (priv->asize - 1); @@ -300,6 +295,16 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len, #endif end = to + len - 1; + /* Is it past the end? or did the u32 wrap? */ + if (end > mtd->size) { +#ifdef CONFIG_MTD_PMC551_DEBUG + printk(KERN_DEBUG "pmc551_write() out of bounds (end: %ld, " + "size: %ld, to: %ld)\n", (long)end, (long)mtd->size, + (long)to); +#endif + return -EINVAL; + } + soff_hi = to & ~(priv->asize - 1); eoff_hi = end & ~(priv->asize - 1); soff_lo = to & (priv->asize - 1); @@ -353,7 +358,7 @@ static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len, * mechanism * returns the size of the memory region found. */ -static int fixup_pmc551(struct pci_dev *dev) +static u32 fixup_pmc551(struct pci_dev *dev) { #ifdef CONFIG_MTD_PMC551_BUGFIX u32 dram_data; @@ -663,7 +668,7 @@ static int __init init_pmc551(void) struct mypriv *priv; int found = 0; struct mtd_info *mtd; - int length = 0; + u32 length = 0; if (msize) { msize = (1 << (ffs(msize) - 1)) << 20; @@ -781,11 +786,11 @@ static int __init init_pmc551(void) mtd->size = msize; mtd->flags = MTD_CAP_RAM; - mtd->_erase = pmc551_erase; - mtd->_read = pmc551_read; - mtd->_write = pmc551_write; - mtd->_point = pmc551_point; - mtd->_unpoint = pmc551_unpoint; + mtd->erase = pmc551_erase; + mtd->read = pmc551_read; + mtd->write = pmc551_write; + mtd->point = pmc551_point; + mtd->unpoint = pmc551_unpoint; mtd->type = MTD_RAM; mtd->name = "PMC551 RAM board"; mtd->erasesize = 0x10000; diff --git a/trunk/drivers/mtd/devices/slram.c b/trunk/drivers/mtd/devices/slram.c index 8f52fc858e48..288594163c22 100644 --- a/trunk/drivers/mtd/devices/slram.c +++ b/trunk/drivers/mtd/devices/slram.c @@ -75,7 +75,7 @@ static slram_mtd_list_t *slram_mtdlist = NULL; static int slram_erase(struct mtd_info *, struct erase_info *); static int slram_point(struct mtd_info *, loff_t, size_t, size_t *, void **, resource_size_t *); -static int slram_unpoint(struct mtd_info *, loff_t, size_t); +static void slram_unpoint(struct mtd_info *, loff_t, size_t); static int slram_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int slram_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); @@ -83,13 +83,21 @@ static int slram_erase(struct mtd_info *mtd, struct erase_info *instr) { slram_priv_t *priv = mtd->priv; + if (instr->addr + instr->len > mtd->size) { + return(-EINVAL); + } + memset(priv->start + instr->addr, 0xff, instr->len); + /* This'll catch a few races. Free the thing before returning :) * I don't feel at all ashamed. This kind of thing is possible anyway * with flash, but unlikely. */ + instr->state = MTD_ERASE_DONE; + mtd_erase_callback(instr); + return(0); } @@ -98,14 +106,20 @@ static int slram_point(struct mtd_info *mtd, loff_t from, size_t len, { slram_priv_t *priv = mtd->priv; + /* can we return a physical address with this driver? */ + if (phys) + return -EINVAL; + + if (from + len > mtd->size) + return -EINVAL; + *virt = priv->start + from; *retlen = len; return(0); } -static int slram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static void slram_unpoint(struct mtd_info *mtd, loff_t from, size_t len) { - return 0; } static int slram_read(struct mtd_info *mtd, loff_t from, size_t len, @@ -113,7 +127,14 @@ static int slram_read(struct mtd_info *mtd, loff_t from, size_t len, { slram_priv_t *priv = mtd->priv; + if (from > mtd->size) + return -EINVAL; + + if (from + len > mtd->size) + len = mtd->size - from; + memcpy(buf, priv->start + from, len); + *retlen = len; return(0); } @@ -123,7 +144,11 @@ static int slram_write(struct mtd_info *mtd, loff_t to, size_t len, { slram_priv_t *priv = mtd->priv; + if (to + len > mtd->size) + return -EINVAL; + memcpy(priv->start + to, buf, len); + *retlen = len; return(0); } @@ -174,11 +199,11 @@ static int register_device(char *name, unsigned long start, unsigned long length (*curmtd)->mtdinfo->name = name; (*curmtd)->mtdinfo->size = length; (*curmtd)->mtdinfo->flags = MTD_CAP_RAM; - (*curmtd)->mtdinfo->_erase = slram_erase; - (*curmtd)->mtdinfo->_point = slram_point; - (*curmtd)->mtdinfo->_unpoint = slram_unpoint; - (*curmtd)->mtdinfo->_read = slram_read; - (*curmtd)->mtdinfo->_write = slram_write; + (*curmtd)->mtdinfo->erase = slram_erase; + (*curmtd)->mtdinfo->point = slram_point; + (*curmtd)->mtdinfo->unpoint = slram_unpoint; + (*curmtd)->mtdinfo->read = slram_read; + (*curmtd)->mtdinfo->write = slram_write; (*curmtd)->mtdinfo->owner = THIS_MODULE; (*curmtd)->mtdinfo->type = MTD_RAM; (*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ; diff --git a/trunk/drivers/mtd/devices/spear_smi.c b/trunk/drivers/mtd/devices/spear_smi.c deleted file mode 100644 index 797d43cd3550..000000000000 --- a/trunk/drivers/mtd/devices/spear_smi.c +++ /dev/null @@ -1,1147 +0,0 @@ -/* - * SMI (Serial Memory Controller) device driver for Serial NOR Flash on - * SPEAr platform - * The serial nor interface is largely based on drivers/mtd/m25p80.c, - * however the SPI interface has been replaced by SMI. - * - * Copyright © 2010 STMicroelectronics. - * Ashish Priyadarshi - * Shiraz Hashim - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* SMI clock rate */ -#define SMI_MAX_CLOCK_FREQ 50000000 /* 50 MHz */ - -/* MAX time out to safely come out of a erase or write busy conditions */ -#define SMI_PROBE_TIMEOUT (HZ / 10) -#define SMI_MAX_TIME_OUT (3 * HZ) - -/* timeout for command completion */ -#define SMI_CMD_TIMEOUT (HZ / 10) - -/* registers of smi */ -#define SMI_CR1 0x0 /* SMI control register 1 */ -#define SMI_CR2 0x4 /* SMI control register 2 */ -#define SMI_SR 0x8 /* SMI status register */ -#define SMI_TR 0xC /* SMI transmit register */ -#define SMI_RR 0x10 /* SMI receive register */ - -/* defines for control_reg 1 */ -#define BANK_EN (0xF << 0) /* enables all banks */ -#define DSEL_TIME (0x6 << 4) /* Deselect time 6 + 1 SMI_CK periods */ -#define SW_MODE (0x1 << 28) /* enables SW Mode */ -#define WB_MODE (0x1 << 29) /* Write Burst Mode */ -#define FAST_MODE (0x1 << 15) /* Fast Mode */ -#define HOLD1 (0x1 << 16) /* Clock Hold period selection */ - -/* defines for control_reg 2 */ -#define SEND (0x1 << 7) /* Send data */ -#define TFIE (0x1 << 8) /* Transmission Flag Interrupt Enable */ -#define WCIE (0x1 << 9) /* Write Complete Interrupt Enable */ -#define RD_STATUS_REG (0x1 << 10) /* reads status reg */ -#define WE (0x1 << 11) /* Write Enable */ - -#define TX_LEN_SHIFT 0 -#define RX_LEN_SHIFT 4 -#define BANK_SHIFT 12 - -/* defines for status register */ -#define SR_WIP 0x1 /* Write in progress */ -#define SR_WEL 0x2 /* Write enable latch */ -#define SR_BP0 0x4 /* Block protect 0 */ -#define SR_BP1 0x8 /* Block protect 1 */ -#define SR_BP2 0x10 /* Block protect 2 */ -#define SR_SRWD 0x80 /* SR write protect */ -#define TFF 0x100 /* Transfer Finished Flag */ -#define WCF 0x200 /* Transfer Finished Flag */ -#define ERF1 0x400 /* Forbidden Write Request */ -#define ERF2 0x800 /* Forbidden Access */ - -#define WM_SHIFT 12 - -/* flash opcodes */ -#define OPCODE_RDID 0x9f /* Read JEDEC ID */ - -/* Flash Device Ids maintenance section */ - -/* data structure to maintain flash ids from different vendors */ -struct flash_device { - char *name; - u8 erase_cmd; - u32 device_id; - u32 pagesize; - unsigned long sectorsize; - unsigned long size_in_bytes; -}; - -#define FLASH_ID(n, es, id, psize, ssize, size) \ -{ \ - .name = n, \ - .erase_cmd = es, \ - .device_id = id, \ - .pagesize = psize, \ - .sectorsize = ssize, \ - .size_in_bytes = size \ -} - -static struct flash_device flash_devices[] = { - FLASH_ID("st m25p16" , 0xd8, 0x00152020, 0x100, 0x10000, 0x200000), - FLASH_ID("st m25p32" , 0xd8, 0x00162020, 0x100, 0x10000, 0x400000), - FLASH_ID("st m25p64" , 0xd8, 0x00172020, 0x100, 0x10000, 0x800000), - FLASH_ID("st m25p128" , 0xd8, 0x00182020, 0x100, 0x40000, 0x1000000), - FLASH_ID("st m25p05" , 0xd8, 0x00102020, 0x80 , 0x8000 , 0x10000), - FLASH_ID("st m25p10" , 0xd8, 0x00112020, 0x80 , 0x8000 , 0x20000), - FLASH_ID("st m25p20" , 0xd8, 0x00122020, 0x100, 0x10000, 0x40000), - FLASH_ID("st m25p40" , 0xd8, 0x00132020, 0x100, 0x10000, 0x80000), - FLASH_ID("st m25p80" , 0xd8, 0x00142020, 0x100, 0x10000, 0x100000), - FLASH_ID("st m45pe10" , 0xd8, 0x00114020, 0x100, 0x10000, 0x20000), - FLASH_ID("st m45pe20" , 0xd8, 0x00124020, 0x100, 0x10000, 0x40000), - FLASH_ID("st m45pe40" , 0xd8, 0x00134020, 0x100, 0x10000, 0x80000), - FLASH_ID("st m45pe80" , 0xd8, 0x00144020, 0x100, 0x10000, 0x100000), - FLASH_ID("sp s25fl004" , 0xd8, 0x00120201, 0x100, 0x10000, 0x80000), - FLASH_ID("sp s25fl008" , 0xd8, 0x00130201, 0x100, 0x10000, 0x100000), - FLASH_ID("sp s25fl016" , 0xd8, 0x00140201, 0x100, 0x10000, 0x200000), - FLASH_ID("sp s25fl032" , 0xd8, 0x00150201, 0x100, 0x10000, 0x400000), - FLASH_ID("sp s25fl064" , 0xd8, 0x00160201, 0x100, 0x10000, 0x800000), - FLASH_ID("atmel 25f512" , 0x52, 0x0065001F, 0x80 , 0x8000 , 0x10000), - FLASH_ID("atmel 25f1024" , 0x52, 0x0060001F, 0x100, 0x8000 , 0x20000), - FLASH_ID("atmel 25f2048" , 0x52, 0x0063001F, 0x100, 0x10000, 0x40000), - FLASH_ID("atmel 25f4096" , 0x52, 0x0064001F, 0x100, 0x10000, 0x80000), - FLASH_ID("atmel 25fs040" , 0xd7, 0x0004661F, 0x100, 0x10000, 0x80000), - FLASH_ID("mac 25l512" , 0xd8, 0x001020C2, 0x010, 0x10000, 0x10000), - FLASH_ID("mac 25l1005" , 0xd8, 0x001120C2, 0x010, 0x10000, 0x20000), - FLASH_ID("mac 25l2005" , 0xd8, 0x001220C2, 0x010, 0x10000, 0x40000), - FLASH_ID("mac 25l4005" , 0xd8, 0x001320C2, 0x010, 0x10000, 0x80000), - FLASH_ID("mac 25l4005a" , 0xd8, 0x001320C2, 0x010, 0x10000, 0x80000), - FLASH_ID("mac 25l8005" , 0xd8, 0x001420C2, 0x010, 0x10000, 0x100000), - FLASH_ID("mac 25l1605" , 0xd8, 0x001520C2, 0x100, 0x10000, 0x200000), - FLASH_ID("mac 25l1605a" , 0xd8, 0x001520C2, 0x010, 0x10000, 0x200000), - FLASH_ID("mac 25l3205" , 0xd8, 0x001620C2, 0x100, 0x10000, 0x400000), - FLASH_ID("mac 25l3205a" , 0xd8, 0x001620C2, 0x100, 0x10000, 0x400000), - FLASH_ID("mac 25l6405" , 0xd8, 0x001720C2, 0x100, 0x10000, 0x800000), -}; - -/* Define spear specific structures */ - -struct spear_snor_flash; - -/** - * struct spear_smi - Structure for SMI Device - * - * @clk: functional clock - * @status: current status register of SMI. - * @clk_rate: functional clock rate of SMI (default: SMI_MAX_CLOCK_FREQ) - * @lock: lock to prevent parallel access of SMI. - * @io_base: base address for registers of SMI. - * @pdev: platform device - * @cmd_complete: queue to wait for command completion of NOR-flash. - * @num_flashes: number of flashes actually present on board. - * @flash: separate structure for each Serial NOR-flash attached to SMI. - */ -struct spear_smi { - struct clk *clk; - u32 status; - unsigned long clk_rate; - struct mutex lock; - void __iomem *io_base; - struct platform_device *pdev; - wait_queue_head_t cmd_complete; - u32 num_flashes; - struct spear_snor_flash *flash[MAX_NUM_FLASH_CHIP]; -}; - -/** - * struct spear_snor_flash - Structure for Serial NOR Flash - * - * @bank: Bank number(0, 1, 2, 3) for each NOR-flash. - * @dev_id: Device ID of NOR-flash. - * @lock: lock to manage flash read, write and erase operations - * @mtd: MTD info for each NOR-flash. - * @num_parts: Total number of partition in each bank of NOR-flash. - * @parts: Partition info for each bank of NOR-flash. - * @page_size: Page size of NOR-flash. - * @base_addr: Base address of NOR-flash. - * @erase_cmd: erase command may vary on different flash types - * @fast_mode: flash supports read in fast mode - */ -struct spear_snor_flash { - u32 bank; - u32 dev_id; - struct mutex lock; - struct mtd_info mtd; - u32 num_parts; - struct mtd_partition *parts; - u32 page_size; - void __iomem *base_addr; - u8 erase_cmd; - u8 fast_mode; -}; - -static inline struct spear_snor_flash *get_flash_data(struct mtd_info *mtd) -{ - return container_of(mtd, struct spear_snor_flash, mtd); -} - -/** - * spear_smi_read_sr - Read status register of flash through SMI - * @dev: structure of SMI information. - * @bank: bank to which flash is connected - * - * This routine will return the status register of the flash chip present at the - * given bank. - */ -static int spear_smi_read_sr(struct spear_smi *dev, u32 bank) -{ - int ret; - u32 ctrlreg1; - - mutex_lock(&dev->lock); - dev->status = 0; /* Will be set in interrupt handler */ - - ctrlreg1 = readl(dev->io_base + SMI_CR1); - /* program smi in hw mode */ - writel(ctrlreg1 & ~(SW_MODE | WB_MODE), dev->io_base + SMI_CR1); - - /* performing a rsr instruction in hw mode */ - writel((bank << BANK_SHIFT) | RD_STATUS_REG | TFIE, - dev->io_base + SMI_CR2); - - /* wait for tff */ - ret = wait_event_interruptible_timeout(dev->cmd_complete, - dev->status & TFF, SMI_CMD_TIMEOUT); - - /* copy dev->status (lower 16 bits) in order to release lock */ - if (ret > 0) - ret = dev->status & 0xffff; - else - ret = -EIO; - - /* restore the ctrl regs state */ - writel(ctrlreg1, dev->io_base + SMI_CR1); - writel(0, dev->io_base + SMI_CR2); - mutex_unlock(&dev->lock); - - return ret; -} - -/** - * spear_smi_wait_till_ready - wait till flash is ready - * @dev: structure of SMI information. - * @bank: flash corresponding to this bank - * @timeout: timeout for busy wait condition - * - * This routine checks for WIP (write in progress) bit in Status register - * If successful the routine returns 0 else -EBUSY - */ -static int spear_smi_wait_till_ready(struct spear_smi *dev, u32 bank, - unsigned long timeout) -{ - unsigned long finish; - int status; - - finish = jiffies + timeout; - do { - status = spear_smi_read_sr(dev, bank); - if (status < 0) - continue; /* try till timeout */ - else if (!(status & SR_WIP)) - return 0; - - cond_resched(); - } while (!time_after_eq(jiffies, finish)); - - dev_err(&dev->pdev->dev, "smi controller is busy, timeout\n"); - return status; -} - -/** - * spear_smi_int_handler - SMI Interrupt Handler. - * @irq: irq number - * @dev_id: structure of SMI device, embedded in dev_id. - * - * The handler clears all interrupt conditions and records the status in - * dev->status which is used by the driver later. - */ -static irqreturn_t spear_smi_int_handler(int irq, void *dev_id) -{ - u32 status = 0; - struct spear_smi *dev = dev_id; - - status = readl(dev->io_base + SMI_SR); - - if (unlikely(!status)) - return IRQ_NONE; - - /* clear all interrupt conditions */ - writel(0, dev->io_base + SMI_SR); - - /* copy the status register in dev->status */ - dev->status |= status; - - /* send the completion */ - wake_up_interruptible(&dev->cmd_complete); - - return IRQ_HANDLED; -} - -/** - * spear_smi_hw_init - initializes the smi controller. - * @dev: structure of smi device - * - * this routine initializes the smi controller wit the default values - */ -static void spear_smi_hw_init(struct spear_smi *dev) -{ - unsigned long rate = 0; - u32 prescale = 0; - u32 val; - - rate = clk_get_rate(dev->clk); - - /* functional clock of smi */ - prescale = DIV_ROUND_UP(rate, dev->clk_rate); - - /* - * setting the standard values, fast mode, prescaler for - * SMI_MAX_CLOCK_FREQ (50MHz) operation and bank enable - */ - val = HOLD1 | BANK_EN | DSEL_TIME | (prescale << 8); - - mutex_lock(&dev->lock); - writel(val, dev->io_base + SMI_CR1); - mutex_unlock(&dev->lock); -} - -/** - * get_flash_index - match chip id from a flash list. - * @flash_id: a valid nor flash chip id obtained from board. - * - * try to validate the chip id by matching from a list, if not found then simply - * returns negative. In case of success returns index in to the flash devices - * array. - */ -static int get_flash_index(u32 flash_id) -{ - int index; - - /* Matches chip-id to entire list of 'serial-nor flash' ids */ - for (index = 0; index < ARRAY_SIZE(flash_devices); index++) { - if (flash_devices[index].device_id == flash_id) - return index; - } - - /* Memory chip is not listed and not supported */ - return -ENODEV; -} - -/** - * spear_smi_write_enable - Enable the flash to do write operation - * @dev: structure of SMI device - * @bank: enable write for flash connected to this bank - * - * Set write enable latch with Write Enable command. - * Returns 0 on success. - */ -static int spear_smi_write_enable(struct spear_smi *dev, u32 bank) -{ - int ret; - u32 ctrlreg1; - - mutex_lock(&dev->lock); - dev->status = 0; /* Will be set in interrupt handler */ - - ctrlreg1 = readl(dev->io_base + SMI_CR1); - /* program smi in h/w mode */ - writel(ctrlreg1 & ~SW_MODE, dev->io_base + SMI_CR1); - - /* give the flash, write enable command */ - writel((bank << BANK_SHIFT) | WE | TFIE, dev->io_base + SMI_CR2); - - ret = wait_event_interruptible_timeout(dev->cmd_complete, - dev->status & TFF, SMI_CMD_TIMEOUT); - - /* restore the ctrl regs state */ - writel(ctrlreg1, dev->io_base + SMI_CR1); - writel(0, dev->io_base + SMI_CR2); - - if (ret <= 0) { - ret = -EIO; - dev_err(&dev->pdev->dev, - "smi controller failed on write enable\n"); - } else { - /* check whether write mode status is set for required bank */ - if (dev->status & (1 << (bank + WM_SHIFT))) - ret = 0; - else { - dev_err(&dev->pdev->dev, "couldn't enable write\n"); - ret = -EIO; - } - } - - mutex_unlock(&dev->lock); - return ret; -} - -static inline u32 -get_sector_erase_cmd(struct spear_snor_flash *flash, u32 offset) -{ - u32 cmd; - u8 *x = (u8 *)&cmd; - - x[0] = flash->erase_cmd; - x[1] = offset >> 16; - x[2] = offset >> 8; - x[3] = offset; - - return cmd; -} - -/** - * spear_smi_erase_sector - erase one sector of flash - * @dev: structure of SMI information - * @command: erase command to be send - * @bank: bank to which this command needs to be send - * @bytes: size of command - * - * Erase one sector of flash memory at offset ``offset'' which is any - * address within the sector which should be erased. - * Returns 0 if successful, non-zero otherwise. - */ -static int spear_smi_erase_sector(struct spear_smi *dev, - u32 bank, u32 command, u32 bytes) -{ - u32 ctrlreg1 = 0; - int ret; - - ret = spear_smi_wait_till_ready(dev, bank, SMI_MAX_TIME_OUT); - if (ret) - return ret; - - ret = spear_smi_write_enable(dev, bank); - if (ret) - return ret; - - mutex_lock(&dev->lock); - - ctrlreg1 = readl(dev->io_base + SMI_CR1); - writel((ctrlreg1 | SW_MODE) & ~WB_MODE, dev->io_base + SMI_CR1); - - /* send command in sw mode */ - writel(command, dev->io_base + SMI_TR); - - writel((bank << BANK_SHIFT) | SEND | TFIE | (bytes << TX_LEN_SHIFT), - dev->io_base + SMI_CR2); - - ret = wait_event_interruptible_timeout(dev->cmd_complete, - dev->status & TFF, SMI_CMD_TIMEOUT); - - if (ret <= 0) { - ret = -EIO; - dev_err(&dev->pdev->dev, "sector erase failed\n"); - } else - ret = 0; /* success */ - - /* restore ctrl regs */ - writel(ctrlreg1, dev->io_base + SMI_CR1); - writel(0, dev->io_base + SMI_CR2); - - mutex_unlock(&dev->lock); - return ret; -} - -/** - * spear_mtd_erase - perform flash erase operation as requested by user - * @mtd: Provides the memory characteristics - * @e_info: Provides the erase information - * - * Erase an address range on the flash chip. The address range may extend - * one or more erase sectors. Return an error is there is a problem erasing. - */ -static int spear_mtd_erase(struct mtd_info *mtd, struct erase_info *e_info) -{ - struct spear_snor_flash *flash = get_flash_data(mtd); - struct spear_smi *dev = mtd->priv; - u32 addr, command, bank; - int len, ret; - - if (!flash || !dev) - return -ENODEV; - - bank = flash->bank; - if (bank > dev->num_flashes - 1) { - dev_err(&dev->pdev->dev, "Invalid Bank Num"); - return -EINVAL; - } - - addr = e_info->addr; - len = e_info->len; - - mutex_lock(&flash->lock); - - /* now erase sectors in loop */ - while (len) { - command = get_sector_erase_cmd(flash, addr); - /* preparing the command for flash */ - ret = spear_smi_erase_sector(dev, bank, command, 4); - if (ret) { - e_info->state = MTD_ERASE_FAILED; - mutex_unlock(&flash->lock); - return ret; - } - addr += mtd->erasesize; - len -= mtd->erasesize; - } - - mutex_unlock(&flash->lock); - e_info->state = MTD_ERASE_DONE; - mtd_erase_callback(e_info); - - return 0; -} - -/** - * spear_mtd_read - performs flash read operation as requested by the user - * @mtd: MTD information of the memory bank - * @from: Address from which to start read - * @len: Number of bytes to be read - * @retlen: Fills the Number of bytes actually read - * @buf: Fills this after reading - * - * Read an address range from the flash chip. The address range - * may be any size provided it is within the physical boundaries. - * Returns 0 on success, non zero otherwise - */ -static int spear_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u8 *buf) -{ - struct spear_snor_flash *flash = get_flash_data(mtd); - struct spear_smi *dev = mtd->priv; - void *src; - u32 ctrlreg1, val; - int ret; - - if (!flash || !dev) - return -ENODEV; - - if (flash->bank > dev->num_flashes - 1) { - dev_err(&dev->pdev->dev, "Invalid Bank Num"); - return -EINVAL; - } - - /* select address as per bank number */ - src = flash->base_addr + from; - - mutex_lock(&flash->lock); - - /* wait till previous write/erase is done. */ - ret = spear_smi_wait_till_ready(dev, flash->bank, SMI_MAX_TIME_OUT); - if (ret) { - mutex_unlock(&flash->lock); - return ret; - } - - mutex_lock(&dev->lock); - /* put smi in hw mode not wbt mode */ - ctrlreg1 = val = readl(dev->io_base + SMI_CR1); - val &= ~(SW_MODE | WB_MODE); - if (flash->fast_mode) - val |= FAST_MODE; - - writel(val, dev->io_base + SMI_CR1); - - memcpy_fromio(buf, (u8 *)src, len); - - /* restore ctrl reg1 */ - writel(ctrlreg1, dev->io_base + SMI_CR1); - mutex_unlock(&dev->lock); - - *retlen = len; - mutex_unlock(&flash->lock); - - return 0; -} - -static inline int spear_smi_cpy_toio(struct spear_smi *dev, u32 bank, - void *dest, const void *src, size_t len) -{ - int ret; - u32 ctrlreg1; - - /* wait until finished previous write command. */ - ret = spear_smi_wait_till_ready(dev, bank, SMI_MAX_TIME_OUT); - if (ret) - return ret; - - /* put smi in write enable */ - ret = spear_smi_write_enable(dev, bank); - if (ret) - return ret; - - /* put smi in hw, write burst mode */ - mutex_lock(&dev->lock); - - ctrlreg1 = readl(dev->io_base + SMI_CR1); - writel((ctrlreg1 | WB_MODE) & ~SW_MODE, dev->io_base + SMI_CR1); - - memcpy_toio(dest, src, len); - - writel(ctrlreg1, dev->io_base + SMI_CR1); - - mutex_unlock(&dev->lock); - return 0; -} - -/** - * spear_mtd_write - performs write operation as requested by the user. - * @mtd: MTD information of the memory bank. - * @to: Address to write. - * @len: Number of bytes to be written. - * @retlen: Number of bytes actually wrote. - * @buf: Buffer from which the data to be taken. - * - * Write an address range to the flash chip. Data must be written in - * flash_page_size chunks. The address range may be any size provided - * it is within the physical boundaries. - * Returns 0 on success, non zero otherwise - */ -static int spear_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u8 *buf) -{ - struct spear_snor_flash *flash = get_flash_data(mtd); - struct spear_smi *dev = mtd->priv; - void *dest; - u32 page_offset, page_size; - int ret; - - if (!flash || !dev) - return -ENODEV; - - if (flash->bank > dev->num_flashes - 1) { - dev_err(&dev->pdev->dev, "Invalid Bank Num"); - return -EINVAL; - } - - /* select address as per bank number */ - dest = flash->base_addr + to; - mutex_lock(&flash->lock); - - page_offset = (u32)to % flash->page_size; - - /* do if all the bytes fit onto one page */ - if (page_offset + len <= flash->page_size) { - ret = spear_smi_cpy_toio(dev, flash->bank, dest, buf, len); - if (!ret) - *retlen += len; - } else { - u32 i; - - /* the size of data remaining on the first page */ - page_size = flash->page_size - page_offset; - - ret = spear_smi_cpy_toio(dev, flash->bank, dest, buf, - page_size); - if (ret) - goto err_write; - else - *retlen += page_size; - - /* write everything in pagesize chunks */ - for (i = page_size; i < len; i += page_size) { - page_size = len - i; - if (page_size > flash->page_size) - page_size = flash->page_size; - - ret = spear_smi_cpy_toio(dev, flash->bank, dest + i, - buf + i, page_size); - if (ret) - break; - else - *retlen += page_size; - } - } - -err_write: - mutex_unlock(&flash->lock); - - return ret; -} - -/** - * spear_smi_probe_flash - Detects the NOR Flash chip. - * @dev: structure of SMI information. - * @bank: bank on which flash must be probed - * - * This routine will check whether there exists a flash chip on a given memory - * bank ID. - * Return index of the probed flash in flash devices structure - */ -static int spear_smi_probe_flash(struct spear_smi *dev, u32 bank) -{ - int ret; - u32 val = 0; - - ret = spear_smi_wait_till_ready(dev, bank, SMI_PROBE_TIMEOUT); - if (ret) - return ret; - - mutex_lock(&dev->lock); - - dev->status = 0; /* Will be set in interrupt handler */ - /* put smi in sw mode */ - val = readl(dev->io_base + SMI_CR1); - writel(val | SW_MODE, dev->io_base + SMI_CR1); - - /* send readid command in sw mode */ - writel(OPCODE_RDID, dev->io_base + SMI_TR); - - val = (bank << BANK_SHIFT) | SEND | (1 << TX_LEN_SHIFT) | - (3 << RX_LEN_SHIFT) | TFIE; - writel(val, dev->io_base + SMI_CR2); - - /* wait for TFF */ - ret = wait_event_interruptible_timeout(dev->cmd_complete, - dev->status & TFF, SMI_CMD_TIMEOUT); - if (ret <= 0) { - ret = -ENODEV; - goto err_probe; - } - - /* get memory chip id */ - val = readl(dev->io_base + SMI_RR); - val &= 0x00ffffff; - ret = get_flash_index(val); - -err_probe: - /* clear sw mode */ - val = readl(dev->io_base + SMI_CR1); - writel(val & ~SW_MODE, dev->io_base + SMI_CR1); - - mutex_unlock(&dev->lock); - return ret; -} - - -#ifdef CONFIG_OF -static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev, - struct device_node *np) -{ - struct spear_smi_plat_data *pdata = dev_get_platdata(&pdev->dev); - struct device_node *pp = NULL; - const __be32 *addr; - u32 val; - int len; - int i = 0; - - if (!np) - return -ENODEV; - - of_property_read_u32(np, "clock-rate", &val); - pdata->clk_rate = val; - - pdata->board_flash_info = devm_kzalloc(&pdev->dev, - sizeof(*pdata->board_flash_info), - GFP_KERNEL); - - /* Fill structs for each subnode (flash device) */ - while ((pp = of_get_next_child(np, pp))) { - struct spear_smi_flash_info *flash_info; - - flash_info = &pdata->board_flash_info[i]; - pdata->np[i] = pp; - - /* Read base-addr and size from DT */ - addr = of_get_property(pp, "reg", &len); - pdata->board_flash_info->mem_base = be32_to_cpup(&addr[0]); - pdata->board_flash_info->size = be32_to_cpup(&addr[1]); - - if (of_get_property(pp, "st,smi-fast-mode", NULL)) - pdata->board_flash_info->fast_mode = 1; - - i++; - } - - pdata->num_flashes = i; - - return 0; -} -#else -static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev, - struct device_node *np) -{ - return -ENOSYS; -} -#endif - -static int spear_smi_setup_banks(struct platform_device *pdev, - u32 bank, struct device_node *np) -{ - struct spear_smi *dev = platform_get_drvdata(pdev); - struct mtd_part_parser_data ppdata = {}; - struct spear_smi_flash_info *flash_info; - struct spear_smi_plat_data *pdata; - struct spear_snor_flash *flash; - struct mtd_partition *parts = NULL; - int count = 0; - int flash_index; - int ret = 0; - - pdata = dev_get_platdata(&pdev->dev); - if (bank > pdata->num_flashes - 1) - return -EINVAL; - - flash_info = &pdata->board_flash_info[bank]; - if (!flash_info) - return -ENODEV; - - flash = kzalloc(sizeof(*flash), GFP_ATOMIC); - if (!flash) - return -ENOMEM; - flash->bank = bank; - flash->fast_mode = flash_info->fast_mode ? 1 : 0; - mutex_init(&flash->lock); - - /* verify whether nor flash is really present on board */ - flash_index = spear_smi_probe_flash(dev, bank); - if (flash_index < 0) { - dev_info(&dev->pdev->dev, "smi-nor%d not found\n", bank); - ret = flash_index; - goto err_probe; - } - /* map the memory for nor flash chip */ - flash->base_addr = ioremap(flash_info->mem_base, flash_info->size); - if (!flash->base_addr) { - ret = -EIO; - goto err_probe; - } - - dev->flash[bank] = flash; - flash->mtd.priv = dev; - - if (flash_info->name) - flash->mtd.name = flash_info->name; - else - flash->mtd.name = flash_devices[flash_index].name; - - flash->mtd.type = MTD_NORFLASH; - flash->mtd.writesize = 1; - flash->mtd.flags = MTD_CAP_NORFLASH; - flash->mtd.size = flash_info->size; - flash->mtd.erasesize = flash_devices[flash_index].sectorsize; - flash->page_size = flash_devices[flash_index].pagesize; - flash->mtd.writebufsize = flash->page_size; - flash->erase_cmd = flash_devices[flash_index].erase_cmd; - flash->mtd._erase = spear_mtd_erase; - flash->mtd._read = spear_mtd_read; - flash->mtd._write = spear_mtd_write; - flash->dev_id = flash_devices[flash_index].device_id; - - dev_info(&dev->pdev->dev, "mtd .name=%s .size=%llx(%lluM)\n", - flash->mtd.name, flash->mtd.size, - flash->mtd.size / (1024 * 1024)); - - dev_info(&dev->pdev->dev, ".erasesize = 0x%x(%uK)\n", - flash->mtd.erasesize, flash->mtd.erasesize / 1024); - -#ifndef CONFIG_OF - if (flash_info->partitions) { - parts = flash_info->partitions; - count = flash_info->nr_partitions; - } -#endif - ppdata.of_node = np; - - ret = mtd_device_parse_register(&flash->mtd, NULL, &ppdata, parts, - count); - if (ret) { - dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret); - goto err_map; - } - - return 0; - -err_map: - iounmap(flash->base_addr); - -err_probe: - kfree(flash); - return ret; -} - -/** - * spear_smi_probe - Entry routine - * @pdev: platform device structure - * - * This is the first routine which gets invoked during booting and does all - * initialization/allocation work. The routine looks for available memory banks, - * and do proper init for any found one. - * Returns 0 on success, non zero otherwise - */ -static int __devinit spear_smi_probe(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - struct spear_smi_plat_data *pdata = NULL; - struct spear_smi *dev; - struct resource *smi_base; - int irq, ret = 0; - int i; - - if (np) { - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - pr_err("%s: ERROR: no memory", __func__); - ret = -ENOMEM; - goto err; - } - pdev->dev.platform_data = pdata; - ret = spear_smi_probe_config_dt(pdev, np); - if (ret) { - ret = -ENODEV; - dev_err(&pdev->dev, "no platform data\n"); - goto err; - } - } else { - pdata = dev_get_platdata(&pdev->dev); - if (pdata < 0) { - ret = -ENODEV; - dev_err(&pdev->dev, "no platform data\n"); - goto err; - } - } - - smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!smi_base) { - ret = -ENODEV; - dev_err(&pdev->dev, "invalid smi base address\n"); - goto err; - } - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - ret = -ENODEV; - dev_err(&pdev->dev, "invalid smi irq\n"); - goto err; - } - - dev = kzalloc(sizeof(*dev), GFP_ATOMIC); - if (!dev) { - ret = -ENOMEM; - dev_err(&pdev->dev, "mem alloc fail\n"); - goto err; - } - - smi_base = request_mem_region(smi_base->start, resource_size(smi_base), - pdev->name); - if (!smi_base) { - ret = -EBUSY; - dev_err(&pdev->dev, "request mem region fail\n"); - goto err_mem; - } - - dev->io_base = ioremap(smi_base->start, resource_size(smi_base)); - if (!dev->io_base) { - ret = -EIO; - dev_err(&pdev->dev, "ioremap fail\n"); - goto err_ioremap; - } - - dev->pdev = pdev; - dev->clk_rate = pdata->clk_rate; - - if (dev->clk_rate < 0 || dev->clk_rate > SMI_MAX_CLOCK_FREQ) - dev->clk_rate = SMI_MAX_CLOCK_FREQ; - - dev->num_flashes = pdata->num_flashes; - - if (dev->num_flashes > MAX_NUM_FLASH_CHIP) { - dev_err(&pdev->dev, "exceeding max number of flashes\n"); - dev->num_flashes = MAX_NUM_FLASH_CHIP; - } - - dev->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(dev->clk)) { - ret = PTR_ERR(dev->clk); - goto err_clk; - } - - ret = clk_enable(dev->clk); - if (ret) - goto err_clk_enable; - - ret = request_irq(irq, spear_smi_int_handler, 0, pdev->name, dev); - if (ret) { - dev_err(&dev->pdev->dev, "SMI IRQ allocation failed\n"); - goto err_irq; - } - - mutex_init(&dev->lock); - init_waitqueue_head(&dev->cmd_complete); - spear_smi_hw_init(dev); - platform_set_drvdata(pdev, dev); - - /* loop for each serial nor-flash which is connected to smi */ - for (i = 0; i < dev->num_flashes; i++) { - ret = spear_smi_setup_banks(pdev, i, pdata->np[i]); - if (ret) { - dev_err(&dev->pdev->dev, "bank setup failed\n"); - goto err_bank_setup; - } - } - - return 0; - -err_bank_setup: - free_irq(irq, dev); - platform_set_drvdata(pdev, NULL); -err_irq: - clk_disable(dev->clk); -err_clk_enable: - clk_put(dev->clk); -err_clk: - iounmap(dev->io_base); -err_ioremap: - release_mem_region(smi_base->start, resource_size(smi_base)); -err_mem: - kfree(dev); -err: - return ret; -} - -/** - * spear_smi_remove - Exit routine - * @pdev: platform device structure - * - * free all allocations and delete the partitions. - */ -static int __devexit spear_smi_remove(struct platform_device *pdev) -{ - struct spear_smi *dev; - struct spear_smi_plat_data *pdata; - struct spear_snor_flash *flash; - struct resource *smi_base; - int ret; - int i, irq; - - dev = platform_get_drvdata(pdev); - if (!dev) { - dev_err(&pdev->dev, "dev is null\n"); - return -ENODEV; - } - - pdata = dev_get_platdata(&pdev->dev); - - /* clean up for all nor flash */ - for (i = 0; i < dev->num_flashes; i++) { - flash = dev->flash[i]; - if (!flash) - continue; - - /* clean up mtd stuff */ - ret = mtd_device_unregister(&flash->mtd); - if (ret) - dev_err(&pdev->dev, "error removing mtd\n"); - - iounmap(flash->base_addr); - kfree(flash); - } - - irq = platform_get_irq(pdev, 0); - free_irq(irq, dev); - - clk_disable(dev->clk); - clk_put(dev->clk); - iounmap(dev->io_base); - kfree(dev); - - smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(smi_base->start, resource_size(smi_base)); - platform_set_drvdata(pdev, NULL); - - return 0; -} - -int spear_smi_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct spear_smi *dev = platform_get_drvdata(pdev); - - if (dev && dev->clk) - clk_disable(dev->clk); - - return 0; -} - -int spear_smi_resume(struct platform_device *pdev) -{ - struct spear_smi *dev = platform_get_drvdata(pdev); - int ret = -EPERM; - - if (dev && dev->clk) - ret = clk_enable(dev->clk); - - if (!ret) - spear_smi_hw_init(dev); - return ret; -} - -#ifdef CONFIG_OF -static const struct of_device_id spear_smi_id_table[] = { - { .compatible = "st,spear600-smi" }, - {} -}; -MODULE_DEVICE_TABLE(of, spear_smi_id_table); -#endif - -static struct platform_driver spear_smi_driver = { - .driver = { - .name = "smi", - .bus = &platform_bus_type, - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(spear_smi_id_table), - }, - .probe = spear_smi_probe, - .remove = __devexit_p(spear_smi_remove), - .suspend = spear_smi_suspend, - .resume = spear_smi_resume, -}; - -static int spear_smi_init(void) -{ - return platform_driver_register(&spear_smi_driver); -} -module_init(spear_smi_init); - -static void spear_smi_exit(void) -{ - platform_driver_unregister(&spear_smi_driver); -} -module_exit(spear_smi_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim "); -MODULE_DESCRIPTION("MTD SMI driver for serial nor flash chips"); diff --git a/trunk/drivers/mtd/devices/sst25l.c b/trunk/drivers/mtd/devices/sst25l.c index ab8a2f4c8d60..5fc198350b94 100644 --- a/trunk/drivers/mtd/devices/sst25l.c +++ b/trunk/drivers/mtd/devices/sst25l.c @@ -175,6 +175,9 @@ static int sst25l_erase(struct mtd_info *mtd, struct erase_info *instr) int err; /* Sanity checks */ + if (instr->addr + instr->len > flash->mtd.size) + return -EINVAL; + if ((uint32_t)instr->len % mtd->erasesize) return -EINVAL; @@ -220,6 +223,16 @@ static int sst25l_read(struct mtd_info *mtd, loff_t from, size_t len, unsigned char command[4]; int ret; + /* Sanity checking */ + if (len == 0) + return 0; + + if (from + len > flash->mtd.size) + return -EINVAL; + + if (retlen) + *retlen = 0; + spi_message_init(&message); memset(&transfer, 0, sizeof(transfer)); @@ -261,6 +274,13 @@ static int sst25l_write(struct mtd_info *mtd, loff_t to, size_t len, int i, j, ret, bytes, copied = 0; unsigned char command[5]; + /* Sanity checks */ + if (!len) + return 0; + + if (to + len > flash->mtd.size) + return -EINVAL; + if ((uint32_t)to % mtd->writesize) return -EINVAL; @@ -382,11 +402,10 @@ static int __devinit sst25l_probe(struct spi_device *spi) flash->mtd.flags = MTD_CAP_NORFLASH; flash->mtd.erasesize = flash_info->erase_size; flash->mtd.writesize = flash_info->page_size; - flash->mtd.writebufsize = flash_info->page_size; flash->mtd.size = flash_info->page_size * flash_info->nr_pages; - flash->mtd._erase = sst25l_erase; - flash->mtd._read = sst25l_read; - flash->mtd._write = sst25l_write; + flash->mtd.erase = sst25l_erase; + flash->mtd.read = sst25l_read; + flash->mtd.write = sst25l_write; dev_info(&spi->dev, "%s (%lld KiB)\n", flash_info->name, (long long)flash->mtd.size >> 10); @@ -399,9 +418,9 @@ static int __devinit sst25l_probe(struct spi_device *spi) flash->mtd.numeraseregions); - ret = mtd_device_parse_register(&flash->mtd, NULL, NULL, - data ? data->parts : NULL, - data ? data->nr_parts : 0); + ret = mtd_device_parse_register(&flash->mtd, NULL, 0, + data ? data->parts : NULL, + data ? data->nr_parts : 0); if (ret) { kfree(flash); dev_set_drvdata(&spi->dev, NULL); @@ -431,7 +450,18 @@ static struct spi_driver sst25l_driver = { .remove = __devexit_p(sst25l_remove), }; -module_spi_driver(sst25l_driver); +static int __init sst25l_init(void) +{ + return spi_register_driver(&sst25l_driver); +} + +static void __exit sst25l_exit(void) +{ + spi_unregister_driver(&sst25l_driver); +} + +module_init(sst25l_init); +module_exit(sst25l_exit); MODULE_DESCRIPTION("MTD SPI driver for SST25L Flash chips"); MODULE_AUTHOR("Andre Renaud , " diff --git a/trunk/drivers/mtd/inftlcore.c b/trunk/drivers/mtd/inftlcore.c index 3af351484098..28646c95cfb8 100644 --- a/trunk/drivers/mtd/inftlcore.c +++ b/trunk/drivers/mtd/inftlcore.c @@ -56,7 +56,7 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) if (memcmp(mtd->name, "DiskOnChip", 10)) return; - if (!mtd->_block_isbad) { + if (!mtd->block_isbad) { printk(KERN_ERR "INFTL no longer supports the old DiskOnChip drivers loaded via docprobe.\n" "Please use the new diskonchip driver under the NAND subsystem.\n"); diff --git a/trunk/drivers/mtd/lpddr/lpddr_cmds.c b/trunk/drivers/mtd/lpddr/lpddr_cmds.c index d3cfe26beeaa..536bbceaeaad 100644 --- a/trunk/drivers/mtd/lpddr/lpddr_cmds.c +++ b/trunk/drivers/mtd/lpddr/lpddr_cmds.c @@ -40,7 +40,7 @@ static int lpddr_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len); static int lpddr_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, size_t *retlen, void **mtdbuf, resource_size_t *phys); -static int lpddr_unpoint(struct mtd_info *mtd, loff_t adr, size_t len); +static void lpddr_unpoint(struct mtd_info *mtd, loff_t adr, size_t len); static int get_chip(struct map_info *map, struct flchip *chip, int mode); static int chip_ready(struct map_info *map, struct flchip *chip, int mode); static void put_chip(struct map_info *map, struct flchip *chip); @@ -63,18 +63,18 @@ struct mtd_info *lpddr_cmdset(struct map_info *map) mtd->type = MTD_NORFLASH; /* Fill in the default mtd operations */ - mtd->_read = lpddr_read; + mtd->read = lpddr_read; mtd->type = MTD_NORFLASH; mtd->flags = MTD_CAP_NORFLASH; mtd->flags &= ~MTD_BIT_WRITEABLE; - mtd->_erase = lpddr_erase; - mtd->_write = lpddr_write_buffers; - mtd->_writev = lpddr_writev; - mtd->_lock = lpddr_lock; - mtd->_unlock = lpddr_unlock; + mtd->erase = lpddr_erase; + mtd->write = lpddr_write_buffers; + mtd->writev = lpddr_writev; + mtd->lock = lpddr_lock; + mtd->unlock = lpddr_unlock; if (map_is_linear(map)) { - mtd->_point = lpddr_point; - mtd->_unpoint = lpddr_unpoint; + mtd->point = lpddr_point; + mtd->unpoint = lpddr_unpoint; } mtd->size = 1 << lpddr->qinfo->DevSizeShift; mtd->erasesize = 1 << lpddr->qinfo->UniformBlockSizeShift; @@ -530,12 +530,14 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, struct flchip *chip = &lpddr->chips[chipnum]; int ret = 0; - if (!map->virt) + if (!map->virt || (adr + len > mtd->size)) return -EINVAL; /* ofs: offset within the first chip that the first read should start */ ofs = adr - (chipnum << lpddr->chipshift); + *mtdbuf = (void *)map->virt + chip->start + ofs; + *retlen = 0; while (len) { unsigned long thislen; @@ -573,11 +575,11 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, return 0; } -static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) +static void lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) { struct map_info *map = mtd->priv; struct lpddr_private *lpddr = map->fldrv_priv; - int chipnum = adr >> lpddr->chipshift, err = 0; + int chipnum = adr >> lpddr->chipshift; unsigned long ofs; /* ofs: offset within the first chip that the first read should start */ @@ -601,11 +603,9 @@ static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) chip->ref_point_counter--; if (chip->ref_point_counter == 0) chip->state = FL_READY; - } else { + } else printk(KERN_WARNING "%s: Warning: unpoint called on non" "pointed region\n", map->name); - err = -EINVAL; - } put_chip(map, chip); mutex_unlock(&chip->mutex); @@ -614,8 +614,6 @@ static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) ofs = 0; chipnum++; } - - return err; } static int lpddr_write_buffers(struct mtd_info *mtd, loff_t to, size_t len, @@ -639,11 +637,13 @@ static int lpddr_writev(struct mtd_info *mtd, const struct kvec *vecs, int chipnum; unsigned long ofs, vec_seek, i; int wbufsize = 1 << lpddr->qinfo->BufSizeShift; + size_t len = 0; for (i = 0; i < count; i++) len += vecs[i].iov_len; + *retlen = 0; if (!len) return 0; @@ -688,6 +688,9 @@ static int lpddr_erase(struct mtd_info *mtd, struct erase_info *instr) ofs = instr->addr; len = instr->len; + if (ofs > mtd->size || (len + ofs) > mtd->size) + return -EINVAL; + while (len > 0) { ret = do_erase_oneblock(mtd, ofs); if (ret) diff --git a/trunk/drivers/mtd/maps/bfin-async-flash.c b/trunk/drivers/mtd/maps/bfin-async-flash.c index ef5cde84a8b3..650126c361f1 100644 --- a/trunk/drivers/mtd/maps/bfin-async-flash.c +++ b/trunk/drivers/mtd/maps/bfin-async-flash.c @@ -164,8 +164,8 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev) return -ENXIO; } - mtd_device_parse_register(state->mtd, part_probe_types, NULL, - pdata->parts, pdata->nr_parts); + mtd_device_parse_register(state->mtd, part_probe_types, 0, + pdata->parts, pdata->nr_parts); platform_set_drvdata(pdev, state); diff --git a/trunk/drivers/mtd/maps/dc21285.c b/trunk/drivers/mtd/maps/dc21285.c index 080f06053bd4..f43b365b848c 100644 --- a/trunk/drivers/mtd/maps/dc21285.c +++ b/trunk/drivers/mtd/maps/dc21285.c @@ -196,7 +196,7 @@ static int __init init_dc21285(void) dc21285_mtd->owner = THIS_MODULE; - mtd_device_parse_register(dc21285_mtd, probes, NULL, NULL, 0); + mtd_device_parse_register(dc21285_mtd, probes, 0, NULL, 0); if(machine_is_ebsa285()) { /* diff --git a/trunk/drivers/mtd/maps/gpio-addr-flash.c b/trunk/drivers/mtd/maps/gpio-addr-flash.c index e4de96ba52b3..33cce895859f 100644 --- a/trunk/drivers/mtd/maps/gpio-addr-flash.c +++ b/trunk/drivers/mtd/maps/gpio-addr-flash.c @@ -252,8 +252,8 @@ static int __devinit gpio_flash_probe(struct platform_device *pdev) } - mtd_device_parse_register(state->mtd, part_probe_types, NULL, - pdata->parts, pdata->nr_parts); + mtd_device_parse_register(state->mtd, part_probe_types, 0, + pdata->parts, pdata->nr_parts); return 0; } diff --git a/trunk/drivers/mtd/maps/h720x-flash.c b/trunk/drivers/mtd/maps/h720x-flash.c index 8ed6cb4529d8..49c14187fc66 100644 --- a/trunk/drivers/mtd/maps/h720x-flash.c +++ b/trunk/drivers/mtd/maps/h720x-flash.c @@ -85,8 +85,8 @@ static int __init h720x_mtd_init(void) if (mymtd) { mymtd->owner = THIS_MODULE; - mtd_device_parse_register(mymtd, NULL, NULL, - h720x_partitions, NUM_PARTITIONS); + mtd_device_parse_register(mymtd, NULL, 0, + h720x_partitions, NUM_PARTITIONS); return 0; } diff --git a/trunk/drivers/mtd/maps/impa7.c b/trunk/drivers/mtd/maps/impa7.c index 834a06c56f56..f47aedb24366 100644 --- a/trunk/drivers/mtd/maps/impa7.c +++ b/trunk/drivers/mtd/maps/impa7.c @@ -91,7 +91,7 @@ static int __init init_impa7(void) if (impa7_mtd[i]) { impa7_mtd[i]->owner = THIS_MODULE; devicesfound++; - mtd_device_parse_register(impa7_mtd[i], NULL, NULL, + mtd_device_parse_register(impa7_mtd[i], NULL, 0, partitions, ARRAY_SIZE(partitions)); } diff --git a/trunk/drivers/mtd/maps/intel_vr_nor.c b/trunk/drivers/mtd/maps/intel_vr_nor.c index 92e1f41634c7..08c239604ee4 100644 --- a/trunk/drivers/mtd/maps/intel_vr_nor.c +++ b/trunk/drivers/mtd/maps/intel_vr_nor.c @@ -72,7 +72,7 @@ static int __devinit vr_nor_init_partitions(struct vr_nor_mtd *p) { /* register the flash bank */ /* partition the flash bank */ - return mtd_device_parse_register(p->info, NULL, NULL, NULL, 0); + return mtd_device_parse_register(p->info, NULL, 0, NULL, 0); } static void __devexit vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p) diff --git a/trunk/drivers/mtd/maps/ixp2000.c b/trunk/drivers/mtd/maps/ixp2000.c index 4a41ced0f710..fc7d4d0d9a4e 100644 --- a/trunk/drivers/mtd/maps/ixp2000.c +++ b/trunk/drivers/mtd/maps/ixp2000.c @@ -226,7 +226,7 @@ static int ixp2000_flash_probe(struct platform_device *dev) } info->mtd->owner = THIS_MODULE; - err = mtd_device_parse_register(info->mtd, probes, NULL, NULL, 0); + err = mtd_device_parse_register(info->mtd, probes, 0, NULL, 0); if (err) goto Error; diff --git a/trunk/drivers/mtd/maps/ixp4xx.c b/trunk/drivers/mtd/maps/ixp4xx.c index e864fc6c58f9..8b5410162d70 100644 --- a/trunk/drivers/mtd/maps/ixp4xx.c +++ b/trunk/drivers/mtd/maps/ixp4xx.c @@ -182,9 +182,6 @@ static int ixp4xx_flash_probe(struct platform_device *dev) { struct flash_platform_data *plat = dev->dev.platform_data; struct ixp4xx_flash_info *info; - struct mtd_part_parser_data ppdata = { - .origin = dev->resource->start, - }; int err = -1; if (!plat) @@ -250,7 +247,7 @@ static int ixp4xx_flash_probe(struct platform_device *dev) /* Use the fast version */ info->map.write = ixp4xx_write16; - err = mtd_device_parse_register(info->mtd, probes, &ppdata, + err = mtd_device_parse_register(info->mtd, probes, dev->resource->start, plat->parts, plat->nr_parts); if (err) { printk(KERN_ERR "Could not parse partitions\n"); diff --git a/trunk/drivers/mtd/maps/l440gx.c b/trunk/drivers/mtd/maps/l440gx.c index 74bd98ee635f..dd0360ba2412 100644 --- a/trunk/drivers/mtd/maps/l440gx.c +++ b/trunk/drivers/mtd/maps/l440gx.c @@ -27,21 +27,17 @@ static struct mtd_info *mymtd; /* Is this really the vpp port? */ -static DEFINE_SPINLOCK(l440gx_vpp_lock); -static int l440gx_vpp_refcnt; static void l440gx_set_vpp(struct map_info *map, int vpp) { - unsigned long flags; + unsigned long l; - spin_lock_irqsave(&l440gx_vpp_lock, flags); + l = inl(VPP_PORT); if (vpp) { - if (++l440gx_vpp_refcnt == 1) /* first nested 'on' */ - outl(inl(VPP_PORT) | 1, VPP_PORT); + l |= 1; } else { - if (--l440gx_vpp_refcnt == 0) /* last nested 'off' */ - outl(inl(VPP_PORT) & ~1, VPP_PORT); + l &= ~1; } - spin_unlock_irqrestore(&l440gx_vpp_lock, flags); + outl(l, VPP_PORT); } static struct map_info l440gx_map = { diff --git a/trunk/drivers/mtd/maps/lantiq-flash.c b/trunk/drivers/mtd/maps/lantiq-flash.c index b5401e355745..7b889de9477b 100644 --- a/trunk/drivers/mtd/maps/lantiq-flash.c +++ b/trunk/drivers/mtd/maps/lantiq-flash.c @@ -45,7 +45,6 @@ struct ltq_mtd { }; static char ltq_map_name[] = "ltq_nor"; -static const char *ltq_probe_types[] __devinitconst = { "cmdlinepart", NULL }; static map_word ltq_read16(struct map_info *map, unsigned long adr) @@ -169,9 +168,8 @@ ltq_mtd_probe(struct platform_device *pdev) cfi->addr_unlock1 ^= 1; cfi->addr_unlock2 ^= 1; - err = mtd_device_parse_register(ltq_mtd->mtd, ltq_probe_types, NULL, - ltq_mtd_data->parts, - ltq_mtd_data->nr_parts); + err = mtd_device_parse_register(ltq_mtd->mtd, NULL, 0, + ltq_mtd_data->parts, ltq_mtd_data->nr_parts); if (err) { dev_err(&pdev->dev, "failed to add partitions\n"); goto err_destroy; diff --git a/trunk/drivers/mtd/maps/latch-addr-flash.c b/trunk/drivers/mtd/maps/latch-addr-flash.c index 3c7ad17fca78..8fed58e3a4a8 100644 --- a/trunk/drivers/mtd/maps/latch-addr-flash.c +++ b/trunk/drivers/mtd/maps/latch-addr-flash.c @@ -199,9 +199,8 @@ static int __devinit latch_addr_flash_probe(struct platform_device *dev) } info->mtd->owner = THIS_MODULE; - mtd_device_parse_register(info->mtd, NULL, NULL, - latch_addr_data->parts, - latch_addr_data->nr_parts); + mtd_device_parse_register(info->mtd, NULL, 0, + latch_addr_data->parts, latch_addr_data->nr_parts); return 0; iounmap: diff --git a/trunk/drivers/mtd/maps/pcmciamtd.c b/trunk/drivers/mtd/maps/pcmciamtd.c index a3cfad392ed6..0259cf583022 100644 --- a/trunk/drivers/mtd/maps/pcmciamtd.c +++ b/trunk/drivers/mtd/maps/pcmciamtd.c @@ -294,24 +294,13 @@ static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *f } -static DEFINE_SPINLOCK(pcmcia_vpp_lock); -static int pcmcia_vpp_refcnt; static void pcmciamtd_set_vpp(struct map_info *map, int on) { struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1; struct pcmcia_device *link = dev->p_dev; - unsigned long flags; pr_debug("dev = %p on = %d vpp = %d\n\n", dev, on, dev->vpp); - spin_lock_irqsave(&pcmcia_vpp_lock, flags); - if (on) { - if (++pcmcia_vpp_refcnt == 1) /* first nested 'on' */ - pcmcia_fixup_vpp(link, dev->vpp); - } else { - if (--pcmcia_vpp_refcnt == 0) /* last nested 'off' */ - pcmcia_fixup_vpp(link, 0); - } - spin_unlock_irqrestore(&pcmcia_vpp_lock, flags); + pcmcia_fixup_vpp(link, on ? dev->vpp : 0); } diff --git a/trunk/drivers/mtd/maps/physmap.c b/trunk/drivers/mtd/maps/physmap.c index 21b0b713cacb..abc562653b31 100644 --- a/trunk/drivers/mtd/maps/physmap.c +++ b/trunk/drivers/mtd/maps/physmap.c @@ -27,8 +27,6 @@ struct physmap_flash_info { struct mtd_info *mtd[MAX_RESOURCES]; struct mtd_info *cmtd; struct map_info map[MAX_RESOURCES]; - spinlock_t vpp_lock; - int vpp_refcnt; }; static int physmap_flash_remove(struct platform_device *dev) @@ -65,26 +63,12 @@ static void physmap_set_vpp(struct map_info *map, int state) { struct platform_device *pdev; struct physmap_flash_data *physmap_data; - struct physmap_flash_info *info; - unsigned long flags; pdev = (struct platform_device *)map->map_priv_1; physmap_data = pdev->dev.platform_data; - if (!physmap_data->set_vpp) - return; - - info = platform_get_drvdata(pdev); - - spin_lock_irqsave(&info->vpp_lock, flags); - if (state) { - if (++info->vpp_refcnt == 1) /* first nested 'on' */ - physmap_data->set_vpp(pdev, 1); - } else { - if (--info->vpp_refcnt == 0) /* last nested 'off' */ - physmap_data->set_vpp(pdev, 0); - } - spin_unlock_irqrestore(&info->vpp_lock, flags); + if (physmap_data->set_vpp) + physmap_data->set_vpp(pdev, state); } static const char *rom_probe_types[] = { @@ -188,11 +172,9 @@ static int physmap_flash_probe(struct platform_device *dev) if (err) goto err_out; - spin_lock_init(&info->vpp_lock); - part_types = physmap_data->part_probe_types ? : part_probe_types; - mtd_device_parse_register(info->cmtd, part_types, NULL, + mtd_device_parse_register(info->cmtd, part_types, 0, physmap_data->parts, physmap_data->nr_parts); return 0; diff --git a/trunk/drivers/mtd/maps/plat-ram.c b/trunk/drivers/mtd/maps/plat-ram.c index 891558de3ec1..45876d0e5b8e 100644 --- a/trunk/drivers/mtd/maps/plat-ram.c +++ b/trunk/drivers/mtd/maps/plat-ram.c @@ -222,9 +222,8 @@ static int platram_probe(struct platform_device *pdev) /* check to see if there are any available partitions, or wether * to add this device whole */ - err = mtd_device_parse_register(info->mtd, pdata->probes, NULL, - pdata->partitions, - pdata->nr_partitions); + err = mtd_device_parse_register(info->mtd, pdata->probes, 0, + pdata->partitions, pdata->nr_partitions); if (!err) dev_info(&pdev->dev, "registered mtd device\n"); diff --git a/trunk/drivers/mtd/maps/pxa2xx-flash.c b/trunk/drivers/mtd/maps/pxa2xx-flash.c index 81884c277405..436d121185b1 100644 --- a/trunk/drivers/mtd/maps/pxa2xx-flash.c +++ b/trunk/drivers/mtd/maps/pxa2xx-flash.c @@ -98,8 +98,7 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev) } info->mtd->owner = THIS_MODULE; - mtd_device_parse_register(info->mtd, probes, NULL, flash->parts, - flash->nr_parts); + mtd_device_parse_register(info->mtd, probes, 0, flash->parts, flash->nr_parts); platform_set_drvdata(pdev, info); return 0; diff --git a/trunk/drivers/mtd/maps/rbtx4939-flash.c b/trunk/drivers/mtd/maps/rbtx4939-flash.c index 6f52e1f288b6..3da63fc6f16e 100644 --- a/trunk/drivers/mtd/maps/rbtx4939-flash.c +++ b/trunk/drivers/mtd/maps/rbtx4939-flash.c @@ -102,8 +102,8 @@ static int rbtx4939_flash_probe(struct platform_device *dev) info->mtd->owner = THIS_MODULE; if (err) goto err_out; - err = mtd_device_parse_register(info->mtd, NULL, NULL, pdata->parts, - pdata->nr_parts); + err = mtd_device_parse_register(info->mtd, NULL, 0, + pdata->parts, pdata->nr_parts); if (err) goto err_out; diff --git a/trunk/drivers/mtd/maps/sa1100-flash.c b/trunk/drivers/mtd/maps/sa1100-flash.c index a675bdbcb0fe..cbc3b7867910 100644 --- a/trunk/drivers/mtd/maps/sa1100-flash.c +++ b/trunk/drivers/mtd/maps/sa1100-flash.c @@ -36,22 +36,10 @@ struct sa_info { struct sa_subdev_info subdev[0]; }; -static DEFINE_SPINLOCK(sa1100_vpp_lock); -static int sa1100_vpp_refcnt; static void sa1100_set_vpp(struct map_info *map, int on) { struct sa_subdev_info *subdev = container_of(map, struct sa_subdev_info, map); - unsigned long flags; - - spin_lock_irqsave(&sa1100_vpp_lock, flags); - if (on) { - if (++sa1100_vpp_refcnt == 1) /* first nested 'on' */ - subdev->plat->set_vpp(1); - } else { - if (--sa1100_vpp_refcnt == 0) /* last nested 'off' */ - subdev->plat->set_vpp(0); - } - spin_unlock_irqrestore(&sa1100_vpp_lock, flags); + subdev->plat->set_vpp(on); } static void sa1100_destroy_subdev(struct sa_subdev_info *subdev) @@ -264,8 +252,8 @@ static int __devinit sa1100_mtd_probe(struct platform_device *pdev) /* * Partition selection stuff. */ - mtd_device_parse_register(info->mtd, part_probes, NULL, plat->parts, - plat->nr_parts); + mtd_device_parse_register(info->mtd, part_probes, 0, + plat->parts, plat->nr_parts); platform_set_drvdata(pdev, info); err = 0; diff --git a/trunk/drivers/mtd/maps/solutionengine.c b/trunk/drivers/mtd/maps/solutionengine.c index 9d900ada6708..496c40704aff 100644 --- a/trunk/drivers/mtd/maps/solutionengine.c +++ b/trunk/drivers/mtd/maps/solutionengine.c @@ -92,8 +92,8 @@ static int __init init_soleng_maps(void) mtd_device_register(eprom_mtd, NULL, 0); } - mtd_device_parse_register(flash_mtd, probes, NULL, - superh_se_partitions, NUM_PARTITIONS); + mtd_device_parse_register(flash_mtd, probes, 0, + superh_se_partitions, NUM_PARTITIONS); return 0; } diff --git a/trunk/drivers/mtd/maps/uclinux.c b/trunk/drivers/mtd/maps/uclinux.c index cfff454f628b..6793074f3f40 100644 --- a/trunk/drivers/mtd/maps/uclinux.c +++ b/trunk/drivers/mtd/maps/uclinux.c @@ -85,7 +85,7 @@ static int __init uclinux_mtd_init(void) } mtd->owner = THIS_MODULE; - mtd->_point = uclinux_point; + mtd->point = uclinux_point; mtd->priv = mapp; uclinux_ram_mtdinfo = mtd; diff --git a/trunk/drivers/mtd/maps/vmu-flash.c b/trunk/drivers/mtd/maps/vmu-flash.c index 2e2b0945edc7..3a04b078576a 100644 --- a/trunk/drivers/mtd/maps/vmu-flash.c +++ b/trunk/drivers/mtd/maps/vmu-flash.c @@ -360,6 +360,9 @@ static int vmu_flash_read(struct mtd_info *mtd, loff_t from, size_t len, int index = 0, retval, partition, leftover, numblocks; unsigned char cx; + if (len < 1) + return -EIO; + mpart = mtd->priv; mdev = mpart->mdev; partition = mpart->partition; @@ -431,6 +434,11 @@ static int vmu_flash_write(struct mtd_info *mtd, loff_t to, size_t len, partition = mpart->partition; card = maple_get_drvdata(mdev); + /* simple sanity checks */ + if (len < 1) { + error = -EIO; + goto failed; + } numblocks = card->parts[partition].numblocks; if (to + len > numblocks * card->blocklen) len = numblocks * card->blocklen - to; @@ -536,9 +544,9 @@ static void vmu_queryblocks(struct mapleq *mq) mtd_cur->flags = MTD_WRITEABLE|MTD_NO_ERASE; mtd_cur->size = part_cur->numblocks * card->blocklen; mtd_cur->erasesize = card->blocklen; - mtd_cur->_write = vmu_flash_write; - mtd_cur->_read = vmu_flash_read; - mtd_cur->_sync = vmu_flash_sync; + mtd_cur->write = vmu_flash_write; + mtd_cur->read = vmu_flash_read; + mtd_cur->sync = vmu_flash_sync; mtd_cur->writesize = card->blocklen; mpart = kmalloc(sizeof(struct mdev_part), GFP_KERNEL); diff --git a/trunk/drivers/mtd/maps/wr_sbc82xx_flash.c b/trunk/drivers/mtd/maps/wr_sbc82xx_flash.c index 71b0ba797912..aa7e0cb2893c 100644 --- a/trunk/drivers/mtd/maps/wr_sbc82xx_flash.c +++ b/trunk/drivers/mtd/maps/wr_sbc82xx_flash.c @@ -142,7 +142,7 @@ static int __init init_sbc82xx_flash(void) nr_parts = ARRAY_SIZE(smallflash_parts); } - mtd_device_parse_register(sbcmtd[i], part_probes, NULL, + mtd_device_parse_register(sbcmtd[i], part_probes, 0, defparts, nr_parts); } return 0; diff --git a/trunk/drivers/mtd/mtd_blkdevs.c b/trunk/drivers/mtd/mtd_blkdevs.c index f1f06715d4e0..424ca5f93c6c 100644 --- a/trunk/drivers/mtd/mtd_blkdevs.c +++ b/trunk/drivers/mtd/mtd_blkdevs.c @@ -233,7 +233,6 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode) ret = __get_mtd_device(dev->mtd); if (ret) goto error_release; - dev->file_mode = mode; unlock: dev->open++; diff --git a/trunk/drivers/mtd/mtdblock.c b/trunk/drivers/mtd/mtdblock.c index 6c6d80736fad..af6591237b9b 100644 --- a/trunk/drivers/mtd/mtdblock.c +++ b/trunk/drivers/mtd/mtdblock.c @@ -321,12 +321,8 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd) mutex_unlock(&mtdblk->cache_mutex); if (!--mtdblk->count) { - /* - * It was the last usage. Free the cache, but only sync if - * opened for writing. - */ - if (mbd->file_mode & FMODE_WRITE) - mtd_sync(mbd->mtd); + /* It was the last usage. Free the cache */ + mtd_sync(mbd->mtd); vfree(mtdblk->cache_data); } diff --git a/trunk/drivers/mtd/mtdchar.c b/trunk/drivers/mtd/mtdchar.c index 58fc65f5c817..c57ae92ebda4 100644 --- a/trunk/drivers/mtd/mtdchar.c +++ b/trunk/drivers/mtd/mtdchar.c @@ -39,6 +39,7 @@ #include static DEFINE_MUTEX(mtd_mutex); +static struct vfsmount *mtd_inode_mnt __read_mostly; /* * Data structure to hold the pointer to the mtd device as well @@ -74,9 +75,7 @@ static loff_t mtdchar_lseek(struct file *file, loff_t offset, int orig) return -EINVAL; } -static int count; -static struct vfsmount *mnt; -static struct file_system_type mtd_inodefs_type; + static int mtdchar_open(struct inode *inode, struct file *file) { @@ -93,10 +92,6 @@ static int mtdchar_open(struct inode *inode, struct file *file) if ((file->f_mode & FMODE_WRITE) && (minor & 1)) return -EACCES; - ret = simple_pin_fs(&mtd_inodefs_type, &mnt, &count); - if (ret) - return ret; - mutex_lock(&mtd_mutex); mtd = get_mtd_device(NULL, devnum); @@ -106,14 +101,16 @@ static int mtdchar_open(struct inode *inode, struct file *file) } if (mtd->type == MTD_ABSENT) { + put_mtd_device(mtd); ret = -ENODEV; - goto out1; + goto out; } - mtd_ino = iget_locked(mnt->mnt_sb, devnum); + mtd_ino = iget_locked(mtd_inode_mnt->mnt_sb, devnum); if (!mtd_ino) { + put_mtd_device(mtd); ret = -ENOMEM; - goto out1; + goto out; } if (mtd_ino->i_state & I_NEW) { mtd_ino->i_private = mtd; @@ -125,28 +122,25 @@ static int mtdchar_open(struct inode *inode, struct file *file) /* You can't open it RW if it's not a writeable device */ if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) { + iput(mtd_ino); + put_mtd_device(mtd); ret = -EACCES; - goto out2; + goto out; } mfi = kzalloc(sizeof(*mfi), GFP_KERNEL); if (!mfi) { + iput(mtd_ino); + put_mtd_device(mtd); ret = -ENOMEM; - goto out2; + goto out; } mfi->ino = mtd_ino; mfi->mtd = mtd; file->private_data = mfi; - mutex_unlock(&mtd_mutex); - return 0; -out2: - iput(mtd_ino); -out1: - put_mtd_device(mtd); out: mutex_unlock(&mtd_mutex); - simple_release_fs(&mnt, &count); return ret; } /* mtdchar_open */ @@ -168,7 +162,6 @@ static int mtdchar_close(struct inode *inode, struct file *file) put_mtd_device(mtd); file->private_data = NULL; kfree(mfi); - simple_release_fs(&mnt, &count); return 0; } /* mtdchar_close */ @@ -412,7 +405,7 @@ static int mtdchar_writeoob(struct file *file, struct mtd_info *mtd, if (length > 4096) return -EINVAL; - if (!mtd->_write_oob) + if (!mtd->write_oob) ret = -EOPNOTSUPP; else ret = access_ok(VERIFY_READ, ptr, length) ? 0 : -EFAULT; @@ -583,7 +576,7 @@ static int mtdchar_write_ioctl(struct mtd_info *mtd, !access_ok(VERIFY_READ, req.usr_data, req.len) || !access_ok(VERIFY_READ, req.usr_oob, req.ooblen)) return -EFAULT; - if (!mtd->_write_oob) + if (!mtd->write_oob) return -EOPNOTSUPP; ops.mode = req.mode; @@ -1182,15 +1175,10 @@ static const struct file_operations mtd_fops = { #endif }; -static const struct super_operations mtd_ops = { - .drop_inode = generic_delete_inode, - .statfs = simple_statfs, -}; - static struct dentry *mtd_inodefs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { - return mount_pseudo(fs_type, "mtd_inode:", &mtd_ops, NULL, MTD_INODE_FS_MAGIC); + return mount_pseudo(fs_type, "mtd_inode:", NULL, NULL, MTD_INODE_FS_MAGIC); } static struct file_system_type mtd_inodefs_type = { @@ -1199,6 +1187,26 @@ static struct file_system_type mtd_inodefs_type = { .kill_sb = kill_anon_super, }; +static void mtdchar_notify_add(struct mtd_info *mtd) +{ +} + +static void mtdchar_notify_remove(struct mtd_info *mtd) +{ + struct inode *mtd_ino = ilookup(mtd_inode_mnt->mnt_sb, mtd->index); + + if (mtd_ino) { + /* Destroy the inode if it exists */ + clear_nlink(mtd_ino); + iput(mtd_ino); + } +} + +static struct mtd_notifier mtdchar_notifier = { + .add = mtdchar_notify_add, + .remove = mtdchar_notify_remove, +}; + static int __init init_mtdchar(void) { int ret; @@ -1216,8 +1224,19 @@ static int __init init_mtdchar(void) pr_notice("Can't register mtd_inodefs filesystem: %d\n", ret); goto err_unregister_chdev; } + + mtd_inode_mnt = kern_mount(&mtd_inodefs_type); + if (IS_ERR(mtd_inode_mnt)) { + ret = PTR_ERR(mtd_inode_mnt); + pr_notice("Error mounting mtd_inodefs filesystem: %d\n", ret); + goto err_unregister_filesystem; + } + register_mtd_user(&mtdchar_notifier); + return ret; +err_unregister_filesystem: + unregister_filesystem(&mtd_inodefs_type); err_unregister_chdev: __unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd"); return ret; @@ -1225,6 +1244,8 @@ static int __init init_mtdchar(void) static void __exit cleanup_mtdchar(void) { + unregister_mtd_user(&mtdchar_notifier); + kern_unmount(mtd_inode_mnt); unregister_filesystem(&mtd_inodefs_type); __unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd"); } diff --git a/trunk/drivers/mtd/mtdconcat.c b/trunk/drivers/mtd/mtdconcat.c index b9000563b9f4..1ed5103b219b 100644 --- a/trunk/drivers/mtd/mtdconcat.c +++ b/trunk/drivers/mtd/mtdconcat.c @@ -72,6 +72,8 @@ concat_read(struct mtd_info *mtd, loff_t from, size_t len, int ret = 0, err; int i; + *retlen = 0; + for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; size_t size, retsize; @@ -124,6 +126,11 @@ concat_write(struct mtd_info *mtd, loff_t to, size_t len, int err = -EINVAL; int i; + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + + *retlen = 0; + for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; size_t size, retsize; @@ -138,7 +145,11 @@ concat_write(struct mtd_info *mtd, loff_t to, size_t len, else size = len; - err = mtd_write(subdev, to, size, &retsize, buf); + if (!(subdev->flags & MTD_WRITEABLE)) + err = -EROFS; + else + err = mtd_write(subdev, to, size, &retsize, buf); + if (err) break; @@ -165,10 +176,19 @@ concat_writev(struct mtd_info *mtd, const struct kvec *vecs, int i; int err = -EINVAL; + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + + *retlen = 0; + /* Calculate total length of data */ for (i = 0; i < count; i++) total_len += vecs[i].iov_len; + /* Do not allow write past end of device */ + if ((to + total_len) > mtd->size) + return -EINVAL; + /* Check alignment */ if (mtd->writesize > 1) { uint64_t __to = to; @@ -204,8 +224,12 @@ concat_writev(struct mtd_info *mtd, const struct kvec *vecs, old_iov_len = vecs_copy[entry_high].iov_len; vecs_copy[entry_high].iov_len = size; - err = mtd_writev(subdev, &vecs_copy[entry_low], - entry_high - entry_low + 1, to, &retsize); + if (!(subdev->flags & MTD_WRITEABLE)) + err = -EROFS; + else + err = mtd_writev(subdev, &vecs_copy[entry_low], + entry_high - entry_low + 1, to, + &retsize); vecs_copy[entry_high].iov_len = old_iov_len - size; vecs_copy[entry_high].iov_base += size; @@ -379,6 +403,15 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr) uint64_t length, offset = 0; struct erase_info *erase; + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + + if (instr->addr > concat->mtd.size) + return -EINVAL; + + if (instr->len + instr->addr > concat->mtd.size) + return -EINVAL; + /* * Check for proper erase block alignment of the to-be-erased area. * It is easier to do this based on the super device's erase @@ -426,6 +459,8 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr) return -EINVAL; } + instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; + /* make a local copy of instr to avoid modifying the caller's struct */ erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL); @@ -464,6 +499,10 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr) else erase->len = length; + if (!(subdev->flags & MTD_WRITEABLE)) { + err = -EROFS; + break; + } length -= erase->len; if ((err = concat_dev_erase(subdev, erase))) { /* sanity check: should never happen since @@ -499,6 +538,9 @@ static int concat_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) struct mtd_concat *concat = CONCAT(mtd); int i, err = -EINVAL; + if ((len + ofs) > mtd->size) + return -EINVAL; + for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; uint64_t size; @@ -533,6 +575,9 @@ static int concat_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) struct mtd_concat *concat = CONCAT(mtd); int i, err = 0; + if ((len + ofs) > mtd->size) + return -EINVAL; + for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; uint64_t size; @@ -605,6 +650,9 @@ static int concat_block_isbad(struct mtd_info *mtd, loff_t ofs) if (!mtd_can_have_bb(concat->subdev[0])) return res; + if (ofs > mtd->size) + return -EINVAL; + for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; @@ -625,6 +673,12 @@ static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs) struct mtd_concat *concat = CONCAT(mtd); int i, err = -EINVAL; + if (!mtd_can_have_bb(concat->subdev[0])) + return 0; + + if (ofs > mtd->size) + return -EINVAL; + for (i = 0; i < concat->num_subdev; i++) { struct mtd_info *subdev = concat->subdev[i]; @@ -662,6 +716,10 @@ static unsigned long concat_get_unmapped_area(struct mtd_info *mtd, continue; } + /* we've found the subdev over which the mapping will reside */ + if (offset + len > subdev->size) + return (unsigned long) -EINVAL; + return mtd_get_unmapped_area(subdev, len, offset, flags); } @@ -719,16 +777,16 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c concat->mtd.subpage_sft = subdev[0]->subpage_sft; concat->mtd.oobsize = subdev[0]->oobsize; concat->mtd.oobavail = subdev[0]->oobavail; - if (subdev[0]->_writev) - concat->mtd._writev = concat_writev; - if (subdev[0]->_read_oob) - concat->mtd._read_oob = concat_read_oob; - if (subdev[0]->_write_oob) - concat->mtd._write_oob = concat_write_oob; - if (subdev[0]->_block_isbad) - concat->mtd._block_isbad = concat_block_isbad; - if (subdev[0]->_block_markbad) - concat->mtd._block_markbad = concat_block_markbad; + if (subdev[0]->writev) + concat->mtd.writev = concat_writev; + if (subdev[0]->read_oob) + concat->mtd.read_oob = concat_read_oob; + if (subdev[0]->write_oob) + concat->mtd.write_oob = concat_write_oob; + if (subdev[0]->block_isbad) + concat->mtd.block_isbad = concat_block_isbad; + if (subdev[0]->block_markbad) + concat->mtd.block_markbad = concat_block_markbad; concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks; @@ -775,8 +833,8 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c if (concat->mtd.writesize != subdev[i]->writesize || concat->mtd.subpage_sft != subdev[i]->subpage_sft || concat->mtd.oobsize != subdev[i]->oobsize || - !concat->mtd._read_oob != !subdev[i]->_read_oob || - !concat->mtd._write_oob != !subdev[i]->_write_oob) { + !concat->mtd.read_oob != !subdev[i]->read_oob || + !concat->mtd.write_oob != !subdev[i]->write_oob) { kfree(concat); printk("Incompatible OOB or ECC data on \"%s\"\n", subdev[i]->name); @@ -791,15 +849,15 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c concat->num_subdev = num_devs; concat->mtd.name = name; - concat->mtd._erase = concat_erase; - concat->mtd._read = concat_read; - concat->mtd._write = concat_write; - concat->mtd._sync = concat_sync; - concat->mtd._lock = concat_lock; - concat->mtd._unlock = concat_unlock; - concat->mtd._suspend = concat_suspend; - concat->mtd._resume = concat_resume; - concat->mtd._get_unmapped_area = concat_get_unmapped_area; + concat->mtd.erase = concat_erase; + concat->mtd.read = concat_read; + concat->mtd.write = concat_write; + concat->mtd.sync = concat_sync; + concat->mtd.lock = concat_lock; + concat->mtd.unlock = concat_unlock; + concat->mtd.suspend = concat_suspend; + concat->mtd.resume = concat_resume; + concat->mtd.get_unmapped_area = concat_get_unmapped_area; /* * Combine the erase block size info of the subdevices: diff --git a/trunk/drivers/mtd/mtdcore.c b/trunk/drivers/mtd/mtdcore.c index c837507dfb1c..9a9ce71a71fc 100644 --- a/trunk/drivers/mtd/mtdcore.c +++ b/trunk/drivers/mtd/mtdcore.c @@ -107,7 +107,7 @@ static LIST_HEAD(mtd_notifiers); */ static void mtd_release(struct device *dev) { - struct mtd_info __maybe_unused *mtd = dev_get_drvdata(dev); + struct mtd_info *mtd = dev_get_drvdata(dev); dev_t index = MTD_DEVT(mtd->index); /* remove /dev/mtdXro node if needed */ @@ -126,7 +126,7 @@ static int mtd_cls_resume(struct device *dev) { struct mtd_info *mtd = dev_get_drvdata(dev); - if (mtd) + if (mtd && mtd->resume) mtd_resume(mtd); return 0; } @@ -610,8 +610,8 @@ int __get_mtd_device(struct mtd_info *mtd) if (!try_module_get(mtd->owner)) return -ENODEV; - if (mtd->_get_device) { - err = mtd->_get_device(mtd); + if (mtd->get_device) { + err = mtd->get_device(mtd); if (err) { module_put(mtd->owner); @@ -675,266 +675,13 @@ void __put_mtd_device(struct mtd_info *mtd) --mtd->usecount; BUG_ON(mtd->usecount < 0); - if (mtd->_put_device) - mtd->_put_device(mtd); + if (mtd->put_device) + mtd->put_device(mtd); module_put(mtd->owner); } EXPORT_SYMBOL_GPL(__put_mtd_device); -/* - * Erase is an asynchronous operation. Device drivers are supposed - * to call instr->callback() whenever the operation completes, even - * if it completes with a failure. - * Callers are supposed to pass a callback function and wait for it - * to be called before writing to the block. - */ -int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) -{ - if (instr->addr > mtd->size || instr->len > mtd->size - instr->addr) - return -EINVAL; - if (!(mtd->flags & MTD_WRITEABLE)) - return -EROFS; - instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; - if (!instr->len) { - instr->state = MTD_ERASE_DONE; - mtd_erase_callback(instr); - return 0; - } - return mtd->_erase(mtd, instr); -} -EXPORT_SYMBOL_GPL(mtd_erase); - -/* - * This stuff for eXecute-In-Place. phys is optional and may be set to NULL. - */ -int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, - void **virt, resource_size_t *phys) -{ - *retlen = 0; - *virt = NULL; - if (phys) - *phys = 0; - if (!mtd->_point) - return -EOPNOTSUPP; - if (from < 0 || from > mtd->size || len > mtd->size - from) - return -EINVAL; - if (!len) - return 0; - return mtd->_point(mtd, from, len, retlen, virt, phys); -} -EXPORT_SYMBOL_GPL(mtd_point); - -/* We probably shouldn't allow XIP if the unpoint isn't a NULL */ -int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len) -{ - if (!mtd->_point) - return -EOPNOTSUPP; - if (from < 0 || from > mtd->size || len > mtd->size - from) - return -EINVAL; - if (!len) - return 0; - return mtd->_unpoint(mtd, from, len); -} -EXPORT_SYMBOL_GPL(mtd_unpoint); - -/* - * Allow NOMMU mmap() to directly map the device (if not NULL) - * - return the address to which the offset maps - * - return -ENOSYS to indicate refusal to do the mapping - */ -unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, unsigned long len, - unsigned long offset, unsigned long flags) -{ - if (!mtd->_get_unmapped_area) - return -EOPNOTSUPP; - if (offset > mtd->size || len > mtd->size - offset) - return -EINVAL; - return mtd->_get_unmapped_area(mtd, len, offset, flags); -} -EXPORT_SYMBOL_GPL(mtd_get_unmapped_area); - -int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, - u_char *buf) -{ - *retlen = 0; - if (from < 0 || from > mtd->size || len > mtd->size - from) - return -EINVAL; - if (!len) - return 0; - return mtd->_read(mtd, from, len, retlen, buf); -} -EXPORT_SYMBOL_GPL(mtd_read); - -int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, - const u_char *buf) -{ - *retlen = 0; - if (to < 0 || to > mtd->size || len > mtd->size - to) - return -EINVAL; - if (!mtd->_write || !(mtd->flags & MTD_WRITEABLE)) - return -EROFS; - if (!len) - return 0; - return mtd->_write(mtd, to, len, retlen, buf); -} -EXPORT_SYMBOL_GPL(mtd_write); - -/* - * In blackbox flight recorder like scenarios we want to make successful writes - * in interrupt context. panic_write() is only intended to be called when its - * known the kernel is about to panic and we need the write to succeed. Since - * the kernel is not going to be running for much longer, this function can - * break locks and delay to ensure the write succeeds (but not sleep). - */ -int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, - const u_char *buf) -{ - *retlen = 0; - if (!mtd->_panic_write) - return -EOPNOTSUPP; - if (to < 0 || to > mtd->size || len > mtd->size - to) - return -EINVAL; - if (!(mtd->flags & MTD_WRITEABLE)) - return -EROFS; - if (!len) - return 0; - return mtd->_panic_write(mtd, to, len, retlen, buf); -} -EXPORT_SYMBOL_GPL(mtd_panic_write); - -/* - * Method to access the protection register area, present in some flash - * devices. The user data is one time programmable but the factory data is read - * only. - */ -int mtd_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf, - size_t len) -{ - if (!mtd->_get_fact_prot_info) - return -EOPNOTSUPP; - if (!len) - return 0; - return mtd->_get_fact_prot_info(mtd, buf, len); -} -EXPORT_SYMBOL_GPL(mtd_get_fact_prot_info); - -int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) -{ - *retlen = 0; - if (!mtd->_read_fact_prot_reg) - return -EOPNOTSUPP; - if (!len) - return 0; - return mtd->_read_fact_prot_reg(mtd, from, len, retlen, buf); -} -EXPORT_SYMBOL_GPL(mtd_read_fact_prot_reg); - -int mtd_get_user_prot_info(struct mtd_info *mtd, struct otp_info *buf, - size_t len) -{ - if (!mtd->_get_user_prot_info) - return -EOPNOTSUPP; - if (!len) - return 0; - return mtd->_get_user_prot_info(mtd, buf, len); -} -EXPORT_SYMBOL_GPL(mtd_get_user_prot_info); - -int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) -{ - *retlen = 0; - if (!mtd->_read_user_prot_reg) - return -EOPNOTSUPP; - if (!len) - return 0; - return mtd->_read_user_prot_reg(mtd, from, len, retlen, buf); -} -EXPORT_SYMBOL_GPL(mtd_read_user_prot_reg); - -int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, u_char *buf) -{ - *retlen = 0; - if (!mtd->_write_user_prot_reg) - return -EOPNOTSUPP; - if (!len) - return 0; - return mtd->_write_user_prot_reg(mtd, to, len, retlen, buf); -} -EXPORT_SYMBOL_GPL(mtd_write_user_prot_reg); - -int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len) -{ - if (!mtd->_lock_user_prot_reg) - return -EOPNOTSUPP; - if (!len) - return 0; - return mtd->_lock_user_prot_reg(mtd, from, len); -} -EXPORT_SYMBOL_GPL(mtd_lock_user_prot_reg); - -/* Chip-supported device locking */ -int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) -{ - if (!mtd->_lock) - return -EOPNOTSUPP; - if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) - return -EINVAL; - if (!len) - return 0; - return mtd->_lock(mtd, ofs, len); -} -EXPORT_SYMBOL_GPL(mtd_lock); - -int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) -{ - if (!mtd->_unlock) - return -EOPNOTSUPP; - if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) - return -EINVAL; - if (!len) - return 0; - return mtd->_unlock(mtd, ofs, len); -} -EXPORT_SYMBOL_GPL(mtd_unlock); - -int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) -{ - if (!mtd->_is_locked) - return -EOPNOTSUPP; - if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) - return -EINVAL; - if (!len) - return 0; - return mtd->_is_locked(mtd, ofs, len); -} -EXPORT_SYMBOL_GPL(mtd_is_locked); - -int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) -{ - if (!mtd->_block_isbad) - return 0; - if (ofs < 0 || ofs > mtd->size) - return -EINVAL; - return mtd->_block_isbad(mtd, ofs); -} -EXPORT_SYMBOL_GPL(mtd_block_isbad); - -int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs) -{ - if (!mtd->_block_markbad) - return -EOPNOTSUPP; - if (ofs < 0 || ofs > mtd->size) - return -EINVAL; - if (!(mtd->flags & MTD_WRITEABLE)) - return -EROFS; - return mtd->_block_markbad(mtd, ofs); -} -EXPORT_SYMBOL_GPL(mtd_block_markbad); - /* * default_mtd_writev - the default writev method * @mtd: mtd device description object pointer @@ -982,11 +729,9 @@ int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen) { *retlen = 0; - if (!(mtd->flags & MTD_WRITEABLE)) - return -EROFS; - if (!mtd->_writev) + if (!mtd->writev) return default_mtd_writev(mtd, vecs, count, to, retlen); - return mtd->_writev(mtd, vecs, count, to, retlen); + return mtd->writev(mtd, vecs, count, to, retlen); } EXPORT_SYMBOL_GPL(mtd_writev); diff --git a/trunk/drivers/mtd/mtdoops.c b/trunk/drivers/mtd/mtdoops.c index ae36d7e1e913..3ce99e00a49e 100644 --- a/trunk/drivers/mtd/mtdoops.c +++ b/trunk/drivers/mtd/mtdoops.c @@ -169,7 +169,7 @@ static void mtdoops_workfunc_erase(struct work_struct *work) cxt->nextpage = 0; } - while (1) { + while (mtd_can_have_bb(mtd)) { ret = mtd_block_isbad(mtd, cxt->nextpage * record_size); if (!ret) break; @@ -199,9 +199,9 @@ static void mtdoops_workfunc_erase(struct work_struct *work) return; } - if (ret == -EIO) { + if (mtd_can_have_bb(mtd) && ret == -EIO) { ret = mtd_block_markbad(mtd, cxt->nextpage * record_size); - if (ret < 0 && ret != -EOPNOTSUPP) { + if (ret < 0) { printk(KERN_ERR "mtdoops: block_markbad failed, aborting\n"); return; } @@ -257,7 +257,8 @@ static void find_next_position(struct mtdoops_context *cxt) size_t retlen; for (page = 0; page < cxt->oops_pages; page++) { - if (mtd_block_isbad(mtd, page * record_size)) + if (mtd_can_have_bb(mtd) && + mtd_block_isbad(mtd, page * record_size)) continue; /* Assume the page is used */ mark_page_used(cxt, page); diff --git a/trunk/drivers/mtd/mtdpart.c b/trunk/drivers/mtd/mtdpart.c index 9651c06de0a9..a3d44c3416b4 100644 --- a/trunk/drivers/mtd/mtdpart.c +++ b/trunk/drivers/mtd/mtdpart.c @@ -65,8 +65,12 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len, int res; stats = part->master->ecc_stats; - res = part->master->_read(part->master, from + part->offset, len, - retlen, buf); + + if (from >= mtd->size) + len = 0; + else if (from + len > mtd->size) + len = mtd->size - from; + res = mtd_read(part->master, from + part->offset, len, retlen, buf); if (unlikely(res)) { if (mtd_is_bitflip(res)) mtd->ecc_stats.corrected += part->master->ecc_stats.corrected - stats.corrected; @@ -80,16 +84,19 @@ static int part_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys) { struct mtd_part *part = PART(mtd); - - return part->master->_point(part->master, from + part->offset, len, - retlen, virt, phys); + if (from >= mtd->size) + len = 0; + else if (from + len > mtd->size) + len = mtd->size - from; + return mtd_point(part->master, from + part->offset, len, retlen, + virt, phys); } -static int part_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len) { struct mtd_part *part = PART(mtd); - return part->master->_unpoint(part->master, from + part->offset, len); + mtd_unpoint(part->master, from + part->offset, len); } static unsigned long part_get_unmapped_area(struct mtd_info *mtd, @@ -100,8 +107,7 @@ static unsigned long part_get_unmapped_area(struct mtd_info *mtd, struct mtd_part *part = PART(mtd); offset += part->offset; - return part->master->_get_unmapped_area(part->master, len, offset, - flags); + return mtd_get_unmapped_area(part->master, len, offset, flags); } static int part_read_oob(struct mtd_info *mtd, loff_t from, @@ -132,7 +138,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from, return -EINVAL; } - res = part->master->_read_oob(part->master, from + part->offset, ops); + res = mtd_read_oob(part->master, from + part->offset, ops); if (unlikely(res)) { if (mtd_is_bitflip(res)) mtd->ecc_stats.corrected++; @@ -146,46 +152,55 @@ static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { struct mtd_part *part = PART(mtd); - return part->master->_read_user_prot_reg(part->master, from, len, - retlen, buf); + return mtd_read_user_prot_reg(part->master, from, len, retlen, buf); } static int part_get_user_prot_info(struct mtd_info *mtd, struct otp_info *buf, size_t len) { struct mtd_part *part = PART(mtd); - return part->master->_get_user_prot_info(part->master, buf, len); + return mtd_get_user_prot_info(part->master, buf, len); } static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { struct mtd_part *part = PART(mtd); - return part->master->_read_fact_prot_reg(part->master, from, len, - retlen, buf); + return mtd_read_fact_prot_reg(part->master, from, len, retlen, buf); } static int part_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf, size_t len) { struct mtd_part *part = PART(mtd); - return part->master->_get_fact_prot_info(part->master, buf, len); + return mtd_get_fact_prot_info(part->master, buf, len); } static int part_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { struct mtd_part *part = PART(mtd); - return part->master->_write(part->master, to + part->offset, len, - retlen, buf); + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + if (to >= mtd->size) + len = 0; + else if (to + len > mtd->size) + len = mtd->size - to; + return mtd_write(part->master, to + part->offset, len, retlen, buf); } static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { struct mtd_part *part = PART(mtd); - return part->master->_panic_write(part->master, to + part->offset, len, - retlen, buf); + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + if (to >= mtd->size) + len = 0; + else if (to + len > mtd->size) + len = mtd->size - to; + return mtd_panic_write(part->master, to + part->offset, len, retlen, + buf); } static int part_write_oob(struct mtd_info *mtd, loff_t to, @@ -193,43 +208,50 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to, { struct mtd_part *part = PART(mtd); + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + if (to >= mtd->size) return -EINVAL; if (ops->datbuf && to + ops->len > mtd->size) return -EINVAL; - return part->master->_write_oob(part->master, to + part->offset, ops); + return mtd_write_oob(part->master, to + part->offset, ops); } static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { struct mtd_part *part = PART(mtd); - return part->master->_write_user_prot_reg(part->master, from, len, - retlen, buf); + return mtd_write_user_prot_reg(part->master, from, len, retlen, buf); } static int part_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len) { struct mtd_part *part = PART(mtd); - return part->master->_lock_user_prot_reg(part->master, from, len); + return mtd_lock_user_prot_reg(part->master, from, len); } static int part_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen) { struct mtd_part *part = PART(mtd); - return part->master->_writev(part->master, vecs, count, - to + part->offset, retlen); + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + return mtd_writev(part->master, vecs, count, to + part->offset, + retlen); } static int part_erase(struct mtd_info *mtd, struct erase_info *instr) { struct mtd_part *part = PART(mtd); int ret; - + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + if (instr->addr >= mtd->size) + return -EINVAL; instr->addr += part->offset; - ret = part->master->_erase(part->master, instr); + ret = mtd_erase(part->master, instr); if (ret) { if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) instr->fail_addr -= part->offset; @@ -240,7 +262,7 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr) void mtd_erase_callback(struct erase_info *instr) { - if (instr->mtd->_erase == part_erase) { + if (instr->mtd->erase == part_erase) { struct mtd_part *part = PART(instr->mtd); if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) @@ -255,44 +277,52 @@ EXPORT_SYMBOL_GPL(mtd_erase_callback); static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { struct mtd_part *part = PART(mtd); - return part->master->_lock(part->master, ofs + part->offset, len); + if ((len + ofs) > mtd->size) + return -EINVAL; + return mtd_lock(part->master, ofs + part->offset, len); } static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { struct mtd_part *part = PART(mtd); - return part->master->_unlock(part->master, ofs + part->offset, len); + if ((len + ofs) > mtd->size) + return -EINVAL; + return mtd_unlock(part->master, ofs + part->offset, len); } static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) { struct mtd_part *part = PART(mtd); - return part->master->_is_locked(part->master, ofs + part->offset, len); + if ((len + ofs) > mtd->size) + return -EINVAL; + return mtd_is_locked(part->master, ofs + part->offset, len); } static void part_sync(struct mtd_info *mtd) { struct mtd_part *part = PART(mtd); - part->master->_sync(part->master); + mtd_sync(part->master); } static int part_suspend(struct mtd_info *mtd) { struct mtd_part *part = PART(mtd); - return part->master->_suspend(part->master); + return mtd_suspend(part->master); } static void part_resume(struct mtd_info *mtd) { struct mtd_part *part = PART(mtd); - part->master->_resume(part->master); + mtd_resume(part->master); } static int part_block_isbad(struct mtd_info *mtd, loff_t ofs) { struct mtd_part *part = PART(mtd); + if (ofs >= mtd->size) + return -EINVAL; ofs += part->offset; - return part->master->_block_isbad(part->master, ofs); + return mtd_block_isbad(part->master, ofs); } static int part_block_markbad(struct mtd_info *mtd, loff_t ofs) @@ -300,8 +330,12 @@ static int part_block_markbad(struct mtd_info *mtd, loff_t ofs) struct mtd_part *part = PART(mtd); int res; + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + if (ofs >= mtd->size) + return -EINVAL; ofs += part->offset; - res = part->master->_block_markbad(part->master, ofs); + res = mtd_block_markbad(part->master, ofs); if (!res) mtd->ecc_stats.badblocks++; return res; @@ -376,55 +410,54 @@ static struct mtd_part *allocate_partition(struct mtd_info *master, */ slave->mtd.dev.parent = master->dev.parent; - slave->mtd._read = part_read; - slave->mtd._write = part_write; + slave->mtd.read = part_read; + slave->mtd.write = part_write; - if (master->_panic_write) - slave->mtd._panic_write = part_panic_write; + if (master->panic_write) + slave->mtd.panic_write = part_panic_write; - if (master->_point && master->_unpoint) { - slave->mtd._point = part_point; - slave->mtd._unpoint = part_unpoint; + if (master->point && master->unpoint) { + slave->mtd.point = part_point; + slave->mtd.unpoint = part_unpoint; } - if (master->_get_unmapped_area) - slave->mtd._get_unmapped_area = part_get_unmapped_area; - if (master->_read_oob) - slave->mtd._read_oob = part_read_oob; - if (master->_write_oob) - slave->mtd._write_oob = part_write_oob; - if (master->_read_user_prot_reg) - slave->mtd._read_user_prot_reg = part_read_user_prot_reg; - if (master->_read_fact_prot_reg) - slave->mtd._read_fact_prot_reg = part_read_fact_prot_reg; - if (master->_write_user_prot_reg) - slave->mtd._write_user_prot_reg = part_write_user_prot_reg; - if (master->_lock_user_prot_reg) - slave->mtd._lock_user_prot_reg = part_lock_user_prot_reg; - if (master->_get_user_prot_info) - slave->mtd._get_user_prot_info = part_get_user_prot_info; - if (master->_get_fact_prot_info) - slave->mtd._get_fact_prot_info = part_get_fact_prot_info; - if (master->_sync) - slave->mtd._sync = part_sync; - if (!partno && !master->dev.class && master->_suspend && - master->_resume) { - slave->mtd._suspend = part_suspend; - slave->mtd._resume = part_resume; + if (master->get_unmapped_area) + slave->mtd.get_unmapped_area = part_get_unmapped_area; + if (master->read_oob) + slave->mtd.read_oob = part_read_oob; + if (master->write_oob) + slave->mtd.write_oob = part_write_oob; + if (master->read_user_prot_reg) + slave->mtd.read_user_prot_reg = part_read_user_prot_reg; + if (master->read_fact_prot_reg) + slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg; + if (master->write_user_prot_reg) + slave->mtd.write_user_prot_reg = part_write_user_prot_reg; + if (master->lock_user_prot_reg) + slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg; + if (master->get_user_prot_info) + slave->mtd.get_user_prot_info = part_get_user_prot_info; + if (master->get_fact_prot_info) + slave->mtd.get_fact_prot_info = part_get_fact_prot_info; + if (master->sync) + slave->mtd.sync = part_sync; + if (!partno && !master->dev.class && master->suspend && master->resume) { + slave->mtd.suspend = part_suspend; + slave->mtd.resume = part_resume; } - if (master->_writev) - slave->mtd._writev = part_writev; - if (master->_lock) - slave->mtd._lock = part_lock; - if (master->_unlock) - slave->mtd._unlock = part_unlock; - if (master->_is_locked) - slave->mtd._is_locked = part_is_locked; - if (master->_block_isbad) - slave->mtd._block_isbad = part_block_isbad; - if (master->_block_markbad) - slave->mtd._block_markbad = part_block_markbad; - slave->mtd._erase = part_erase; + if (master->writev) + slave->mtd.writev = part_writev; + if (master->lock) + slave->mtd.lock = part_lock; + if (master->unlock) + slave->mtd.unlock = part_unlock; + if (master->is_locked) + slave->mtd.is_locked = part_is_locked; + if (master->block_isbad) + slave->mtd.block_isbad = part_block_isbad; + if (master->block_markbad) + slave->mtd.block_markbad = part_block_markbad; + slave->mtd.erase = part_erase; slave->master = master; slave->offset = part->offset; @@ -516,8 +549,7 @@ static struct mtd_part *allocate_partition(struct mtd_info *master, } slave->mtd.ecclayout = master->ecclayout; - slave->mtd.ecc_strength = master->ecc_strength; - if (master->_block_isbad) { + if (master->block_isbad) { uint64_t offs = 0; while (offs < slave->mtd.size) { @@ -729,7 +761,7 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types, for ( ; ret <= 0 && *types; types++) { parser = get_partition_parser(*types); if (!parser && !request_module("%s", *types)) - parser = get_partition_parser(*types); + parser = get_partition_parser(*types); if (!parser) continue; ret = (*parser->parse_fn)(master, pparts, data); diff --git a/trunk/drivers/mtd/nand/Kconfig b/trunk/drivers/mtd/nand/Kconfig index 7d17cecad69d..a3c4de551ebe 100644 --- a/trunk/drivers/mtd/nand/Kconfig +++ b/trunk/drivers/mtd/nand/Kconfig @@ -314,26 +314,6 @@ config MTD_NAND_DISKONCHIP_BBTWRITE load time (assuming you build diskonchip as a module) with the module parameter "inftl_bbt_write=1". -config MTD_NAND_DOCG4 - tristate "Support for DiskOnChip G4 (EXPERIMENTAL)" - depends on EXPERIMENTAL - select BCH - select BITREVERSE - help - Support for diskonchip G4 nand flash, found in various smartphones and - PDAs, among them the Palm Treo680, HTC Prophet and Wizard, Toshiba - Portege G900, Asus P526, and O2 XDA Zinc. - - With this driver you will be able to use UBI and create a ubifs on the - device, so you may wish to consider enabling UBI and UBIFS as well. - - These devices ship with the Mys/Sandisk SAFTL formatting, for which - there is currently no mtd parser, so you may want to use command line - partitioning to segregate write-protected blocks. On the Treo680, the - first five erase blocks (256KiB each) are write-protected, followed - by the block containing the saftl partition table. This is probably - typical. - config MTD_NAND_SHARPSL tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)" depends on ARCH_PXA @@ -441,6 +421,7 @@ config MTD_NAND_NANDSIM config MTD_NAND_GPMI_NAND bool "GPMI NAND Flash Controller driver" depends on MTD_NAND && (SOC_IMX23 || SOC_IMX28) + select MTD_CMDLINE_PARTS help Enables NAND Flash support for IMX23 or IMX28. The GPMI controller is very powerful, with the help of BCH diff --git a/trunk/drivers/mtd/nand/Makefile b/trunk/drivers/mtd/nand/Makefile index d4b4d8739bd8..19bc8cb1d187 100644 --- a/trunk/drivers/mtd/nand/Makefile +++ b/trunk/drivers/mtd/nand/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o -obj-$(CONFIG_MTD_NAND_DOCG4) += docg4.o obj-$(CONFIG_MTD_NAND_FSMC) += fsmc_nand.o obj-$(CONFIG_MTD_NAND_H1900) += h1910.o obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o diff --git a/trunk/drivers/mtd/nand/alauda.c b/trunk/drivers/mtd/nand/alauda.c index 4f20e1d8bef1..6a5ff64a139e 100644 --- a/trunk/drivers/mtd/nand/alauda.c +++ b/trunk/drivers/mtd/nand/alauda.c @@ -585,13 +585,12 @@ static int alauda_init_media(struct alauda *al) mtd->writesize = 1<pageshift; mtd->type = MTD_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH; - mtd->_read = alauda_read; - mtd->_write = alauda_write; - mtd->_erase = alauda_erase; - mtd->_block_isbad = alauda_isbad; + mtd->read = alauda_read; + mtd->write = alauda_write; + mtd->erase = alauda_erase; + mtd->block_isbad = alauda_isbad; mtd->priv = al; mtd->owner = THIS_MODULE; - mtd->ecc_strength = 1; err = mtd_device_register(mtd, NULL, 0); if (err) { diff --git a/trunk/drivers/mtd/nand/atmel_nand.c b/trunk/drivers/mtd/nand/atmel_nand.c index 2165576a1c67..ae7e37d9ac17 100644 --- a/trunk/drivers/mtd/nand/atmel_nand.c +++ b/trunk/drivers/mtd/nand/atmel_nand.c @@ -603,7 +603,6 @@ static int __init atmel_nand_probe(struct platform_device *pdev) nand_chip->ecc.hwctl = atmel_nand_hwctl; nand_chip->ecc.read_page = atmel_nand_read_page; nand_chip->ecc.bytes = 4; - nand_chip->ecc.strength = 1; } nand_chip->chip_delay = 20; /* 20us command delay time */ diff --git a/trunk/drivers/mtd/nand/bcm_umi_nand.c b/trunk/drivers/mtd/nand/bcm_umi_nand.c index 6908cdde3065..64c9cbaf86a1 100644 --- a/trunk/drivers/mtd/nand/bcm_umi_nand.c +++ b/trunk/drivers/mtd/nand/bcm_umi_nand.c @@ -475,14 +475,6 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev) largepage_bbt.options = NAND_BBT_SCAN2NDPAGE; this->badblock_pattern = &largepage_bbt; } - - /* - * FIXME: ecc strength value of 6 bits per 512 bytes of data is a - * conservative guess, given 13 ecc bytes and using bch alg. - * (Assume Galois field order m=15 to allow a margin of error.) - */ - this->ecc.strength = 6; - #endif /* Now finish off the scan, now that ecc.layout has been initialized. */ @@ -495,7 +487,7 @@ static int __devinit bcm_umi_nand_probe(struct platform_device *pdev) /* Register the partitions */ board_mtd->name = "bcm_umi-nand"; - mtd_device_parse_register(board_mtd, NULL, NULL, NULL, 0); + mtd_device_parse_register(board_mtd, NULL, 0, NULL, 0); /* Return happy */ return 0; diff --git a/trunk/drivers/mtd/nand/bf5xx_nand.c b/trunk/drivers/mtd/nand/bf5xx_nand.c index d7b86b925de5..dd899cb5d366 100644 --- a/trunk/drivers/mtd/nand/bf5xx_nand.c +++ b/trunk/drivers/mtd/nand/bf5xx_nand.c @@ -702,11 +702,9 @@ static int bf5xx_nand_scan(struct mtd_info *mtd) if (likely(mtd->writesize >= 512)) { chip->ecc.size = 512; chip->ecc.bytes = 6; - chip->ecc.strength = 2; } else { chip->ecc.size = 256; chip->ecc.bytes = 3; - chip->ecc.strength = 1; bfin_write_NFC_CTL(bfin_read_NFC_CTL() & ~(1 << NFC_PG_SIZE_OFFSET)); SSYNC(); } diff --git a/trunk/drivers/mtd/nand/cafe_nand.c b/trunk/drivers/mtd/nand/cafe_nand.c index 2a96e1a12062..72d3f23490c5 100644 --- a/trunk/drivers/mtd/nand/cafe_nand.c +++ b/trunk/drivers/mtd/nand/cafe_nand.c @@ -783,7 +783,6 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, cafe->nand.ecc.mode = NAND_ECC_HW_SYNDROME; cafe->nand.ecc.size = mtd->writesize; cafe->nand.ecc.bytes = 14; - cafe->nand.ecc.strength = 4; cafe->nand.ecc.hwctl = (void *)cafe_nand_bug; cafe->nand.ecc.calculate = (void *)cafe_nand_bug; cafe->nand.ecc.correct = (void *)cafe_nand_bug; @@ -800,7 +799,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, mtd); mtd->name = "cafe_nand"; - mtd_device_parse_register(mtd, part_probes, NULL, NULL, 0); + mtd_device_parse_register(mtd, part_probes, 0, NULL, 0); goto out; diff --git a/trunk/drivers/mtd/nand/cmx270_nand.c b/trunk/drivers/mtd/nand/cmx270_nand.c index 1024bfc05c86..737ef9a04fdb 100644 --- a/trunk/drivers/mtd/nand/cmx270_nand.c +++ b/trunk/drivers/mtd/nand/cmx270_nand.c @@ -219,7 +219,7 @@ static int __init cmx270_init(void) } /* Register the partitions */ - ret = mtd_device_parse_register(cmx270_nand_mtd, NULL, NULL, + ret = mtd_device_parse_register(cmx270_nand_mtd, NULL, 0, partition_info, NUM_PARTITIONS); if (ret) goto err_scan; diff --git a/trunk/drivers/mtd/nand/cs553x_nand.c b/trunk/drivers/mtd/nand/cs553x_nand.c index 821c34c62500..414afa793563 100644 --- a/trunk/drivers/mtd/nand/cs553x_nand.c +++ b/trunk/drivers/mtd/nand/cs553x_nand.c @@ -248,8 +248,6 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) goto out_ior; } - this->ecc.strength = 1; - new_mtd->name = kasprintf(GFP_KERNEL, "cs553x_nand_cs%d", cs); cs553x_mtd[cs] = new_mtd; @@ -315,7 +313,7 @@ static int __init cs553x_init(void) for (i = 0; i < NR_CS553X_CONTROLLERS; i++) { if (cs553x_mtd[i]) { /* If any devices registered, return success. Else the last error. */ - mtd_device_parse_register(cs553x_mtd[i], NULL, NULL, + mtd_device_parse_register(cs553x_mtd[i], NULL, 0, NULL, 0); err = 0; } diff --git a/trunk/drivers/mtd/nand/davinci_nand.c b/trunk/drivers/mtd/nand/davinci_nand.c index d94b03c207af..6e566156956f 100644 --- a/trunk/drivers/mtd/nand/davinci_nand.c +++ b/trunk/drivers/mtd/nand/davinci_nand.c @@ -641,7 +641,6 @@ static int __init nand_davinci_probe(struct platform_device *pdev) info->chip.ecc.bytes = 3; } info->chip.ecc.size = 512; - info->chip.ecc.strength = pdata->ecc_bits; break; default: ret = -EINVAL; @@ -753,8 +752,8 @@ static int __init nand_davinci_probe(struct platform_device *pdev) if (ret < 0) goto err_scan; - ret = mtd_device_parse_register(&info->mtd, NULL, NULL, pdata->parts, - pdata->nr_parts); + ret = mtd_device_parse_register(&info->mtd, NULL, 0, + pdata->parts, pdata->nr_parts); if (ret < 0) goto err_scan; diff --git a/trunk/drivers/mtd/nand/denali.c b/trunk/drivers/mtd/nand/denali.c index a9e57d686297..3984d488f9ab 100644 --- a/trunk/drivers/mtd/nand/denali.c +++ b/trunk/drivers/mtd/nand/denali.c @@ -1590,7 +1590,6 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) ECC_15BITS * (denali->mtd.writesize / ECC_SECTOR_SIZE)))) { /* if MLC OOB size is large enough, use 15bit ECC*/ - denali->nand.ecc.strength = 15; denali->nand.ecc.layout = &nand_15bit_oob; denali->nand.ecc.bytes = ECC_15BITS; iowrite32(15, denali->flash_reg + ECC_CORRECTION); @@ -1601,14 +1600,12 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) " contain 8bit ECC correction codes"); goto failed_req_irq; } else { - denali->nand.ecc.strength = 8; denali->nand.ecc.layout = &nand_8bit_oob; denali->nand.ecc.bytes = ECC_8BITS; iowrite32(8, denali->flash_reg + ECC_CORRECTION); } denali->nand.ecc.bytes *= denali->devnum; - denali->nand.ecc.strength *= denali->devnum; denali->nand.ecc.layout->eccbytes *= denali->mtd.writesize / ECC_SECTOR_SIZE; denali->nand.ecc.layout->oobfree[0].offset = diff --git a/trunk/drivers/mtd/nand/diskonchip.c b/trunk/drivers/mtd/nand/diskonchip.c index e2ca067631cf..df921e7a496c 100644 --- a/trunk/drivers/mtd/nand/diskonchip.c +++ b/trunk/drivers/mtd/nand/diskonchip.c @@ -1653,7 +1653,6 @@ static int __init doc_probe(unsigned long physadr) nand->ecc.mode = NAND_ECC_HW_SYNDROME; nand->ecc.size = 512; nand->ecc.bytes = 6; - nand->ecc.strength = 2; nand->bbt_options = NAND_BBT_USE_FLASH; doc->physadr = physadr; diff --git a/trunk/drivers/mtd/nand/docg4.c b/trunk/drivers/mtd/nand/docg4.c deleted file mode 100644 index b08202664543..000000000000 --- a/trunk/drivers/mtd/nand/docg4.c +++ /dev/null @@ -1,1377 +0,0 @@ -/* - * Copyright © 2012 Mike Dunn - * - * mtd nand driver for M-Systems DiskOnChip G4 - * - * 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. - * - * Tested on the Palm Treo 680. The G4 is also present on Toshiba Portege, Asus - * P526, some HTC smartphones (Wizard, Prophet, ...), O2 XDA Zinc, maybe others. - * Should work on these as well. Let me know! - * - * TODO: - * - * Mechanism for management of password-protected areas - * - * Hamming ecc when reading oob only - * - * According to the M-Sys documentation, this device is also available in a - * "dual-die" configuration having a 256MB capacity, but no mechanism for - * detecting this variant is documented. Currently this driver assumes 128MB - * capacity. - * - * Support for multiple cascaded devices ("floors"). Not sure which gadgets - * contain multiple G4s in a cascaded configuration, if any. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * You'll want to ignore badblocks if you're reading a partition that contains - * data written by the TrueFFS library (i.e., by PalmOS, Windows, etc), since - * it does not use mtd nand's method for marking bad blocks (using oob area). - * This will also skip the check of the "page written" flag. - */ -static bool ignore_badblocks; -module_param(ignore_badblocks, bool, 0); -MODULE_PARM_DESC(ignore_badblocks, "no badblock checking performed"); - -struct docg4_priv { - struct mtd_info *mtd; - struct device *dev; - void __iomem *virtadr; - int status; - struct { - unsigned int command; - int column; - int page; - } last_command; - uint8_t oob_buf[16]; - uint8_t ecc_buf[7]; - int oob_page; - struct bch_control *bch; -}; - -/* - * Defines prefixed with DOCG4 are unique to the diskonchip G4. All others are - * shared with other diskonchip devices (P3, G3 at least). - * - * Functions with names prefixed with docg4_ are mtd / nand interface functions - * (though they may also be called internally). All others are internal. - */ - -#define DOC_IOSPACE_DATA 0x0800 - -/* register offsets */ -#define DOC_CHIPID 0x1000 -#define DOC_DEVICESELECT 0x100a -#define DOC_ASICMODE 0x100c -#define DOC_DATAEND 0x101e -#define DOC_NOP 0x103e - -#define DOC_FLASHSEQUENCE 0x1032 -#define DOC_FLASHCOMMAND 0x1034 -#define DOC_FLASHADDRESS 0x1036 -#define DOC_FLASHCONTROL 0x1038 -#define DOC_ECCCONF0 0x1040 -#define DOC_ECCCONF1 0x1042 -#define DOC_HAMMINGPARITY 0x1046 -#define DOC_BCH_SYNDROM(idx) (0x1048 + idx) - -#define DOC_ASICMODECONFIRM 0x1072 -#define DOC_CHIPID_INV 0x1074 -#define DOC_POWERMODE 0x107c - -#define DOCG4_MYSTERY_REG 0x1050 - -/* apparently used only to write oob bytes 6 and 7 */ -#define DOCG4_OOB_6_7 0x1052 - -/* DOC_FLASHSEQUENCE register commands */ -#define DOC_SEQ_RESET 0x00 -#define DOCG4_SEQ_PAGE_READ 0x03 -#define DOCG4_SEQ_FLUSH 0x29 -#define DOCG4_SEQ_PAGEWRITE 0x16 -#define DOCG4_SEQ_PAGEPROG 0x1e -#define DOCG4_SEQ_BLOCKERASE 0x24 - -/* DOC_FLASHCOMMAND register commands */ -#define DOCG4_CMD_PAGE_READ 0x00 -#define DOC_CMD_ERASECYCLE2 0xd0 -#define DOCG4_CMD_FLUSH 0x70 -#define DOCG4_CMD_READ2 0x30 -#define DOC_CMD_PROG_BLOCK_ADDR 0x60 -#define DOCG4_CMD_PAGEWRITE 0x80 -#define DOC_CMD_PROG_CYCLE2 0x10 -#define DOC_CMD_RESET 0xff - -/* DOC_POWERMODE register bits */ -#define DOC_POWERDOWN_READY 0x80 - -/* DOC_FLASHCONTROL register bits */ -#define DOC_CTRL_CE 0x10 -#define DOC_CTRL_UNKNOWN 0x40 -#define DOC_CTRL_FLASHREADY 0x01 - -/* DOC_ECCCONF0 register bits */ -#define DOC_ECCCONF0_READ_MODE 0x8000 -#define DOC_ECCCONF0_UNKNOWN 0x2000 -#define DOC_ECCCONF0_ECC_ENABLE 0x1000 -#define DOC_ECCCONF0_DATA_BYTES_MASK 0x07ff - -/* DOC_ECCCONF1 register bits */ -#define DOC_ECCCONF1_BCH_SYNDROM_ERR 0x80 -#define DOC_ECCCONF1_ECC_ENABLE 0x07 -#define DOC_ECCCONF1_PAGE_IS_WRITTEN 0x20 - -/* DOC_ASICMODE register bits */ -#define DOC_ASICMODE_RESET 0x00 -#define DOC_ASICMODE_NORMAL 0x01 -#define DOC_ASICMODE_POWERDOWN 0x02 -#define DOC_ASICMODE_MDWREN 0x04 -#define DOC_ASICMODE_BDETCT_RESET 0x08 -#define DOC_ASICMODE_RSTIN_RESET 0x10 -#define DOC_ASICMODE_RAM_WE 0x20 - -/* good status values read after read/write/erase operations */ -#define DOCG4_PROGSTATUS_GOOD 0x51 -#define DOCG4_PROGSTATUS_GOOD_2 0xe0 - -/* - * On read operations (page and oob-only), the first byte read from I/O reg is a - * status. On error, it reads 0x73; otherwise, it reads either 0x71 (first read - * after reset only) or 0x51, so bit 1 is presumed to be an error indicator. - */ -#define DOCG4_READ_ERROR 0x02 /* bit 1 indicates read error */ - -/* anatomy of the device */ -#define DOCG4_CHIP_SIZE 0x8000000 -#define DOCG4_PAGE_SIZE 0x200 -#define DOCG4_PAGES_PER_BLOCK 0x200 -#define DOCG4_BLOCK_SIZE (DOCG4_PAGES_PER_BLOCK * DOCG4_PAGE_SIZE) -#define DOCG4_NUMBLOCKS (DOCG4_CHIP_SIZE / DOCG4_BLOCK_SIZE) -#define DOCG4_OOB_SIZE 0x10 -#define DOCG4_CHIP_SHIFT 27 /* log_2(DOCG4_CHIP_SIZE) */ -#define DOCG4_PAGE_SHIFT 9 /* log_2(DOCG4_PAGE_SIZE) */ -#define DOCG4_ERASE_SHIFT 18 /* log_2(DOCG4_BLOCK_SIZE) */ - -/* all but the last byte is included in ecc calculation */ -#define DOCG4_BCH_SIZE (DOCG4_PAGE_SIZE + DOCG4_OOB_SIZE - 1) - -#define DOCG4_USERDATA_LEN 520 /* 512 byte page plus 8 oob avail to user */ - -/* expected values from the ID registers */ -#define DOCG4_IDREG1_VALUE 0x0400 -#define DOCG4_IDREG2_VALUE 0xfbff - -/* primitive polynomial used to build the Galois field used by hw ecc gen */ -#define DOCG4_PRIMITIVE_POLY 0x4443 - -#define DOCG4_M 14 /* Galois field is of order 2^14 */ -#define DOCG4_T 4 /* BCH alg corrects up to 4 bit errors */ - -#define DOCG4_FACTORY_BBT_PAGE 16 /* page where read-only factory bbt lives */ - -/* - * Oob bytes 0 - 6 are available to the user. - * Byte 7 is hamming ecc for first 7 bytes. Bytes 8 - 14 are hw-generated ecc. - * Byte 15 (the last) is used by the driver as a "page written" flag. - */ -static struct nand_ecclayout docg4_oobinfo = { - .eccbytes = 9, - .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, - .oobavail = 7, - .oobfree = { {0, 7} } -}; - -/* - * The device has a nop register which M-Sys claims is for the purpose of - * inserting precise delays. But beware; at least some operations fail if the - * nop writes are replaced with a generic delay! - */ -static inline void write_nop(void __iomem *docptr) -{ - writew(0, docptr + DOC_NOP); -} - -static void docg4_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) -{ - int i; - struct nand_chip *nand = mtd->priv; - uint16_t *p = (uint16_t *) buf; - len >>= 1; - - for (i = 0; i < len; i++) - p[i] = readw(nand->IO_ADDR_R); -} - -static void docg4_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) -{ - int i; - struct nand_chip *nand = mtd->priv; - uint16_t *p = (uint16_t *) buf; - len >>= 1; - - for (i = 0; i < len; i++) - writew(p[i], nand->IO_ADDR_W); -} - -static int poll_status(struct docg4_priv *doc) -{ - /* - * Busy-wait for the FLASHREADY bit to be set in the FLASHCONTROL - * register. Operations known to take a long time (e.g., block erase) - * should sleep for a while before calling this. - */ - - uint16_t flash_status; - unsigned int timeo; - void __iomem *docptr = doc->virtadr; - - dev_dbg(doc->dev, "%s...\n", __func__); - - /* hardware quirk requires reading twice initially */ - flash_status = readw(docptr + DOC_FLASHCONTROL); - - timeo = 1000; - do { - cpu_relax(); - flash_status = readb(docptr + DOC_FLASHCONTROL); - } while (!(flash_status & DOC_CTRL_FLASHREADY) && --timeo); - - - if (!timeo) { - dev_err(doc->dev, "%s: timed out!\n", __func__); - return NAND_STATUS_FAIL; - } - - if (unlikely(timeo < 50)) - dev_warn(doc->dev, "%s: nearly timed out; %d remaining\n", - __func__, timeo); - - return 0; -} - - -static int docg4_wait(struct mtd_info *mtd, struct nand_chip *nand) -{ - - struct docg4_priv *doc = nand->priv; - int status = NAND_STATUS_WP; /* inverse logic?? */ - dev_dbg(doc->dev, "%s...\n", __func__); - - /* report any previously unreported error */ - if (doc->status) { - status |= doc->status; - doc->status = 0; - return status; - } - - status |= poll_status(doc); - return status; -} - -static void docg4_select_chip(struct mtd_info *mtd, int chip) -{ - /* - * Select among multiple cascaded chips ("floors"). Multiple floors are - * not yet supported, so the only valid non-negative value is 0. - */ - struct nand_chip *nand = mtd->priv; - struct docg4_priv *doc = nand->priv; - void __iomem *docptr = doc->virtadr; - - dev_dbg(doc->dev, "%s: chip %d\n", __func__, chip); - - if (chip < 0) - return; /* deselected */ - - if (chip > 0) - dev_warn(doc->dev, "multiple floors currently unsupported\n"); - - writew(0, docptr + DOC_DEVICESELECT); -} - -static void reset(struct mtd_info *mtd) -{ - /* full device reset */ - - struct nand_chip *nand = mtd->priv; - struct docg4_priv *doc = nand->priv; - void __iomem *docptr = doc->virtadr; - - writew(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN, - docptr + DOC_ASICMODE); - writew(~(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN), - docptr + DOC_ASICMODECONFIRM); - write_nop(docptr); - - writew(DOC_ASICMODE_NORMAL | DOC_ASICMODE_MDWREN, - docptr + DOC_ASICMODE); - writew(~(DOC_ASICMODE_NORMAL | DOC_ASICMODE_MDWREN), - docptr + DOC_ASICMODECONFIRM); - - writew(DOC_ECCCONF1_ECC_ENABLE, docptr + DOC_ECCCONF1); - - poll_status(doc); -} - -static void read_hw_ecc(void __iomem *docptr, uint8_t *ecc_buf) -{ - /* read the 7 hw-generated ecc bytes */ - - int i; - for (i = 0; i < 7; i++) { /* hw quirk; read twice */ - ecc_buf[i] = readb(docptr + DOC_BCH_SYNDROM(i)); - ecc_buf[i] = readb(docptr + DOC_BCH_SYNDROM(i)); - } -} - -static int correct_data(struct mtd_info *mtd, uint8_t *buf, int page) -{ - /* - * Called after a page read when hardware reports bitflips. - * Up to four bitflips can be corrected. - */ - - struct nand_chip *nand = mtd->priv; - struct docg4_priv *doc = nand->priv; - void __iomem *docptr = doc->virtadr; - int i, numerrs, errpos[4]; - const uint8_t blank_read_hwecc[8] = { - 0xcf, 0x72, 0xfc, 0x1b, 0xa9, 0xc7, 0xb9, 0 }; - - read_hw_ecc(docptr, doc->ecc_buf); /* read 7 hw-generated ecc bytes */ - - /* check if read error is due to a blank page */ - if (!memcmp(doc->ecc_buf, blank_read_hwecc, 7)) - return 0; /* yes */ - - /* skip additional check of "written flag" if ignore_badblocks */ - if (ignore_badblocks == false) { - - /* - * If the hw ecc bytes are not those of a blank page, there's - * still a chance that the page is blank, but was read with - * errors. Check the "written flag" in last oob byte, which - * is set to zero when a page is written. If more than half - * the bits are set, assume a blank page. Unfortunately, the - * bit flips(s) are not reported in stats. - */ - - if (doc->oob_buf[15]) { - int bit, numsetbits = 0; - unsigned long written_flag = doc->oob_buf[15]; - for_each_set_bit(bit, &written_flag, 8) - numsetbits++; - if (numsetbits > 4) { /* assume blank */ - dev_warn(doc->dev, - "error(s) in blank page " - "at offset %08x\n", - page * DOCG4_PAGE_SIZE); - return 0; - } - } - } - - /* - * The hardware ecc unit produces oob_ecc ^ calc_ecc. The kernel's bch - * algorithm is used to decode this. However the hw operates on page - * data in a bit order that is the reverse of that of the bch alg, - * requiring that the bits be reversed on the result. Thanks to Ivan - * Djelic for his analysis! - */ - for (i = 0; i < 7; i++) - doc->ecc_buf[i] = bitrev8(doc->ecc_buf[i]); - - numerrs = decode_bch(doc->bch, NULL, DOCG4_USERDATA_LEN, NULL, - doc->ecc_buf, NULL, errpos); - - if (numerrs == -EBADMSG) { - dev_warn(doc->dev, "uncorrectable errors at offset %08x\n", - page * DOCG4_PAGE_SIZE); - return -EBADMSG; - } - - BUG_ON(numerrs < 0); /* -EINVAL, or anything other than -EBADMSG */ - - /* undo last step in BCH alg (modulo mirroring not needed) */ - for (i = 0; i < numerrs; i++) - errpos[i] = (errpos[i] & ~7)|(7-(errpos[i] & 7)); - - /* fix the errors */ - for (i = 0; i < numerrs; i++) { - - /* ignore if error within oob ecc bytes */ - if (errpos[i] > DOCG4_USERDATA_LEN * 8) - continue; - - /* if error within oob area preceeding ecc bytes... */ - if (errpos[i] > DOCG4_PAGE_SIZE * 8) - change_bit(errpos[i] - DOCG4_PAGE_SIZE * 8, - (unsigned long *)doc->oob_buf); - - else /* error in page data */ - change_bit(errpos[i], (unsigned long *)buf); - } - - dev_notice(doc->dev, "%d error(s) corrected at offset %08x\n", - numerrs, page * DOCG4_PAGE_SIZE); - - return numerrs; -} - -static uint8_t docg4_read_byte(struct mtd_info *mtd) -{ - struct nand_chip *nand = mtd->priv; - struct docg4_priv *doc = nand->priv; - - dev_dbg(doc->dev, "%s\n", __func__); - - if (doc->last_command.command == NAND_CMD_STATUS) { - int status; - - /* - * Previous nand command was status request, so nand - * infrastructure code expects to read the status here. If an - * error occurred in a previous operation, report it. - */ - doc->last_command.command = 0; - - if (doc->status) { - status = doc->status; - doc->status = 0; - } - - /* why is NAND_STATUS_WP inverse logic?? */ - else - status = NAND_STATUS_WP | NAND_STATUS_READY; - - return status; - } - - dev_warn(doc->dev, "unexpectd call to read_byte()\n"); - - return 0; -} - -static void write_addr(struct docg4_priv *doc, uint32_t docg4_addr) -{ - /* write the four address bytes packed in docg4_addr to the device */ - - void __iomem *docptr = doc->virtadr; - writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); - docg4_addr >>= 8; - writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); - docg4_addr >>= 8; - writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); - docg4_addr >>= 8; - writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); -} - -static int read_progstatus(struct docg4_priv *doc) -{ - /* - * This apparently checks the status of programming. Done after an - * erasure, and after page data is written. On error, the status is - * saved, to be later retrieved by the nand infrastructure code. - */ - void __iomem *docptr = doc->virtadr; - - /* status is read from the I/O reg */ - uint16_t status1 = readw(docptr + DOC_IOSPACE_DATA); - uint16_t status2 = readw(docptr + DOC_IOSPACE_DATA); - uint16_t status3 = readw(docptr + DOCG4_MYSTERY_REG); - - dev_dbg(doc->dev, "docg4: %s: %02x %02x %02x\n", - __func__, status1, status2, status3); - - if (status1 != DOCG4_PROGSTATUS_GOOD - || status2 != DOCG4_PROGSTATUS_GOOD_2 - || status3 != DOCG4_PROGSTATUS_GOOD_2) { - doc->status = NAND_STATUS_FAIL; - dev_warn(doc->dev, "read_progstatus failed: " - "%02x, %02x, %02x\n", status1, status2, status3); - return -EIO; - } - return 0; -} - -static int pageprog(struct mtd_info *mtd) -{ - /* - * Final step in writing a page. Writes the contents of its - * internal buffer out to the flash array, or some such. - */ - - struct nand_chip *nand = mtd->priv; - struct docg4_priv *doc = nand->priv; - void __iomem *docptr = doc->virtadr; - int retval = 0; - - dev_dbg(doc->dev, "docg4: %s\n", __func__); - - writew(DOCG4_SEQ_PAGEPROG, docptr + DOC_FLASHSEQUENCE); - writew(DOC_CMD_PROG_CYCLE2, docptr + DOC_FLASHCOMMAND); - write_nop(docptr); - write_nop(docptr); - - /* Just busy-wait; usleep_range() slows things down noticeably. */ - poll_status(doc); - - writew(DOCG4_SEQ_FLUSH, docptr + DOC_FLASHSEQUENCE); - writew(DOCG4_CMD_FLUSH, docptr + DOC_FLASHCOMMAND); - writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0); - write_nop(docptr); - write_nop(docptr); - write_nop(docptr); - write_nop(docptr); - write_nop(docptr); - - retval = read_progstatus(doc); - writew(0, docptr + DOC_DATAEND); - write_nop(docptr); - poll_status(doc); - write_nop(docptr); - - return retval; -} - -static void sequence_reset(struct mtd_info *mtd) -{ - /* common starting sequence for all operations */ - - struct nand_chip *nand = mtd->priv; - struct docg4_priv *doc = nand->priv; - void __iomem *docptr = doc->virtadr; - - writew(DOC_CTRL_UNKNOWN | DOC_CTRL_CE, docptr + DOC_FLASHCONTROL); - writew(DOC_SEQ_RESET, docptr + DOC_FLASHSEQUENCE); - writew(DOC_CMD_RESET, docptr + DOC_FLASHCOMMAND); - write_nop(docptr); - write_nop(docptr); - poll_status(doc); - write_nop(docptr); -} - -static void read_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr) -{ - /* first step in reading a page */ - - struct nand_chip *nand = mtd->priv; - struct docg4_priv *doc = nand->priv; - void __iomem *docptr = doc->virtadr; - - dev_dbg(doc->dev, - "docg4: %s: g4 page %08x\n", __func__, docg4_addr); - - sequence_reset(mtd); - - writew(DOCG4_SEQ_PAGE_READ, docptr + DOC_FLASHSEQUENCE); - writew(DOCG4_CMD_PAGE_READ, docptr + DOC_FLASHCOMMAND); - write_nop(docptr); - - write_addr(doc, docg4_addr); - - write_nop(docptr); - writew(DOCG4_CMD_READ2, docptr + DOC_FLASHCOMMAND); - write_nop(docptr); - write_nop(docptr); - - poll_status(doc); -} - -static void write_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr) -{ - /* first step in writing a page */ - - struct nand_chip *nand = mtd->priv; - struct docg4_priv *doc = nand->priv; - void __iomem *docptr = doc->virtadr; - - dev_dbg(doc->dev, - "docg4: %s: g4 addr: %x\n", __func__, docg4_addr); - sequence_reset(mtd); - writew(DOCG4_SEQ_PAGEWRITE, docptr + DOC_FLASHSEQUENCE); - writew(DOCG4_CMD_PAGEWRITE, docptr + DOC_FLASHCOMMAND); - write_nop(docptr); - write_addr(doc, docg4_addr); - write_nop(docptr); - write_nop(docptr); - poll_status(doc); -} - -static uint32_t mtd_to_docg4_address(int page, int column) -{ - /* - * Convert mtd address to format used by the device, 32 bit packed. - * - * Some notes on G4 addressing... The M-Sys documentation on this device - * claims that pages are 2K in length, and indeed, the format of the - * address used by the device reflects that. But within each page are - * four 512 byte "sub-pages", each with its own oob data that is - * read/written immediately after the 512 bytes of page data. This oob - * data contains the ecc bytes for the preceeding 512 bytes. - * - * Rather than tell the mtd nand infrastructure that page size is 2k, - * with four sub-pages each, we engage in a little subterfuge and tell - * the infrastructure code that pages are 512 bytes in size. This is - * done because during the course of reverse-engineering the device, I - * never observed an instance where an entire 2K "page" was read or - * written as a unit. Each "sub-page" is always addressed individually, - * its data read/written, and ecc handled before the next "sub-page" is - * addressed. - * - * This requires us to convert addresses passed by the mtd nand - * infrastructure code to those used by the device. - * - * The address that is written to the device consists of four bytes: the - * first two are the 2k page number, and the second is the index into - * the page. The index is in terms of 16-bit half-words and includes - * the preceeding oob data, so e.g., the index into the second - * "sub-page" is 0x108, and the full device address of the start of mtd - * page 0x201 is 0x00800108. - */ - int g4_page = page / 4; /* device's 2K page */ - int g4_index = (page % 4) * 0x108 + column/2; /* offset into page */ - return (g4_page << 16) | g4_index; /* pack */ -} - -static void docg4_command(struct mtd_info *mtd, unsigned command, int column, - int page_addr) -{ - /* handle standard nand commands */ - - struct nand_chip *nand = mtd->priv; - struct docg4_priv *doc = nand->priv; - uint32_t g4_addr = mtd_to_docg4_address(page_addr, column); - - dev_dbg(doc->dev, "%s %x, page_addr=%x, column=%x\n", - __func__, command, page_addr, column); - - /* - * Save the command and its arguments. This enables emulation of - * standard flash devices, and also some optimizations. - */ - doc->last_command.command = command; - doc->last_command.column = column; - doc->last_command.page = page_addr; - - switch (command) { - - case NAND_CMD_RESET: - reset(mtd); - break; - - case NAND_CMD_READ0: - read_page_prologue(mtd, g4_addr); - break; - - case NAND_CMD_STATUS: - /* next call to read_byte() will expect a status */ - break; - - case NAND_CMD_SEQIN: - write_page_prologue(mtd, g4_addr); - - /* hack for deferred write of oob bytes */ - if (doc->oob_page == page_addr) - memcpy(nand->oob_poi, doc->oob_buf, 16); - break; - - case NAND_CMD_PAGEPROG: - pageprog(mtd); - break; - - /* we don't expect these, based on review of nand_base.c */ - case NAND_CMD_READOOB: - case NAND_CMD_READID: - case NAND_CMD_ERASE1: - case NAND_CMD_ERASE2: - dev_warn(doc->dev, "docg4_command: " - "unexpected nand command 0x%x\n", command); - break; - - } -} - -static int read_page(struct mtd_info *mtd, struct nand_chip *nand, - uint8_t *buf, int page, bool use_ecc) -{ - struct docg4_priv *doc = nand->priv; - void __iomem *docptr = doc->virtadr; - uint16_t status, edc_err, *buf16; - - dev_dbg(doc->dev, "%s: page %08x\n", __func__, page); - - writew(DOC_ECCCONF0_READ_MODE | - DOC_ECCCONF0_ECC_ENABLE | - DOC_ECCCONF0_UNKNOWN | - DOCG4_BCH_SIZE, - docptr + DOC_ECCCONF0); - write_nop(docptr); - write_nop(docptr); - write_nop(docptr); - write_nop(docptr); - write_nop(docptr); - - /* the 1st byte from the I/O reg is a status; the rest is page data */ - status = readw(docptr + DOC_IOSPACE_DATA); - if (status & DOCG4_READ_ERROR) { - dev_err(doc->dev, - "docg4_read_page: bad status: 0x%02x\n", status); - writew(0, docptr + DOC_DATAEND); - return -EIO; - } - - dev_dbg(doc->dev, "%s: status = 0x%x\n", __func__, status); - - docg4_read_buf(mtd, buf, DOCG4_PAGE_SIZE); /* read the page data */ - - /* - * Diskonchips read oob immediately after a page read. Mtd - * infrastructure issues a separate command for reading oob after the - * page is read. So we save the oob bytes in a local buffer and just - * copy it if the next command reads oob from the same page. - */ - - /* first 14 oob bytes read from I/O reg */ - docg4_read_buf(mtd, doc->oob_buf, 14); - - /* last 2 read from another reg */ - buf16 = (uint16_t *)(doc->oob_buf + 14); - *buf16 = readw(docptr + DOCG4_MYSTERY_REG); - - write_nop(docptr); - - if (likely(use_ecc == true)) { - - /* read the register that tells us if bitflip(s) detected */ - edc_err = readw(docptr + DOC_ECCCONF1); - edc_err = readw(docptr + DOC_ECCCONF1); - dev_dbg(doc->dev, "%s: edc_err = 0x%02x\n", __func__, edc_err); - - /* If bitflips are reported, attempt to correct with ecc */ - if (edc_err & DOC_ECCCONF1_BCH_SYNDROM_ERR) { - int bits_corrected = correct_data(mtd, buf, page); - if (bits_corrected == -EBADMSG) - mtd->ecc_stats.failed++; - else - mtd->ecc_stats.corrected += bits_corrected; - } - } - - writew(0, docptr + DOC_DATAEND); - return 0; -} - - -static int docg4_read_page_raw(struct mtd_info *mtd, struct nand_chip *nand, - uint8_t *buf, int page) -{ - return read_page(mtd, nand, buf, page, false); -} - -static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand, - uint8_t *buf, int page) -{ - return read_page(mtd, nand, buf, page, true); -} - -static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand, - int page, int sndcmd) -{ - struct docg4_priv *doc = nand->priv; - void __iomem *docptr = doc->virtadr; - uint16_t status; - - dev_dbg(doc->dev, "%s: page %x\n", __func__, page); - - /* - * Oob bytes are read as part of a normal page read. If the previous - * nand command was a read of the page whose oob is now being read, just - * copy the oob bytes that we saved in a local buffer and avoid a - * separate oob read. - */ - if (doc->last_command.command == NAND_CMD_READ0 && - doc->last_command.page == page) { - memcpy(nand->oob_poi, doc->oob_buf, 16); - return 0; - } - - /* - * Separate read of oob data only. - */ - docg4_command(mtd, NAND_CMD_READ0, nand->ecc.size, page); - - writew(DOC_ECCCONF0_READ_MODE | DOCG4_OOB_SIZE, docptr + DOC_ECCCONF0); - write_nop(docptr); - write_nop(docptr); - write_nop(docptr); - write_nop(docptr); - write_nop(docptr); - - /* the 1st byte from the I/O reg is a status; the rest is oob data */ - status = readw(docptr + DOC_IOSPACE_DATA); - if (status & DOCG4_READ_ERROR) { - dev_warn(doc->dev, - "docg4_read_oob failed: status = 0x%02x\n", status); - return -EIO; - } - - dev_dbg(doc->dev, "%s: status = 0x%x\n", __func__, status); - - docg4_read_buf(mtd, nand->oob_poi, 16); - - write_nop(docptr); - write_nop(docptr); - write_nop(docptr); - writew(0, docptr + DOC_DATAEND); - write_nop(docptr); - - return 0; -} - -static void docg4_erase_block(struct mtd_info *mtd, int page) -{ - struct nand_chip *nand = mtd->priv; - struct docg4_priv *doc = nand->priv; - void __iomem *docptr = doc->virtadr; - uint16_t g4_page; - - dev_dbg(doc->dev, "%s: page %04x\n", __func__, page); - - sequence_reset(mtd); - - writew(DOCG4_SEQ_BLOCKERASE, docptr + DOC_FLASHSEQUENCE); - writew(DOC_CMD_PROG_BLOCK_ADDR, docptr + DOC_FLASHCOMMAND); - write_nop(docptr); - - /* only 2 bytes of address are written to specify erase block */ - g4_page = (uint16_t)(page / 4); /* to g4's 2k page addressing */ - writeb(g4_page & 0xff, docptr + DOC_FLASHADDRESS); - g4_page >>= 8; - writeb(g4_page & 0xff, docptr + DOC_FLASHADDRESS); - write_nop(docptr); - - /* start the erasure */ - writew(DOC_CMD_ERASECYCLE2, docptr + DOC_FLASHCOMMAND); - write_nop(docptr); - write_nop(docptr); - - usleep_range(500, 1000); /* erasure is long; take a snooze */ - poll_status(doc); - writew(DOCG4_SEQ_FLUSH, docptr + DOC_FLASHSEQUENCE); - writew(DOCG4_CMD_FLUSH, docptr + DOC_FLASHCOMMAND); - writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0); - write_nop(docptr); - write_nop(docptr); - write_nop(docptr); - write_nop(docptr); - write_nop(docptr); - - read_progstatus(doc); - - writew(0, docptr + DOC_DATAEND); - write_nop(docptr); - poll_status(doc); - write_nop(docptr); -} - -static void write_page(struct mtd_info *mtd, struct nand_chip *nand, - const uint8_t *buf, bool use_ecc) -{ - struct docg4_priv *doc = nand->priv; - void __iomem *docptr = doc->virtadr; - uint8_t ecc_buf[8]; - - dev_dbg(doc->dev, "%s...\n", __func__); - - writew(DOC_ECCCONF0_ECC_ENABLE | - DOC_ECCCONF0_UNKNOWN | - DOCG4_BCH_SIZE, - docptr + DOC_ECCCONF0); - write_nop(docptr); - - /* write the page data */ - docg4_write_buf16(mtd, buf, DOCG4_PAGE_SIZE); - - /* oob bytes 0 through 5 are written to I/O reg */ - docg4_write_buf16(mtd, nand->oob_poi, 6); - - /* oob byte 6 written to a separate reg */ - writew(nand->oob_poi[6], docptr + DOCG4_OOB_6_7); - - write_nop(docptr); - write_nop(docptr); - - /* write hw-generated ecc bytes to oob */ - if (likely(use_ecc == true)) { - /* oob byte 7 is hamming code */ - uint8_t hamming = readb(docptr + DOC_HAMMINGPARITY); - hamming = readb(docptr + DOC_HAMMINGPARITY); /* 2nd read */ - writew(hamming, docptr + DOCG4_OOB_6_7); - write_nop(docptr); - - /* read the 7 bch bytes from ecc regs */ - read_hw_ecc(docptr, ecc_buf); - ecc_buf[7] = 0; /* clear the "page written" flag */ - } - - /* write user-supplied bytes to oob */ - else { - writew(nand->oob_poi[7], docptr + DOCG4_OOB_6_7); - write_nop(docptr); - memcpy(ecc_buf, &nand->oob_poi[8], 8); - } - - docg4_write_buf16(mtd, ecc_buf, 8); - write_nop(docptr); - write_nop(docptr); - writew(0, docptr + DOC_DATAEND); - write_nop(docptr); -} - -static void docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand, - const uint8_t *buf) -{ - return write_page(mtd, nand, buf, false); -} - -static void docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand, - const uint8_t *buf) -{ - return write_page(mtd, nand, buf, true); -} - -static int docg4_write_oob(struct mtd_info *mtd, struct nand_chip *nand, - int page) -{ - /* - * Writing oob-only is not really supported, because MLC nand must write - * oob bytes at the same time as page data. Nonetheless, we save the - * oob buffer contents here, and then write it along with the page data - * if the same page is subsequently written. This allows user space - * utilities that write the oob data prior to the page data to work - * (e.g., nandwrite). The disdvantage is that, if the intention was to - * write oob only, the operation is quietly ignored. Also, oob can get - * corrupted if two concurrent processes are running nandwrite. - */ - - /* note that bytes 7..14 are hw generated hamming/ecc and overwritten */ - struct docg4_priv *doc = nand->priv; - doc->oob_page = page; - memcpy(doc->oob_buf, nand->oob_poi, 16); - return 0; -} - -static int __init read_factory_bbt(struct mtd_info *mtd) -{ - /* - * The device contains a read-only factory bad block table. Read it and - * update the memory-based bbt accordingly. - */ - - struct nand_chip *nand = mtd->priv; - struct docg4_priv *doc = nand->priv; - uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0); - uint8_t *buf; - int i, block, status; - - buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - read_page_prologue(mtd, g4_addr); - status = docg4_read_page(mtd, nand, buf, DOCG4_FACTORY_BBT_PAGE); - if (status) - goto exit; - - /* - * If no memory-based bbt was created, exit. This will happen if module - * parameter ignore_badblocks is set. Then why even call this function? - * For an unknown reason, block erase always fails if it's the first - * operation after device power-up. The above read ensures it never is. - * Ugly, I know. - */ - if (nand->bbt == NULL) /* no memory-based bbt */ - goto exit; - - /* - * Parse factory bbt and update memory-based bbt. Factory bbt format is - * simple: one bit per block, block numbers increase left to right (msb - * to lsb). Bit clear means bad block. - */ - for (i = block = 0; block < DOCG4_NUMBLOCKS; block += 8, i++) { - int bitnum; - unsigned long bits = ~buf[i]; - for_each_set_bit(bitnum, &bits, 8) { - int badblock = block + 7 - bitnum; - nand->bbt[badblock / 4] |= - 0x03 << ((badblock % 4) * 2); - mtd->ecc_stats.badblocks++; - dev_notice(doc->dev, "factory-marked bad block: %d\n", - badblock); - } - } - exit: - kfree(buf); - return status; -} - -static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs) -{ - /* - * Mark a block as bad. Bad blocks are marked in the oob area of the - * first page of the block. The default scan_bbt() in the nand - * infrastructure code works fine for building the memory-based bbt - * during initialization, as does the nand infrastructure function that - * checks if a block is bad by reading the bbt. This function replaces - * the nand default because writes to oob-only are not supported. - */ - - int ret, i; - uint8_t *buf; - struct nand_chip *nand = mtd->priv; - struct docg4_priv *doc = nand->priv; - struct nand_bbt_descr *bbtd = nand->badblock_pattern; - int block = (int)(ofs >> nand->bbt_erase_shift); - int page = (int)(ofs >> nand->page_shift); - uint32_t g4_addr = mtd_to_docg4_address(page, 0); - - dev_dbg(doc->dev, "%s: %08llx\n", __func__, ofs); - - if (unlikely(ofs & (DOCG4_BLOCK_SIZE - 1))) - dev_warn(doc->dev, "%s: ofs %llx not start of block!\n", - __func__, ofs); - - /* allocate blank buffer for page data */ - buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - /* update bbt in memory */ - nand->bbt[block / 4] |= 0x01 << ((block & 0x03) * 2); - - /* write bit-wise negation of pattern to oob buffer */ - memset(nand->oob_poi, 0xff, mtd->oobsize); - for (i = 0; i < bbtd->len; i++) - nand->oob_poi[bbtd->offs + i] = ~bbtd->pattern[i]; - - /* write first page of block */ - write_page_prologue(mtd, g4_addr); - docg4_write_page(mtd, nand, buf); - ret = pageprog(mtd); - if (!ret) - mtd->ecc_stats.badblocks++; - - kfree(buf); - - return ret; -} - -static int docg4_block_neverbad(struct mtd_info *mtd, loff_t ofs, int getchip) -{ - /* only called when module_param ignore_badblocks is set */ - return 0; -} - -static int docg4_suspend(struct platform_device *pdev, pm_message_t state) -{ - /* - * Put the device into "deep power-down" mode. Note that CE# must be - * deasserted for this to take effect. The xscale, e.g., can be - * configured to float this signal when the processor enters power-down, - * and a suitable pull-up ensures its deassertion. - */ - - int i; - uint8_t pwr_down; - struct docg4_priv *doc = platform_get_drvdata(pdev); - void __iomem *docptr = doc->virtadr; - - dev_dbg(doc->dev, "%s...\n", __func__); - - /* poll the register that tells us we're ready to go to sleep */ - for (i = 0; i < 10; i++) { - pwr_down = readb(docptr + DOC_POWERMODE); - if (pwr_down & DOC_POWERDOWN_READY) - break; - usleep_range(1000, 4000); - } - - if (pwr_down & DOC_POWERDOWN_READY) { - dev_err(doc->dev, "suspend failed; " - "timeout polling DOC_POWERDOWN_READY\n"); - return -EIO; - } - - writew(DOC_ASICMODE_POWERDOWN | DOC_ASICMODE_MDWREN, - docptr + DOC_ASICMODE); - writew(~(DOC_ASICMODE_POWERDOWN | DOC_ASICMODE_MDWREN), - docptr + DOC_ASICMODECONFIRM); - - write_nop(docptr); - - return 0; -} - -static int docg4_resume(struct platform_device *pdev) -{ - - /* - * Exit power-down. Twelve consecutive reads of the address below - * accomplishes this, assuming CE# has been asserted. - */ - - struct docg4_priv *doc = platform_get_drvdata(pdev); - void __iomem *docptr = doc->virtadr; - int i; - - dev_dbg(doc->dev, "%s...\n", __func__); - - for (i = 0; i < 12; i++) - readb(docptr + 0x1fff); - - return 0; -} - -static void __init init_mtd_structs(struct mtd_info *mtd) -{ - /* initialize mtd and nand data structures */ - - /* - * Note that some of the following initializations are not usually - * required within a nand driver because they are performed by the nand - * infrastructure code as part of nand_scan(). In this case they need - * to be initialized here because we skip call to nand_scan_ident() (the - * first half of nand_scan()). The call to nand_scan_ident() is skipped - * because for this device the chip id is not read in the manner of a - * standard nand device. Unfortunately, nand_scan_ident() does other - * things as well, such as call nand_set_defaults(). - */ - - struct nand_chip *nand = mtd->priv; - struct docg4_priv *doc = nand->priv; - - mtd->size = DOCG4_CHIP_SIZE; - mtd->name = "Msys_Diskonchip_G4"; - mtd->writesize = DOCG4_PAGE_SIZE; - mtd->erasesize = DOCG4_BLOCK_SIZE; - mtd->oobsize = DOCG4_OOB_SIZE; - nand->chipsize = DOCG4_CHIP_SIZE; - nand->chip_shift = DOCG4_CHIP_SHIFT; - nand->bbt_erase_shift = nand->phys_erase_shift = DOCG4_ERASE_SHIFT; - nand->chip_delay = 20; - nand->page_shift = DOCG4_PAGE_SHIFT; - nand->pagemask = 0x3ffff; - nand->badblockpos = NAND_LARGE_BADBLOCK_POS; - nand->badblockbits = 8; - nand->ecc.layout = &docg4_oobinfo; - nand->ecc.mode = NAND_ECC_HW_SYNDROME; - nand->ecc.size = DOCG4_PAGE_SIZE; - nand->ecc.prepad = 8; - nand->ecc.bytes = 8; - nand->ecc.strength = DOCG4_T; - nand->options = - NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE | NAND_NO_AUTOINCR; - nand->IO_ADDR_R = nand->IO_ADDR_W = doc->virtadr + DOC_IOSPACE_DATA; - nand->controller = &nand->hwcontrol; - spin_lock_init(&nand->controller->lock); - init_waitqueue_head(&nand->controller->wq); - - /* methods */ - nand->cmdfunc = docg4_command; - nand->waitfunc = docg4_wait; - nand->select_chip = docg4_select_chip; - nand->read_byte = docg4_read_byte; - nand->block_markbad = docg4_block_markbad; - nand->read_buf = docg4_read_buf; - nand->write_buf = docg4_write_buf16; - nand->scan_bbt = nand_default_bbt; - nand->erase_cmd = docg4_erase_block; - nand->ecc.read_page = docg4_read_page; - nand->ecc.write_page = docg4_write_page; - nand->ecc.read_page_raw = docg4_read_page_raw; - nand->ecc.write_page_raw = docg4_write_page_raw; - nand->ecc.read_oob = docg4_read_oob; - nand->ecc.write_oob = docg4_write_oob; - - /* - * The way the nand infrastructure code is written, a memory-based bbt - * is not created if NAND_SKIP_BBTSCAN is set. With no memory bbt, - * nand->block_bad() is used. So when ignoring bad blocks, we skip the - * scan and define a dummy block_bad() which always returns 0. - */ - if (ignore_badblocks) { - nand->options |= NAND_SKIP_BBTSCAN; - nand->block_bad = docg4_block_neverbad; - } - -} - -static int __init read_id_reg(struct mtd_info *mtd) -{ - struct nand_chip *nand = mtd->priv; - struct docg4_priv *doc = nand->priv; - void __iomem *docptr = doc->virtadr; - uint16_t id1, id2; - - /* check for presence of g4 chip by reading id registers */ - id1 = readw(docptr + DOC_CHIPID); - id1 = readw(docptr + DOCG4_MYSTERY_REG); - id2 = readw(docptr + DOC_CHIPID_INV); - id2 = readw(docptr + DOCG4_MYSTERY_REG); - - if (id1 == DOCG4_IDREG1_VALUE && id2 == DOCG4_IDREG2_VALUE) { - dev_info(doc->dev, - "NAND device: 128MiB Diskonchip G4 detected\n"); - return 0; - } - - return -ENODEV; -} - -static char const *part_probes[] = { "cmdlinepart", "saftlpart", NULL }; - -static int __init probe_docg4(struct platform_device *pdev) -{ - struct mtd_info *mtd; - struct nand_chip *nand; - void __iomem *virtadr; - struct docg4_priv *doc; - int len, retval; - struct resource *r; - struct device *dev = &pdev->dev; - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (r == NULL) { - dev_err(dev, "no io memory resource defined!\n"); - return -ENODEV; - } - - virtadr = ioremap(r->start, resource_size(r)); - if (!virtadr) { - dev_err(dev, "Diskonchip ioremap failed: %pR\n", r); - return -EIO; - } - - len = sizeof(struct mtd_info) + sizeof(struct nand_chip) + - sizeof(struct docg4_priv); - mtd = kzalloc(len, GFP_KERNEL); - if (mtd == NULL) { - retval = -ENOMEM; - goto fail; - } - nand = (struct nand_chip *) (mtd + 1); - doc = (struct docg4_priv *) (nand + 1); - mtd->priv = nand; - nand->priv = doc; - mtd->owner = THIS_MODULE; - doc->virtadr = virtadr; - doc->dev = dev; - - init_mtd_structs(mtd); - - /* initialize kernel bch algorithm */ - doc->bch = init_bch(DOCG4_M, DOCG4_T, DOCG4_PRIMITIVE_POLY); - if (doc->bch == NULL) { - retval = -EINVAL; - goto fail; - } - - platform_set_drvdata(pdev, doc); - - reset(mtd); - retval = read_id_reg(mtd); - if (retval == -ENODEV) { - dev_warn(dev, "No diskonchip G4 device found.\n"); - goto fail; - } - - retval = nand_scan_tail(mtd); - if (retval) - goto fail; - - retval = read_factory_bbt(mtd); - if (retval) - goto fail; - - retval = mtd_device_parse_register(mtd, part_probes, NULL, NULL, 0); - if (retval) - goto fail; - - doc->mtd = mtd; - return 0; - - fail: - iounmap(virtadr); - if (mtd) { - /* re-declarations avoid compiler warning */ - struct nand_chip *nand = mtd->priv; - struct docg4_priv *doc = nand->priv; - nand_release(mtd); /* deletes partitions and mtd devices */ - platform_set_drvdata(pdev, NULL); - free_bch(doc->bch); - kfree(mtd); - } - - return retval; -} - -static int __exit cleanup_docg4(struct platform_device *pdev) -{ - struct docg4_priv *doc = platform_get_drvdata(pdev); - nand_release(doc->mtd); - platform_set_drvdata(pdev, NULL); - free_bch(doc->bch); - kfree(doc->mtd); - iounmap(doc->virtadr); - return 0; -} - -static struct platform_driver docg4_driver = { - .driver = { - .name = "docg4", - .owner = THIS_MODULE, - }, - .suspend = docg4_suspend, - .resume = docg4_resume, - .remove = __exit_p(cleanup_docg4), -}; - -static int __init docg4_init(void) -{ - return platform_driver_probe(&docg4_driver, probe_docg4); -} - -static void __exit docg4_exit(void) -{ - platform_driver_unregister(&docg4_driver); -} - -module_init(docg4_init); -module_exit(docg4_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mike Dunn"); -MODULE_DESCRIPTION("M-Systems DiskOnChip G4 device driver"); diff --git a/trunk/drivers/mtd/nand/fsl_elbc_nand.c b/trunk/drivers/mtd/nand/fsl_elbc_nand.c index 80b5264f0a32..7195ee6efe12 100644 --- a/trunk/drivers/mtd/nand/fsl_elbc_nand.c +++ b/trunk/drivers/mtd/nand/fsl_elbc_nand.c @@ -813,12 +813,6 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) &fsl_elbc_oob_sp_eccm1 : &fsl_elbc_oob_sp_eccm0; chip->ecc.size = 512; chip->ecc.bytes = 3; - chip->ecc.strength = 1; - /* - * FIXME: can hardware ecc correct 4 bitflips if page size is - * 2k? Then does hardware report number of corrections for this - * case? If so, ecc_stats reporting needs to be fixed as well. - */ } else { /* otherwise fall back to default software ECC */ chip->ecc.mode = NAND_ECC_SOFT; diff --git a/trunk/drivers/mtd/nand/fsmc_nand.c b/trunk/drivers/mtd/nand/fsmc_nand.c index 1b8330e1155a..e53b76064133 100644 --- a/trunk/drivers/mtd/nand/fsmc_nand.c +++ b/trunk/drivers/mtd/nand/fsmc_nand.c @@ -17,10 +17,6 @@ */ #include -#include -#include -#include -#include #include #include #include @@ -31,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -39,7 +34,7 @@ #include #include -static struct nand_ecclayout fsmc_ecc1_128_layout = { +static struct nand_ecclayout fsmc_ecc1_layout = { .eccbytes = 24, .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52, 66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116}, @@ -55,127 +50,7 @@ static struct nand_ecclayout fsmc_ecc1_128_layout = { } }; -static struct nand_ecclayout fsmc_ecc1_64_layout = { - .eccbytes = 12, - .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52}, - .oobfree = { - {.offset = 8, .length = 8}, - {.offset = 24, .length = 8}, - {.offset = 40, .length = 8}, - {.offset = 56, .length = 8}, - } -}; - -static struct nand_ecclayout fsmc_ecc1_16_layout = { - .eccbytes = 3, - .eccpos = {2, 3, 4}, - .oobfree = { - {.offset = 8, .length = 8}, - } -}; - -/* - * ECC4 layout for NAND of pagesize 8192 bytes & OOBsize 256 bytes. 13*16 bytes - * of OB size is reserved for ECC, Byte no. 0 & 1 reserved for bad block and 46 - * bytes are free for use. - */ -static struct nand_ecclayout fsmc_ecc4_256_layout = { - .eccbytes = 208, - .eccpos = { 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, - 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, - 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, - 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, - 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, - 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, - 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, - 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126, - 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, - 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, - 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, - 178, 179, 180, 181, 182, 183, 184, - 185, 186, 187, 188, 189, 190, - 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, - 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, - 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 237, 238, - 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254 - }, - .oobfree = { - {.offset = 15, .length = 3}, - {.offset = 31, .length = 3}, - {.offset = 47, .length = 3}, - {.offset = 63, .length = 3}, - {.offset = 79, .length = 3}, - {.offset = 95, .length = 3}, - {.offset = 111, .length = 3}, - {.offset = 127, .length = 3}, - {.offset = 143, .length = 3}, - {.offset = 159, .length = 3}, - {.offset = 175, .length = 3}, - {.offset = 191, .length = 3}, - {.offset = 207, .length = 3}, - {.offset = 223, .length = 3}, - {.offset = 239, .length = 3}, - {.offset = 255, .length = 1} - } -}; - -/* - * ECC4 layout for NAND of pagesize 4096 bytes & OOBsize 224 bytes. 13*8 bytes - * of OOB size is reserved for ECC, Byte no. 0 & 1 reserved for bad block & 118 - * bytes are free for use. - */ -static struct nand_ecclayout fsmc_ecc4_224_layout = { - .eccbytes = 104, - .eccpos = { 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, - 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, - 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, - 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, - 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, - 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, - 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, - 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126 - }, - .oobfree = { - {.offset = 15, .length = 3}, - {.offset = 31, .length = 3}, - {.offset = 47, .length = 3}, - {.offset = 63, .length = 3}, - {.offset = 79, .length = 3}, - {.offset = 95, .length = 3}, - {.offset = 111, .length = 3}, - {.offset = 127, .length = 97} - } -}; - -/* - * ECC4 layout for NAND of pagesize 4096 bytes & OOBsize 128 bytes. 13*8 bytes - * of OOB size is reserved for ECC, Byte no. 0 & 1 reserved for bad block & 22 - * bytes are free for use. - */ -static struct nand_ecclayout fsmc_ecc4_128_layout = { +static struct nand_ecclayout fsmc_ecc4_lp_layout = { .eccbytes = 104, .eccpos = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, @@ -206,45 +81,6 @@ static struct nand_ecclayout fsmc_ecc4_128_layout = { } }; -/* - * ECC4 layout for NAND of pagesize 2048 bytes & OOBsize 64 bytes. 13*4 bytes of - * OOB size is reserved for ECC, Byte no. 0 & 1 reserved for bad block and 10 - * bytes are free for use. - */ -static struct nand_ecclayout fsmc_ecc4_64_layout = { - .eccbytes = 52, - .eccpos = { 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, - 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, - 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, - 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, - }, - .oobfree = { - {.offset = 15, .length = 3}, - {.offset = 31, .length = 3}, - {.offset = 47, .length = 3}, - {.offset = 63, .length = 1}, - } -}; - -/* - * ECC4 layout for NAND of pagesize 512 bytes & OOBsize 16 bytes. 13 bytes of - * OOB size is reserved for ECC, Byte no. 4 & 5 reserved for bad block and One - * byte is free for use. - */ -static struct nand_ecclayout fsmc_ecc4_16_layout = { - .eccbytes = 13, - .eccpos = { 0, 1, 2, 3, 6, 7, 8, - 9, 10, 11, 12, 13, 14 - }, - .oobfree = { - {.offset = 15, .length = 1}, - } -}; - /* * ECC placement definitions in oobfree type format. * There are 13 bytes of ecc for every 512 byte block and it has to be read @@ -267,6 +103,16 @@ static struct fsmc_eccplace fsmc_ecc4_lp_place = { } }; +static struct nand_ecclayout fsmc_ecc4_sp_layout = { + .eccbytes = 13, + .eccpos = { 0, 1, 2, 3, 6, 7, 8, + 9, 10, 11, 12, 13, 14 + }, + .oobfree = { + {.offset = 15, .length = 1}, + } +}; + static struct fsmc_eccplace fsmc_ecc4_sp_place = { .eccplace = { {.offset = 0, .length = 4}, @@ -274,24 +120,75 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = { } }; +/* + * Default partition tables to be used if the partition information not + * provided through platform data. + * + * Default partition layout for small page(= 512 bytes) devices + * Size for "Root file system" is updated in driver based on actual device size + */ +static struct mtd_partition partition_info_16KB_blk[] = { + { + .name = "X-loader", + .offset = 0, + .size = 4*0x4000, + }, + { + .name = "U-Boot", + .offset = 0x10000, + .size = 20*0x4000, + }, + { + .name = "Kernel", + .offset = 0x60000, + .size = 256*0x4000, + }, + { + .name = "Root File System", + .offset = 0x460000, + .size = MTDPART_SIZ_FULL, + }, +}; + +/* + * Default partition layout for large page(> 512 bytes) devices + * Size for "Root file system" is updated in driver based on actual device size + */ +static struct mtd_partition partition_info_128KB_blk[] = { + { + .name = "X-loader", + .offset = 0, + .size = 4*0x20000, + }, + { + .name = "U-Boot", + .offset = 0x80000, + .size = 12*0x20000, + }, + { + .name = "Kernel", + .offset = 0x200000, + .size = 48*0x20000, + }, + { + .name = "Root File System", + .offset = 0x800000, + .size = MTDPART_SIZ_FULL, + }, +}; + + /** * struct fsmc_nand_data - structure for FSMC NAND device state * * @pid: Part ID on the AMBA PrimeCell format * @mtd: MTD info for a NAND flash. * @nand: Chip related info for a NAND flash. - * @partitions: Partition info for a NAND Flash. - * @nr_partitions: Total number of partition of a NAND flash. * * @ecc_place: ECC placing locations in oobfree type format. * @bank: Bank number for probed device. * @clk: Clock structure for FSMC. * - * @read_dma_chan: DMA channel for read access - * @write_dma_chan: DMA channel for write access to NAND - * @dma_access_complete: Completion structure - * - * @data_pa: NAND Physical port for Data. * @data_va: NAND port for Data. * @cmd_va: NAND port for Command. * @addr_va: NAND port for Address. @@ -301,23 +198,16 @@ struct fsmc_nand_data { u32 pid; struct mtd_info mtd; struct nand_chip nand; - struct mtd_partition *partitions; - unsigned int nr_partitions; struct fsmc_eccplace *ecc_place; unsigned int bank; - struct device *dev; - enum access_mode mode; struct clk *clk; - /* DMA related objects */ - struct dma_chan *read_dma_chan; - struct dma_chan *write_dma_chan; - struct completion dma_access_complete; - - struct fsmc_nand_timings *dev_timings; + struct resource *resregs; + struct resource *rescmd; + struct resource *resaddr; + struct resource *resdata; - dma_addr_t data_pa; void __iomem *data_va; void __iomem *cmd_va; void __iomem *addr_va; @@ -361,29 +251,28 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) struct nand_chip *this = mtd->priv; struct fsmc_nand_data *host = container_of(mtd, struct fsmc_nand_data, mtd); - void *__iomem *regs = host->regs_va; + struct fsmc_regs *regs = host->regs_va; unsigned int bank = host->bank; if (ctrl & NAND_CTRL_CHANGE) { - u32 pc; - if (ctrl & NAND_CLE) { - this->IO_ADDR_R = host->cmd_va; - this->IO_ADDR_W = host->cmd_va; + this->IO_ADDR_R = (void __iomem *)host->cmd_va; + this->IO_ADDR_W = (void __iomem *)host->cmd_va; } else if (ctrl & NAND_ALE) { - this->IO_ADDR_R = host->addr_va; - this->IO_ADDR_W = host->addr_va; + this->IO_ADDR_R = (void __iomem *)host->addr_va; + this->IO_ADDR_W = (void __iomem *)host->addr_va; } else { - this->IO_ADDR_R = host->data_va; - this->IO_ADDR_W = host->data_va; + this->IO_ADDR_R = (void __iomem *)host->data_va; + this->IO_ADDR_W = (void __iomem *)host->data_va; } - pc = readl(FSMC_NAND_REG(regs, bank, PC)); - if (ctrl & NAND_NCE) - pc |= FSMC_ENABLE; - else - pc &= ~FSMC_ENABLE; - writel(pc, FSMC_NAND_REG(regs, bank, PC)); + if (ctrl & NAND_NCE) { + writel(readl(®s->bank_regs[bank].pc) | FSMC_ENABLE, + ®s->bank_regs[bank].pc); + } else { + writel(readl(®s->bank_regs[bank].pc) & ~FSMC_ENABLE, + ®s->bank_regs[bank].pc); + } } mb(); @@ -398,42 +287,22 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) * This routine initializes timing parameters related to NAND memory access in * FSMC registers */ -static void fsmc_nand_setup(void __iomem *regs, uint32_t bank, - uint32_t busw, struct fsmc_nand_timings *timings) +static void __init fsmc_nand_setup(struct fsmc_regs *regs, uint32_t bank, + uint32_t busw) { uint32_t value = FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON; - uint32_t tclr, tar, thiz, thold, twait, tset; - struct fsmc_nand_timings *tims; - struct fsmc_nand_timings default_timings = { - .tclr = FSMC_TCLR_1, - .tar = FSMC_TAR_1, - .thiz = FSMC_THIZ_1, - .thold = FSMC_THOLD_4, - .twait = FSMC_TWAIT_6, - .tset = FSMC_TSET_0, - }; - - if (timings) - tims = timings; - else - tims = &default_timings; - - tclr = (tims->tclr & FSMC_TCLR_MASK) << FSMC_TCLR_SHIFT; - tar = (tims->tar & FSMC_TAR_MASK) << FSMC_TAR_SHIFT; - thiz = (tims->thiz & FSMC_THIZ_MASK) << FSMC_THIZ_SHIFT; - thold = (tims->thold & FSMC_THOLD_MASK) << FSMC_THOLD_SHIFT; - twait = (tims->twait & FSMC_TWAIT_MASK) << FSMC_TWAIT_SHIFT; - tset = (tims->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT; if (busw) - writel(value | FSMC_DEVWID_16, FSMC_NAND_REG(regs, bank, PC)); + writel(value | FSMC_DEVWID_16, ®s->bank_regs[bank].pc); else - writel(value | FSMC_DEVWID_8, FSMC_NAND_REG(regs, bank, PC)); - - writel(readl(FSMC_NAND_REG(regs, bank, PC)) | tclr | tar, - FSMC_NAND_REG(regs, bank, PC)); - writel(thiz | thold | twait | tset, FSMC_NAND_REG(regs, bank, COMM)); - writel(thiz | thold | twait | tset, FSMC_NAND_REG(regs, bank, ATTRIB)); + writel(value | FSMC_DEVWID_8, ®s->bank_regs[bank].pc); + + writel(readl(®s->bank_regs[bank].pc) | FSMC_TCLR_1 | FSMC_TAR_1, + ®s->bank_regs[bank].pc); + writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0, + ®s->bank_regs[bank].comm); + writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0, + ®s->bank_regs[bank].attrib); } /* @@ -443,15 +312,15 @@ static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode) { struct fsmc_nand_data *host = container_of(mtd, struct fsmc_nand_data, mtd); - void __iomem *regs = host->regs_va; + struct fsmc_regs *regs = host->regs_va; uint32_t bank = host->bank; - writel(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCPLEN_256, - FSMC_NAND_REG(regs, bank, PC)); - writel(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCEN, - FSMC_NAND_REG(regs, bank, PC)); - writel(readl(FSMC_NAND_REG(regs, bank, PC)) | FSMC_ECCEN, - FSMC_NAND_REG(regs, bank, PC)); + writel(readl(®s->bank_regs[bank].pc) & ~FSMC_ECCPLEN_256, + ®s->bank_regs[bank].pc); + writel(readl(®s->bank_regs[bank].pc) & ~FSMC_ECCEN, + ®s->bank_regs[bank].pc); + writel(readl(®s->bank_regs[bank].pc) | FSMC_ECCEN, + ®s->bank_regs[bank].pc); } /* @@ -464,42 +333,37 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data, { struct fsmc_nand_data *host = container_of(mtd, struct fsmc_nand_data, mtd); - void __iomem *regs = host->regs_va; + struct fsmc_regs *regs = host->regs_va; uint32_t bank = host->bank; uint32_t ecc_tmp; unsigned long deadline = jiffies + FSMC_BUSY_WAIT_TIMEOUT; do { - if (readl(FSMC_NAND_REG(regs, bank, STS)) & FSMC_CODE_RDY) + if (readl(®s->bank_regs[bank].sts) & FSMC_CODE_RDY) break; else cond_resched(); } while (!time_after_eq(jiffies, deadline)); - if (time_after_eq(jiffies, deadline)) { - dev_err(host->dev, "calculate ecc timed out\n"); - return -ETIMEDOUT; - } - - ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC1)); + ecc_tmp = readl(®s->bank_regs[bank].ecc1); ecc[0] = (uint8_t) (ecc_tmp >> 0); ecc[1] = (uint8_t) (ecc_tmp >> 8); ecc[2] = (uint8_t) (ecc_tmp >> 16); ecc[3] = (uint8_t) (ecc_tmp >> 24); - ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC2)); + ecc_tmp = readl(®s->bank_regs[bank].ecc2); ecc[4] = (uint8_t) (ecc_tmp >> 0); ecc[5] = (uint8_t) (ecc_tmp >> 8); ecc[6] = (uint8_t) (ecc_tmp >> 16); ecc[7] = (uint8_t) (ecc_tmp >> 24); - ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC3)); + ecc_tmp = readl(®s->bank_regs[bank].ecc3); ecc[8] = (uint8_t) (ecc_tmp >> 0); ecc[9] = (uint8_t) (ecc_tmp >> 8); ecc[10] = (uint8_t) (ecc_tmp >> 16); ecc[11] = (uint8_t) (ecc_tmp >> 24); - ecc_tmp = readl(FSMC_NAND_REG(regs, bank, STS)); + ecc_tmp = readl(®s->bank_regs[bank].sts); ecc[12] = (uint8_t) (ecc_tmp >> 16); return 0; @@ -515,11 +379,11 @@ static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data, { struct fsmc_nand_data *host = container_of(mtd, struct fsmc_nand_data, mtd); - void __iomem *regs = host->regs_va; + struct fsmc_regs *regs = host->regs_va; uint32_t bank = host->bank; uint32_t ecc_tmp; - ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC1)); + ecc_tmp = readl(®s->bank_regs[bank].ecc1); ecc[0] = (uint8_t) (ecc_tmp >> 0); ecc[1] = (uint8_t) (ecc_tmp >> 8); ecc[2] = (uint8_t) (ecc_tmp >> 16); @@ -527,166 +391,6 @@ static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data, return 0; } -/* Count the number of 0's in buff upto a max of max_bits */ -static int count_written_bits(uint8_t *buff, int size, int max_bits) -{ - int k, written_bits = 0; - - for (k = 0; k < size; k++) { - written_bits += hweight8(~buff[k]); - if (written_bits > max_bits) - break; - } - - return written_bits; -} - -static void dma_complete(void *param) -{ - struct fsmc_nand_data *host = param; - - complete(&host->dma_access_complete); -} - -static int dma_xfer(struct fsmc_nand_data *host, void *buffer, int len, - enum dma_data_direction direction) -{ - struct dma_chan *chan; - struct dma_device *dma_dev; - struct dma_async_tx_descriptor *tx; - dma_addr_t dma_dst, dma_src, dma_addr; - dma_cookie_t cookie; - unsigned long flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; - int ret; - - if (direction == DMA_TO_DEVICE) - chan = host->write_dma_chan; - else if (direction == DMA_FROM_DEVICE) - chan = host->read_dma_chan; - else - return -EINVAL; - - dma_dev = chan->device; - dma_addr = dma_map_single(dma_dev->dev, buffer, len, direction); - - if (direction == DMA_TO_DEVICE) { - dma_src = dma_addr; - dma_dst = host->data_pa; - flags |= DMA_COMPL_SRC_UNMAP_SINGLE | DMA_COMPL_SKIP_DEST_UNMAP; - } else { - dma_src = host->data_pa; - dma_dst = dma_addr; - flags |= DMA_COMPL_DEST_UNMAP_SINGLE | DMA_COMPL_SKIP_SRC_UNMAP; - } - - tx = dma_dev->device_prep_dma_memcpy(chan, dma_dst, dma_src, - len, flags); - - if (!tx) { - dev_err(host->dev, "device_prep_dma_memcpy error\n"); - dma_unmap_single(dma_dev->dev, dma_addr, len, direction); - return -EIO; - } - - tx->callback = dma_complete; - tx->callback_param = host; - cookie = tx->tx_submit(tx); - - ret = dma_submit_error(cookie); - if (ret) { - dev_err(host->dev, "dma_submit_error %d\n", cookie); - return ret; - } - - dma_async_issue_pending(chan); - - ret = - wait_for_completion_interruptible_timeout(&host->dma_access_complete, - msecs_to_jiffies(3000)); - if (ret <= 0) { - chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); - dev_err(host->dev, "wait_for_completion_timeout\n"); - return ret ? ret : -ETIMEDOUT; - } - - return 0; -} - -/* - * fsmc_write_buf - write buffer to chip - * @mtd: MTD device structure - * @buf: data buffer - * @len: number of bytes to write - */ -static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) -{ - int i; - struct nand_chip *chip = mtd->priv; - - if (IS_ALIGNED((uint32_t)buf, sizeof(uint32_t)) && - IS_ALIGNED(len, sizeof(uint32_t))) { - uint32_t *p = (uint32_t *)buf; - len = len >> 2; - for (i = 0; i < len; i++) - writel(p[i], chip->IO_ADDR_W); - } else { - for (i = 0; i < len; i++) - writeb(buf[i], chip->IO_ADDR_W); - } -} - -/* - * fsmc_read_buf - read chip data into buffer - * @mtd: MTD device structure - * @buf: buffer to store date - * @len: number of bytes to read - */ -static void fsmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) -{ - int i; - struct nand_chip *chip = mtd->priv; - - if (IS_ALIGNED((uint32_t)buf, sizeof(uint32_t)) && - IS_ALIGNED(len, sizeof(uint32_t))) { - uint32_t *p = (uint32_t *)buf; - len = len >> 2; - for (i = 0; i < len; i++) - p[i] = readl(chip->IO_ADDR_R); - } else { - for (i = 0; i < len; i++) - buf[i] = readb(chip->IO_ADDR_R); - } -} - -/* - * fsmc_read_buf_dma - read chip data into buffer - * @mtd: MTD device structure - * @buf: buffer to store date - * @len: number of bytes to read - */ -static void fsmc_read_buf_dma(struct mtd_info *mtd, uint8_t *buf, int len) -{ - struct fsmc_nand_data *host; - - host = container_of(mtd, struct fsmc_nand_data, mtd); - dma_xfer(host, buf, len, DMA_FROM_DEVICE); -} - -/* - * fsmc_write_buf_dma - write buffer to chip - * @mtd: MTD device structure - * @buf: data buffer - * @len: number of bytes to write - */ -static void fsmc_write_buf_dma(struct mtd_info *mtd, const uint8_t *buf, - int len) -{ - struct fsmc_nand_data *host; - - host = container_of(mtd, struct fsmc_nand_data, mtd); - dma_xfer(host, (void *)buf, len, DMA_TO_DEVICE); -} - /* * fsmc_read_page_hwecc * @mtd: mtd info structure @@ -722,6 +426,7 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *oob = (uint8_t *)&ecc_oob[0]; for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) { + chip->cmdfunc(mtd, NAND_CMD_READ0, s * eccsize, page); chip->ecc.hwctl(mtd, NAND_ECC_READ); chip->read_buf(mtd, p, eccsize); @@ -732,19 +437,17 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, group++; /* - * length is intentionally kept a higher multiple of 2 - * to read at least 13 bytes even in case of 16 bit NAND - * devices - */ - if (chip->options & NAND_BUSWIDTH_16) - len = roundup(len, 2); - + * length is intentionally kept a higher multiple of 2 + * to read at least 13 bytes even in case of 16 bit NAND + * devices + */ + len = roundup(len, 2); chip->cmdfunc(mtd, NAND_CMD_READOOB, off, page); chip->read_buf(mtd, oob + j, len); j += len; } - memcpy(&ecc_code[i], oob, chip->ecc.bytes); + memcpy(&ecc_code[i], oob, 13); chip->ecc.calculate(mtd, p, &ecc_calc[i]); stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); @@ -758,7 +461,7 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, } /* - * fsmc_bch8_correct_data + * fsmc_correct_data * @mtd: mtd info structure * @dat: buffer of read data * @read_ecc: ecc read from device spare area @@ -767,51 +470,19 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, * calc_ecc is a 104 bit information containing maximum of 8 error * offset informations of 13 bits each in 512 bytes of read data. */ -static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat, +static int fsmc_correct_data(struct mtd_info *mtd, uint8_t *dat, uint8_t *read_ecc, uint8_t *calc_ecc) { struct fsmc_nand_data *host = container_of(mtd, struct fsmc_nand_data, mtd); - struct nand_chip *chip = mtd->priv; - void __iomem *regs = host->regs_va; + struct fsmc_regs *regs = host->regs_va; unsigned int bank = host->bank; - uint32_t err_idx[8]; + uint16_t err_idx[8]; + uint64_t ecc_data[2]; uint32_t num_err, i; - uint32_t ecc1, ecc2, ecc3, ecc4; - - num_err = (readl(FSMC_NAND_REG(regs, bank, STS)) >> 10) & 0xF; - - /* no bit flipping */ - if (likely(num_err == 0)) - return 0; - - /* too many errors */ - if (unlikely(num_err > 8)) { - /* - * This is a temporary erase check. A newly erased page read - * would result in an ecc error because the oob data is also - * erased to FF and the calculated ecc for an FF data is not - * FF..FF. - * This is a workaround to skip performing correction in case - * data is FF..FF - * - * Logic: - * For every page, each bit written as 0 is counted until these - * number of bits are greater than 8 (the maximum correction - * capability of FSMC for each 512 + 13 bytes) - */ - - int bits_ecc = count_written_bits(read_ecc, chip->ecc.bytes, 8); - int bits_data = count_written_bits(dat, chip->ecc.size, 8); - - if ((bits_ecc + bits_data) <= 8) { - if (bits_data) - memset(dat, 0xff, chip->ecc.size); - return bits_data; - } - return -EBADMSG; - } + /* The calculated ecc is actually the correction index in data */ + memcpy(ecc_data, calc_ecc, 13); /* * ------------------- calc_ecc[] bit wise -----------|--13 bits--| @@ -822,26 +493,27 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat, * uint64_t array and error offset indexes are populated in err_idx * array */ - ecc1 = readl(FSMC_NAND_REG(regs, bank, ECC1)); - ecc2 = readl(FSMC_NAND_REG(regs, bank, ECC2)); - ecc3 = readl(FSMC_NAND_REG(regs, bank, ECC3)); - ecc4 = readl(FSMC_NAND_REG(regs, bank, STS)); - - err_idx[0] = (ecc1 >> 0) & 0x1FFF; - err_idx[1] = (ecc1 >> 13) & 0x1FFF; - err_idx[2] = (((ecc2 >> 0) & 0x7F) << 6) | ((ecc1 >> 26) & 0x3F); - err_idx[3] = (ecc2 >> 7) & 0x1FFF; - err_idx[4] = (((ecc3 >> 0) & 0x1) << 12) | ((ecc2 >> 20) & 0xFFF); - err_idx[5] = (ecc3 >> 1) & 0x1FFF; - err_idx[6] = (ecc3 >> 14) & 0x1FFF; - err_idx[7] = (((ecc4 >> 16) & 0xFF) << 5) | ((ecc3 >> 27) & 0x1F); + for (i = 0; i < 8; i++) { + if (i == 4) { + err_idx[4] = ((ecc_data[1] & 0x1) << 12) | ecc_data[0]; + ecc_data[1] >>= 1; + continue; + } + err_idx[i] = (ecc_data[i/4] & 0x1FFF); + ecc_data[i/4] >>= 13; + } + + num_err = (readl(®s->bank_regs[bank].sts) >> 10) & 0xF; + + if (num_err == 0xF) + return -EBADMSG; i = 0; while (num_err--) { change_bit(0, (unsigned long *)&err_idx[i]); change_bit(1, (unsigned long *)&err_idx[i]); - if (err_idx[i] < chip->ecc.size * 8) { + if (err_idx[i] <= 512 * 8) { change_bit(err_idx[i], (unsigned long *)dat); i++; } @@ -849,44 +521,6 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat, return i; } -static bool filter(struct dma_chan *chan, void *slave) -{ - chan->private = slave; - return true; -} - -#ifdef CONFIG_OF -static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev, - struct device_node *np) -{ - struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); - u32 val; - - /* Set default NAND width to 8 bits */ - pdata->width = 8; - if (!of_property_read_u32(np, "bank-width", &val)) { - if (val == 2) { - pdata->width = 16; - } else if (val != 1) { - dev_err(&pdev->dev, "invalid bank-width %u\n", val); - return -EINVAL; - } - } - of_property_read_u32(np, "st,ale-off", &pdata->ale_off); - of_property_read_u32(np, "st,cle-off", &pdata->cle_off); - if (of_get_property(np, "nand-skip-bbtscan", NULL)) - pdata->options = NAND_SKIP_BBTSCAN; - - return 0; -} -#else -static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev, - struct device_node *np) -{ - return -ENOSYS; -} -#endif - /* * fsmc_nand_probe - Probe function * @pdev: platform device structure @@ -894,109 +528,102 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev, static int __init fsmc_nand_probe(struct platform_device *pdev) { struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct device_node __maybe_unused *np = pdev->dev.of_node; - struct mtd_part_parser_data ppdata = {}; struct fsmc_nand_data *host; struct mtd_info *mtd; struct nand_chip *nand; + struct fsmc_regs *regs; struct resource *res; - dma_cap_mask_t mask; int ret = 0; u32 pid; int i; - if (np) { - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); - pdev->dev.platform_data = pdata; - ret = fsmc_nand_probe_config_dt(pdev, np); - if (ret) { - dev_err(&pdev->dev, "no platform data\n"); - return -ENODEV; - } - } - if (!pdata) { dev_err(&pdev->dev, "platform data is NULL\n"); return -EINVAL; } /* Allocate memory for the device structure (and zero it) */ - host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); + host = kzalloc(sizeof(*host), GFP_KERNEL); if (!host) { dev_err(&pdev->dev, "failed to allocate device structure\n"); return -ENOMEM; } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_data"); - if (!res) - return -EINVAL; + if (!res) { + ret = -EIO; + goto err_probe1; + } - if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), - pdev->name)) { - dev_err(&pdev->dev, "Failed to get memory data resourse\n"); - return -ENOENT; + host->resdata = request_mem_region(res->start, resource_size(res), + pdev->name); + if (!host->resdata) { + ret = -EIO; + goto err_probe1; } - host->data_pa = (dma_addr_t)res->start; - host->data_va = devm_ioremap(&pdev->dev, res->start, - resource_size(res)); + host->data_va = ioremap(res->start, resource_size(res)); if (!host->data_va) { - dev_err(&pdev->dev, "data ioremap failed\n"); - return -ENOMEM; + ret = -EIO; + goto err_probe1; } - if (!devm_request_mem_region(&pdev->dev, res->start + pdata->ale_off, - resource_size(res), pdev->name)) { - dev_err(&pdev->dev, "Failed to get memory ale resourse\n"); - return -ENOENT; + host->resaddr = request_mem_region(res->start + PLAT_NAND_ALE, + resource_size(res), pdev->name); + if (!host->resaddr) { + ret = -EIO; + goto err_probe1; } - host->addr_va = devm_ioremap(&pdev->dev, res->start + pdata->ale_off, - resource_size(res)); + host->addr_va = ioremap(res->start + PLAT_NAND_ALE, resource_size(res)); if (!host->addr_va) { - dev_err(&pdev->dev, "ale ioremap failed\n"); - return -ENOMEM; + ret = -EIO; + goto err_probe1; } - if (!devm_request_mem_region(&pdev->dev, res->start + pdata->cle_off, - resource_size(res), pdev->name)) { - dev_err(&pdev->dev, "Failed to get memory cle resourse\n"); - return -ENOENT; + host->rescmd = request_mem_region(res->start + PLAT_NAND_CLE, + resource_size(res), pdev->name); + if (!host->rescmd) { + ret = -EIO; + goto err_probe1; } - host->cmd_va = devm_ioremap(&pdev->dev, res->start + pdata->cle_off, - resource_size(res)); + host->cmd_va = ioremap(res->start + PLAT_NAND_CLE, resource_size(res)); if (!host->cmd_va) { - dev_err(&pdev->dev, "ale ioremap failed\n"); - return -ENOMEM; + ret = -EIO; + goto err_probe1; } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fsmc_regs"); - if (!res) - return -EINVAL; + if (!res) { + ret = -EIO; + goto err_probe1; + } - if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), - pdev->name)) { - dev_err(&pdev->dev, "Failed to get memory regs resourse\n"); - return -ENOENT; + host->resregs = request_mem_region(res->start, resource_size(res), + pdev->name); + if (!host->resregs) { + ret = -EIO; + goto err_probe1; } - host->regs_va = devm_ioremap(&pdev->dev, res->start, - resource_size(res)); + host->regs_va = ioremap(res->start, resource_size(res)); if (!host->regs_va) { - dev_err(&pdev->dev, "regs ioremap failed\n"); - return -ENOMEM; + ret = -EIO; + goto err_probe1; } host->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(host->clk)) { dev_err(&pdev->dev, "failed to fetch block clock\n"); - return PTR_ERR(host->clk); + ret = PTR_ERR(host->clk); + host->clk = NULL; + goto err_probe1; } ret = clk_enable(host->clk); if (ret) - goto err_clk_enable; + goto err_probe1; /* * This device ID is actually a common AMBA ID as used on the @@ -1012,14 +639,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) host->bank = pdata->bank; host->select_chip = pdata->select_bank; - host->partitions = pdata->partitions; - host->nr_partitions = pdata->nr_partitions; - host->dev = &pdev->dev; - host->dev_timings = pdata->nand_timings; - host->mode = pdata->mode; - - if (host->mode == USE_DMA_ACCESS) - init_completion(&host->dma_access_complete); + regs = host->regs_va; /* Link all private pointers */ mtd = &host->mtd; @@ -1038,53 +658,21 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) nand->ecc.size = 512; nand->options = pdata->options; nand->select_chip = fsmc_select_chip; - nand->badblockbits = 7; if (pdata->width == FSMC_NAND_BW16) nand->options |= NAND_BUSWIDTH_16; - switch (host->mode) { - case USE_DMA_ACCESS: - dma_cap_zero(mask); - dma_cap_set(DMA_MEMCPY, mask); - host->read_dma_chan = dma_request_channel(mask, filter, - pdata->read_dma_priv); - if (!host->read_dma_chan) { - dev_err(&pdev->dev, "Unable to get read dma channel\n"); - goto err_req_read_chnl; - } - host->write_dma_chan = dma_request_channel(mask, filter, - pdata->write_dma_priv); - if (!host->write_dma_chan) { - dev_err(&pdev->dev, "Unable to get write dma channel\n"); - goto err_req_write_chnl; - } - nand->read_buf = fsmc_read_buf_dma; - nand->write_buf = fsmc_write_buf_dma; - break; - - default: - case USE_WORD_ACCESS: - nand->read_buf = fsmc_read_buf; - nand->write_buf = fsmc_write_buf; - break; - } - - fsmc_nand_setup(host->regs_va, host->bank, - nand->options & NAND_BUSWIDTH_16, - host->dev_timings); + fsmc_nand_setup(regs, host->bank, nand->options & NAND_BUSWIDTH_16); if (AMBA_REV_BITS(host->pid) >= 8) { nand->ecc.read_page = fsmc_read_page_hwecc; nand->ecc.calculate = fsmc_read_hwecc_ecc4; - nand->ecc.correct = fsmc_bch8_correct_data; + nand->ecc.correct = fsmc_correct_data; nand->ecc.bytes = 13; - nand->ecc.strength = 8; } else { nand->ecc.calculate = fsmc_read_hwecc_ecc1; nand->ecc.correct = nand_correct_data; nand->ecc.bytes = 3; - nand->ecc.strength = 1; } /* @@ -1093,52 +681,19 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) if (nand_scan_ident(&host->mtd, 1, NULL)) { ret = -ENXIO; dev_err(&pdev->dev, "No NAND Device found!\n"); - goto err_scan_ident; + goto err_probe; } if (AMBA_REV_BITS(host->pid) >= 8) { - switch (host->mtd.oobsize) { - case 16: - nand->ecc.layout = &fsmc_ecc4_16_layout; + if (host->mtd.writesize == 512) { + nand->ecc.layout = &fsmc_ecc4_sp_layout; host->ecc_place = &fsmc_ecc4_sp_place; - break; - case 64: - nand->ecc.layout = &fsmc_ecc4_64_layout; - host->ecc_place = &fsmc_ecc4_lp_place; - break; - case 128: - nand->ecc.layout = &fsmc_ecc4_128_layout; - host->ecc_place = &fsmc_ecc4_lp_place; - break; - case 224: - nand->ecc.layout = &fsmc_ecc4_224_layout; - host->ecc_place = &fsmc_ecc4_lp_place; - break; - case 256: - nand->ecc.layout = &fsmc_ecc4_256_layout; + } else { + nand->ecc.layout = &fsmc_ecc4_lp_layout; host->ecc_place = &fsmc_ecc4_lp_place; - break; - default: - printk(KERN_WARNING "No oob scheme defined for " - "oobsize %d\n", mtd->oobsize); - BUG(); } } else { - switch (host->mtd.oobsize) { - case 16: - nand->ecc.layout = &fsmc_ecc1_16_layout; - break; - case 64: - nand->ecc.layout = &fsmc_ecc1_64_layout; - break; - case 128: - nand->ecc.layout = &fsmc_ecc1_128_layout; - break; - default: - printk(KERN_WARNING "No oob scheme defined for " - "oobsize %d\n", mtd->oobsize); - BUG(); - } + nand->ecc.layout = &fsmc_ecc1_layout; } /* Second stage of scan to fill MTD data-structures */ @@ -1158,9 +713,13 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) * Check for partition info passed */ host->mtd.name = "nand"; - ppdata.of_node = np; - ret = mtd_device_parse_register(&host->mtd, NULL, &ppdata, - host->partitions, host->nr_partitions); + ret = mtd_device_parse_register(&host->mtd, NULL, 0, + host->mtd.size <= 0x04000000 ? + partition_info_16KB_blk : + partition_info_128KB_blk, + host->mtd.size <= 0x04000000 ? + ARRAY_SIZE(partition_info_16KB_blk) : + ARRAY_SIZE(partition_info_128KB_blk)); if (ret) goto err_probe; @@ -1169,16 +728,32 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) return 0; err_probe: -err_scan_ident: - if (host->mode == USE_DMA_ACCESS) - dma_release_channel(host->write_dma_chan); -err_req_write_chnl: - if (host->mode == USE_DMA_ACCESS) - dma_release_channel(host->read_dma_chan); -err_req_read_chnl: clk_disable(host->clk); -err_clk_enable: - clk_put(host->clk); +err_probe1: + if (host->clk) + clk_put(host->clk); + if (host->regs_va) + iounmap(host->regs_va); + if (host->resregs) + release_mem_region(host->resregs->start, + resource_size(host->resregs)); + if (host->cmd_va) + iounmap(host->cmd_va); + if (host->rescmd) + release_mem_region(host->rescmd->start, + resource_size(host->rescmd)); + if (host->addr_va) + iounmap(host->addr_va); + if (host->resaddr) + release_mem_region(host->resaddr->start, + resource_size(host->resaddr)); + if (host->data_va) + iounmap(host->data_va); + if (host->resdata) + release_mem_region(host->resdata->start, + resource_size(host->resdata)); + + kfree(host); return ret; } @@ -1193,15 +768,24 @@ static int fsmc_nand_remove(struct platform_device *pdev) if (host) { nand_release(&host->mtd); - - if (host->mode == USE_DMA_ACCESS) { - dma_release_channel(host->write_dma_chan); - dma_release_channel(host->read_dma_chan); - } clk_disable(host->clk); clk_put(host->clk); - } + iounmap(host->regs_va); + release_mem_region(host->resregs->start, + resource_size(host->resregs)); + iounmap(host->cmd_va); + release_mem_region(host->rescmd->start, + resource_size(host->rescmd)); + iounmap(host->addr_va); + release_mem_region(host->resaddr->start, + resource_size(host->resaddr)); + iounmap(host->data_va); + release_mem_region(host->resdata->start, + resource_size(host->resdata)); + + kfree(host); + } return 0; } @@ -1217,24 +801,15 @@ static int fsmc_nand_suspend(struct device *dev) static int fsmc_nand_resume(struct device *dev) { struct fsmc_nand_data *host = dev_get_drvdata(dev); - if (host) { + if (host) clk_enable(host->clk); - fsmc_nand_setup(host->regs_va, host->bank, - host->nand.options & NAND_BUSWIDTH_16, - host->dev_timings); - } return 0; } -static SIMPLE_DEV_PM_OPS(fsmc_nand_pm_ops, fsmc_nand_suspend, fsmc_nand_resume); -#endif - -#ifdef CONFIG_OF -static const struct of_device_id fsmc_nand_id_table[] = { - { .compatible = "st,spear600-fsmc-nand" }, - {} +static const struct dev_pm_ops fsmc_nand_pm_ops = { + .suspend = fsmc_nand_suspend, + .resume = fsmc_nand_resume, }; -MODULE_DEVICE_TABLE(of, fsmc_nand_id_table); #endif static struct platform_driver fsmc_nand_driver = { @@ -1242,7 +817,6 @@ static struct platform_driver fsmc_nand_driver = { .driver = { .owner = THIS_MODULE, .name = "fsmc-nand", - .of_match_table = of_match_ptr(fsmc_nand_id_table), #ifdef CONFIG_PM .pm = &fsmc_nand_pm_ops, #endif diff --git a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-lib.c index e8ea7107932e..590dd5cceed6 100644 --- a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-lib.c +++ b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-lib.c @@ -848,10 +848,7 @@ int gpmi_send_command(struct gpmi_nand_data *this) sg_init_one(sgl, this->cmd_buffer, this->command_length); dma_map_sg(this->dev, sgl, 1, DMA_TO_DEVICE); - desc = dmaengine_prep_slave_sg(channel, - sgl, 1, DMA_MEM_TO_DEV, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - + desc = dmaengine_prep_slave_sg(channel, sgl, 1, DMA_MEM_TO_DEV, 1); if (!desc) { pr_err("step 2 error\n"); return -1; @@ -892,8 +889,7 @@ int gpmi_send_data(struct gpmi_nand_data *this) /* [2] send DMA request */ prepare_data_dma(this, DMA_TO_DEVICE); desc = dmaengine_prep_slave_sg(channel, &this->data_sgl, - 1, DMA_MEM_TO_DEV, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + 1, DMA_MEM_TO_DEV, 1); if (!desc) { pr_err("step 2 error\n"); return -1; @@ -929,8 +925,7 @@ int gpmi_read_data(struct gpmi_nand_data *this) /* [2] : send DMA request */ prepare_data_dma(this, DMA_FROM_DEVICE); desc = dmaengine_prep_slave_sg(channel, &this->data_sgl, - 1, DMA_DEV_TO_MEM, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + 1, DMA_DEV_TO_MEM, 1); if (!desc) { pr_err("step 2 error\n"); return -1; @@ -975,10 +970,8 @@ int gpmi_send_page(struct gpmi_nand_data *this, pio[4] = payload; pio[5] = auxiliary; - desc = dmaengine_prep_slave_sg(channel, - (struct scatterlist *)pio, - ARRAY_SIZE(pio), DMA_TRANS_NONE, - DMA_CTRL_ACK); + desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio, + ARRAY_SIZE(pio), DMA_TRANS_NONE, 0); if (!desc) { pr_err("step 2 error\n"); return -1; @@ -1042,8 +1035,7 @@ int gpmi_read_page(struct gpmi_nand_data *this, pio[5] = auxiliary; desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio, - ARRAY_SIZE(pio), DMA_TRANS_NONE, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + ARRAY_SIZE(pio), DMA_TRANS_NONE, 1); if (!desc) { pr_err("step 2 error\n"); return -1; @@ -1060,11 +1052,9 @@ int gpmi_read_page(struct gpmi_nand_data *this, | BF_GPMI_CTRL0_ADDRESS(address) | BF_GPMI_CTRL0_XFER_COUNT(geo->page_size); pio[1] = 0; - pio[2] = 0; /* clear GPMI_HW_GPMI_ECCCTRL, disable the BCH. */ desc = dmaengine_prep_slave_sg(channel, - (struct scatterlist *)pio, 3, - DMA_TRANS_NONE, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + (struct scatterlist *)pio, 2, + DMA_TRANS_NONE, 1); if (!desc) { pr_err("step 3 error\n"); return -1; diff --git a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 9ec51cec2e14..493ec2fcf97f 100644 --- a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -266,7 +266,6 @@ int start_dma_without_bch_irq(struct gpmi_nand_data *this, desc->callback = dma_irq_callback; desc->callback_param = this; dmaengine_submit(desc); - dma_async_issue_pending(get_dma_chan(this)); /* Wait for the interrupt from the DMA block. */ err = wait_for_completion_timeout(dma_c, msecs_to_jiffies(1000)); @@ -1125,7 +1124,7 @@ static int gpmi_block_markbad(struct mtd_info *mtd, loff_t ofs) chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); /* Do we have a flash based bad block table ? */ - if (chip->bbt_options & NAND_BBT_USE_FLASH) + if (chip->options & NAND_BBT_USE_FLASH) ret = nand_update_bbt(mtd, ofs); else { chipnr = (int)(ofs >> chip->chip_shift); @@ -1156,7 +1155,7 @@ static int gpmi_block_markbad(struct mtd_info *mtd, loff_t ofs) return ret; } -static int nand_boot_set_geometry(struct gpmi_nand_data *this) +static int __devinit nand_boot_set_geometry(struct gpmi_nand_data *this) { struct boot_rom_geometry *geometry = &this->rom_geometry; @@ -1183,7 +1182,7 @@ static int nand_boot_set_geometry(struct gpmi_nand_data *this) } static const char *fingerprint = "STMP"; -static int mx23_check_transcription_stamp(struct gpmi_nand_data *this) +static int __devinit mx23_check_transcription_stamp(struct gpmi_nand_data *this) { struct boot_rom_geometry *rom_geo = &this->rom_geometry; struct device *dev = this->dev; @@ -1240,7 +1239,7 @@ static int mx23_check_transcription_stamp(struct gpmi_nand_data *this) } /* Writes a transcription stamp. */ -static int mx23_write_transcription_stamp(struct gpmi_nand_data *this) +static int __devinit mx23_write_transcription_stamp(struct gpmi_nand_data *this) { struct device *dev = this->dev; struct boot_rom_geometry *rom_geo = &this->rom_geometry; @@ -1323,7 +1322,7 @@ static int mx23_write_transcription_stamp(struct gpmi_nand_data *this) return 0; } -static int mx23_boot_init(struct gpmi_nand_data *this) +static int __devinit mx23_boot_init(struct gpmi_nand_data *this) { struct device *dev = this->dev; struct nand_chip *chip = &this->nand; @@ -1392,7 +1391,7 @@ static int mx23_boot_init(struct gpmi_nand_data *this) return 0; } -static int nand_boot_init(struct gpmi_nand_data *this) +static int __devinit nand_boot_init(struct gpmi_nand_data *this) { nand_boot_set_geometry(this); @@ -1402,7 +1401,7 @@ static int nand_boot_init(struct gpmi_nand_data *this) return 0; } -static int gpmi_set_geometry(struct gpmi_nand_data *this) +static int __devinit gpmi_set_geometry(struct gpmi_nand_data *this) { int ret; diff --git a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.h index ec6180d4ff8f..e023bccb7781 100644 --- a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.h +++ b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.h @@ -20,7 +20,7 @@ #include #include #include -#include +#include struct resources { void *gpmi_regs; diff --git a/trunk/drivers/mtd/nand/h1910.c b/trunk/drivers/mtd/nand/h1910.c index 11e487813428..5dc6f0d92f1a 100644 --- a/trunk/drivers/mtd/nand/h1910.c +++ b/trunk/drivers/mtd/nand/h1910.c @@ -135,8 +135,8 @@ static int __init h1910_init(void) } /* Register the partitions */ - mtd_device_parse_register(h1910_nand_mtd, NULL, NULL, partition_info, - NUM_PARTITIONS); + mtd_device_parse_register(h1910_nand_mtd, NULL, 0, + partition_info, NUM_PARTITIONS); /* Return happy */ return 0; diff --git a/trunk/drivers/mtd/nand/jz4740_nand.c b/trunk/drivers/mtd/nand/jz4740_nand.c index e4147e8acb7c..ac3b9f255e00 100644 --- a/trunk/drivers/mtd/nand/jz4740_nand.c +++ b/trunk/drivers/mtd/nand/jz4740_nand.c @@ -332,11 +332,6 @@ static int __devinit jz_nand_probe(struct platform_device *pdev) chip->ecc.mode = NAND_ECC_HW_OOB_FIRST; chip->ecc.size = 512; chip->ecc.bytes = 9; - chip->ecc.strength = 2; - /* - * FIXME: ecc_strength value of 2 bits per 512 bytes of data is a - * conservative guess, given 9 ecc bytes and reed-solomon alg. - */ if (pdata) chip->ecc.layout = pdata->ecc_layout; @@ -372,9 +367,9 @@ static int __devinit jz_nand_probe(struct platform_device *pdev) goto err_gpio_free; } - ret = mtd_device_parse_register(mtd, NULL, NULL, - pdata ? pdata->partitions : NULL, - pdata ? pdata->num_partitions : 0); + ret = mtd_device_parse_register(mtd, NULL, 0, + pdata ? pdata->partitions : NULL, + pdata ? pdata->num_partitions : 0); if (ret) { dev_err(&pdev->dev, "Failed to add mtd device\n"); diff --git a/trunk/drivers/mtd/nand/mxc_nand.c b/trunk/drivers/mtd/nand/mxc_nand.c index cc0678a967c1..74a43b818d0e 100644 --- a/trunk/drivers/mtd/nand/mxc_nand.c +++ b/trunk/drivers/mtd/nand/mxc_nand.c @@ -1225,16 +1225,9 @@ static int __init mxcnd_probe(struct platform_device *pdev) goto escan; } - if (this->ecc.mode == NAND_ECC_HW) { - if (nfc_is_v1()) - this->ecc.strength = 1; - else - this->ecc.strength = (host->eccsize == 4) ? 4 : 8; - } - /* Register the partitions */ - mtd_device_parse_register(mtd, part_probes, NULL, pdata->parts, - pdata->nr_parts); + mtd_device_parse_register(mtd, part_probes, 0, + pdata->parts, pdata->nr_parts); platform_set_drvdata(pdev, host); diff --git a/trunk/drivers/mtd/nand/nand_base.c b/trunk/drivers/mtd/nand/nand_base.c index 47b19c0bb070..8a393f9e6027 100644 --- a/trunk/drivers/mtd/nand/nand_base.c +++ b/trunk/drivers/mtd/nand/nand_base.c @@ -123,6 +123,12 @@ static int check_offs_len(struct mtd_info *mtd, ret = -EINVAL; } + /* Do not allow past end of device */ + if (ofs + len > mtd->size) { + pr_debug("%s: past end of device\n", __func__); + ret = -EINVAL; + } + return ret; } @@ -332,7 +338,7 @@ static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) */ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) { - int page, chipnr, res = 0, i = 0; + int page, chipnr, res = 0; struct nand_chip *chip = mtd->priv; u16 bad; @@ -350,29 +356,23 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) chip->select_chip(mtd, chipnr); } - do { - if (chip->options & NAND_BUSWIDTH_16) { - chip->cmdfunc(mtd, NAND_CMD_READOOB, - chip->badblockpos & 0xFE, page); - bad = cpu_to_le16(chip->read_word(mtd)); - if (chip->badblockpos & 0x1) - bad >>= 8; - else - bad &= 0xFF; - } else { - chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos, - page); - bad = chip->read_byte(mtd); - } - - if (likely(chip->badblockbits == 8)) - res = bad != 0xFF; + if (chip->options & NAND_BUSWIDTH_16) { + chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos & 0xFE, + page); + bad = cpu_to_le16(chip->read_word(mtd)); + if (chip->badblockpos & 0x1) + bad >>= 8; else - res = hweight8(bad) < chip->badblockbits; - ofs += mtd->writesize; - page = (int)(ofs >> chip->page_shift) & chip->pagemask; - i++; - } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE)); + bad &= 0xFF; + } else { + chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos, page); + bad = chip->read_byte(mtd); + } + + if (likely(chip->badblockbits == 8)) + res = bad != 0xFF; + else + res = hweight8(bad) < chip->badblockbits; if (getchip) nand_release_device(mtd); @@ -386,79 +386,51 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) * @ofs: offset from device start * * This is the default implementation, which can be overridden by a hardware - * specific driver. We try operations in the following order, according to our - * bbt_options (NAND_BBT_NO_OOB_BBM and NAND_BBT_USE_FLASH): - * (1) erase the affected block, to allow OOB marker to be written cleanly - * (2) update in-memory BBT - * (3) write bad block marker to OOB area of affected block - * (4) update flash-based BBT - * Note that we retain the first error encountered in (3) or (4), finish the - * procedures, and dump the error in the end. + * specific driver. */ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) { struct nand_chip *chip = mtd->priv; uint8_t buf[2] = { 0, 0 }; - int block, res, ret = 0, i = 0; - int write_oob = !(chip->bbt_options & NAND_BBT_NO_OOB_BBM); - - if (write_oob) { - struct erase_info einfo; + int block, ret, i = 0; - /* Attempt erase before marking OOB */ - memset(&einfo, 0, sizeof(einfo)); - einfo.mtd = mtd; - einfo.addr = ofs; - einfo.len = 1 << chip->phys_erase_shift; - nand_erase_nand(mtd, &einfo, 0); - } + if (chip->bbt_options & NAND_BBT_SCANLASTPAGE) + ofs += mtd->erasesize - mtd->writesize; /* Get block number */ block = (int)(ofs >> chip->bbt_erase_shift); - /* Mark block bad in memory-based BBT */ if (chip->bbt) chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); - /* Write bad block marker to OOB */ - if (write_oob) { + /* Do we have a flash based bad block table? */ + if (chip->bbt_options & NAND_BBT_USE_FLASH) + ret = nand_update_bbt(mtd, ofs); + else { struct mtd_oob_ops ops; - loff_t wr_ofs = ofs; nand_get_device(chip, mtd, FL_WRITING); + /* + * Write to first two pages if necessary. If we write to more + * than one location, the first error encountered quits the + * procedure. We write two bytes per location, so we dont have + * to mess with 16 bit access. + */ + ops.len = ops.ooblen = 2; ops.datbuf = NULL; ops.oobbuf = buf; - ops.ooboffs = chip->badblockpos; - if (chip->options & NAND_BUSWIDTH_16) { - ops.ooboffs &= ~0x01; - ops.len = ops.ooblen = 2; - } else { - ops.len = ops.ooblen = 1; - } + ops.ooboffs = chip->badblockpos & ~0x01; ops.mode = MTD_OPS_PLACE_OOB; - - /* Write to first/last page(s) if necessary */ - if (chip->bbt_options & NAND_BBT_SCANLASTPAGE) - wr_ofs += mtd->erasesize - mtd->writesize; do { - res = nand_do_write_oob(mtd, wr_ofs, &ops); - if (!ret) - ret = res; + ret = nand_do_write_oob(mtd, ofs, &ops); i++; - wr_ofs += mtd->writesize; - } while ((chip->bbt_options & NAND_BBT_SCAN2NDPAGE) && i < 2); + ofs += mtd->writesize; + } while (!ret && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE) && + i < 2); nand_release_device(mtd); } - - /* Update flash-based bad block table */ - if (chip->bbt_options & NAND_BBT_USE_FLASH) { - res = nand_update_bbt(mtd, ofs); - if (!ret) - ret = res; - } - if (!ret) mtd->ecc_stats.badblocks++; @@ -1614,14 +1586,25 @@ static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, struct mtd_oob_ops ops; int ret; + /* Do not allow reads past end of device */ + if ((from + len) > mtd->size) + return -EINVAL; + if (!len) + return 0; + nand_get_device(chip, mtd, FL_READING); + ops.len = len; ops.datbuf = buf; ops.oobbuf = NULL; ops.mode = 0; + ret = nand_do_read_ops(mtd, from, &ops); + *retlen = ops.retlen; + nand_release_device(mtd); + return ret; } @@ -2310,6 +2293,12 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len, struct mtd_oob_ops ops; int ret; + /* Do not allow reads past end of device */ + if ((to + len) > mtd->size) + return -EINVAL; + if (!len) + return 0; + /* Wait for the device to get ready */ panic_nand_wait(mtd, chip, 400); @@ -2344,14 +2333,25 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, struct mtd_oob_ops ops; int ret; + /* Do not allow reads past end of device */ + if ((to + len) > mtd->size) + return -EINVAL; + if (!len) + return 0; + nand_get_device(chip, mtd, FL_WRITING); + ops.len = len; ops.datbuf = (uint8_t *)buf; ops.oobbuf = NULL; ops.mode = 0; + ret = nand_do_write_ops(mtd, to, &ops); + *retlen = ops.retlen; + nand_release_device(mtd); + return ret; } @@ -2550,6 +2550,8 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, if (check_offs_len(mtd, instr->addr, instr->len)) return -EINVAL; + instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; + /* Grab the lock and see if the device is available */ nand_get_device(chip, mtd, FL_ERASING); @@ -2713,6 +2715,10 @@ static void nand_sync(struct mtd_info *mtd) */ static int nand_block_isbad(struct mtd_info *mtd, loff_t offs) { + /* Check for invalid offset */ + if (offs > mtd->size) + return -EINVAL; + return nand_block_checkbad(mtd, offs, 1, 0); } @@ -2851,6 +2857,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I') return 0; + pr_info("ONFI flash detected\n"); chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1); for (i = 0; i < 3; i++) { chip->read_buf(mtd, (uint8_t *)p, sizeof(*p)); @@ -2891,8 +2898,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, mtd->writesize = le32_to_cpu(p->byte_per_page); mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize; mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page); - chip->chipsize = le32_to_cpu(p->blocks_per_lun); - chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count; + chip->chipsize = (uint64_t)le32_to_cpu(p->blocks_per_lun) * mtd->erasesize; *busw = 0; if (le16_to_cpu(p->features) & 1) *busw = NAND_BUSWIDTH_16; @@ -2901,7 +2907,6 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, chip->options |= (NAND_NO_READRDY | NAND_NO_AUTOINCR) & NAND_CHIPOPTIONS_MSK; - pr_info("ONFI flash detected\n"); return 1; } @@ -3233,10 +3238,6 @@ int nand_scan_tail(struct mtd_info *mtd) int i; struct nand_chip *chip = mtd->priv; - /* New bad blocks should be marked in OOB, flash-based BBT, or both */ - BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) && - !(chip->bbt_options & NAND_BBT_USE_FLASH)); - if (!(chip->options & NAND_OWN_BUFFERS)) chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL); if (!chip->buffers) @@ -3349,7 +3350,6 @@ int nand_scan_tail(struct mtd_info *mtd) if (!chip->ecc.size) chip->ecc.size = 256; chip->ecc.bytes = 3; - chip->ecc.strength = 1; break; case NAND_ECC_SOFT_BCH: @@ -3384,8 +3384,6 @@ int nand_scan_tail(struct mtd_info *mtd) pr_warn("BCH ECC initialization failed!\n"); BUG(); } - chip->ecc.strength = - chip->ecc.bytes*8 / fls(8*chip->ecc.size); break; case NAND_ECC_NONE: @@ -3399,7 +3397,6 @@ int nand_scan_tail(struct mtd_info *mtd) chip->ecc.write_oob = nand_write_oob_std; chip->ecc.size = mtd->writesize; chip->ecc.bytes = 0; - chip->ecc.strength = 0; break; default: @@ -3464,26 +3461,25 @@ int nand_scan_tail(struct mtd_info *mtd) mtd->type = MTD_NANDFLASH; mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM : MTD_CAP_NANDFLASH; - mtd->_erase = nand_erase; - mtd->_point = NULL; - mtd->_unpoint = NULL; - mtd->_read = nand_read; - mtd->_write = nand_write; - mtd->_panic_write = panic_nand_write; - mtd->_read_oob = nand_read_oob; - mtd->_write_oob = nand_write_oob; - mtd->_sync = nand_sync; - mtd->_lock = NULL; - mtd->_unlock = NULL; - mtd->_suspend = nand_suspend; - mtd->_resume = nand_resume; - mtd->_block_isbad = nand_block_isbad; - mtd->_block_markbad = nand_block_markbad; + mtd->erase = nand_erase; + mtd->point = NULL; + mtd->unpoint = NULL; + mtd->read = nand_read; + mtd->write = nand_write; + mtd->panic_write = panic_nand_write; + mtd->read_oob = nand_read_oob; + mtd->write_oob = nand_write_oob; + mtd->sync = nand_sync; + mtd->lock = NULL; + mtd->unlock = NULL; + mtd->suspend = nand_suspend; + mtd->resume = nand_resume; + mtd->block_isbad = nand_block_isbad; + mtd->block_markbad = nand_block_markbad; mtd->writebufsize = mtd->writesize; - /* propagate ecc info to mtd_info */ + /* propagate ecc.layout to mtd_info */ mtd->ecclayout = chip->ecc.layout; - mtd->ecc_strength = chip->ecc.strength * chip->ecc.steps; /* Check, if we should skip the bad block table scan */ if (chip->options & NAND_SKIP_BBTSCAN) diff --git a/trunk/drivers/mtd/nand/ndfc.c b/trunk/drivers/mtd/nand/ndfc.c index 2b6f632cf274..ec688548c880 100644 --- a/trunk/drivers/mtd/nand/ndfc.c +++ b/trunk/drivers/mtd/nand/ndfc.c @@ -179,7 +179,6 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, chip->ecc.mode = NAND_ECC_HW; chip->ecc.size = 256; chip->ecc.bytes = 3; - chip->ecc.strength = 1; chip->priv = ndfc; ndfc->mtd.priv = chip; diff --git a/trunk/drivers/mtd/nand/omap2.c b/trunk/drivers/mtd/nand/omap2.c index c2b0bba9d8b3..b3a883e2a22f 100644 --- a/trunk/drivers/mtd/nand/omap2.c +++ b/trunk/drivers/mtd/nand/omap2.c @@ -1058,7 +1058,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) { info->nand.ecc.bytes = 3; info->nand.ecc.size = 512; - info->nand.ecc.strength = 1; info->nand.ecc.calculate = omap_calculate_ecc; info->nand.ecc.hwctl = omap_enable_hwecc; info->nand.ecc.correct = omap_correct_data; @@ -1102,8 +1101,8 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) goto out_release_mem_region; } - mtd_device_parse_register(&info->mtd, NULL, NULL, pdata->parts, - pdata->nr_parts); + mtd_device_parse_register(&info->mtd, NULL, 0, + pdata->parts, pdata->nr_parts); platform_set_drvdata(pdev, &info->mtd); diff --git a/trunk/drivers/mtd/nand/orion_nand.c b/trunk/drivers/mtd/nand/orion_nand.c index 1d3bfb26080c..29f505adaf84 100644 --- a/trunk/drivers/mtd/nand/orion_nand.c +++ b/trunk/drivers/mtd/nand/orion_nand.c @@ -129,8 +129,8 @@ static int __init orion_nand_probe(struct platform_device *pdev) } mtd->name = "orion_nand"; - ret = mtd_device_parse_register(mtd, NULL, NULL, board->parts, - board->nr_parts); + ret = mtd_device_parse_register(mtd, NULL, 0, + board->parts, board->nr_parts); if (ret) { nand_release(mtd); goto no_dev; diff --git a/trunk/drivers/mtd/nand/plat_nand.c b/trunk/drivers/mtd/nand/plat_nand.c index 6404e6e81b10..7f2da6953357 100644 --- a/trunk/drivers/mtd/nand/plat_nand.c +++ b/trunk/drivers/mtd/nand/plat_nand.c @@ -99,9 +99,8 @@ static int __devinit plat_nand_probe(struct platform_device *pdev) } err = mtd_device_parse_register(&data->mtd, - pdata->chip.part_probe_types, NULL, - pdata->chip.partitions, - pdata->chip.nr_partitions); + pdata->chip.part_probe_types, 0, + pdata->chip.partitions, pdata->chip.nr_partitions); if (!err) return err; diff --git a/trunk/drivers/mtd/nand/ppchameleonevb.c b/trunk/drivers/mtd/nand/ppchameleonevb.c index 0ddd90e5788f..7e52af51a198 100644 --- a/trunk/drivers/mtd/nand/ppchameleonevb.c +++ b/trunk/drivers/mtd/nand/ppchameleonevb.c @@ -275,10 +275,11 @@ static int __init ppchameleonevb_init(void) ppchameleon_mtd->name = "ppchameleon-nand"; /* Register the partitions */ - mtd_device_parse_register(ppchameleon_mtd, NULL, NULL, - ppchameleon_mtd->size == NAND_SMALL_SIZE ? - partition_info_me : partition_info_hi, - NUM_PARTITIONS); + mtd_device_parse_register(ppchameleon_mtd, NULL, 0, + ppchameleon_mtd->size == NAND_SMALL_SIZE ? + partition_info_me : + partition_info_hi, + NUM_PARTITIONS); nand_evb_init: /**************************** @@ -364,10 +365,11 @@ static int __init ppchameleonevb_init(void) ppchameleonevb_mtd->name = NAND_EVB_MTD_NAME; /* Register the partitions */ - mtd_device_parse_register(ppchameleonevb_mtd, NULL, NULL, - ppchameleon_mtd->size == NAND_SMALL_SIZE ? - partition_info_me : partition_info_hi, - NUM_PARTITIONS); + mtd_device_parse_register(ppchameleonevb_mtd, NULL, 0, + ppchameleon_mtd->size == NAND_SMALL_SIZE ? + partition_info_me : + partition_info_hi, + NUM_PARTITIONS); /* Return happy */ return 0; diff --git a/trunk/drivers/mtd/nand/pxa3xx_nand.c b/trunk/drivers/mtd/nand/pxa3xx_nand.c index def50caa6f84..5c3d719c37e6 100644 --- a/trunk/drivers/mtd/nand/pxa3xx_nand.c +++ b/trunk/drivers/mtd/nand/pxa3xx_nand.c @@ -1002,7 +1002,6 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) KEEP_CONFIG: chip->ecc.mode = NAND_ECC_HW; chip->ecc.size = host->page_size; - chip->ecc.strength = 1; chip->options = NAND_NO_AUTOINCR; chip->options |= NAND_NO_READRDY; @@ -1229,9 +1228,8 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) continue; } - ret = mtd_device_parse_register(info->host[cs]->mtd, NULL, - NULL, pdata->parts[cs], - pdata->nr_parts[cs]); + ret = mtd_device_parse_register(info->host[cs]->mtd, NULL, 0, + pdata->parts[cs], pdata->nr_parts[cs]); if (!ret) probe_success = 1; } diff --git a/trunk/drivers/mtd/nand/r852.c b/trunk/drivers/mtd/nand/r852.c index c2040187c813..769a4e096b3c 100644 --- a/trunk/drivers/mtd/nand/r852.c +++ b/trunk/drivers/mtd/nand/r852.c @@ -891,7 +891,6 @@ int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) chip->ecc.mode = NAND_ECC_HW_SYNDROME; chip->ecc.size = R852_DMA_LEN; chip->ecc.bytes = SM_OOB_SIZE; - chip->ecc.strength = 2; chip->ecc.hwctl = r852_ecc_hwctl; chip->ecc.calculate = r852_ecc_calculate; chip->ecc.correct = r852_ecc_correct; diff --git a/trunk/drivers/mtd/nand/rtc_from4.c b/trunk/drivers/mtd/nand/rtc_from4.c index e55b5cfbe145..f309addc2fa0 100644 --- a/trunk/drivers/mtd/nand/rtc_from4.c +++ b/trunk/drivers/mtd/nand/rtc_from4.c @@ -527,7 +527,6 @@ static int __init rtc_from4_init(void) this->ecc.mode = NAND_ECC_HW_SYNDROME; this->ecc.size = 512; this->ecc.bytes = 8; - this->ecc.strength = 3; /* return the status of extra status and ECC checks */ this->errstat = rtc_from4_errstat; /* set the nand_oobinfo to support FPGA H/W error detection */ diff --git a/trunk/drivers/mtd/nand/s3c2410.c b/trunk/drivers/mtd/nand/s3c2410.c index 91121f33f743..868685db6712 100644 --- a/trunk/drivers/mtd/nand/s3c2410.c +++ b/trunk/drivers/mtd/nand/s3c2410.c @@ -751,8 +751,8 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, if (set) mtd->mtd.name = set->name; - return mtd_device_parse_register(&mtd->mtd, NULL, NULL, - set->partitions, set->nr_partitions); + return mtd_device_parse_register(&mtd->mtd, NULL, 0, + set->partitions, set->nr_partitions); } /** @@ -823,7 +823,6 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, chip->ecc.calculate = s3c2410_nand_calculate_ecc; chip->ecc.correct = s3c2410_nand_correct_data; chip->ecc.mode = NAND_ECC_HW; - chip->ecc.strength = 1; switch (info->cpu_type) { case TYPE_S3C2410: diff --git a/trunk/drivers/mtd/nand/sh_flctl.c b/trunk/drivers/mtd/nand/sh_flctl.c index e9b2b260de3a..93b1f74321c2 100644 --- a/trunk/drivers/mtd/nand/sh_flctl.c +++ b/trunk/drivers/mtd/nand/sh_flctl.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -284,7 +283,7 @@ static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset) static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val) { struct sh_flctl *flctl = mtd_to_flctl(mtd); - uint32_t flcmncr_val = flctl->flcmncr_base & ~SEL_16BIT; + uint32_t flcmncr_val = readl(FLCMNCR(flctl)) & ~SEL_16BIT; uint32_t flcmdcr_val, addr_len_bytes = 0; /* Set SNAND bit if page size is 2048byte */ @@ -304,7 +303,6 @@ static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_va break; case NAND_CMD_READ0: case NAND_CMD_READOOB: - case NAND_CMD_RNDOUT: addr_len_bytes = flctl->rw_ADRCNT; flcmdcr_val |= CDSRC_E; if (flctl->chip.options & NAND_BUSWIDTH_16) @@ -322,7 +320,6 @@ static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_va break; case NAND_CMD_READID: flcmncr_val &= ~SNAND_E; - flcmdcr_val |= CDSRC_E; addr_len_bytes = ADRCNT_1; break; case NAND_CMD_STATUS: @@ -516,8 +513,6 @@ static void flctl_cmdfunc(struct mtd_info *mtd, unsigned int command, struct sh_flctl *flctl = mtd_to_flctl(mtd); uint32_t read_cmd = 0; - pm_runtime_get_sync(&flctl->pdev->dev); - flctl->read_bytes = 0; if (command != NAND_CMD_PAGEPROG) flctl->index = 0; @@ -530,6 +525,7 @@ static void flctl_cmdfunc(struct mtd_info *mtd, unsigned int command, execmd_read_page_sector(mtd, page_addr); break; } + empty_fifo(flctl); if (flctl->page_size) set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8) | command); @@ -551,6 +547,7 @@ static void flctl_cmdfunc(struct mtd_info *mtd, unsigned int command, break; } + empty_fifo(flctl); if (flctl->page_size) { set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8) | NAND_CMD_READ0); @@ -562,35 +559,15 @@ static void flctl_cmdfunc(struct mtd_info *mtd, unsigned int command, flctl->read_bytes = mtd->oobsize; goto read_normal_exit; - case NAND_CMD_RNDOUT: - if (flctl->hwecc) - break; - - if (flctl->page_size) - set_cmd_regs(mtd, command, (NAND_CMD_RNDOUTSTART << 8) - | command); - else - set_cmd_regs(mtd, command, command); - - set_addr(mtd, column, 0); - - flctl->read_bytes = mtd->writesize + mtd->oobsize - column; - goto read_normal_exit; - case NAND_CMD_READID: + empty_fifo(flctl); set_cmd_regs(mtd, command, command); + set_addr(mtd, 0, 0); - /* READID is always performed using an 8-bit bus */ - if (flctl->chip.options & NAND_BUSWIDTH_16) - column <<= 1; - set_addr(mtd, column, 0); - - flctl->read_bytes = 8; + flctl->read_bytes = 4; writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */ - empty_fifo(flctl); start_translation(flctl); - read_fiforeg(flctl, flctl->read_bytes, 0); - wait_completion(flctl); + read_datareg(flctl, 0); /* read and end */ break; case NAND_CMD_ERASE1: @@ -673,55 +650,29 @@ static void flctl_cmdfunc(struct mtd_info *mtd, unsigned int command, default: break; } - goto runtime_exit; + return; read_normal_exit: writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */ - empty_fifo(flctl); start_translation(flctl); read_fiforeg(flctl, flctl->read_bytes, 0); wait_completion(flctl); -runtime_exit: - pm_runtime_put_sync(&flctl->pdev->dev); return; } static void flctl_select_chip(struct mtd_info *mtd, int chipnr) { struct sh_flctl *flctl = mtd_to_flctl(mtd); - int ret; + uint32_t flcmncr_val = readl(FLCMNCR(flctl)); switch (chipnr) { case -1: - flctl->flcmncr_base &= ~CE0_ENABLE; - - pm_runtime_get_sync(&flctl->pdev->dev); - writel(flctl->flcmncr_base, FLCMNCR(flctl)); - - if (flctl->qos_request) { - dev_pm_qos_remove_request(&flctl->pm_qos); - flctl->qos_request = 0; - } - - pm_runtime_put_sync(&flctl->pdev->dev); + flcmncr_val &= ~CE0_ENABLE; + writel(flcmncr_val, FLCMNCR(flctl)); break; case 0: - flctl->flcmncr_base |= CE0_ENABLE; - - if (!flctl->qos_request) { - ret = dev_pm_qos_add_request(&flctl->pdev->dev, - &flctl->pm_qos, 100); - if (ret < 0) - dev_err(&flctl->pdev->dev, - "PM QoS request failed: %d\n", ret); - flctl->qos_request = 1; - } - - if (flctl->holden) { - pm_runtime_get_sync(&flctl->pdev->dev); - writel(HOLDEN, FLHOLDCR(flctl)); - pm_runtime_put_sync(&flctl->pdev->dev); - } + flcmncr_val |= CE0_ENABLE; + writel(flcmncr_val, FLCMNCR(flctl)); break; default: BUG(); @@ -779,6 +730,11 @@ static int flctl_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) return 0; } +static void flctl_register_init(struct sh_flctl *flctl, unsigned long val) +{ + writel(val, FLCMNCR(flctl)); +} + static int flctl_chip_init_tail(struct mtd_info *mtd) { struct sh_flctl *flctl = mtd_to_flctl(mtd); @@ -825,13 +781,13 @@ static int flctl_chip_init_tail(struct mtd_info *mtd) chip->ecc.size = 512; chip->ecc.bytes = 10; - chip->ecc.strength = 4; chip->ecc.read_page = flctl_read_page_hwecc; chip->ecc.write_page = flctl_write_page_hwecc; chip->ecc.mode = NAND_ECC_HW; /* 4 symbols ECC enabled */ - flctl->flcmncr_base |= _4ECCEN | ECCPOS2 | ECCPOS_02; + writel(readl(FLCMNCR(flctl)) | _4ECCEN | ECCPOS2 | ECCPOS_02, + FLCMNCR(flctl)); } else { chip->ecc.mode = NAND_ECC_SOFT; } @@ -863,13 +819,13 @@ static int __devinit flctl_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "failed to get I/O memory\n"); - goto err_iomap; + goto err; } flctl->reg = ioremap(res->start, resource_size(res)); if (flctl->reg == NULL) { dev_err(&pdev->dev, "failed to remap I/O memory\n"); - goto err_iomap; + goto err; } platform_set_drvdata(pdev, flctl); @@ -877,9 +833,9 @@ static int __devinit flctl_probe(struct platform_device *pdev) nand = &flctl->chip; flctl_mtd->priv = nand; flctl->pdev = pdev; - flctl->flcmncr_base = pdata->flcmncr_val; flctl->hwecc = pdata->has_hwecc; - flctl->holden = pdata->use_holden; + + flctl_register_init(flctl, pdata->flcmncr_val); nand->options = NAND_NO_AUTOINCR; @@ -899,28 +855,23 @@ static int __devinit flctl_probe(struct platform_device *pdev) nand->read_word = flctl_read_word; } - pm_runtime_enable(&pdev->dev); - pm_runtime_resume(&pdev->dev); - ret = nand_scan_ident(flctl_mtd, 1, NULL); if (ret) - goto err_chip; + goto err; ret = flctl_chip_init_tail(flctl_mtd); if (ret) - goto err_chip; + goto err; ret = nand_scan_tail(flctl_mtd); if (ret) - goto err_chip; + goto err; mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts); return 0; -err_chip: - pm_runtime_disable(&pdev->dev); -err_iomap: +err: kfree(flctl); return ret; } @@ -930,7 +881,6 @@ static int __devexit flctl_remove(struct platform_device *pdev) struct sh_flctl *flctl = platform_get_drvdata(pdev); nand_release(&flctl->mtd); - pm_runtime_disable(&pdev->dev); kfree(flctl); return 0; diff --git a/trunk/drivers/mtd/nand/sharpsl.c b/trunk/drivers/mtd/nand/sharpsl.c index 3421e3762a5a..b175c0fd8b93 100644 --- a/trunk/drivers/mtd/nand/sharpsl.c +++ b/trunk/drivers/mtd/nand/sharpsl.c @@ -167,7 +167,6 @@ static int __devinit sharpsl_nand_probe(struct platform_device *pdev) this->ecc.mode = NAND_ECC_HW; this->ecc.size = 256; this->ecc.bytes = 3; - this->ecc.strength = 1; this->badblock_pattern = data->badblock_pattern; this->ecc.layout = data->ecc_layout; this->ecc.hwctl = sharpsl_nand_enable_hwecc; @@ -182,8 +181,8 @@ static int __devinit sharpsl_nand_probe(struct platform_device *pdev) /* Register the partitions */ sharpsl->mtd.name = "sharpsl-nand"; - err = mtd_device_parse_register(&sharpsl->mtd, NULL, NULL, - data->partitions, data->nr_partitions); + err = mtd_device_parse_register(&sharpsl->mtd, NULL, 0, + data->partitions, data->nr_partitions); if (err) goto err_add; diff --git a/trunk/drivers/mtd/nand/tmio_nand.c b/trunk/drivers/mtd/nand/tmio_nand.c index 5aa518081c51..6caa0cd9d6a7 100644 --- a/trunk/drivers/mtd/nand/tmio_nand.c +++ b/trunk/drivers/mtd/nand/tmio_nand.c @@ -430,7 +430,6 @@ static int tmio_probe(struct platform_device *dev) nand_chip->ecc.mode = NAND_ECC_HW; nand_chip->ecc.size = 512; nand_chip->ecc.bytes = 6; - nand_chip->ecc.strength = 2; nand_chip->ecc.hwctl = tmio_nand_enable_hwecc; nand_chip->ecc.calculate = tmio_nand_calculate_ecc; nand_chip->ecc.correct = tmio_nand_correct_data; @@ -457,9 +456,9 @@ static int tmio_probe(struct platform_device *dev) goto err_scan; } /* Register the partitions */ - retval = mtd_device_parse_register(mtd, NULL, NULL, - data ? data->partition : NULL, - data ? data->num_partitions : 0); + retval = mtd_device_parse_register(mtd, NULL, 0, + data ? data->partition : NULL, + data ? data->num_partitions : 0); if (!retval) return retval; diff --git a/trunk/drivers/mtd/nand/txx9ndfmc.c b/trunk/drivers/mtd/nand/txx9ndfmc.c index 26398dcf21cf..c7c4f1d11c77 100644 --- a/trunk/drivers/mtd/nand/txx9ndfmc.c +++ b/trunk/drivers/mtd/nand/txx9ndfmc.c @@ -356,7 +356,6 @@ static int __init txx9ndfmc_probe(struct platform_device *dev) /* txx9ndfmc_nand_scan will overwrite ecc.size and ecc.bytes */ chip->ecc.size = 256; chip->ecc.bytes = 3; - chip->ecc.strength = 1; chip->chip_delay = 100; chip->controller = &drvdata->hw_control; @@ -387,7 +386,7 @@ static int __init txx9ndfmc_probe(struct platform_device *dev) } mtd->name = txx9_priv->mtdname; - mtd_device_parse_register(mtd, NULL, NULL, NULL, 0); + mtd_device_parse_register(mtd, NULL, 0, NULL, 0); drvdata->mtds[i] = mtd; } diff --git a/trunk/drivers/mtd/nftlcore.c b/trunk/drivers/mtd/nftlcore.c index c5f4ebf4b384..a75382aff5f6 100644 --- a/trunk/drivers/mtd/nftlcore.c +++ b/trunk/drivers/mtd/nftlcore.c @@ -56,6 +56,13 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) if (memcmp(mtd->name, "DiskOnChip", 10)) return; + if (!mtd_can_have_bb(mtd)) { + printk(KERN_ERR +"NFTL no longer supports the old DiskOnChip drivers loaded via docprobe.\n" +"Please use the new diskonchip driver under the NAND subsystem.\n"); + return; + } + pr_debug("NFTL: add_mtd for %s\n", mtd->name); nftl = kzalloc(sizeof(struct NFTLrecord), GFP_KERNEL); diff --git a/trunk/drivers/mtd/onenand/generic.c b/trunk/drivers/mtd/onenand/generic.c index 1c4f97c63e62..0ccd5bff2544 100644 --- a/trunk/drivers/mtd/onenand/generic.c +++ b/trunk/drivers/mtd/onenand/generic.c @@ -70,9 +70,9 @@ static int __devinit generic_onenand_probe(struct platform_device *pdev) goto out_iounmap; } - err = mtd_device_parse_register(&info->mtd, NULL, NULL, - pdata ? pdata->parts : NULL, - pdata ? pdata->nr_parts : 0); + err = mtd_device_parse_register(&info->mtd, NULL, 0, + pdata ? pdata->parts : NULL, + pdata ? pdata->nr_parts : 0); platform_set_drvdata(pdev, info); diff --git a/trunk/drivers/mtd/onenand/omap2.c b/trunk/drivers/mtd/onenand/omap2.c index 398a82783848..7e9ea6852b67 100644 --- a/trunk/drivers/mtd/onenand/omap2.c +++ b/trunk/drivers/mtd/onenand/omap2.c @@ -751,9 +751,9 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev) if ((r = onenand_scan(&c->mtd, 1)) < 0) goto err_release_regulator; - r = mtd_device_parse_register(&c->mtd, NULL, NULL, - pdata ? pdata->parts : NULL, - pdata ? pdata->nr_parts : 0); + r = mtd_device_parse_register(&c->mtd, NULL, 0, + pdata ? pdata->parts : NULL, + pdata ? pdata->nr_parts : 0); if (r) goto err_release_onenand; diff --git a/trunk/drivers/mtd/onenand/onenand_base.c b/trunk/drivers/mtd/onenand/onenand_base.c index b3ce12ef359e..a061bc163da2 100644 --- a/trunk/drivers/mtd/onenand/onenand_base.c +++ b/trunk/drivers/mtd/onenand/onenand_base.c @@ -1753,6 +1753,16 @@ static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len, pr_debug("%s: to = 0x%08x, len = %i\n", __func__, (unsigned int)to, (int)len); + /* Initialize retlen, in case of early exit */ + *retlen = 0; + + /* Do not allow writes past end of device */ + if (unlikely((to + len) > mtd->size)) { + printk(KERN_ERR "%s: Attempt write to past end of device\n", + __func__); + return -EINVAL; + } + /* Reject writes, which are not page aligned */ if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) { printk(KERN_ERR "%s: Attempt to write not page aligned data\n", @@ -1880,6 +1890,13 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to, ops->retlen = 0; ops->oobretlen = 0; + /* Do not allow writes past end of device */ + if (unlikely((to + len) > mtd->size)) { + printk(KERN_ERR "%s: Attempt write to past end of device\n", + __func__); + return -EINVAL; + } + /* Reject writes, which are not page aligned */ if (unlikely(NOTALIGNED(to) || NOTALIGNED(len))) { printk(KERN_ERR "%s: Attempt to write not page aligned data\n", @@ -2476,6 +2493,12 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) (unsigned long long)instr->addr, (unsigned long long)instr->len); + /* Do not allow erase past end of device */ + if (unlikely((len + addr) > mtd->size)) { + printk(KERN_ERR "%s: Erase past end of device\n", __func__); + return -EINVAL; + } + if (FLEXONENAND(this)) { /* Find the eraseregion of this address */ int i = flexonenand_region(mtd, addr); @@ -2502,6 +2525,8 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) return -EINVAL; } + instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; + /* Grab the lock and see if the device is available */ onenand_get_device(mtd, FL_ERASING); @@ -4078,34 +4103,33 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) mtd->oobavail = this->ecclayout->oobavail; mtd->ecclayout = this->ecclayout; - mtd->ecc_strength = 1; /* Fill in remaining MTD driver data */ mtd->type = ONENAND_IS_MLC(this) ? MTD_MLCNANDFLASH : MTD_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH; - mtd->_erase = onenand_erase; - mtd->_point = NULL; - mtd->_unpoint = NULL; - mtd->_read = onenand_read; - mtd->_write = onenand_write; - mtd->_read_oob = onenand_read_oob; - mtd->_write_oob = onenand_write_oob; - mtd->_panic_write = onenand_panic_write; + mtd->erase = onenand_erase; + mtd->point = NULL; + mtd->unpoint = NULL; + mtd->read = onenand_read; + mtd->write = onenand_write; + mtd->read_oob = onenand_read_oob; + mtd->write_oob = onenand_write_oob; + mtd->panic_write = onenand_panic_write; #ifdef CONFIG_MTD_ONENAND_OTP - mtd->_get_fact_prot_info = onenand_get_fact_prot_info; - mtd->_read_fact_prot_reg = onenand_read_fact_prot_reg; - mtd->_get_user_prot_info = onenand_get_user_prot_info; - mtd->_read_user_prot_reg = onenand_read_user_prot_reg; - mtd->_write_user_prot_reg = onenand_write_user_prot_reg; - mtd->_lock_user_prot_reg = onenand_lock_user_prot_reg; + mtd->get_fact_prot_info = onenand_get_fact_prot_info; + mtd->read_fact_prot_reg = onenand_read_fact_prot_reg; + mtd->get_user_prot_info = onenand_get_user_prot_info; + mtd->read_user_prot_reg = onenand_read_user_prot_reg; + mtd->write_user_prot_reg = onenand_write_user_prot_reg; + mtd->lock_user_prot_reg = onenand_lock_user_prot_reg; #endif - mtd->_sync = onenand_sync; - mtd->_lock = onenand_lock; - mtd->_unlock = onenand_unlock; - mtd->_suspend = onenand_suspend; - mtd->_resume = onenand_resume; - mtd->_block_isbad = onenand_block_isbad; - mtd->_block_markbad = onenand_block_markbad; + mtd->sync = onenand_sync; + mtd->lock = onenand_lock; + mtd->unlock = onenand_unlock; + mtd->suspend = onenand_suspend; + mtd->resume = onenand_resume; + mtd->block_isbad = onenand_block_isbad; + mtd->block_markbad = onenand_block_markbad; mtd->owner = THIS_MODULE; mtd->writebufsize = mtd->writesize; diff --git a/trunk/drivers/mtd/onenand/samsung.c b/trunk/drivers/mtd/onenand/samsung.c index 8e4b3f2742ba..fa1ee43f735b 100644 --- a/trunk/drivers/mtd/onenand/samsung.c +++ b/trunk/drivers/mtd/onenand/samsung.c @@ -923,7 +923,7 @@ static int s3c_onenand_probe(struct platform_device *pdev) r = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!r) { dev_err(&pdev->dev, "no buffer memory resource defined\n"); - err = -ENOENT; + return -ENOENT; goto ahb_resource_failed; } @@ -964,7 +964,7 @@ static int s3c_onenand_probe(struct platform_device *pdev) r = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!r) { dev_err(&pdev->dev, "no dma memory resource defined\n"); - err = -ENOENT; + return -ENOENT; goto dma_resource_failed; } @@ -1014,7 +1014,7 @@ static int s3c_onenand_probe(struct platform_device *pdev) if (s3c_read_reg(MEM_CFG_OFFSET) & ONENAND_SYS_CFG1_SYNC_READ) dev_info(&onenand->pdev->dev, "OneNAND Sync. Burst Read enabled\n"); - err = mtd_device_parse_register(mtd, NULL, NULL, + err = mtd_device_parse_register(mtd, NULL, 0, pdata ? pdata->parts : NULL, pdata ? pdata->nr_parts : 0); diff --git a/trunk/drivers/mtd/redboot.c b/trunk/drivers/mtd/redboot.c index 580035c803d6..48970c14beff 100644 --- a/trunk/drivers/mtd/redboot.c +++ b/trunk/drivers/mtd/redboot.c @@ -78,7 +78,8 @@ static int parse_redboot_partitions(struct mtd_info *master, if ( directory < 0 ) { offset = master->size + directory * master->erasesize; - while (mtd_block_isbad(master, offset)) { + while (mtd_can_have_bb(master) && + mtd_block_isbad(master, offset)) { if (!offset) { nogood: printk(KERN_NOTICE "Failed to find a non-bad block to check for RedBoot partition table\n"); @@ -88,7 +89,8 @@ static int parse_redboot_partitions(struct mtd_info *master, } } else { offset = directory * master->erasesize; - while (mtd_block_isbad(master, offset)) { + while (mtd_can_have_bb(master) && + mtd_block_isbad(master, offset)) { offset += master->erasesize; if (offset == master->size) goto nogood; diff --git a/trunk/drivers/mtd/sm_ftl.c b/trunk/drivers/mtd/sm_ftl.c index 9e2dfd517aa5..072ed5970e2f 100644 --- a/trunk/drivers/mtd/sm_ftl.c +++ b/trunk/drivers/mtd/sm_ftl.c @@ -1256,7 +1256,7 @@ static void sm_remove_dev(struct mtd_blktrans_dev *dev) static struct mtd_blktrans_ops sm_ftl_ops = { .name = "smblk", - .major = 0, + .major = -1, .part_bits = SM_FTL_PARTN_BITS, .blksize = SM_SECTOR_SIZE, .getgeo = sm_getgeo, diff --git a/trunk/drivers/mtd/ubi/debug.c b/trunk/drivers/mtd/ubi/debug.c index 61af9bb560ab..e2cdebf40840 100644 --- a/trunk/drivers/mtd/ubi/debug.c +++ b/trunk/drivers/mtd/ubi/debug.c @@ -386,11 +386,19 @@ static ssize_t dfs_file_write(struct file *file, const char __user *user_buf, return count; } +static int default_open(struct inode *inode, struct file *file) +{ + if (inode->i_private) + file->private_data = inode->i_private; + + return 0; +} + /* File operations for all UBI debugfs files */ static const struct file_operations dfs_fops = { .read = dfs_file_read, .write = dfs_file_write, - .open = simple_open, + .open = default_open, .llseek = no_llseek, .owner = THIS_MODULE, }; diff --git a/trunk/drivers/mtd/ubi/gluebi.c b/trunk/drivers/mtd/ubi/gluebi.c index 90b98822d9a4..941bc3c05d6e 100644 --- a/trunk/drivers/mtd/ubi/gluebi.c +++ b/trunk/drivers/mtd/ubi/gluebi.c @@ -174,7 +174,11 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len, int err = 0, lnum, offs, total_read; struct gluebi_device *gluebi; + if (len < 0 || from < 0 || from + len > mtd->size) + return -EINVAL; + gluebi = container_of(mtd, struct gluebi_device, mtd); + lnum = div_u64_rem(from, mtd->erasesize, &offs); total_read = len; while (total_read) { @@ -214,7 +218,14 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len, int err = 0, lnum, offs, total_written; struct gluebi_device *gluebi; + if (len < 0 || to < 0 || len + to > mtd->size) + return -EINVAL; + gluebi = container_of(mtd, struct gluebi_device, mtd); + + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + lnum = div_u64_rem(to, mtd->erasesize, &offs); if (len % mtd->writesize || offs % mtd->writesize) @@ -254,13 +265,21 @@ static int gluebi_erase(struct mtd_info *mtd, struct erase_info *instr) int err, i, lnum, count; struct gluebi_device *gluebi; + if (instr->addr < 0 || instr->addr > mtd->size - mtd->erasesize) + return -EINVAL; + if (instr->len < 0 || instr->addr + instr->len > mtd->size) + return -EINVAL; if (mtd_mod_by_ws(instr->addr, mtd) || mtd_mod_by_ws(instr->len, mtd)) return -EINVAL; lnum = mtd_div_by_eb(instr->addr, mtd); count = mtd_div_by_eb(instr->len, mtd); + gluebi = container_of(mtd, struct gluebi_device, mtd); + if (!(mtd->flags & MTD_WRITEABLE)) + return -EROFS; + for (i = 0; i < count - 1; i++) { err = ubi_leb_unmap(gluebi->desc, lnum + i); if (err) @@ -321,11 +340,11 @@ static int gluebi_create(struct ubi_device_info *di, mtd->owner = THIS_MODULE; mtd->writesize = di->min_io_size; mtd->erasesize = vi->usable_leb_size; - mtd->_read = gluebi_read; - mtd->_write = gluebi_write; - mtd->_erase = gluebi_erase; - mtd->_get_device = gluebi_get_device; - mtd->_put_device = gluebi_put_device; + mtd->read = gluebi_read; + mtd->write = gluebi_write; + mtd->erase = gluebi_erase; + mtd->get_device = gluebi_get_device; + mtd->put_device = gluebi_put_device; /* * In case of dynamic a volume, MTD device size is just volume size. In diff --git a/trunk/drivers/net/arcnet/arc-rimi.c b/trunk/drivers/net/arcnet/arc-rimi.c index b8b4c7ba884f..25197b698dd6 100644 --- a/trunk/drivers/net/arcnet/arc-rimi.c +++ b/trunk/drivers/net/arcnet/arc-rimi.c @@ -89,16 +89,16 @@ static int __init arcrimi_probe(struct net_device *dev) BUGLVL(D_NORMAL) printk(VERSION); BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n"); - BUGLVL(D_NORMAL) printk("Given: node %02Xh, shmem %lXh, irq %d\n", + BUGMSG(D_NORMAL, "Given: node %02Xh, shmem %lXh, irq %d\n", dev->dev_addr[0], dev->mem_start, dev->irq); if (dev->mem_start <= 0 || dev->irq <= 0) { - BUGLVL(D_NORMAL) printk("No autoprobe for RIM I; you " + BUGMSG(D_NORMAL, "No autoprobe for RIM I; you " "must specify the shmem and irq!\n"); return -ENODEV; } if (dev->dev_addr[0] == 0) { - BUGLVL(D_NORMAL) printk("You need to specify your card's station " + BUGMSG(D_NORMAL, "You need to specify your card's station " "ID!\n"); return -ENODEV; } @@ -109,7 +109,7 @@ static int __init arcrimi_probe(struct net_device *dev) * will be taken. */ if (!request_mem_region(dev->mem_start, MIRROR_SIZE, "arcnet (90xx)")) { - BUGLVL(D_NORMAL) printk("Card memory already allocated\n"); + BUGMSG(D_NORMAL, "Card memory already allocated\n"); return -ENODEV; } return arcrimi_found(dev); diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index 62d2409bb293..0c76186bb9e7 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -891,15 +891,9 @@ static void bond_do_fail_over_mac(struct bonding *bond, switch (bond->params.fail_over_mac) { case BOND_FOM_ACTIVE: - if (new_active) { + if (new_active) memcpy(bond->dev->dev_addr, new_active->dev->dev_addr, new_active->dev->addr_len); - write_unlock_bh(&bond->curr_slave_lock); - read_unlock(&bond->lock); - call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev); - read_lock(&bond->lock); - write_lock_bh(&bond->curr_slave_lock); - } break; case BOND_FOM_FOLLOW: /* @@ -2034,9 +2028,6 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) write_unlock_bh(&bond->lock); unblock_netpoll_tx(); - if (bond->slave_cnt == 0) - call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev); - bond_compute_features(bond); if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) && (old_features & NETIF_F_VLAN_CHALLENGED)) @@ -3010,11 +3001,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) trans_start + delta_in_ticks)) || bond->curr_active_slave != slave) { slave->link = BOND_LINK_UP; - if (bond->current_arp_slave) { - bond_set_slave_inactive_flags( - bond->current_arp_slave); - bond->current_arp_slave = NULL; - } + bond->current_arp_slave = NULL; pr_info("%s: link status definitely up for interface %s.\n", bond->dev->name, slave->dev->name); @@ -3708,52 +3695,17 @@ static void bond_set_multicast_list(struct net_device *bond_dev) read_unlock(&bond->lock); } -static int bond_neigh_init(struct neighbour *n) +static int bond_neigh_setup(struct net_device *dev, struct neigh_parms *parms) { - struct bonding *bond = netdev_priv(n->dev); + struct bonding *bond = netdev_priv(dev); struct slave *slave = bond->first_slave; - const struct net_device_ops *slave_ops; - struct neigh_parms parms; - int ret; - - if (!slave) - return 0; - - slave_ops = slave->dev->netdev_ops; - - if (!slave_ops->ndo_neigh_setup) - return 0; - - parms.neigh_setup = NULL; - parms.neigh_cleanup = NULL; - ret = slave_ops->ndo_neigh_setup(slave->dev, &parms); - if (ret) - return ret; - - /* - * Assign slave's neigh_cleanup to neighbour in case cleanup is called - * after the last slave has been detached. Assumes that all slaves - * utilize the same neigh_cleanup (true at this writing as only user - * is ipoib). - */ - n->parms->neigh_cleanup = parms.neigh_cleanup; - - if (!parms.neigh_setup) - return 0; - - return parms.neigh_setup(n); -} - -/* - * The bonding ndo_neigh_setup is called at init time beofre any - * slave exists. So we must declare proxy setup function which will - * be used at run time to resolve the actual slave neigh param setup. - */ -static int bond_neigh_setup(struct net_device *dev, - struct neigh_parms *parms) -{ - parms->neigh_setup = bond_neigh_init; + if (slave) { + const struct net_device_ops *slave_ops + = slave->dev->netdev_ops; + if (slave_ops->ndo_neigh_setup) + return slave_ops->ndo_neigh_setup(slave->dev, parms); + } return 0; } diff --git a/trunk/drivers/net/caif/caif_hsi.c b/trunk/drivers/net/caif/caif_hsi.c index 9c1c8cd5223f..9a66e2a910ae 100644 --- a/trunk/drivers/net/caif/caif_hsi.c +++ b/trunk/drivers/net/caif/caif_hsi.c @@ -744,14 +744,14 @@ static void cfhsi_wake_up(struct work_struct *work) size_t fifo_occupancy = 0; /* Wakeup timeout */ - dev_dbg(&cfhsi->ndev->dev, "%s: Timeout.\n", + dev_err(&cfhsi->ndev->dev, "%s: Timeout.\n", __func__); /* Check FIFO to check if modem has sent something. */ WARN_ON(cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev, &fifo_occupancy)); - dev_dbg(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n", + dev_err(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n", __func__, (unsigned) fifo_occupancy); /* Check if we misssed the interrupt. */ @@ -1210,7 +1210,7 @@ int cfhsi_probe(struct platform_device *pdev) static void cfhsi_shutdown(struct cfhsi *cfhsi) { - u8 *tx_buf, *rx_buf, *flip_buf; + u8 *tx_buf, *rx_buf; /* Stop TXing */ netif_tx_stop_all_queues(cfhsi->ndev); @@ -1234,7 +1234,7 @@ static void cfhsi_shutdown(struct cfhsi *cfhsi) /* Store bufferes: will be freed later. */ tx_buf = cfhsi->tx_buf; rx_buf = cfhsi->rx_buf; - flip_buf = cfhsi->rx_flip_buf; + /* Flush transmit queues. */ cfhsi_abort_tx(cfhsi); @@ -1247,7 +1247,6 @@ static void cfhsi_shutdown(struct cfhsi *cfhsi) /* Free buffers. */ kfree(tx_buf); kfree(rx_buf); - kfree(flip_buf); } int cfhsi_remove(struct platform_device *pdev) diff --git a/trunk/drivers/net/caif/caif_spi.c b/trunk/drivers/net/caif/caif_spi.c index b71ce9bf0afb..96391c36fa74 100644 --- a/trunk/drivers/net/caif/caif_spi.c +++ b/trunk/drivers/net/caif/caif_spi.c @@ -127,6 +127,12 @@ static inline void dev_debugfs_rem(struct cfspi *cfspi) debugfs_remove(cfspi->dbgfs_dir); } +static int dbgfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static ssize_t dbgfs_state(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -237,13 +243,13 @@ static ssize_t dbgfs_frame(struct file *file, char __user *user_buf, } static const struct file_operations dbgfs_state_fops = { - .open = simple_open, + .open = dbgfs_open, .read = dbgfs_state, .owner = THIS_MODULE }; static const struct file_operations dbgfs_frame_fops = { - .open = simple_open, + .open = dbgfs_open, .read = dbgfs_frame, .owner = THIS_MODULE }; diff --git a/trunk/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/trunk/drivers/net/can/usb/peak_usb/pcan_usb_pro.c index 629c4ba5d49d..5234586dff15 100644 --- a/trunk/drivers/net/can/usb/peak_usb/pcan_usb_pro.c +++ b/trunk/drivers/net/can/usb/peak_usb/pcan_usb_pro.c @@ -875,7 +875,6 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev) PCAN_USBPRO_INFO_FW, &fi, sizeof(fi)); if (err) { - kfree(usb_if); dev_err(dev->netdev->dev.parent, "unable to read %s firmware info (err %d)\n", pcan_usb_pro.name, err); @@ -886,7 +885,6 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev) PCAN_USBPRO_INFO_BL, &bi, sizeof(bi)); if (err) { - kfree(usb_if); dev_err(dev->netdev->dev.parent, "unable to read %s bootloader info (err %d)\n", pcan_usb_pro.name, err); diff --git a/trunk/drivers/net/dummy.c b/trunk/drivers/net/dummy.c index 442d91a2747b..d5c6d92f1ee7 100644 --- a/trunk/drivers/net/dummy.c +++ b/trunk/drivers/net/dummy.c @@ -107,14 +107,14 @@ static int dummy_dev_init(struct net_device *dev) return 0; } -static void dummy_dev_uninit(struct net_device *dev) +static void dummy_dev_free(struct net_device *dev) { free_percpu(dev->dstats); + free_netdev(dev); } static const struct net_device_ops dummy_netdev_ops = { .ndo_init = dummy_dev_init, - .ndo_uninit = dummy_dev_uninit, .ndo_start_xmit = dummy_xmit, .ndo_validate_addr = eth_validate_addr, .ndo_set_rx_mode = set_multicast_list, @@ -128,7 +128,7 @@ static void dummy_setup(struct net_device *dev) /* Initialize the device structure. */ dev->netdev_ops = &dummy_netdev_ops; - dev->destructor = free_netdev; + dev->destructor = dummy_dev_free; /* Fill in device structure with ethernet-generic values. */ dev->tx_queue_len = 0; diff --git a/trunk/drivers/net/eql.c b/trunk/drivers/net/eql.c index f219d38acf58..a59cf961a436 100644 --- a/trunk/drivers/net/eql.c +++ b/trunk/drivers/net/eql.c @@ -125,7 +125,6 @@ #include #include #include -#include #include @@ -144,7 +143,7 @@ static void eql_timer(unsigned long param) equalizer_t *eql = (equalizer_t *) param; struct list_head *this, *tmp, *head; - spin_lock(&eql->queue.lock); + spin_lock_bh(&eql->queue.lock); head = &eql->queue.all_slaves; list_for_each_safe(this, tmp, head) { slave_t *slave = list_entry(this, slave_t, list); @@ -158,7 +157,7 @@ static void eql_timer(unsigned long param) } } - spin_unlock(&eql->queue.lock); + spin_unlock_bh(&eql->queue.lock); eql->timer.expires = jiffies + EQL_DEFAULT_RESCHED_IVAL; add_timer(&eql->timer); @@ -342,7 +341,7 @@ static netdev_tx_t eql_slave_xmit(struct sk_buff *skb, struct net_device *dev) struct net_device *slave_dev = slave->dev; skb->dev = slave_dev; - skb->priority = TC_PRIO_FILLER; + skb->priority = 1; slave->bytes_queued += skb->len; dev_queue_xmit(skb); dev->stats.tx_packets++; diff --git a/trunk/drivers/net/ethernet/atheros/atlx/atl1.c b/trunk/drivers/net/ethernet/atheros/atlx/atl1.c index c926857e8205..40ac41436549 100644 --- a/trunk/drivers/net/ethernet/atheros/atlx/atl1.c +++ b/trunk/drivers/net/ethernet/atheros/atlx/atl1.c @@ -2476,7 +2476,7 @@ static irqreturn_t atl1_intr(int irq, void *data) "pcie phy link down %x\n", status); if (netif_running(adapter->netdev)) { /* reset MAC */ iowrite32(0, adapter->hw.hw_addr + REG_IMR); - schedule_work(&adapter->reset_dev_task); + schedule_work(&adapter->pcie_dma_to_rst_task); return IRQ_HANDLED; } } @@ -2488,7 +2488,7 @@ static irqreturn_t atl1_intr(int irq, void *data) "pcie DMA r/w error (status = 0x%x)\n", status); iowrite32(0, adapter->hw.hw_addr + REG_IMR); - schedule_work(&adapter->reset_dev_task); + schedule_work(&adapter->pcie_dma_to_rst_task); return IRQ_HANDLED; } @@ -2633,10 +2633,10 @@ static void atl1_down(struct atl1_adapter *adapter) atl1_clean_rx_ring(adapter); } -static void atl1_reset_dev_task(struct work_struct *work) +static void atl1_tx_timeout_task(struct work_struct *work) { struct atl1_adapter *adapter = - container_of(work, struct atl1_adapter, reset_dev_task); + container_of(work, struct atl1_adapter, tx_timeout_task); struct net_device *netdev = adapter->netdev; netif_device_detach(netdev); @@ -3038,10 +3038,12 @@ static int __devinit atl1_probe(struct pci_dev *pdev, (unsigned long)adapter); adapter->phy_timer_pending = false; - INIT_WORK(&adapter->reset_dev_task, atl1_reset_dev_task); + INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task); INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task); + INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task); + err = register_netdev(netdev); if (err) goto err_common; diff --git a/trunk/drivers/net/ethernet/atheros/atlx/atl1.h b/trunk/drivers/net/ethernet/atheros/atlx/atl1.h index e04bf4d71e46..109d6da8be97 100644 --- a/trunk/drivers/net/ethernet/atheros/atlx/atl1.h +++ b/trunk/drivers/net/ethernet/atheros/atlx/atl1.h @@ -758,8 +758,9 @@ struct atl1_adapter { u16 link_speed; u16 link_duplex; spinlock_t lock; - struct work_struct reset_dev_task; + struct work_struct tx_timeout_task; struct work_struct link_chg_task; + struct work_struct pcie_dma_to_rst_task; struct timer_list phy_config_timer; bool phy_timer_pending; diff --git a/trunk/drivers/net/ethernet/atheros/atlx/atlx.c b/trunk/drivers/net/ethernet/atheros/atlx/atlx.c index c9e9dc57986c..3cd8837236dc 100644 --- a/trunk/drivers/net/ethernet/atheros/atlx/atlx.c +++ b/trunk/drivers/net/ethernet/atheros/atlx/atlx.c @@ -194,7 +194,7 @@ static void atlx_tx_timeout(struct net_device *netdev) { struct atlx_adapter *adapter = netdev_priv(netdev); /* Do the reset outside of interrupt context */ - schedule_work(&adapter->reset_dev_task); + schedule_work(&adapter->tx_timeout_task); } /* diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 2c9ee552dffc..e37161f19250 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1173,13 +1173,6 @@ enum { }; -struct bnx2x_prev_path_list { - u8 bus; - u8 slot; - u8 path; - struct list_head list; -}; - struct bnx2x { /* Fields used in the tx and intr/napi performance paths * are grouped together in the beginning of the structure diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 4b054812713a..f1f3ca65667a 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1721,29 +1721,6 @@ static void bnx2x_squeeze_objects(struct bnx2x *bp) } while (0) #endif -bool bnx2x_test_firmware_version(struct bnx2x *bp, bool is_err) -{ - /* build FW version dword */ - u32 my_fw = (BCM_5710_FW_MAJOR_VERSION) + - (BCM_5710_FW_MINOR_VERSION << 8) + - (BCM_5710_FW_REVISION_VERSION << 16) + - (BCM_5710_FW_ENGINEERING_VERSION << 24); - - /* read loaded FW from chip */ - u32 loaded_fw = REG_RD(bp, XSEM_REG_PRAM); - - DP(NETIF_MSG_IFUP, "loaded fw %x, my fw %x\n", loaded_fw, my_fw); - - if (loaded_fw != my_fw) { - if (is_err) - BNX2X_ERR("bnx2x with FW %x was already loaded, which mismatches my %x FW. aborting\n", - loaded_fw, my_fw); - return false; - } - - return true; -} - /* must be called with rtnl_lock */ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) { @@ -1838,8 +1815,23 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) } if (load_code != FW_MSG_CODE_DRV_LOAD_COMMON_CHIP && load_code != FW_MSG_CODE_DRV_LOAD_COMMON) { + /* build FW version dword */ + u32 my_fw = (BCM_5710_FW_MAJOR_VERSION) + + (BCM_5710_FW_MINOR_VERSION << 8) + + (BCM_5710_FW_REVISION_VERSION << 16) + + (BCM_5710_FW_ENGINEERING_VERSION << 24); + + /* read loaded FW from chip */ + u32 loaded_fw = REG_RD(bp, XSEM_REG_PRAM); + + DP(BNX2X_MSG_SP, "loaded fw %x, my fw %x", + loaded_fw, my_fw); + /* abort nic load if version mismatch */ - if (!bnx2x_test_firmware_version(bp, true)) { + if (my_fw != loaded_fw) { + BNX2X_ERR("bnx2x with FW %x already loaded, " + "which mismatches my %x FW. aborting", + loaded_fw, my_fw); rc = -EBUSY; LOAD_ERROR_EXIT(bp, load_error2); } @@ -1874,6 +1866,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) * bnx2x_periodic_task(). */ smp_mb(); + queue_delayed_work(bnx2x_wq, &bp->period_task, 0); } else bp->port.pmf = 0; diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 5c27454d2ec2..8b163388659a 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -431,9 +431,6 @@ void bnx2x_panic_dump(struct bnx2x *bp); void bnx2x_fw_dump_lvl(struct bnx2x *bp, const char *lvl); -/* validate currect fw is loaded */ -bool bnx2x_test_firmware_version(struct bnx2x *bp, bool is_err); - /* dev_close main block */ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h index b9b263323436..cd6dfa9eaa3a 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h @@ -25,31 +25,31 @@ (IRO[149].base + ((funcId) * IRO[149].m1)) #define CSTORM_IGU_MODE_OFFSET (IRO[157].base) #define CSTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \ - (IRO[316].base + ((pfId) * IRO[316].m1)) + (IRO[315].base + ((pfId) * IRO[315].m1)) #define CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \ - (IRO[317].base + ((pfId) * IRO[317].m1)) + (IRO[316].base + ((pfId) * IRO[316].m1)) #define CSTORM_ISCSI_EQ_CONS_OFFSET(pfId, iscsiEqId) \ - (IRO[309].base + ((pfId) * IRO[309].m1) + ((iscsiEqId) * IRO[309].m2)) + (IRO[308].base + ((pfId) * IRO[308].m1) + ((iscsiEqId) * IRO[308].m2)) #define CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(pfId, iscsiEqId) \ - (IRO[311].base + ((pfId) * IRO[311].m1) + ((iscsiEqId) * IRO[311].m2)) -#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfId, iscsiEqId) \ (IRO[310].base + ((pfId) * IRO[310].m1) + ((iscsiEqId) * IRO[310].m2)) +#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfId, iscsiEqId) \ + (IRO[309].base + ((pfId) * IRO[309].m1) + ((iscsiEqId) * IRO[309].m2)) #define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(pfId, iscsiEqId) \ - (IRO[312].base + ((pfId) * IRO[312].m1) + ((iscsiEqId) * IRO[312].m2)) + (IRO[311].base + ((pfId) * IRO[311].m1) + ((iscsiEqId) * IRO[311].m2)) #define CSTORM_ISCSI_EQ_PROD_OFFSET(pfId, iscsiEqId) \ - (IRO[308].base + ((pfId) * IRO[308].m1) + ((iscsiEqId) * IRO[308].m2)) + (IRO[307].base + ((pfId) * IRO[307].m1) + ((iscsiEqId) * IRO[307].m2)) #define CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(pfId, iscsiEqId) \ - (IRO[314].base + ((pfId) * IRO[314].m1) + ((iscsiEqId) * IRO[314].m2)) -#define CSTORM_ISCSI_EQ_SB_NUM_OFFSET(pfId, iscsiEqId) \ (IRO[313].base + ((pfId) * IRO[313].m1) + ((iscsiEqId) * IRO[313].m2)) +#define CSTORM_ISCSI_EQ_SB_NUM_OFFSET(pfId, iscsiEqId) \ + (IRO[312].base + ((pfId) * IRO[312].m1) + ((iscsiEqId) * IRO[312].m2)) #define CSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \ - (IRO[315].base + ((pfId) * IRO[315].m1)) + (IRO[314].base + ((pfId) * IRO[314].m1)) #define CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ - (IRO[307].base + ((pfId) * IRO[307].m1)) -#define CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ (IRO[306].base + ((pfId) * IRO[306].m1)) -#define CSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ +#define CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ (IRO[305].base + ((pfId) * IRO[305].m1)) +#define CSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ + (IRO[304].base + ((pfId) * IRO[304].m1)) #define CSTORM_RECORD_SLOW_PATH_OFFSET(funcId) \ (IRO[151].base + ((funcId) * IRO[151].m1)) #define CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(pfId) \ @@ -96,37 +96,37 @@ #define TSTORM_FUNC_EN_OFFSET(funcId) \ (IRO[103].base + ((funcId) * IRO[103].m1)) #define TSTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \ - (IRO[272].base + ((pfId) * IRO[272].m1)) + (IRO[271].base + ((pfId) * IRO[271].m1)) #define TSTORM_ISCSI_L2_ISCSI_OOO_CID_TABLE_OFFSET(pfId) \ - (IRO[273].base + ((pfId) * IRO[273].m1)) + (IRO[272].base + ((pfId) * IRO[272].m1)) #define TSTORM_ISCSI_L2_ISCSI_OOO_CLIENT_ID_TABLE_OFFSET(pfId) \ - (IRO[274].base + ((pfId) * IRO[274].m1)) + (IRO[273].base + ((pfId) * IRO[273].m1)) #define TSTORM_ISCSI_L2_ISCSI_OOO_PROD_OFFSET(pfId) \ - (IRO[275].base + ((pfId) * IRO[275].m1)) + (IRO[274].base + ((pfId) * IRO[274].m1)) #define TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ - (IRO[271].base + ((pfId) * IRO[271].m1)) -#define TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ (IRO[270].base + ((pfId) * IRO[270].m1)) -#define TSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ +#define TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ (IRO[269].base + ((pfId) * IRO[269].m1)) -#define TSTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \ +#define TSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ (IRO[268].base + ((pfId) * IRO[268].m1)) +#define TSTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \ + (IRO[267].base + ((pfId) * IRO[267].m1)) #define TSTORM_ISCSI_TCP_LOCAL_ADV_WND_OFFSET(pfId) \ - (IRO[277].base + ((pfId) * IRO[277].m1)) + (IRO[276].base + ((pfId) * IRO[276].m1)) #define TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \ - (IRO[264].base + ((pfId) * IRO[264].m1)) + (IRO[263].base + ((pfId) * IRO[263].m1)) #define TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfId) \ - (IRO[265].base + ((pfId) * IRO[265].m1)) + (IRO[264].base + ((pfId) * IRO[264].m1)) #define TSTORM_ISCSI_TCP_VARS_MID_LOCAL_MAC_ADDR_OFFSET(pfId) \ - (IRO[266].base + ((pfId) * IRO[266].m1)) + (IRO[265].base + ((pfId) * IRO[265].m1)) #define TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfId) \ - (IRO[267].base + ((pfId) * IRO[267].m1)) + (IRO[266].base + ((pfId) * IRO[266].m1)) #define TSTORM_MAC_FILTER_CONFIG_OFFSET(pfId) \ (IRO[202].base + ((pfId) * IRO[202].m1)) #define TSTORM_RECORD_SLOW_PATH_OFFSET(funcId) \ (IRO[105].base + ((funcId) * IRO[105].m1)) #define TSTORM_TCP_MAX_CWND_OFFSET(pfId) \ - (IRO[217].base + ((pfId) * IRO[217].m1)) + (IRO[216].base + ((pfId) * IRO[216].m1)) #define TSTORM_VF_TO_PF_OFFSET(funcId) \ (IRO[104].base + ((funcId) * IRO[104].m1)) #define USTORM_AGG_DATA_OFFSET (IRO[206].base) @@ -140,29 +140,29 @@ #define USTORM_ETH_PAUSE_ENABLED_OFFSET(portId) \ (IRO[183].base + ((portId) * IRO[183].m1)) #define USTORM_FCOE_EQ_PROD_OFFSET(pfId) \ - (IRO[318].base + ((pfId) * IRO[318].m1)) + (IRO[317].base + ((pfId) * IRO[317].m1)) #define USTORM_FUNC_EN_OFFSET(funcId) \ (IRO[178].base + ((funcId) * IRO[178].m1)) #define USTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \ - (IRO[282].base + ((pfId) * IRO[282].m1)) + (IRO[281].base + ((pfId) * IRO[281].m1)) #define USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \ - (IRO[283].base + ((pfId) * IRO[283].m1)) + (IRO[282].base + ((pfId) * IRO[282].m1)) #define USTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \ - (IRO[287].base + ((pfId) * IRO[287].m1)) + (IRO[286].base + ((pfId) * IRO[286].m1)) #define USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfId) \ - (IRO[284].base + ((pfId) * IRO[284].m1)) + (IRO[283].base + ((pfId) * IRO[283].m1)) #define USTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ - (IRO[280].base + ((pfId) * IRO[280].m1)) -#define USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ (IRO[279].base + ((pfId) * IRO[279].m1)) -#define USTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ +#define USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ (IRO[278].base + ((pfId) * IRO[278].m1)) +#define USTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ + (IRO[277].base + ((pfId) * IRO[277].m1)) #define USTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \ - (IRO[281].base + ((pfId) * IRO[281].m1)) + (IRO[280].base + ((pfId) * IRO[280].m1)) #define USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(pfId) \ - (IRO[285].base + ((pfId) * IRO[285].m1)) + (IRO[284].base + ((pfId) * IRO[284].m1)) #define USTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \ - (IRO[286].base + ((pfId) * IRO[286].m1)) + (IRO[285].base + ((pfId) * IRO[285].m1)) #define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(pfId) \ (IRO[182].base + ((pfId) * IRO[182].m1)) #define USTORM_RECORD_SLOW_PATH_OFFSET(funcId) \ @@ -188,39 +188,39 @@ #define XSTORM_FUNC_EN_OFFSET(funcId) \ (IRO[47].base + ((funcId) * IRO[47].m1)) #define XSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \ - (IRO[295].base + ((pfId) * IRO[295].m1)) + (IRO[294].base + ((pfId) * IRO[294].m1)) #define XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(pfId) \ - (IRO[298].base + ((pfId) * IRO[298].m1)) + (IRO[297].base + ((pfId) * IRO[297].m1)) #define XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(pfId) \ - (IRO[299].base + ((pfId) * IRO[299].m1)) + (IRO[298].base + ((pfId) * IRO[298].m1)) #define XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(pfId) \ - (IRO[300].base + ((pfId) * IRO[300].m1)) + (IRO[299].base + ((pfId) * IRO[299].m1)) #define XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(pfId) \ - (IRO[301].base + ((pfId) * IRO[301].m1)) + (IRO[300].base + ((pfId) * IRO[300].m1)) #define XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(pfId) \ - (IRO[302].base + ((pfId) * IRO[302].m1)) + (IRO[301].base + ((pfId) * IRO[301].m1)) #define XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(pfId) \ - (IRO[303].base + ((pfId) * IRO[303].m1)) + (IRO[302].base + ((pfId) * IRO[302].m1)) #define XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfId) \ - (IRO[304].base + ((pfId) * IRO[304].m1)) + (IRO[303].base + ((pfId) * IRO[303].m1)) #define XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ - (IRO[294].base + ((pfId) * IRO[294].m1)) -#define XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ (IRO[293].base + ((pfId) * IRO[293].m1)) -#define XSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ +#define XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ (IRO[292].base + ((pfId) * IRO[292].m1)) +#define XSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ + (IRO[291].base + ((pfId) * IRO[291].m1)) #define XSTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \ - (IRO[297].base + ((pfId) * IRO[297].m1)) -#define XSTORM_ISCSI_SQ_SIZE_OFFSET(pfId) \ (IRO[296].base + ((pfId) * IRO[296].m1)) +#define XSTORM_ISCSI_SQ_SIZE_OFFSET(pfId) \ + (IRO[295].base + ((pfId) * IRO[295].m1)) #define XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(pfId) \ - (IRO[291].base + ((pfId) * IRO[291].m1)) -#define XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \ (IRO[290].base + ((pfId) * IRO[290].m1)) -#define XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(pfId) \ +#define XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \ (IRO[289].base + ((pfId) * IRO[289].m1)) -#define XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(pfId) \ +#define XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(pfId) \ (IRO[288].base + ((pfId) * IRO[288].m1)) +#define XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(pfId) \ + (IRO[287].base + ((pfId) * IRO[287].m1)) #define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(pfId) \ (IRO[44].base + ((pfId) * IRO[44].m1)) #define XSTORM_RECORD_SLOW_PATH_OFFSET(funcId) \ diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index dbff5915b81a..5d71b7d43237 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h @@ -1251,9 +1251,6 @@ struct drv_func_mb { #define DRV_MSG_CODE_LINK_STATUS_CHANGED 0x01000000 - #define DRV_MSG_CODE_INITIATE_FLR 0x02000000 - #define REQ_BC_VER_4_INITIATE_FLR 0x00070213 - #define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000 #define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000 #define BIOS_MSG_CODE_VIRT_MAC_PRIM 0xff030000 diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 64392ec410a3..beb4cdbdb6e1 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -35,6 +35,7 @@ #define ETH_MAX_PACKET_SIZE 1500 #define ETH_MAX_JUMBO_PACKET_SIZE 9600 #define MDIO_ACCESS_TIMEOUT 1000 +#define BMAC_CONTROL_RX_ENABLE 2 #define WC_LANE_MAX 4 #define I2C_SWITCH_WIDTH 2 #define I2C_BSC0 0 @@ -942,12 +943,6 @@ static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params, const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 : DCBX_E3B0_MAX_NUM_COS_PORT0; - if (pri >= max_num_of_cos) { - DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " - "parameter Illegal strict priority\n"); - return -EINVAL; - } - if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) { DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " "parameter There can't be two COS's with " @@ -955,6 +950,12 @@ static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params, return -EINVAL; } + if (pri > max_num_of_cos) { + DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " + "parameter Illegal strict priority\n"); + return -EINVAL; + } + sp_pri_to_cos[pri] = cos_entry; return 0; @@ -1371,14 +1372,7 @@ static void bnx2x_update_pfc_xmac(struct link_params *params, pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN | XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN | XMAC_PFC_CTRL_HI_REG_RX_PFC_EN | - XMAC_PFC_CTRL_HI_REG_TX_PFC_EN | - XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON; - /* Write pause and PFC registers */ - REG_WR(bp, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val); - REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val); - REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val); - pfc1_val &= ~XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON; - + XMAC_PFC_CTRL_HI_REG_TX_PFC_EN; } /* Write pause and PFC registers */ @@ -3655,33 +3649,6 @@ static void bnx2x_ext_phy_update_adv_fc(struct bnx2x_phy *phy, if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) { bnx2x_cl22_read(bp, phy, 0x4, &ld_pause); bnx2x_cl22_read(bp, phy, 0x5, &lp_pause); - } else if (CHIP_IS_E3(bp) && - SINGLE_MEDIA_DIRECT(params)) { - u8 lane = bnx2x_get_warpcore_lane(phy, params); - u16 gp_status, gp_mask; - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_4, - &gp_status); - gp_mask = (MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL | - MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP) << - lane; - if ((gp_status & gp_mask) == gp_mask) { - bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, - MDIO_AN_REG_ADV_PAUSE, &ld_pause); - bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, - MDIO_AN_REG_LP_AUTO_NEG, &lp_pause); - } else { - bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LD, &ld_pause); - bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LP, &lp_pause); - ld_pause = ((ld_pause & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) - << 3); - lp_pause = ((lp_pause & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) - << 3); - } } else { bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, @@ -3732,23 +3699,7 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, u16 val16 = 0, lane, bam37 = 0; struct bnx2x *bp = params->bp; DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n"); - /* Set to default registers that may be overriden by 10G force */ - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_WC_REG_PAR_DET_10G_CTRL, 0); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0xff); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0x5555); - bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, - MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_RX66_CONTROL, 0x7415); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190); + /* Disable Autoneg: re-enable it after adv is done. */ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0); @@ -3994,13 +3945,13 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, } else { misc1_val |= 0x9; - tap_val = ((0x0f << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | - (0x2b << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | - (0x02 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET)); + tap_val = ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | + (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | + (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET)); tx_driver_val = - ((0x03 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | + ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | - (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)); + (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)); } bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val); @@ -4418,7 +4369,7 @@ static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy, switch (serdes_net_if) { case PORT_HW_CFG_NET_SERDES_IF_KR: /* Enable KR Auto Neg */ - if (params->loopback_mode != LOOPBACK_EXT) + if (params->loopback_mode == LOOPBACK_NONE) bnx2x_warpcore_enable_AN_KR(phy, params, vars); else { DP(NETIF_MSG_LINK, "Setting KR 10G-Force\n"); @@ -6216,14 +6167,12 @@ int bnx2x_set_led(struct link_params *params, tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); if (params->phy[EXT_PHY1].type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) - tmp &= ~(EMAC_LED_1000MB_OVERRIDE | - EMAC_LED_100MB_OVERRIDE | - EMAC_LED_10MB_OVERRIDE); - else - tmp |= EMAC_LED_OVERRIDE; - - EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp); + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) + EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp & 0xfff1); + else { + EMAC_WR(bp, EMAC_REG_EMAC_LED, + (tmp | EMAC_LED_OVERRIDE)); + } break; case LED_MODE_OPER: @@ -6278,15 +6227,10 @@ int bnx2x_set_led(struct link_params *params, hw_led_mode); } else if ((params->phy[EXT_PHY1].type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) && - (mode == LED_MODE_ON)) { + (mode != LED_MODE_OPER)) { REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); - EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp | - EMAC_LED_OVERRIDE | EMAC_LED_1000MB_OVERRIDE); - /* Break here; otherwise, it'll disable the - * intended override. - */ - break; + EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp | 0x3); } else REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode); @@ -6301,9 +6245,13 @@ int bnx2x_set_led(struct link_params *params, LED_BLINK_RATE_VAL_E1X_E2); REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 + port*4, 1); - tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); - EMAC_WR(bp, EMAC_REG_EMAC_LED, - (tmp & (~EMAC_LED_OVERRIDE))); + if ((params->phy[EXT_PHY1].type != + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) && + (mode != LED_MODE_OPER)) { + tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); + EMAC_WR(bp, EMAC_REG_EMAC_LED, + (tmp & (~EMAC_LED_OVERRIDE))); + } if (CHIP_IS_E1(bp) && ((speed == SPEED_2500) || @@ -6896,12 +6844,6 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) SINGLE_MEDIA_DIRECT(params)) && (phy_vars[active_external_phy].fault_detected == 0)); - /* Update the PFC configuration in case it was changed */ - if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) - vars->link_status |= LINK_STATUS_PFC_ENABLED; - else - vars->link_status &= ~LINK_STATUS_PFC_ENABLED; - if (vars->link_up) rc = bnx2x_update_link_up(params, vars, link_10g_plus); else @@ -8089,9 +8031,7 @@ static int bnx2x_verify_sfp_module(struct bnx2x_phy *phy, netdev_err(bp->dev, "Warning: Unqualified SFP+ module detected," " Port %d from %s part number %s\n", params->port, vendor_name, vendor_pn); - if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) != - PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_WARNING_MSG) - phy->flags |= FLAGS_SFP_NOT_APPROVED; + phy->flags |= FLAGS_SFP_NOT_APPROVED; return -EINVAL; } @@ -9151,12 +9091,6 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy, tmp2 &= 0xFFEF; bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2); - bnx2x_cl45_read(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, - &tmp2); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, - (tmp2 & 0x7fff)); } return 0; @@ -9337,11 +9271,12 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, ((1<<5) | (1<<2))); } - - if (!(phy->flags & FLAGS_SFP_NOT_APPROVED)) { - DP(NETIF_MSG_LINK, "Enabling 8727 TX laser\n"); - bnx2x_sfp_set_transmitter(params, phy, 1); - } else { + DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n"); + bnx2x_8727_specific_func(phy, params, ENABLE_TX); + /* If transmitter is disabled, ignore false link up indication */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1); + if (val1 & (1<<15)) { DP(NETIF_MSG_LINK, "Tx is disabled\n"); return 0; } @@ -9435,7 +9370,8 @@ static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy, if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) { bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 0x400f, &fw_ver1); - bnx2x_save_spirom_version(bp, port, fw_ver1 & 0xfff, + bnx2x_save_spirom_version(bp, port, + ((fw_ver1 & 0xf000)>>5) | (fw_ver1 & 0x7f), phy->ver_addr); } else { /* For 32-bit registers in 848xx, access via MDIO2ARM i/f. */ @@ -9858,15 +9794,6 @@ static int bnx2x_84833_hw_reset_phy(struct bnx2x_phy *phy, other_shmem_base_addr)); u32 shmem_base_path[2]; - - /* Work around for 84833 LED failure inside RESET status */ - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_MII_CTRL, - MDIO_AN_REG_8481_MII_CTRL_FORCE_1G); - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_AN_REG_8481_1G_100T_EXT_CTRL, - MIDO_AN_REG_8481_EXT_CTRL_FORCE_LEDS_OFF); - shmem_base_path[0] = params->shmem_base; shmem_base_path[1] = other_shmem_base_addr; @@ -10177,7 +10104,7 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy, u8 port; u16 val16; - if (!(CHIP_IS_E1x(bp))) + if (!(CHIP_IS_E1(bp))) port = BP_PATH(bp); else port = params->port; @@ -10204,7 +10131,7 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, u16 val; u8 port; - if (!(CHIP_IS_E1x(bp))) + if (!(CHIP_IS_E1(bp))) port = BP_PATH(bp); else port = params->port; @@ -12123,9 +12050,6 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) bnx2x_emac_init(params, vars); - if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) - vars->link_status |= LINK_STATUS_PFC_ENABLED; - if (params->num_phys == 0) { DP(NETIF_MSG_LINK, "No phy found for initialization !!\n"); return -EINVAL; @@ -12205,10 +12129,10 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, * Hold it as vars low */ /* clear link led */ - bnx2x_set_mdio_clk(bp, params->chip_id, port); bnx2x_set_led(params, vars, LED_MODE_OFF, 0); if (reset_ext_phy) { + bnx2x_set_mdio_clk(bp, params->chip_id, port); for (phy_index = EXT_PHY1; phy_index < params->num_phys; phy_index++) { if (params->phy[phy_index].link_reset) { diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index 763535ee4832..7ba557a610da 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h @@ -89,8 +89,6 @@ #define PFC_BRB_FULL_LB_XON_THRESHOLD 250 #define MAXVAL(a, b) (((a) > (b)) ? (a) : (b)) - -#define BMAC_CONTROL_RX_ENABLE 2 /***********************************************************/ /* Structs */ /***********************************************************/ diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index e077d2508727..f7f9aa807264 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -52,7 +52,6 @@ #include #include #include -#include #include #include @@ -212,10 +211,6 @@ static DEFINE_PCI_DEVICE_TABLE(bnx2x_pci_tbl) = { MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl); -/* Global resources for unloading a previously loaded device */ -#define BNX2X_PREV_WAIT_NEEDED 1 -static DEFINE_SEMAPHORE(bnx2x_prev_sem); -static LIST_HEAD(bnx2x_prev_list); /**************************************************************************** * General service functions ****************************************************************************/ @@ -8817,371 +8812,109 @@ static inline void bnx2x_undi_int_disable(struct bnx2x *bp) bnx2x_undi_int_disable_e1h(bp); } -static void __devinit bnx2x_prev_unload_close_mac(struct bnx2x *bp) +static void __devinit bnx2x_undi_unload(struct bnx2x *bp) { - u32 val, base_addr, offset, mask, reset_reg; - bool mac_stopped = false; - u8 port = BP_PORT(bp); - - reset_reg = REG_RD(bp, MISC_REG_RESET_REG_2); - - if (!CHIP_IS_E3(bp)) { - val = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port * 4); - mask = MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port; - if ((mask & reset_reg) && val) { - u32 wb_data[2]; - BNX2X_DEV_INFO("Disable bmac Rx\n"); - base_addr = BP_PORT(bp) ? NIG_REG_INGRESS_BMAC1_MEM - : NIG_REG_INGRESS_BMAC0_MEM; - offset = CHIP_IS_E2(bp) ? BIGMAC2_REGISTER_BMAC_CONTROL - : BIGMAC_REGISTER_BMAC_CONTROL; - - /* - * use rd/wr since we cannot use dmae. This is safe - * since MCP won't access the bus due to the request - * to unload, and no function on the path can be - * loaded at this time. - */ - wb_data[0] = REG_RD(bp, base_addr + offset); - wb_data[1] = REG_RD(bp, base_addr + offset + 0x4); - wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; - REG_WR(bp, base_addr + offset, wb_data[0]); - REG_WR(bp, base_addr + offset + 0x4, wb_data[1]); - - } - BNX2X_DEV_INFO("Disable emac Rx\n"); - REG_WR(bp, NIG_REG_NIG_EMAC0_EN + BP_PORT(bp)*4, 0); - - mac_stopped = true; - } else { - if (reset_reg & MISC_REGISTERS_RESET_REG_2_XMAC) { - BNX2X_DEV_INFO("Disable xmac Rx\n"); - base_addr = BP_PORT(bp) ? GRCBASE_XMAC1 : GRCBASE_XMAC0; - val = REG_RD(bp, base_addr + XMAC_REG_PFC_CTRL_HI); - REG_WR(bp, base_addr + XMAC_REG_PFC_CTRL_HI, - val & ~(1 << 1)); - REG_WR(bp, base_addr + XMAC_REG_PFC_CTRL_HI, - val | (1 << 1)); - REG_WR(bp, base_addr + XMAC_REG_CTRL, 0); - mac_stopped = true; - } - mask = MISC_REGISTERS_RESET_REG_2_UMAC0 << port; - if (mask & reset_reg) { - BNX2X_DEV_INFO("Disable umac Rx\n"); - base_addr = BP_PORT(bp) ? GRCBASE_UMAC1 : GRCBASE_UMAC0; - REG_WR(bp, base_addr + UMAC_REG_COMMAND_CONFIG, 0); - mac_stopped = true; - } - } - - if (mac_stopped) - msleep(20); - -} - -#define BNX2X_PREV_UNDI_PROD_ADDR(p) (BAR_TSTRORM_INTMEM + 0x1508 + ((p) << 4)) -#define BNX2X_PREV_UNDI_RCQ(val) ((val) & 0xffff) -#define BNX2X_PREV_UNDI_BD(val) ((val) >> 16 & 0xffff) -#define BNX2X_PREV_UNDI_PROD(rcq, bd) ((bd) << 16 | (rcq)) - -static void __devinit bnx2x_prev_unload_undi_inc(struct bnx2x *bp, u8 port, - u8 inc) -{ - u16 rcq, bd; - u32 tmp_reg = REG_RD(bp, BNX2X_PREV_UNDI_PROD_ADDR(port)); - - rcq = BNX2X_PREV_UNDI_RCQ(tmp_reg) + inc; - bd = BNX2X_PREV_UNDI_BD(tmp_reg) + inc; - - tmp_reg = BNX2X_PREV_UNDI_PROD(rcq, bd); - REG_WR(bp, BNX2X_PREV_UNDI_PROD_ADDR(port), tmp_reg); - - BNX2X_DEV_INFO("UNDI producer [%d] rings bd -> 0x%04x, rcq -> 0x%04x\n", - port, bd, rcq); -} - -static int __devinit bnx2x_prev_mcp_done(struct bnx2x *bp) -{ - u32 rc = bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); - if (!rc) { - BNX2X_ERR("MCP response failure, aborting\n"); - return -EBUSY; - } - - return 0; -} - -static bool __devinit bnx2x_prev_is_path_marked(struct bnx2x *bp) -{ - struct bnx2x_prev_path_list *tmp_list; - int rc = false; - - if (down_trylock(&bnx2x_prev_sem)) - return false; - - list_for_each_entry(tmp_list, &bnx2x_prev_list, list) { - if (PCI_SLOT(bp->pdev->devfn) == tmp_list->slot && - bp->pdev->bus->number == tmp_list->bus && - BP_PATH(bp) == tmp_list->path) { - rc = true; - BNX2X_DEV_INFO("Path %d was already cleaned from previous drivers\n", - BP_PATH(bp)); - break; - } - } - - up(&bnx2x_prev_sem); - - return rc; -} - -static int __devinit bnx2x_prev_mark_path(struct bnx2x *bp) -{ - struct bnx2x_prev_path_list *tmp_list; - int rc; - - tmp_list = (struct bnx2x_prev_path_list *) - kmalloc(sizeof(struct bnx2x_prev_path_list), GFP_KERNEL); - if (!tmp_list) { - BNX2X_ERR("Failed to allocate 'bnx2x_prev_path_list'\n"); - return -ENOMEM; - } - - tmp_list->bus = bp->pdev->bus->number; - tmp_list->slot = PCI_SLOT(bp->pdev->devfn); - tmp_list->path = BP_PATH(bp); - - rc = down_interruptible(&bnx2x_prev_sem); - if (rc) { - BNX2X_ERR("Received %d when tried to take lock\n", rc); - kfree(tmp_list); - } else { - BNX2X_DEV_INFO("Marked path [%d] - finished previous unload\n", - BP_PATH(bp)); - list_add(&tmp_list->list, &bnx2x_prev_list); - up(&bnx2x_prev_sem); - } - - return rc; -} - -static bool __devinit bnx2x_can_flr(struct bnx2x *bp) -{ - int pos; - u32 cap; - struct pci_dev *dev = bp->pdev; - - pos = pci_pcie_cap(dev); - if (!pos) - return false; - - pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP, &cap); - if (!(cap & PCI_EXP_DEVCAP_FLR)) - return false; - - return true; -} - -static int __devinit bnx2x_do_flr(struct bnx2x *bp) -{ - int i, pos; - u16 status; - struct pci_dev *dev = bp->pdev; - - /* probe the capability first */ - if (bnx2x_can_flr(bp)) - return -ENOTTY; - - pos = pci_pcie_cap(dev); - if (!pos) - return -ENOTTY; - - /* Wait for Transaction Pending bit clean */ - for (i = 0; i < 4; i++) { - if (i) - msleep((1 << (i - 1)) * 100); - - pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &status); - if (!(status & PCI_EXP_DEVSTA_TRPND)) - goto clear; - } - - dev_err(&dev->dev, - "transaction is not cleared; proceeding with reset anyway\n"); - -clear: - if (bp->common.bc_ver < REQ_BC_VER_4_INITIATE_FLR) { - BNX2X_ERR("FLR not supported by BC_VER: 0x%x\n", - bp->common.bc_ver); - return -EINVAL; - } - - bnx2x_fw_command(bp, DRV_MSG_CODE_INITIATE_FLR, 0); - - return 0; -} - -static int __devinit bnx2x_prev_unload_uncommon(struct bnx2x *bp) -{ - int rc; - - BNX2X_DEV_INFO("Uncommon unload Flow\n"); - - /* Test if previous unload process was already finished for this path */ - if (bnx2x_prev_is_path_marked(bp)) - return bnx2x_prev_mcp_done(bp); - - /* If function has FLR capabilities, and existing FW version matches - * the one required, then FLR will be sufficient to clean any residue - * left by previous driver - */ - if (bnx2x_test_firmware_version(bp, false) && bnx2x_can_flr(bp)) - return bnx2x_do_flr(bp); - - /* Close the MCP request, return failure*/ - rc = bnx2x_prev_mcp_done(bp); - if (!rc) - rc = BNX2X_PREV_WAIT_NEEDED; - - return rc; -} - -static int __devinit bnx2x_prev_unload_common(struct bnx2x *bp) -{ - u32 reset_reg, tmp_reg = 0, rc; - /* It is possible a previous function received 'common' answer, - * but hasn't loaded yet, therefore creating a scenario of - * multiple functions receiving 'common' on the same path. - */ - BNX2X_DEV_INFO("Common unload Flow\n"); - - if (bnx2x_prev_is_path_marked(bp)) - return bnx2x_prev_mcp_done(bp); - - reset_reg = REG_RD(bp, MISC_REG_RESET_REG_1); + u32 val; - /* Reset should be performed after BRB is emptied */ - if (reset_reg & MISC_REGISTERS_RESET_REG_1_RST_BRB1) { - u32 timer_count = 1000; - bool prev_undi = false; + /* possibly another driver is trying to reset the chip */ + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RESET); - /* Close the MAC Rx to prevent BRB from filling up */ - bnx2x_prev_unload_close_mac(bp); + /* check if doorbell queue is reset */ + if (REG_RD(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET) + & MISC_REGISTERS_RESET_REG_1_RST_DORQ) { - /* Check if the UNDI driver was previously loaded + /* + * Check if it is the UNDI driver * UNDI driver initializes CID offset for normal bell to 0x7 */ - reset_reg = REG_RD(bp, MISC_REG_RESET_REG_1); - if (reset_reg & MISC_REGISTERS_RESET_REG_1_RST_DORQ) { - tmp_reg = REG_RD(bp, DORQ_REG_NORM_CID_OFST); - if (tmp_reg == 0x7) { - BNX2X_DEV_INFO("UNDI previously loaded\n"); - prev_undi = true; - /* clear the UNDI indication */ - REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0); + val = REG_RD(bp, DORQ_REG_NORM_CID_OFST); + if (val == 0x7) { + u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; + /* save our pf_num */ + int orig_pf_num = bp->pf_num; + int port; + u32 swap_en, swap_val, value; + + /* clear the UNDI indication */ + REG_WR(bp, DORQ_REG_NORM_CID_OFST, 0); + + BNX2X_DEV_INFO("UNDI is active! reset device\n"); + + /* try unload UNDI on port 0 */ + bp->pf_num = 0; + bp->fw_seq = + (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & + DRV_MSG_SEQ_NUMBER_MASK); + reset_code = bnx2x_fw_command(bp, reset_code, 0); + + /* if UNDI is loaded on the other port */ + if (reset_code != FW_MSG_CODE_DRV_UNLOAD_COMMON) { + + /* send "DONE" for previous unload */ + bnx2x_fw_command(bp, + DRV_MSG_CODE_UNLOAD_DONE, 0); + + /* unload UNDI on port 1 */ + bp->pf_num = 1; + bp->fw_seq = + (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & + DRV_MSG_SEQ_NUMBER_MASK); + reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; + + bnx2x_fw_command(bp, reset_code, 0); } - } - /* wait until BRB is empty */ - tmp_reg = REG_RD(bp, BRB1_REG_NUM_OF_FULL_BLOCKS); - while (timer_count) { - u32 prev_brb = tmp_reg; - tmp_reg = REG_RD(bp, BRB1_REG_NUM_OF_FULL_BLOCKS); - if (!tmp_reg) - break; - - BNX2X_DEV_INFO("BRB still has 0x%08x\n", tmp_reg); - - /* reset timer as long as BRB actually gets emptied */ - if (prev_brb > tmp_reg) - timer_count = 1000; - else - timer_count--; - - /* If UNDI resides in memory, manually increment it */ - if (prev_undi) - bnx2x_prev_unload_undi_inc(bp, BP_PORT(bp), 1); - - udelay(10); - } - - if (!timer_count) - BNX2X_ERR("Failed to empty BRB, hope for the best\n"); - - } - - /* No packets are in the pipeline, path is ready for reset */ - bnx2x_reset_common(bp); - - rc = bnx2x_prev_mark_path(bp); - if (rc) { - bnx2x_prev_mcp_done(bp); - return rc; - } - - return bnx2x_prev_mcp_done(bp); -} - -static int __devinit bnx2x_prev_unload(struct bnx2x *bp) -{ - int time_counter = 10; - u32 rc, fw, hw_lock_reg, hw_lock_val; - BNX2X_DEV_INFO("Entering Previous Unload Flow\n"); - - /* Release previously held locks */ - hw_lock_reg = (BP_FUNC(bp) <= 5) ? - (MISC_REG_DRIVER_CONTROL_1 + BP_FUNC(bp) * 8) : - (MISC_REG_DRIVER_CONTROL_7 + (BP_FUNC(bp) - 6) * 8); - - hw_lock_val = (REG_RD(bp, hw_lock_reg)); - if (hw_lock_val) { - if (hw_lock_val & HW_LOCK_RESOURCE_NVRAM) { - BNX2X_DEV_INFO("Release Previously held NVRAM lock\n"); - REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB, - (MCPR_NVM_SW_ARB_ARB_REQ_CLR1 << BP_PORT(bp))); - } - - BNX2X_DEV_INFO("Release Previously held hw lock\n"); - REG_WR(bp, hw_lock_reg, 0xffffffff); - } else - BNX2X_DEV_INFO("No need to release hw/nvram locks\n"); + bnx2x_undi_int_disable(bp); + port = BP_PORT(bp); + + /* close input traffic and wait for it */ + /* Do not rcv packets to BRB */ + REG_WR(bp, (port ? NIG_REG_LLH1_BRB1_DRV_MASK : + NIG_REG_LLH0_BRB1_DRV_MASK), 0x0); + /* Do not direct rcv packets that are not for MCP to + * the BRB */ + REG_WR(bp, (port ? NIG_REG_LLH1_BRB1_NOT_MCP : + NIG_REG_LLH0_BRB1_NOT_MCP), 0x0); + /* clear AEU */ + REG_WR(bp, (port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : + MISC_REG_AEU_MASK_ATTN_FUNC_0), 0); + msleep(10); + + /* save NIG port swap info */ + swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); + swap_en = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); + /* reset device */ + REG_WR(bp, + GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, + 0xd3ffffff); + + value = 0x1400; + if (CHIP_IS_E3(bp)) { + value |= MISC_REGISTERS_RESET_REG_2_MSTAT0; + value |= MISC_REGISTERS_RESET_REG_2_MSTAT1; + } - if (MCPR_ACCESS_LOCK_LOCK & REG_RD(bp, MCP_REG_MCPR_ACCESS_LOCK)) { - BNX2X_DEV_INFO("Release previously held alr\n"); - REG_WR(bp, MCP_REG_MCPR_ACCESS_LOCK, 0); - } + REG_WR(bp, + GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + value); + /* take the NIG out of reset and restore swap values */ + REG_WR(bp, + GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, + MISC_REGISTERS_RESET_REG_1_RST_NIG); + REG_WR(bp, NIG_REG_PORT_SWAP, swap_val); + REG_WR(bp, NIG_REG_STRAP_OVERRIDE, swap_en); - do { - /* Lock MCP using an unload request */ - fw = bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS, 0); - if (!fw) { - BNX2X_ERR("MCP response failure, aborting\n"); - rc = -EBUSY; - break; - } + /* send unload done to the MCP */ + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); - if (fw == FW_MSG_CODE_DRV_UNLOAD_COMMON) { - rc = bnx2x_prev_unload_common(bp); - break; + /* restore our func and fw_seq */ + bp->pf_num = orig_pf_num; } - - /* non-common reply from MCP night require looping */ - rc = bnx2x_prev_unload_uncommon(bp); - if (rc != BNX2X_PREV_WAIT_NEEDED) - break; - - msleep(20); - } while (--time_counter); - - if (!time_counter || rc) { - BNX2X_ERR("Failed unloading previous driver, aborting\n"); - rc = -EBUSY; } - BNX2X_DEV_INFO("Finished Previous Unload Flow [%d]\n", rc); - - return rc; + /* now it's safe to release the lock */ + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESET); } static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) @@ -10367,16 +10100,8 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) func = BP_FUNC(bp); /* need to reset chip if undi was active */ - if (!BP_NOMCP(bp)) { - /* init fw_seq */ - bp->fw_seq = - SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & - DRV_MSG_SEQ_NUMBER_MASK; - BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); - - bnx2x_prev_unload(bp); - } - + if (!BP_NOMCP(bp)) + bnx2x_undi_unload(bp); if (CHIP_REV_IS_FPGA(bp)) dev_err(&bp->pdev->dev, "FPGA detected\n"); @@ -11706,18 +11431,9 @@ static int __init bnx2x_init(void) static void __exit bnx2x_cleanup(void) { - struct list_head *pos, *q; pci_unregister_driver(&bnx2x_pci_driver); destroy_workqueue(bnx2x_wq); - - /* Free globablly allocated resources */ - list_for_each_safe(pos, q, &bnx2x_prev_list) { - struct bnx2x_prev_path_list *tmp = - list_entry(pos, struct bnx2x_prev_path_list, list); - list_del(pos); - kfree(tmp); - } } void bnx2x_notify_link_changed(struct bnx2x *bp) diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index c25803b9c0ca..fd7fb4581849 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h @@ -987,7 +987,6 @@ * clear; 1 = set. Data valid only in addresses 0-4. all the rest are zero. */ #define IGU_REG_WRITE_DONE_PENDING 0x130480 #define MCP_A_REG_MCPR_SCRATCH 0x3a0000 -#define MCP_REG_MCPR_ACCESS_LOCK 0x8009c #define MCP_REG_MCPR_CPU_PROGRAM_COUNTER 0x8501c #define MCP_REG_MCPR_GP_INPUTS 0x800c0 #define MCP_REG_MCPR_GP_OENABLE 0x800c8 @@ -1687,7 +1686,6 @@ [10] rst_dbg; [11] rst_misc_core; [12] rst_dbue (UART); [13] Pci_resetmdio_n; [14] rst_emac0_hard_core; [15] rst_emac1_hard_core; 16] rst_pxp_rq_rd_wr; 31:17] reserved */ -#define MISC_REG_RESET_REG_1 0xa580 #define MISC_REG_RESET_REG_2 0xa590 /* [RW 20] 20 bit GRC address where the scratch-pad of the MCP that is shared with the driver resides */ @@ -5354,7 +5352,6 @@ #define XMAC_CTRL_REG_TX_EN (0x1<<0) #define XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN (0x1<<18) #define XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN (0x1<<17) -#define XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON (0x1<<1) #define XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN (0x1<<0) #define XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN (0x1<<3) #define XMAC_PFC_CTRL_HI_REG_RX_PFC_EN (0x1<<4) @@ -5609,7 +5606,6 @@ /* [RC 32] Parity register #0 read clear */ #define XSEM_REG_XSEM_PRTY_STS_CLR_0 0x280128 #define XSEM_REG_XSEM_PRTY_STS_CLR_1 0x280138 -#define MCPR_ACCESS_LOCK_LOCK (1L<<31) #define MCPR_NVM_ACCESS_ENABLE_EN (1L<<0) #define MCPR_NVM_ACCESS_ENABLE_WR_EN (1L<<1) #define MCPR_NVM_ADDR_NVM_ADDR_VALUE (0xffffffL<<0) @@ -5736,7 +5732,6 @@ #define MISC_REGISTERS_GPIO_PORT_SHIFT 4 #define MISC_REGISTERS_GPIO_SET_POS 8 #define MISC_REGISTERS_RESET_REG_1_CLEAR 0x588 -#define MISC_REGISTERS_RESET_REG_1_RST_BRB1 (0x1<<0) #define MISC_REGISTERS_RESET_REG_1_RST_DORQ (0x1<<19) #define MISC_REGISTERS_RESET_REG_1_RST_HC (0x1<<29) #define MISC_REGISTERS_RESET_REG_1_RST_NIG (0x1<<7) @@ -6821,13 +6816,10 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_AN_REG_8481_10GBASE_T_AN_CTRL 0x0020 #define MDIO_AN_REG_8481_LEGACY_MII_CTRL 0xffe0 -#define MDIO_AN_REG_8481_MII_CTRL_FORCE_1G 0x40 #define MDIO_AN_REG_8481_LEGACY_MII_STATUS 0xffe1 #define MDIO_AN_REG_8481_LEGACY_AN_ADV 0xffe4 #define MDIO_AN_REG_8481_LEGACY_AN_EXPANSION 0xffe6 #define MDIO_AN_REG_8481_1000T_CTRL 0xffe9 -#define MDIO_AN_REG_8481_1G_100T_EXT_CTRL 0xfff0 -#define MIDO_AN_REG_8481_EXT_CTRL_FORCE_LEDS_OFF 0x0008 #define MDIO_AN_REG_8481_EXPANSION_REG_RD_RW 0xfff5 #define MDIO_AN_REG_8481_EXPANSION_REG_ACCESS 0xfff7 #define MDIO_AN_REG_8481_AUX_CTRL 0xfff8 @@ -6947,10 +6939,6 @@ Theotherbitsarereservedandshouldbezero*/ #define MDIO_WC_REG_GP2_STATUS_GP_2_2 0x81d2 #define MDIO_WC_REG_GP2_STATUS_GP_2_3 0x81d3 #define MDIO_WC_REG_GP2_STATUS_GP_2_4 0x81d4 -#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL 0x1000 -#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_AN_CMPL 0x0100 -#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP 0x0010 -#define MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_AN_CAP 0x1 #define MDIO_WC_REG_UC_INFO_B0_DEAD_TRAP 0x81EE #define MDIO_WC_REG_UC_INFO_B1_VERSION 0x81F0 #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE 0x81F2 diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 513573321625..3f52fadee3ed 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -3847,7 +3847,7 @@ static bool bnx2x_credit_pool_get_entry( continue; /* If we've got here we are going to find a free entry */ - for (idx = vec * BIT_VEC64_ELEM_SZ, i = 0; + for (idx = vec * BNX2X_POOL_VEC_SIZE, i = 0; i < BIT_VEC64_ELEM_SZ; idx++, i++) if (BIT_VEC64_TEST_BIT(o->pool_mirror, idx)) { diff --git a/trunk/drivers/net/ethernet/broadcom/tg3.c b/trunk/drivers/net/ethernet/broadcom/tg3.c index ceeab8e852ef..4e4bb3875868 100644 --- a/trunk/drivers/net/ethernet/broadcom/tg3.c +++ b/trunk/drivers/net/ethernet/broadcom/tg3.c @@ -879,13 +879,8 @@ static inline unsigned int tg3_has_work(struct tg3_napi *tnapi) if (sblk->status & SD_STATUS_LINK_CHG) work_exists = 1; } - - /* check for TX work to do */ - if (sblk->idx[0].tx_consumer != tnapi->tx_cons) - work_exists = 1; - - /* check for RX work to do */ - if (tnapi->rx_rcb_prod_idx && + /* check for RX/TX work to do */ + if (sblk->idx[0].tx_consumer != tnapi->tx_cons || *(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr) work_exists = 1; @@ -2783,9 +2778,7 @@ static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 && - (tp->phy_flags & TG3_PHYFLG_MII_SERDES)) || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 && - !tp->pci_fn)) + (tp->phy_flags & TG3_PHYFLG_MII_SERDES))) return; if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX || @@ -6129,9 +6122,6 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget) return work_done; } - if (!tnapi->rx_rcb_prod_idx) - return work_done; - /* run RX thread, within the bounds set by NAPI. * All RX "locking" is done by ensuring outside * code synchronizes with tg3->napi.poll() @@ -7575,12 +7565,6 @@ static int tg3_alloc_consistent(struct tg3 *tp) */ switch (i) { default: - if (tg3_flag(tp, ENABLE_RSS)) { - tnapi->rx_rcb_prod_idx = NULL; - break; - } - /* Fall through */ - case 1: tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer; break; case 2: diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/trunk/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c index abb6ce7c1b7e..63bfdd10bd6d 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +++ b/trunk/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c @@ -1149,48 +1149,6 @@ static int update_tpsram(struct adapter *adap) return ret; } -/** - * t3_synchronize_rx - wait for current Rx processing on a port to complete - * @adap: the adapter - * @p: the port - * - * Ensures that current Rx processing on any of the queues associated with - * the given port completes before returning. We do this by acquiring and - * releasing the locks of the response queues associated with the port. - */ -static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p) -{ - int i; - - for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) { - struct sge_rspq *q = &adap->sge.qs[i].rspq; - - spin_lock_irq(&q->lock); - spin_unlock_irq(&q->lock); - } -} - -static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features) -{ - struct port_info *pi = netdev_priv(dev); - struct adapter *adapter = pi->adapter; - - if (adapter->params.rev > 0) { - t3_set_vlan_accel(adapter, 1 << pi->port_id, - features & NETIF_F_HW_VLAN_RX); - } else { - /* single control for all ports */ - unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX; - - for_each_port(adapter, i) - have_vlans |= - adapter->port[i]->features & NETIF_F_HW_VLAN_RX; - - t3_set_vlan_accel(adapter, 1, have_vlans); - } - t3_synchronize_rx(adapter, pi); -} - /** * cxgb_up - enable the adapter * @adapter: adapter being enabled @@ -1203,7 +1161,7 @@ static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features) */ static int cxgb_up(struct adapter *adap) { - int i, err; + int err; if (!(adap->flags & FULL_INIT_DONE)) { err = t3_check_fw_version(adap); @@ -1240,9 +1198,6 @@ static int cxgb_up(struct adapter *adap) if (err) goto out; - for_each_port(adap, i) - cxgb_vlan_mode(adap->port[i], adap->port[i]->features); - setup_rss(adap); if (!(adap->flags & NAPI_INIT)) init_napi(adap); @@ -2553,6 +2508,48 @@ static int cxgb_set_mac_addr(struct net_device *dev, void *p) return 0; } +/** + * t3_synchronize_rx - wait for current Rx processing on a port to complete + * @adap: the adapter + * @p: the port + * + * Ensures that current Rx processing on any of the queues associated with + * the given port completes before returning. We do this by acquiring and + * releasing the locks of the response queues associated with the port. + */ +static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p) +{ + int i; + + for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) { + struct sge_rspq *q = &adap->sge.qs[i].rspq; + + spin_lock_irq(&q->lock); + spin_unlock_irq(&q->lock); + } +} + +static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features) +{ + struct port_info *pi = netdev_priv(dev); + struct adapter *adapter = pi->adapter; + + if (adapter->params.rev > 0) { + t3_set_vlan_accel(adapter, 1 << pi->port_id, + features & NETIF_F_HW_VLAN_RX); + } else { + /* single control for all ports */ + unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX; + + for_each_port(adapter, i) + have_vlans |= + adapter->port[i]->features & NETIF_F_HW_VLAN_RX; + + t3_set_vlan_accel(adapter, 1, have_vlans); + } + t3_synchronize_rx(adapter, pi); +} + static netdev_features_t cxgb_fix_features(struct net_device *dev, netdev_features_t features) { @@ -3356,6 +3353,9 @@ static int __devinit init_one(struct pci_dev *pdev, err = sysfs_create_group(&adapter->port[0]->dev.kobj, &cxgb3_attr_group); + for_each_port(adapter, i) + cxgb_vlan_mode(adapter->port[i], adapter->port[i]->features); + print_port_info(adapter, ai); return 0; diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index b126b98065a9..05ff076af06d 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -2000,6 +2000,13 @@ static const struct ethtool_ops cxgb_ethtool_ops = { /* * debugfs support */ + +static int mem_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static ssize_t mem_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { @@ -2043,7 +2050,7 @@ static ssize_t mem_read(struct file *file, char __user *buf, size_t count, static const struct file_operations mem_debugfs_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = mem_open, .read = mem_read, .llseek = default_llseek, }; diff --git a/trunk/drivers/net/ethernet/dlink/dl2k.c b/trunk/drivers/net/ethernet/dlink/dl2k.c index 2e09edb9cdf8..b2dc2c81a147 100644 --- a/trunk/drivers/net/ethernet/dlink/dl2k.c +++ b/trunk/drivers/net/ethernet/dlink/dl2k.c @@ -1259,21 +1259,55 @@ rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) { int phy_addr; struct netdev_private *np = netdev_priv(dev); - struct mii_ioctl_data *miidata = if_mii(rq); + struct mii_data *miidata = (struct mii_data *) &rq->ifr_ifru; + + struct netdev_desc *desc; + int i; phy_addr = np->phy_addr; switch (cmd) { - case SIOCGMIIPHY: - miidata->phy_id = phy_addr; + case SIOCDEVPRIVATE: + break; + + case SIOCDEVPRIVATE + 1: + miidata->out_value = mii_read (dev, phy_addr, miidata->reg_num); break; - case SIOCGMIIREG: - miidata->val_out = mii_read (dev, phy_addr, miidata->reg_num); + case SIOCDEVPRIVATE + 2: + mii_write (dev, phy_addr, miidata->reg_num, miidata->in_value); break; - case SIOCSMIIREG: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - mii_write (dev, phy_addr, miidata->reg_num, miidata->val_in); + case SIOCDEVPRIVATE + 3: + break; + case SIOCDEVPRIVATE + 4: + break; + case SIOCDEVPRIVATE + 5: + netif_stop_queue (dev); break; + case SIOCDEVPRIVATE + 6: + netif_wake_queue (dev); + break; + case SIOCDEVPRIVATE + 7: + printk + ("tx_full=%x cur_tx=%lx old_tx=%lx cur_rx=%lx old_rx=%lx\n", + netif_queue_stopped(dev), np->cur_tx, np->old_tx, np->cur_rx, + np->old_rx); + break; + case SIOCDEVPRIVATE + 8: + printk("TX ring:\n"); + for (i = 0; i < TX_RING_SIZE; i++) { + desc = &np->tx_ring[i]; + printk + ("%02x:cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x", + i, + (u32) (np->tx_ring_dma + i * sizeof (*desc)), + (u32)le64_to_cpu(desc->next_desc), + (u32)le64_to_cpu(desc->status), + (u32)(le64_to_cpu(desc->fraginfo) >> 32), + (u32)le64_to_cpu(desc->fraginfo)); + printk ("\n"); + } + printk ("\n"); + break; + default: return -EOPNOTSUPP; } diff --git a/trunk/drivers/net/ethernet/dlink/dl2k.h b/trunk/drivers/net/ethernet/dlink/dl2k.h index 30c2da3de548..ba0adcafa55a 100644 --- a/trunk/drivers/net/ethernet/dlink/dl2k.h +++ b/trunk/drivers/net/ethernet/dlink/dl2k.h @@ -365,6 +365,13 @@ struct ioctl_data { char *data; }; +struct mii_data { + __u16 reserved; + __u16 reg_num; + __u16 in_value; + __u16 out_value; +}; + /* The Rx and Tx buffer descriptors. */ struct netdev_desc { __le64 next_desc; diff --git a/trunk/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/trunk/drivers/net/ethernet/freescale/fsl_pq_mdio.c index f7f0bf5d037b..9eb815941df5 100644 --- a/trunk/drivers/net/ethernet/freescale/fsl_pq_mdio.c +++ b/trunk/drivers/net/ethernet/freescale/fsl_pq_mdio.c @@ -356,13 +356,13 @@ static int fsl_pq_mdio_probe(struct platform_device *ofdev) if (prop) tbiaddr = *prop; + } - if (tbiaddr == -1) { - err = -EBUSY; - goto err_free_irqs; - } else { - out_be32(tbipa, tbiaddr); - } + if (tbiaddr == -1) { + err = -EBUSY; + goto err_free_irqs; + } else { + out_be32(tbipa, tbiaddr); } err = of_mdiobus_register(new_bus, np); diff --git a/trunk/drivers/net/ethernet/freescale/ucc_geth.c b/trunk/drivers/net/ethernet/freescale/ucc_geth.c index 9ac14f804851..4e3cd2f8debb 100644 --- a/trunk/drivers/net/ethernet/freescale/ucc_geth.c +++ b/trunk/drivers/net/ethernet/freescale/ucc_geth.c @@ -116,10 +116,10 @@ static struct ucc_geth_info ugeth_primary_info = { .maxGroupAddrInHash = 4, .maxIndAddrInHash = 4, .prel = 7, - .maxFrameLength = 1518+16, /* Add extra bytes for VLANs etc. */ + .maxFrameLength = 1518, .minFrameLength = 64, - .maxD1Length = 1520+16, /* Add extra bytes for VLANs etc. */ - .maxD2Length = 1520+16, /* Add extra bytes for VLANs etc. */ + .maxD1Length = 1520, + .maxD2Length = 1520, .vlantype = 0x8100, .ecamptr = ((uint32_t) NULL), .eventRegMask = UCCE_OTHER, @@ -3945,8 +3945,6 @@ static int ucc_geth_probe(struct platform_device* ofdev) } if (max_speed == SPEED_1000) { - unsigned int snums = qe_get_num_of_snums(); - /* configure muram FIFOs for gigabit operation */ ug_info->uf_info.urfs = UCC_GETH_URFS_GIGA_INIT; ug_info->uf_info.urfet = UCC_GETH_URFET_GIGA_INIT; @@ -3956,11 +3954,11 @@ static int ucc_geth_probe(struct platform_device* ofdev) ug_info->uf_info.utftt = UCC_GETH_UTFTT_GIGA_INIT; ug_info->numThreadsTx = UCC_GETH_NUM_OF_THREADS_4; - /* If QE's snum number is 46/76 which means we need to support + /* If QE's snum number is 46 which means we need to support * 4 UECs at 1000Base-T simultaneously, we need to allocate * more Threads to Rx. */ - if ((snums == 76) || (snums == 46)) + if (qe_get_num_of_snums() == 46) ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_6; else ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_4; diff --git a/trunk/drivers/net/ethernet/freescale/ucc_geth.h b/trunk/drivers/net/ethernet/freescale/ucc_geth.h index f71b3e7b12de..2e395a2566b8 100644 --- a/trunk/drivers/net/ethernet/freescale/ucc_geth.h +++ b/trunk/drivers/net/ethernet/freescale/ucc_geth.h @@ -877,7 +877,7 @@ struct ucc_geth_hardware_statistics { /* Driver definitions */ #define TX_BD_RING_LEN 0x10 -#define RX_BD_RING_LEN 0x20 +#define RX_BD_RING_LEN 0x10 #define TX_RING_MOD_MASK(size) (size-1) #define RX_RING_MOD_MASK(size) (size-1) diff --git a/trunk/drivers/net/ethernet/ibm/ehea/ehea_main.c b/trunk/drivers/net/ethernet/ibm/ehea/ehea_main.c index c9069a28832b..3516e17a399d 100644 --- a/trunk/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/trunk/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -290,18 +290,16 @@ static void ehea_update_bcmc_registrations(void) arr[i].adh = adapter->handle; arr[i].port_id = port->logical_port_id; - arr[i].reg_type = EHEA_BCMC_MULTICAST | + arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | + EHEA_BCMC_MULTICAST | EHEA_BCMC_UNTAGGED; - if (mc_entry->macaddr == 0) - arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL; arr[i++].macaddr = mc_entry->macaddr; arr[i].adh = adapter->handle; arr[i].port_id = port->logical_port_id; - arr[i].reg_type = EHEA_BCMC_MULTICAST | + arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | + EHEA_BCMC_MULTICAST | EHEA_BCMC_VLANID_ALL; - if (mc_entry->macaddr == 0) - arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL; arr[i++].macaddr = mc_entry->macaddr; num_registrations -= 2; } @@ -1840,9 +1838,8 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr, u64 hret; u8 reg_type; - reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_UNTAGGED; - if (mc_mac_addr == 0) - reg_type |= EHEA_BCMC_SCOPE_ALL; + reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST + | EHEA_BCMC_UNTAGGED; hret = ehea_h_reg_dereg_bcmc(port->adapter->handle, port->logical_port_id, @@ -1850,9 +1847,8 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr, if (hret) goto out; - reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_VLANID_ALL; - if (mc_mac_addr == 0) - reg_type |= EHEA_BCMC_SCOPE_ALL; + reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST + | EHEA_BCMC_VLANID_ALL; hret = ehea_h_reg_dereg_bcmc(port->adapter->handle, port->logical_port_id, @@ -1902,7 +1898,7 @@ static void ehea_allmulti(struct net_device *dev, int enable) netdev_err(dev, "failed enabling IFF_ALLMULTI\n"); } - } else { + } else if (!enable) { /* Disable ALLMULTI */ hret = ehea_multicast_reg_helper(port, 0, H_DEREG_BCMC); @@ -1912,7 +1908,6 @@ static void ehea_allmulti(struct net_device *dev, int enable) netdev_err(dev, "failed disabling IFF_ALLMULTI\n"); } - } } static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr) @@ -1946,7 +1941,11 @@ static void ehea_set_multicast_list(struct net_device *dev) struct netdev_hw_addr *ha; int ret; - ehea_promiscuous(dev, !!(dev->flags & IFF_PROMISC)); + if (port->promisc) { + ehea_promiscuous(dev, 1); + return; + } + ehea_promiscuous(dev, 0); if (dev->flags & IFF_ALLMULTI) { ehea_allmulti(dev, 1); @@ -2464,7 +2463,6 @@ static int ehea_down(struct net_device *dev) return 0; ehea_drop_multicast_list(dev); - ehea_allmulti(dev, 0); ehea_broadcast_reg_helper(port, H_DEREG_BCMC); ehea_free_interrupts(dev); @@ -3263,7 +3261,6 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev, struct ehea_adapter *adapter; const u64 *adapter_handle; int ret; - int i; if (!dev || !dev->dev.of_node) { pr_err("Invalid ibmebus device probed\n"); @@ -3317,9 +3314,17 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev, tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet, (unsigned long)adapter); + ret = ibmebus_request_irq(adapter->neq->attr.ist1, + ehea_interrupt_neq, IRQF_DISABLED, + "ehea_neq", adapter); + if (ret) { + dev_err(&dev->dev, "requesting NEQ IRQ failed\n"); + goto out_kill_eq; + } + ret = ehea_create_device_sysfs(dev); if (ret) - goto out_kill_eq; + goto out_free_irq; ret = ehea_setup_ports(adapter); if (ret) { @@ -3327,28 +3332,15 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev, goto out_rem_dev_sysfs; } - ret = ibmebus_request_irq(adapter->neq->attr.ist1, - ehea_interrupt_neq, IRQF_DISABLED, - "ehea_neq", adapter); - if (ret) { - dev_err(&dev->dev, "requesting NEQ IRQ failed\n"); - goto out_shutdown_ports; - } - - ret = 0; goto out; -out_shutdown_ports: - for (i = 0; i < EHEA_MAX_PORTS; i++) - if (adapter->port[i]) { - ehea_shutdown_single_port(adapter->port[i]); - adapter->port[i] = NULL; - } - out_rem_dev_sysfs: ehea_remove_device_sysfs(dev); +out_free_irq: + ibmebus_free_irq(adapter->neq->attr.ist1, adapter); + out_kill_eq: ehea_destroy_eq(adapter->neq); diff --git a/trunk/drivers/net/ethernet/ibm/ehea/ehea_phyp.h b/trunk/drivers/net/ethernet/ibm/ehea/ehea_phyp.h index 8364815c32ff..52c456ec4d6c 100644 --- a/trunk/drivers/net/ethernet/ibm/ehea/ehea_phyp.h +++ b/trunk/drivers/net/ethernet/ibm/ehea/ehea_phyp.h @@ -450,7 +450,7 @@ u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num, void *cb_addr); #define H_REGBCMC_PN EHEA_BMASK_IBM(48, 63) -#define H_REGBCMC_REGTYPE EHEA_BMASK_IBM(60, 63) +#define H_REGBCMC_REGTYPE EHEA_BMASK_IBM(61, 63) #define H_REGBCMC_MACADDR EHEA_BMASK_IBM(16, 63) #define H_REGBCMC_VLANID EHEA_BMASK_IBM(52, 63) diff --git a/trunk/drivers/net/ethernet/intel/e1000/e1000_main.c b/trunk/drivers/net/ethernet/intel/e1000/e1000_main.c index 4348b6fd44fa..0e9aec8f6917 100644 --- a/trunk/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/trunk/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -164,8 +164,6 @@ static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter, static bool e1000_vlan_used(struct e1000_adapter *adapter); static void e1000_vlan_mode(struct net_device *netdev, netdev_features_t features); -static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter, - bool filter_on); static int e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid); static int e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); static void e1000_restore_vlan(struct e1000_adapter *adapter); @@ -217,8 +215,7 @@ MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); -#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK) -static int debug = -1; +static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); @@ -982,7 +979,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, adapter = netdev_priv(netdev); adapter->netdev = netdev; adapter->pdev = pdev; - adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); + adapter->msg_enable = (1 << debug) - 1; adapter->bars = bars; adapter->need_ioport = need_ioport; @@ -1217,7 +1214,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (err) goto err_register; - e1000_vlan_filter_on_off(adapter, false); + e1000_vlan_mode(netdev, netdev->features); /* print bus type/speed/width info */ e_info(probe, "(PCI%s:%dMHz:%d-bit) %pM\n", @@ -4773,22 +4770,6 @@ static bool e1000_vlan_used(struct e1000_adapter *adapter) return false; } -static void __e1000_vlan_mode(struct e1000_adapter *adapter, - netdev_features_t features) -{ - struct e1000_hw *hw = &adapter->hw; - u32 ctrl; - - ctrl = er32(CTRL); - if (features & NETIF_F_HW_VLAN_RX) { - /* enable VLAN tag insert/strip */ - ctrl |= E1000_CTRL_VME; - } else { - /* disable VLAN tag insert/strip */ - ctrl &= ~E1000_CTRL_VME; - } - ew32(CTRL, ctrl); -} static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter, bool filter_on) { @@ -4798,7 +4779,6 @@ static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter, if (!test_bit(__E1000_DOWN, &adapter->flags)) e1000_irq_disable(adapter); - __e1000_vlan_mode(adapter, adapter->netdev->features); if (filter_on) { /* enable VLAN receive filtering */ rctl = er32(RCTL); @@ -4819,14 +4799,24 @@ static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter, } static void e1000_vlan_mode(struct net_device *netdev, - netdev_features_t features) + netdev_features_t features) { struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_hw *hw = &adapter->hw; + u32 ctrl; if (!test_bit(__E1000_DOWN, &adapter->flags)) e1000_irq_disable(adapter); - __e1000_vlan_mode(adapter, features); + ctrl = er32(CTRL); + if (features & NETIF_F_HW_VLAN_RX) { + /* enable VLAN tag insert/strip */ + ctrl |= E1000_CTRL_VME; + } else { + /* disable VLAN tag insert/strip */ + ctrl &= ~E1000_CTRL_VME; + } + ew32(CTRL, ctrl); if (!test_bit(__E1000_DOWN, &adapter->flags)) e1000_irq_enable(adapter); diff --git a/trunk/drivers/net/ethernet/intel/e1000e/e1000.h b/trunk/drivers/net/ethernet/intel/e1000e/e1000.h index b83897f76ee3..86cdd4793992 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/trunk/drivers/net/ethernet/intel/e1000e/e1000.h @@ -161,12 +161,6 @@ struct e1000_info; /* Time to wait before putting the device into D3 if there's no link (in ms). */ #define LINK_TIMEOUT 100 -/* - * Count for polling __E1000_RESET condition every 10-20msec. - * Experimentation has shown the reset can take approximately 210msec. - */ -#define E1000_CHECK_RESET_COUNT 25 - #define DEFAULT_RDTR 0 #define DEFAULT_RADV 8 #define BURST_RDTR 0x20 diff --git a/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.c b/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.c index b461c24945e3..64c76443a7aa 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1310,6 +1310,10 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state) if (mac_reg & E1000_PHY_CTRL_D0A_LPLU) oem_reg |= HV_OEM_BITS_LPLU; + + /* Set Restart auto-neg to activate the bits */ + if (!hw->phy.ops.check_reset_block(hw)) + oem_reg |= HV_OEM_BITS_RESTART_AN; } else { if (mac_reg & (E1000_PHY_CTRL_GBE_DISABLE | E1000_PHY_CTRL_NOND0A_GBE_DISABLE)) @@ -1320,11 +1324,6 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state) oem_reg |= HV_OEM_BITS_LPLU; } - /* Set Restart auto-neg to activate the bits */ - if ((d0_state || (hw->mac.type != e1000_pchlan)) && - !hw->phy.ops.check_reset_block(hw)) - oem_reg |= HV_OEM_BITS_RESTART_AN; - ret_val = hw->phy.ops.write_reg_locked(hw, HV_OEM_BITS, oem_reg); release: @@ -3683,11 +3682,7 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) if (hw->mac.type >= e1000_pchlan) { e1000_oem_bits_config_ich8lan(hw, false); - - /* Reset PHY to activate OEM bits on 82577/8 */ - if (hw->mac.type == e1000_pchlan) - e1000e_phy_hw_reset_generic(hw); - + e1000_phy_hw_reset_ich8lan(hw); ret_val = hw->phy.ops.acquire(hw); if (ret_val) return; diff --git a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c index 9520a6ac1f30..7152eb11b7b9 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c @@ -60,11 +60,6 @@ char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; -#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK) -static int debug = -1; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); - static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state); static const struct e1000_info *e1000_info_tbl[] = { @@ -1059,13 +1054,6 @@ static void e1000_print_hw_hang(struct work_struct *work) ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); /* execute the writes immediately */ e1e_flush(); - /* - * Due to rare timing issues, write to TIDV again to ensure - * the write is successful - */ - ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); - /* execute the writes immediately */ - e1e_flush(); adapter->tx_hang_recheck = true; return; } @@ -3623,16 +3611,6 @@ static void e1000e_flush_descriptors(struct e1000_adapter *adapter) /* execute the writes immediately */ e1e_flush(); - - /* - * due to rare timing issues, write to TIDV/RDTR again to ensure the - * write is successful - */ - ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); - ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD); - - /* execute the writes immediately */ - e1e_flush(); } static void e1000e_update_stats(struct e1000_adapter *adapter); @@ -3799,7 +3777,7 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter) /* fire an unusual interrupt on the test handler */ ew32(ICS, E1000_ICS_RXSEQ); e1e_flush(); - msleep(100); + msleep(50); e1000_irq_disable(adapter); @@ -3985,10 +3963,6 @@ static int e1000_close(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); struct pci_dev *pdev = adapter->pdev; - int count = E1000_CHECK_RESET_COUNT; - - while (test_bit(__E1000_RESETTING, &adapter->state) && count--) - usleep_range(10000, 20000); WARN_ON(test_bit(__E1000_RESETTING, &adapter->state)); @@ -5493,11 +5467,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake, netif_device_detach(netdev); if (netif_running(netdev)) { - int count = E1000_CHECK_RESET_COUNT; - - while (test_bit(__E1000_RESETTING, &adapter->state) && count--) - usleep_range(10000, 20000); - WARN_ON(test_bit(__E1000_RESETTING, &adapter->state)); e1000e_down(adapter); e1000_free_irq(adapter); @@ -6203,7 +6172,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, adapter->hw.adapter = adapter; adapter->hw.mac.type = ei->mac; adapter->max_hw_frame_size = ei->max_hw_frame_size; - adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); + adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1; mmio_start = pci_resource_start(pdev, 0); mmio_len = pci_resource_len(pdev, 0); diff --git a/trunk/drivers/net/ethernet/intel/e1000e/param.c b/trunk/drivers/net/ethernet/intel/e1000e/param.c index 16adeb9418a8..ff796e42c3eb 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/param.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/param.c @@ -106,7 +106,7 @@ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay"); /* * Interrupt Throttle Rate (interrupts/sec) * - * Valid Range: 100-100000 or one of: 0=off, 1=dynamic, 3=dynamic conservative + * Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative) */ E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate"); #define DEFAULT_ITR 3 @@ -344,60 +344,53 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) if (num_InterruptThrottleRate > bd) { adapter->itr = InterruptThrottleRate[bd]; - - /* - * Make sure a message is printed for non-special - * values. And in case of an invalid option, display - * warning, use default and got through itr/itr_setting - * adjustment logic below - */ - if ((adapter->itr > 4) && - e1000_validate_option(&adapter->itr, &opt, adapter)) - adapter->itr = opt.def; + switch (adapter->itr) { + case 0: + e_info("%s turned off\n", opt.name); + break; + case 1: + e_info("%s set to dynamic mode\n", opt.name); + adapter->itr_setting = adapter->itr; + adapter->itr = 20000; + break; + case 3: + e_info("%s set to dynamic conservative mode\n", + opt.name); + adapter->itr_setting = adapter->itr; + adapter->itr = 20000; + break; + case 4: + e_info("%s set to simplified (2000-8000 ints) " + "mode\n", opt.name); + adapter->itr_setting = 4; + break; + default: + /* + * Save the setting, because the dynamic bits + * change itr. + */ + if (e1000_validate_option(&adapter->itr, &opt, + adapter) && + (adapter->itr == 3)) { + /* + * In case of invalid user value, + * default to conservative mode. + */ + adapter->itr_setting = adapter->itr; + adapter->itr = 20000; + } else { + /* + * Clear the lower two bits because + * they are used as control. + */ + adapter->itr_setting = + adapter->itr & ~3; + } + break; + } } else { - /* - * If no option specified, use default value and go - * through the logic below to adjust itr/itr_setting - */ - adapter->itr = opt.def; - - /* - * Make sure a message is printed for non-special - * default values - */ - if (adapter->itr > 40) - e_info("%s set to default %d\n", opt.name, - adapter->itr); - } - - adapter->itr_setting = adapter->itr; - switch (adapter->itr) { - case 0: - e_info("%s turned off\n", opt.name); - break; - case 1: - e_info("%s set to dynamic mode\n", opt.name); - adapter->itr = 20000; - break; - case 3: - e_info("%s set to dynamic conservative mode\n", - opt.name); + adapter->itr_setting = opt.def; adapter->itr = 20000; - break; - case 4: - e_info("%s set to simplified (2000-8000 ints) mode\n", - opt.name); - break; - default: - /* - * Save the setting, because the dynamic bits - * change itr. - * - * Clear the lower two bits because - * they are used as control. - */ - adapter->itr_setting &= ~3; - break; } } { /* Interrupt Mode */ diff --git a/trunk/drivers/net/ethernet/intel/igb/igb_main.c b/trunk/drivers/net/ethernet/intel/igb/igb_main.c index 5ec31598ee47..c4902411d749 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb_main.c +++ b/trunk/drivers/net/ethernet/intel/igb/igb_main.c @@ -238,11 +238,6 @@ MODULE_DESCRIPTION("Intel(R) Gigabit Ethernet Network Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); -#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK) -static int debug = -1; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); - struct igb_reg_info { u32 ofs; char *name; @@ -1898,7 +1893,7 @@ static int __devinit igb_probe(struct pci_dev *pdev, adapter->pdev = pdev; hw = &adapter->hw; hw->back = adapter; - adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); + adapter->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE; mmio_start = pci_resource_start(pdev, 0); mmio_len = pci_resource_len(pdev, 0); diff --git a/trunk/drivers/net/ethernet/intel/igbvf/netdev.c b/trunk/drivers/net/ethernet/intel/igbvf/netdev.c index 8ec74b07f940..217c143686d2 100644 --- a/trunk/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/trunk/drivers/net/ethernet/intel/igbvf/netdev.c @@ -55,11 +55,6 @@ static const char igbvf_driver_string[] = static const char igbvf_copyright[] = "Copyright (c) 2009 - 2012 Intel Corporation."; -#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK) -static int debug = -1; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); - static int igbvf_poll(struct napi_struct *napi, int budget); static void igbvf_reset(struct igbvf_adapter *); static void igbvf_set_interrupt_capability(struct igbvf_adapter *); @@ -2654,7 +2649,7 @@ static int __devinit igbvf_probe(struct pci_dev *pdev, adapter->flags = ei->flags; adapter->hw.back = adapter; adapter->hw.mac.type = ei->mac; - adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); + adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1; /* PCI config space info */ @@ -2731,14 +2726,14 @@ static int __devinit igbvf_probe(struct pci_dev *pdev, netdev->addr_len); } - if (!is_valid_ether_addr(netdev->dev_addr)) { + if (!is_valid_ether_addr(netdev->perm_addr)) { dev_err(&pdev->dev, "Invalid MAC Address: %pM\n", netdev->dev_addr); err = -EIO; goto err_hw_init; } - memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); + memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len); setup_timer(&adapter->watchdog_timer, &igbvf_watchdog, (unsigned long) adapter); diff --git a/trunk/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/trunk/drivers/net/ethernet/intel/ixgb/ixgb_main.c index 5fce363d810a..82aaa792cbf3 100644 --- a/trunk/drivers/net/ethernet/intel/ixgb/ixgb_main.c +++ b/trunk/drivers/net/ethernet/intel/ixgb/ixgb_main.c @@ -134,8 +134,8 @@ MODULE_DESCRIPTION("Intel(R) PRO/10GbE Network Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); -#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK) -static int debug = -1; +#define DEFAULT_DEBUG_LEVEL_SHIFT 3 +static int debug = DEFAULT_DEBUG_LEVEL_SHIFT; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); @@ -442,7 +442,7 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->netdev = netdev; adapter->pdev = pdev; adapter->hw.back = adapter; - adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); + adapter->msg_enable = netif_msg_init(debug, DEFAULT_DEBUG_LEVEL_SHIFT); adapter->hw.hw_addr = pci_ioremap_bar(pdev, BAR_0); if (!adapter->hw.hw_addr) { diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 74e192107f9a..80e26ff30ebf 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -544,7 +544,7 @@ struct ixgbe_fdir_filter { u16 action; }; -enum ixgbe_state_t { +enum ixbge_state_t { __IXGBE_TESTING, __IXGBE_RESETTING, __IXGBE_DOWN, diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c index 652e4b09546d..dde65f951400 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c @@ -44,94 +44,62 @@ #define DCB_NO_HW_CHG 1 /* DCB configuration did not change */ #define DCB_HW_CHG 2 /* DCB configuration changed, no reset */ -int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *scfg, - struct ixgbe_dcb_config *dcfg, int tc_max) +int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg, + struct ixgbe_dcb_config *dst_dcb_cfg, int tc_max) { - struct tc_configuration *src = NULL; - struct tc_configuration *dst = NULL; - int i, j; - int tx = DCB_TX_CONFIG; - int rx = DCB_RX_CONFIG; - int changes = 0; + struct tc_configuration *src_tc_cfg = NULL; + struct tc_configuration *dst_tc_cfg = NULL; + int i; - if (!scfg || !dcfg) - return changes; + if (!src_dcb_cfg || !dst_dcb_cfg) + return -EINVAL; for (i = DCB_PG_ATTR_TC_0; i < tc_max + DCB_PG_ATTR_TC_0; i++) { - src = &scfg->tc_config[i - DCB_PG_ATTR_TC_0]; - dst = &dcfg->tc_config[i - DCB_PG_ATTR_TC_0]; + src_tc_cfg = &src_dcb_cfg->tc_config[i - DCB_PG_ATTR_TC_0]; + dst_tc_cfg = &dst_dcb_cfg->tc_config[i - DCB_PG_ATTR_TC_0]; - if (dst->path[tx].prio_type != src->path[tx].prio_type) { - dst->path[tx].prio_type = src->path[tx].prio_type; - changes |= BIT_PG_TX; - } + dst_tc_cfg->path[DCB_TX_CONFIG].prio_type = + src_tc_cfg->path[DCB_TX_CONFIG].prio_type; - if (dst->path[tx].bwg_id != src->path[tx].bwg_id) { - dst->path[tx].bwg_id = src->path[tx].bwg_id; - changes |= BIT_PG_TX; - } + dst_tc_cfg->path[DCB_TX_CONFIG].bwg_id = + src_tc_cfg->path[DCB_TX_CONFIG].bwg_id; - if (dst->path[tx].bwg_percent != src->path[tx].bwg_percent) { - dst->path[tx].bwg_percent = src->path[tx].bwg_percent; - changes |= BIT_PG_TX; - } + dst_tc_cfg->path[DCB_TX_CONFIG].bwg_percent = + src_tc_cfg->path[DCB_TX_CONFIG].bwg_percent; - if (dst->path[tx].up_to_tc_bitmap != - src->path[tx].up_to_tc_bitmap) { - dst->path[tx].up_to_tc_bitmap = - src->path[tx].up_to_tc_bitmap; - changes |= (BIT_PG_TX | BIT_PFC | BIT_APP_UPCHG); - } + dst_tc_cfg->path[DCB_TX_CONFIG].up_to_tc_bitmap = + src_tc_cfg->path[DCB_TX_CONFIG].up_to_tc_bitmap; - if (dst->path[rx].prio_type != src->path[rx].prio_type) { - dst->path[rx].prio_type = src->path[rx].prio_type; - changes |= BIT_PG_RX; - } + dst_tc_cfg->path[DCB_RX_CONFIG].prio_type = + src_tc_cfg->path[DCB_RX_CONFIG].prio_type; - if (dst->path[rx].bwg_id != src->path[rx].bwg_id) { - dst->path[rx].bwg_id = src->path[rx].bwg_id; - changes |= BIT_PG_RX; - } + dst_tc_cfg->path[DCB_RX_CONFIG].bwg_id = + src_tc_cfg->path[DCB_RX_CONFIG].bwg_id; - if (dst->path[rx].bwg_percent != src->path[rx].bwg_percent) { - dst->path[rx].bwg_percent = src->path[rx].bwg_percent; - changes |= BIT_PG_RX; - } + dst_tc_cfg->path[DCB_RX_CONFIG].bwg_percent = + src_tc_cfg->path[DCB_RX_CONFIG].bwg_percent; - if (dst->path[rx].up_to_tc_bitmap != - src->path[rx].up_to_tc_bitmap) { - dst->path[rx].up_to_tc_bitmap = - src->path[rx].up_to_tc_bitmap; - changes |= (BIT_PG_RX | BIT_PFC | BIT_APP_UPCHG); - } + dst_tc_cfg->path[DCB_RX_CONFIG].up_to_tc_bitmap = + src_tc_cfg->path[DCB_RX_CONFIG].up_to_tc_bitmap; } for (i = DCB_PG_ATTR_BW_ID_0; i < DCB_PG_ATTR_BW_ID_MAX; i++) { - j = i - DCB_PG_ATTR_BW_ID_0; - if (dcfg->bw_percentage[tx][j] != scfg->bw_percentage[tx][j]) { - dcfg->bw_percentage[tx][j] = scfg->bw_percentage[tx][j]; - changes |= BIT_PG_TX; - } - if (dcfg->bw_percentage[rx][j] != scfg->bw_percentage[rx][j]) { - dcfg->bw_percentage[rx][j] = scfg->bw_percentage[rx][j]; - changes |= BIT_PG_RX; - } + dst_dcb_cfg->bw_percentage[DCB_TX_CONFIG] + [i-DCB_PG_ATTR_BW_ID_0] = src_dcb_cfg->bw_percentage + [DCB_TX_CONFIG][i-DCB_PG_ATTR_BW_ID_0]; + dst_dcb_cfg->bw_percentage[DCB_RX_CONFIG] + [i-DCB_PG_ATTR_BW_ID_0] = src_dcb_cfg->bw_percentage + [DCB_RX_CONFIG][i-DCB_PG_ATTR_BW_ID_0]; } for (i = DCB_PFC_UP_ATTR_0; i < DCB_PFC_UP_ATTR_MAX; i++) { - j = i - DCB_PFC_UP_ATTR_0; - if (dcfg->tc_config[j].dcb_pfc != scfg->tc_config[j].dcb_pfc) { - dcfg->tc_config[j].dcb_pfc = scfg->tc_config[j].dcb_pfc; - changes |= BIT_PFC; - } + dst_dcb_cfg->tc_config[i - DCB_PFC_UP_ATTR_0].dcb_pfc = + src_dcb_cfg->tc_config[i - DCB_PFC_UP_ATTR_0].dcb_pfc; } - if (dcfg->pfc_mode_enable != scfg->pfc_mode_enable) { - dcfg->pfc_mode_enable = scfg->pfc_mode_enable; - changes |= BIT_PFC; - } + dst_dcb_cfg->pfc_mode_enable = src_dcb_cfg->pfc_mode_enable; - return changes; + return 0; } static u8 ixgbe_dcbnl_get_state(struct net_device *netdev) @@ -211,6 +179,20 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc, if (up_map != DCB_ATTR_VALUE_UNDEFINED) adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap = up_map; + + if ((adapter->temp_dcb_cfg.tc_config[tc].path[0].prio_type != + adapter->dcb_cfg.tc_config[tc].path[0].prio_type) || + (adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_id != + adapter->dcb_cfg.tc_config[tc].path[0].bwg_id) || + (adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent != + adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent) || + (adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap != + adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap)) + adapter->dcb_set_bitmap |= BIT_PG_TX; + + if (adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap != + adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap) + adapter->dcb_set_bitmap |= BIT_PFC | BIT_APP_UPCHG; } static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, @@ -219,6 +201,10 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, struct ixgbe_adapter *adapter = netdev_priv(netdev); adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct; + + if (adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] != + adapter->dcb_cfg.bw_percentage[0][bwg_id]) + adapter->dcb_set_bitmap |= BIT_PG_TX; } static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc, @@ -237,6 +223,20 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc, if (up_map != DCB_ATTR_VALUE_UNDEFINED) adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap = up_map; + + if ((adapter->temp_dcb_cfg.tc_config[tc].path[1].prio_type != + adapter->dcb_cfg.tc_config[tc].path[1].prio_type) || + (adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_id != + adapter->dcb_cfg.tc_config[tc].path[1].bwg_id) || + (adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent != + adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent) || + (adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap != + adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap)) + adapter->dcb_set_bitmap |= BIT_PG_RX; + + if (adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap != + adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap) + adapter->dcb_set_bitmap |= BIT_PFC; } static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, @@ -245,6 +245,10 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, struct ixgbe_adapter *adapter = netdev_priv(netdev); adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct; + + if (adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] != + adapter->dcb_cfg.bw_percentage[1][bwg_id]) + adapter->dcb_set_bitmap |= BIT_PG_RX; } static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, @@ -294,8 +298,10 @@ static void ixgbe_dcbnl_set_pfc_cfg(struct net_device *netdev, int priority, adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc = setting; if (adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc != - adapter->dcb_cfg.tc_config[priority].dcb_pfc) + adapter->dcb_cfg.tc_config[priority].dcb_pfc) { + adapter->dcb_set_bitmap |= BIT_PFC; adapter->temp_dcb_cfg.pfc_mode_enable = true; + } } static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority, @@ -330,8 +336,7 @@ static void ixgbe_dcbnl_devreset(struct net_device *dev) static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - int ret = DCB_NO_HW_CHG; - int i; + int ret, i; #ifdef IXGBE_FCOE struct dcb_app app = { .selector = DCB_APP_IDTYPE_ETHTYPE, @@ -350,13 +355,12 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) /* Fail command if not in CEE mode */ if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) - return ret; + return 1; - adapter->dcb_set_bitmap |= ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, - &adapter->dcb_cfg, - MAX_TRAFFIC_CLASS); - if (!adapter->dcb_set_bitmap) - return ret; + ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, + MAX_TRAFFIC_CLASS); + if (ret) + return DCB_NO_HW_CHG; if (adapter->dcb_cfg.pfc_mode_enable) { switch (adapter->hw.mac.type) { @@ -416,8 +420,6 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) netdev_set_prio_tc_map(netdev, i, prio_tc[i]); - - ret = DCB_HW_CHG_RST; } if (adapter->dcb_set_bitmap & BIT_PFC) { @@ -428,8 +430,7 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) DCB_TX_CONFIG, prio_tc); ixgbe_dcb_unpack_pfc(&adapter->dcb_cfg, &pfc_en); ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc_en, prio_tc); - if (ret != DCB_HW_CHG_RST) - ret = DCB_HW_CHG; + ret = DCB_HW_CHG; } if (adapter->dcb_cfg.pfc_mode_enable) @@ -530,6 +531,9 @@ static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state) struct ixgbe_adapter *adapter = netdev_priv(netdev); adapter->temp_dcb_cfg.pfc_mode_enable = state; + if (adapter->temp_dcb_cfg.pfc_mode_enable != + adapter->dcb_cfg.pfc_mode_enable) + adapter->dcb_set_bitmap |= BIT_PFC; } /** diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c index bc07933d67da..77ea4b716535 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c @@ -437,7 +437,6 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, */ if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) && (fctl & FC_FC_END_SEQ)) { - skb_linearize(skb); crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc)); crc->fcoe_eof = FC_EOF_T; } diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c index ed1b47dc0834..027d7a75be39 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c @@ -622,16 +622,6 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, int v_idx, if (adapter->hw.mac.type == ixgbe_mac_82599EB) set_bit(__IXGBE_RX_CSUM_UDP_ZERO_ERR, &ring->state); -#ifdef IXGBE_FCOE - if (adapter->netdev->features & NETIF_F_FCOE_MTU) { - struct ixgbe_ring_feature *f; - f = &adapter->ring_feature[RING_F_FCOE]; - if ((rxr_idx >= f->mask) && - (rxr_idx < f->mask + f->indices)) - set_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state); - } - -#endif /* IXGBE_FCOE */ /* apply Rx specific ring traits */ ring->count = adapter->rx_ring_count; ring->queue_index = rxr_idx; diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 88f6b2e9b72d..398fc223cab9 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -63,8 +63,8 @@ static char ixgbe_default_device_descr[] = "Intel(R) 10 Gigabit Network Connection"; #endif #define MAJ 3 -#define MIN 8 -#define BUILD 21 +#define MIN 6 +#define BUILD 7 #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \ __stringify(BUILD) "-k" const char ixgbe_driver_version[] = DRV_VERSION; @@ -141,16 +141,13 @@ module_param(allow_unsupported_sfp, uint, 0); MODULE_PARM_DESC(allow_unsupported_sfp, "Allow unsupported and untested SFP+ modules on 82599-based adapters"); -#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK) -static int debug = -1; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); - MODULE_AUTHOR("Intel Corporation, "); MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); +#define DEFAULT_DEBUG_LEVEL_SHIFT 3 + static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter) { if (!test_bit(__IXGBE_DOWN, &adapter->state) && @@ -3154,6 +3151,14 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) set_ring_rsc_enabled(rx_ring); else clear_ring_rsc_enabled(rx_ring); +#ifdef IXGBE_FCOE + if (netdev->features & NETIF_F_FCOE_MTU) { + struct ixgbe_ring_feature *f; + f = &adapter->ring_feature[RING_F_FCOE]; + if ((i >= f->mask) && (i < f->mask + f->indices)) + set_bit(__IXGBE_RX_FCOE_BUFSZ, &rx_ring->state); + } +#endif /* IXGBE_FCOE */ } } @@ -4828,9 +4833,7 @@ static int ixgbe_resume(struct pci_dev *pdev) pci_wake_from_d3(pdev, false); - rtnl_lock(); err = ixgbe_init_interrupt_scheme(adapter); - rtnl_unlock(); if (err) { e_dev_err("Cannot initialize interrupts for device\n"); return err; @@ -4873,6 +4876,10 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) } ixgbe_clear_interrupt_scheme(adapter); +#ifdef CONFIG_DCB + kfree(adapter->ixgbe_ieee_pfc); + kfree(adapter->ixgbe_ieee_ets); +#endif #ifdef CONFIG_PM retval = pci_save_state(pdev); @@ -4883,16 +4890,6 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) if (wufc) { ixgbe_set_rx_mode(netdev); - /* - * enable the optics for both mult-speed fiber and - * 82599 SFP+ fiber as we can WoL. - */ - if (hw->mac.ops.enable_tx_laser && - (hw->phy.multispeed_fiber || - (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber && - hw->mac.type == ixgbe_mac_82599EB))) - hw->mac.ops.enable_tx_laser(hw); - /* turn on all-multi mode if wake on multicast is enabled */ if (wufc & IXGBE_WUFC_MC) { fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); @@ -6837,7 +6834,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, adapter->pdev = pdev; hw = &adapter->hw; hw->back = adapter; - adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); + adapter->msg_enable = (1 << DEFAULT_DEBUG_LEVEL_SHIFT) - 1; hw->hw_addr = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); @@ -7220,11 +7217,6 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) ixgbe_release_hw_control(adapter); -#ifdef CONFIG_DCB - kfree(adapter->ixgbe_ieee_pfc); - kfree(adapter->ixgbe_ieee_ets); - -#endif iounmap(adapter->hw.hw_addr); pci_release_selected_regions(pdev, pci_select_bars(pdev, IORESOURCE_MEM)); diff --git a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 307611ae831d..581c65976bb4 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/trunk/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -91,10 +91,7 @@ MODULE_DESCRIPTION("Intel(R) 82599 Virtual Function Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_VERSION); -#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK) -static int debug = -1; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); +#define DEFAULT_DEBUG_LEVEL_SHIFT 3 /* forward decls */ static void ixgbevf_set_itr_msix(struct ixgbevf_q_vector *q_vector); @@ -3370,7 +3367,7 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, adapter->pdev = pdev; hw = &adapter->hw; hw->back = adapter; - adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); + adapter->msg_enable = (1 << DEFAULT_DEBUG_LEVEL_SHIFT) - 1; /* * call save state here in standalone driver because it relies on diff --git a/trunk/drivers/net/ethernet/marvell/sky2.c b/trunk/drivers/net/ethernet/marvell/sky2.c index 487a6c8bd4ec..423a1a2a702e 100644 --- a/trunk/drivers/net/ethernet/marvell/sky2.c +++ b/trunk/drivers/net/ethernet/marvell/sky2.c @@ -1767,14 +1767,13 @@ static int sky2_open(struct net_device *dev) sky2_hw_up(sky2); - /* Enable interrupts from phy/mac for port */ - imask = sky2_read32(hw, B0_IMSK); - if (hw->chip_id == CHIP_ID_YUKON_OPT || hw->chip_id == CHIP_ID_YUKON_PRM || hw->chip_id == CHIP_ID_YUKON_OP_2) imask |= Y2_IS_PHY_QLNK; /* enable PHY Quick Link */ + /* Enable interrupts from phy/mac for port */ + imask = sky2_read32(hw, B0_IMSK); imask |= portirq_msk[port]; sky2_write32(hw, B0_IMSK, imask); sky2_read32(hw, B0_IMSK); @@ -2469,17 +2468,6 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) return err; } -static inline bool needs_copy(const struct rx_ring_info *re, - unsigned length) -{ -#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS - /* Some architectures need the IP header to be aligned */ - if (!IS_ALIGNED(re->data_addr + ETH_HLEN, sizeof(u32))) - return true; -#endif - return length < copybreak; -} - /* For small just reuse existing skb for next receive */ static struct sk_buff *receive_copy(struct sky2_port *sky2, const struct rx_ring_info *re, @@ -2494,13 +2482,8 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2, skb_copy_from_linear_data(re->skb, skb->data, length); skb->ip_summed = re->skb->ip_summed; skb->csum = re->skb->csum; - skb->rxhash = re->skb->rxhash; - skb->vlan_tci = re->skb->vlan_tci; - pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr, length, PCI_DMA_FROMDEVICE); - re->skb->vlan_tci = 0; - re->skb->rxhash = 0; re->skb->ip_summed = CHECKSUM_NONE; skb_put(skb, length); } @@ -2585,6 +2568,9 @@ static struct sk_buff *sky2_receive(struct net_device *dev, struct sk_buff *skb = NULL; u16 count = (status & GMR_FS_LEN) >> 16; + if (status & GMR_FS_VLAN) + count -= VLAN_HLEN; /* Account for vlan tag */ + netif_printk(sky2, rx_status, KERN_DEBUG, dev, "rx slot %u status 0x%x len %d\n", sky2->rx_next, status, length); @@ -2592,9 +2578,6 @@ static struct sk_buff *sky2_receive(struct net_device *dev, sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending; prefetch(sky2->rx_ring + sky2->rx_next); - if (vlan_tx_tag_present(re->skb)) - count -= VLAN_HLEN; /* Account for vlan tag */ - /* This chip has hardware problems that generates bogus status. * So do only marginal checking and expect higher level protocols * to handle crap frames. @@ -2615,7 +2598,7 @@ static struct sk_buff *sky2_receive(struct net_device *dev, goto error; okay: - if (needs_copy(re, length)) + if (length < copybreak) skb = receive_copy(sky2, re, length); else skb = receive_new(sky2, re, length); @@ -2652,8 +2635,11 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last) } static inline void sky2_skb_rx(const struct sky2_port *sky2, - struct sk_buff *skb) + u32 status, struct sk_buff *skb) { + if (status & GMR_FS_VLAN) + __vlan_hwaccel_put_tag(skb, be16_to_cpu(sky2->rx_tag)); + if (skb->ip_summed == CHECKSUM_NONE) netif_receive_skb(skb); else @@ -2707,14 +2693,6 @@ static void sky2_rx_checksum(struct sky2_port *sky2, u32 status) } } -static void sky2_rx_tag(struct sky2_port *sky2, u16 length) -{ - struct sk_buff *skb; - - skb = sky2->rx_ring[sky2->rx_next].skb; - __vlan_hwaccel_put_tag(skb, be16_to_cpu(length)); -} - static void sky2_rx_hash(struct sky2_port *sky2, u32 status) { struct sk_buff *skb; @@ -2773,7 +2751,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) } skb->protocol = eth_type_trans(skb, dev); - sky2_skb_rx(sky2, skb); + + sky2_skb_rx(sky2, status, skb); /* Stop after net poll weight */ if (++work_done >= to_do) @@ -2781,11 +2760,11 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) break; case OP_RXVLAN: - sky2_rx_tag(sky2, length); + sky2->rx_tag = length; break; case OP_RXCHKSVLAN: - sky2_rx_tag(sky2, length); + sky2->rx_tag = length; /* fall through */ case OP_RXCHKS: if (likely(dev->features & NETIF_F_RXCSUM)) diff --git a/trunk/drivers/net/ethernet/marvell/sky2.h b/trunk/drivers/net/ethernet/marvell/sky2.h index 3c896ce80b71..ff6f58bf822a 100644 --- a/trunk/drivers/net/ethernet/marvell/sky2.h +++ b/trunk/drivers/net/ethernet/marvell/sky2.h @@ -2241,6 +2241,7 @@ struct sky2_port { u16 rx_pending; u16 rx_data_size; u16 rx_nfrags; + u16 rx_tag; struct { unsigned long last; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index d69fee41f24a..9e2b911a1230 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -83,9 +83,8 @@ #define MLX4_EN_WATCHDOG_TIMEOUT (15 * HZ) -/* Use the maximum between 16384 and a single page */ -#define MLX4_EN_ALLOC_SIZE PAGE_ALIGN(16384) -#define MLX4_EN_ALLOC_ORDER get_order(MLX4_EN_ALLOC_SIZE) +#define MLX4_EN_ALLOC_ORDER 2 +#define MLX4_EN_ALLOC_SIZE (PAGE_SIZE << MLX4_EN_ALLOC_ORDER) #define MLX4_EN_MAX_LRO_DESCRIPTORS 32 diff --git a/trunk/drivers/net/ethernet/micrel/ks8851.c b/trunk/drivers/net/ethernet/micrel/ks8851.c index f8dda009d3c0..c722aa607d07 100644 --- a/trunk/drivers/net/ethernet/micrel/ks8851.c +++ b/trunk/drivers/net/ethernet/micrel/ks8851.c @@ -889,17 +889,16 @@ static int ks8851_net_stop(struct net_device *dev) netif_stop_queue(dev); mutex_lock(&ks->lock); - /* turn off the IRQs and ack any outstanding */ - ks8851_wrreg16(ks, KS_IER, 0x0000); - ks8851_wrreg16(ks, KS_ISR, 0xffff); - mutex_unlock(&ks->lock); /* stop any outstanding work */ flush_work(&ks->irq_work); flush_work(&ks->tx_work); flush_work(&ks->rxctrl_work); - mutex_lock(&ks->lock); + /* turn off the IRQs and ack any outstanding */ + ks8851_wrreg16(ks, KS_IER, 0x0000); + ks8851_wrreg16(ks, KS_ISR, 0xffff); + /* shutdown RX process */ ks8851_wrreg16(ks, KS_RXCR1, 0x0000); @@ -908,7 +907,6 @@ static int ks8851_net_stop(struct net_device *dev) /* set powermode to soft power down to save power */ ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN); - mutex_unlock(&ks->lock); /* ensure any queued tx buffers are dumped */ while (!skb_queue_empty(&ks->txq)) { @@ -920,6 +918,7 @@ static int ks8851_net_stop(struct net_device *dev) dev_kfree_skb(txb); } + mutex_unlock(&ks->lock); return 0; } @@ -1419,7 +1418,6 @@ static int __devinit ks8851_probe(struct spi_device *spi) struct net_device *ndev; struct ks8851_net *ks; int ret; - unsigned cider; ndev = alloc_etherdev(sizeof(struct ks8851_net)); if (!ndev) @@ -1486,8 +1484,8 @@ static int __devinit ks8851_probe(struct spi_device *spi) ks8851_soft_reset(ks, GRR_GSR); /* simple check for a valid chip being connected to the bus */ - cider = ks8851_rdreg16(ks, KS_CIDER); - if ((cider & ~CIDER_REV_MASK) != CIDER_ID) { + + if ((ks8851_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) { dev_err(&spi->dev, "failed to read device ID\n"); ret = -ENODEV; goto err_id; @@ -1518,14 +1516,15 @@ static int __devinit ks8851_probe(struct spi_device *spi) } netdev_info(ndev, "revision %d, MAC %pM, IRQ %d, %s EEPROM\n", - CIDER_REV_GET(cider), ndev->dev_addr, ndev->irq, + CIDER_REV_GET(ks8851_rdreg16(ks, KS_CIDER)), + ndev->dev_addr, ndev->irq, ks->rc_ccr & CCR_EEPROM ? "has" : "no"); return 0; err_netdev: - free_irq(ndev->irq, ks); + free_irq(ndev->irq, ndev); err_id: err_irq: diff --git a/trunk/drivers/net/ethernet/micrel/ks8851_mll.c b/trunk/drivers/net/ethernet/micrel/ks8851_mll.c index 5ffde23ac8fb..b8104d9f4081 100644 --- a/trunk/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/trunk/drivers/net/ethernet/micrel/ks8851_mll.c @@ -40,7 +40,7 @@ #define DRV_NAME "ks8851_mll" static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x86, 0x95, 0x11 }; -#define MAX_RECV_FRAMES 255 +#define MAX_RECV_FRAMES 32 #define MAX_BUF_SIZE 2048 #define TX_BUF_SIZE 2000 #define RX_BUF_SIZE 2000 diff --git a/trunk/drivers/net/ethernet/micrel/ksz884x.c b/trunk/drivers/net/ethernet/micrel/ksz884x.c index eaf9ff0262a9..ef723b185d85 100644 --- a/trunk/drivers/net/ethernet/micrel/ksz884x.c +++ b/trunk/drivers/net/ethernet/micrel/ksz884x.c @@ -5675,7 +5675,7 @@ static int netdev_set_mac_address(struct net_device *dev, void *addr) memcpy(hw->override_addr, mac->sa_data, ETH_ALEN); } - memcpy(dev->dev_addr, mac->sa_data, ETH_ALEN); + memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN); interrupt = hw_block_intr(hw); diff --git a/trunk/drivers/net/ethernet/nxp/lpc_eth.c b/trunk/drivers/net/ethernet/nxp/lpc_eth.c index 6dfc26d85e47..69444247c20b 100644 --- a/trunk/drivers/net/ethernet/nxp/lpc_eth.c +++ b/trunk/drivers/net/ethernet/nxp/lpc_eth.c @@ -1441,7 +1441,7 @@ static int lpc_eth_drv_probe(struct platform_device *pdev) } #endif if (!is_valid_ether_addr(ndev->dev_addr)) - eth_hw_addr_random(ndev); + dev_hw_addr_random(ndev, ndev->dev_addr); /* Reset the ethernet controller */ __lpc_eth_reset(pldat); diff --git a/trunk/drivers/net/ethernet/realtek/8139cp.c b/trunk/drivers/net/ethernet/realtek/8139cp.c index b3287c0fe279..abc79076f867 100644 --- a/trunk/drivers/net/ethernet/realtek/8139cp.c +++ b/trunk/drivers/net/ethernet/realtek/8139cp.c @@ -958,11 +958,6 @@ static inline void cp_start_hw (struct cp_private *cp) cpw8(Cmd, RxOn | TxOn); } -static void cp_enable_irq(struct cp_private *cp) -{ - cpw16_f(IntrMask, cp_intr_mask); -} - static void cp_init_hw (struct cp_private *cp) { struct net_device *dev = cp->dev; @@ -1002,6 +997,8 @@ static void cp_init_hw (struct cp_private *cp) cpw16(MultiIntr, 0); + cpw16_f(IntrMask, cp_intr_mask); + cpw8_f(Cfg9346, Cfg9346_Lock); } @@ -1133,8 +1130,6 @@ static int cp_open (struct net_device *dev) if (rc) goto err_out_hw; - cp_enable_irq(cp); - netif_carrier_off(dev); mii_check_media(&cp->mii_if, netif_msg_link(cp), true); netif_start_queue(dev); @@ -2036,7 +2031,6 @@ static int cp_resume (struct pci_dev *pdev) /* FIXME: sh*t may happen if the Rx ring buffer is depleted */ cp_init_rings_index (cp); cp_init_hw (cp); - cp_enable_irq(cp); netif_start_queue (dev); spin_lock_irqsave (&cp->lock, flags); diff --git a/trunk/drivers/net/ethernet/realtek/r8169.c b/trunk/drivers/net/ethernet/realtek/r8169.c index f54509377efa..7b23554f80b6 100644 --- a/trunk/drivers/net/ethernet/realtek/r8169.c +++ b/trunk/drivers/net/ethernet/realtek/r8169.c @@ -5810,10 +5810,7 @@ static void __rtl8169_resume(struct net_device *dev) rtl_pll_power_up(tp); - rtl_lock_work(tp); - napi_enable(&tp->napi); set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); - rtl_unlock_work(tp); rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); } diff --git a/trunk/drivers/net/ethernet/renesas/Kconfig b/trunk/drivers/net/ethernet/renesas/Kconfig index 3fb2355af37e..9755b49bbefb 100644 --- a/trunk/drivers/net/ethernet/renesas/Kconfig +++ b/trunk/drivers/net/ethernet/renesas/Kconfig @@ -7,8 +7,7 @@ config SH_ETH depends on SUPERH && \ (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \ CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \ - CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7734 || \ - CPU_SUBTYPE_SH7757) + CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7757) select CRC32 select NET_CORE select MII @@ -17,4 +16,4 @@ config SH_ETH ---help--- Renesas SuperH Ethernet device driver. This driver supporting CPUs are: - - SH7619, SH7710, SH7712, SH7724, SH7734, SH7763 and SH7757. + - SH7710, SH7712, SH7763, SH7619, SH7724, and SH7757. diff --git a/trunk/drivers/net/ethernet/renesas/sh_eth.c b/trunk/drivers/net/ethernet/renesas/sh_eth.c index d63e09b29a96..8615961c1287 100644 --- a/trunk/drivers/net/ethernet/renesas/sh_eth.c +++ b/trunk/drivers/net/ethernet/renesas/sh_eth.c @@ -1,8 +1,8 @@ /* * SuperH Ethernet device driver * - * Copyright (C) 2006-2012 Nobuhiro Iwamatsu - * Copyright (C) 2008-2012 Renesas Solutions Corp. + * Copyright (C) 2006-2008 Nobuhiro Iwamatsu + * Copyright (C) 2008-2009 Renesas Solutions Corp. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -38,7 +38,6 @@ #include #include #include -#include #include #include "sh_eth.h" @@ -280,9 +279,8 @@ static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp) return &sh_eth_my_cpu_data; } -#elif defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763) +#elif defined(CONFIG_CPU_SUBTYPE_SH7763) #define SH_ETH_HAS_TSU 1 -static void sh_eth_reset_hw_crc(struct net_device *ndev); static void sh_eth_chip_reset(struct net_device *ndev) { struct sh_eth_private *mdp = netdev_priv(ndev); @@ -316,9 +314,6 @@ static void sh_eth_reset(struct net_device *ndev) sh_eth_write(ndev, 0x0, RDFAR); sh_eth_write(ndev, 0x0, RDFXR); sh_eth_write(ndev, 0x0, RDFFR); - - /* Reset HW CRC register */ - sh_eth_reset_hw_crc(ndev); } static void sh_eth_set_duplex(struct net_device *ndev) @@ -375,17 +370,8 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { .no_trimd = 1, .no_ade = 1, .tsu = 1, -#if defined(CONFIG_CPU_SUBTYPE_SH7734) - .hw_crc = 1, -#endif }; -static void sh_eth_reset_hw_crc(struct net_device *ndev) -{ - if (sh_eth_my_cpu_data.hw_crc) - sh_eth_write(ndev, 0x0, CSMR); -} - #elif defined(CONFIG_CPU_SUBTYPE_SH7619) #define SH_ETH_RESET_DEFAULT 1 static struct sh_eth_cpu_data sh_eth_my_cpu_data = { @@ -804,7 +790,7 @@ static int sh_eth_dev_init(struct net_device *ndev) /* all sh_eth int mask */ sh_eth_write(ndev, 0, EESIPR); -#if defined(__LITTLE_ENDIAN) +#if defined(__LITTLE_ENDIAN__) if (mdp->cd->hw_swap) sh_eth_write(ndev, EDMR_EL, EDMR); else diff --git a/trunk/drivers/net/ethernet/renesas/sh_eth.h b/trunk/drivers/net/ethernet/renesas/sh_eth.h index 0fa14afce23d..57dc26261116 100644 --- a/trunk/drivers/net/ethernet/renesas/sh_eth.h +++ b/trunk/drivers/net/ethernet/renesas/sh_eth.h @@ -1,8 +1,8 @@ /* * SuperH Ethernet device driver * - * Copyright (C) 2006-2012 Nobuhiro Iwamatsu - * Copyright (C) 2008-2012 Renesas Solutions Corp. + * Copyright (C) 2006-2008 Nobuhiro Iwamatsu + * Copyright (C) 2008-2011 Renesas Solutions Corp. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -98,8 +98,6 @@ enum { CEECR, MAFCR, RTRATE, - CSMR, - RMII_MII, /* TSU Absolute address */ ARSTR, @@ -174,7 +172,6 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = { [RMCR] = 0x0458, [RPADIR] = 0x0460, [FCFTR] = 0x0468, - [CSMR] = 0x04E4, [ECMR] = 0x0500, [ECSR] = 0x0510, @@ -203,7 +200,6 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = { [CERCR] = 0x0768, [CEECR] = 0x0770, [MAFCR] = 0x0778, - [RMII_MII] = 0x0790, [ARSTR] = 0x0000, [TSU_CTRST] = 0x0004, @@ -381,7 +377,7 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = { /* * Register's bits */ -#if defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763) +#ifdef CONFIG_CPU_SUBTYPE_SH7763 /* EDSR */ enum EDSR_BIT { EDSR_ENT = 0x01, EDSR_ENR = 0x02, @@ -693,7 +689,7 @@ enum TSU_FWSLC_BIT { */ struct sh_eth_txdesc { u32 status; /* TD0 */ -#if defined(__LITTLE_ENDIAN) +#if defined(CONFIG_CPU_LITTLE_ENDIAN) u16 pad0; /* TD1 */ u16 buffer_length; /* TD1 */ #else @@ -710,7 +706,7 @@ struct sh_eth_txdesc { */ struct sh_eth_rxdesc { u32 status; /* RD0 */ -#if defined(__LITTLE_ENDIAN) +#if defined(CONFIG_CPU_LITTLE_ENDIAN) u16 frame_length; /* RD1 */ u16 buffer_length; /* RD1 */ #else @@ -755,7 +751,6 @@ struct sh_eth_cpu_data { unsigned rpadir:1; /* E-DMAC have RPADIR */ unsigned no_trimd:1; /* E-DMAC DO NOT have TRIMD */ unsigned no_ade:1; /* E-DMAC DO NOT have ADE bit in EESR */ - unsigned hw_crc:1; /* E-DMAC have CSMR */ }; struct sh_eth_private { diff --git a/trunk/drivers/net/ethernet/sfc/mtd.c b/trunk/drivers/net/ethernet/sfc/mtd.c index 758148379b0e..26b3c23b0b6f 100644 --- a/trunk/drivers/net/ethernet/sfc/mtd.c +++ b/trunk/drivers/net/ethernet/sfc/mtd.c @@ -193,7 +193,7 @@ static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase) erase->state = MTD_ERASE_DONE; } else { erase->state = MTD_ERASE_FAILED; - erase->fail_addr = MTD_FAIL_ADDR_UNKNOWN; + erase->fail_addr = 0xffffffff; } mtd_erase_callback(erase); return rc; @@ -263,10 +263,10 @@ static int efx_mtd_probe_device(struct efx_nic *efx, struct efx_mtd *efx_mtd) part->mtd.owner = THIS_MODULE; part->mtd.priv = efx_mtd; part->mtd.name = part->name; - part->mtd._erase = efx_mtd_erase; - part->mtd._read = efx_mtd->ops->read; - part->mtd._write = efx_mtd->ops->write; - part->mtd._sync = efx_mtd_sync; + part->mtd.erase = efx_mtd_erase; + part->mtd.read = efx_mtd->ops->read; + part->mtd.write = efx_mtd->ops->write; + part->mtd.sync = efx_mtd_sync; if (mtd_device_register(&part->mtd, NULL, 0)) goto fail; diff --git a/trunk/drivers/net/ethernet/smsc/smsc911x.c b/trunk/drivers/net/ethernet/smsc/smsc911x.c index cd3defb11ffb..4a6971027076 100644 --- a/trunk/drivers/net/ethernet/smsc/smsc911x.c +++ b/trunk/drivers/net/ethernet/smsc/smsc911x.c @@ -1166,8 +1166,10 @@ smsc911x_rx_counterrors(struct net_device *dev, unsigned int rxstat) /* Quickly dumps bad packets */ static void -smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktwords) +smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes) { + unsigned int pktwords = (pktbytes + NET_IP_ALIGN + 3) >> 2; + if (likely(pktwords >= 4)) { unsigned int timeout = 500; unsigned int val; @@ -1231,7 +1233,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget) continue; } - skb = netdev_alloc_skb(dev, pktwords << 2); + skb = netdev_alloc_skb(dev, pktlength + NET_IP_ALIGN); if (unlikely(!skb)) { SMSC_WARN(pdata, rx_err, "Unable to allocate skb for rx packet"); @@ -1241,12 +1243,14 @@ static int smsc911x_poll(struct napi_struct *napi, int budget) break; } - pdata->ops->rx_readfifo(pdata, - (unsigned int *)skb->data, pktwords); + skb->data = skb->head; + skb_reset_tail_pointer(skb); /* Align IP on 16B boundary */ skb_reserve(skb, NET_IP_ALIGN); skb_put(skb, pktlength - 4); + pdata->ops->rx_readfifo(pdata, + (unsigned int *)skb->head, pktwords); skb->protocol = eth_type_trans(skb, dev); skb_checksum_none_assert(skb); netif_receive_skb(skb); @@ -1561,7 +1565,7 @@ static int smsc911x_open(struct net_device *dev) smsc911x_reg_write(pdata, FIFO_INT, temp); /* set RX Data offset to 2 bytes for alignment */ - smsc911x_reg_write(pdata, RX_CFG, (NET_IP_ALIGN << 8)); + smsc911x_reg_write(pdata, RX_CFG, (2 << 8)); /* enable NAPI polling before enabling RX interrupts */ napi_enable(&pdata->napi); @@ -2378,6 +2382,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) SET_NETDEV_DEV(dev, &pdev->dev); pdata = netdev_priv(dev); + dev->irq = irq_res->start; irq_flags = irq_res->flags & IRQF_TRIGGER_MASK; pdata->ioaddr = ioremap_nocache(res->start, res_size); @@ -2441,7 +2446,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) if (retval) { SMSC_WARN(pdata, probe, "Unable to claim requested irq: %d", dev->irq); - goto out_disable_resources; + goto out_free_irq; } retval = register_netdev(dev); diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 48d56da62f08..e85ffbd54830 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1737,12 +1737,10 @@ static int stmmac_hw_init(struct stmmac_priv *priv) struct mac_device_info *mac; /* Identify the MAC HW device */ - if (priv->plat->has_gmac) { - priv->dev->priv_flags |= IFF_UNICAST_FLT; + if (priv->plat->has_gmac) mac = dwmac1000_setup(priv->ioaddr); - } else { + else mac = dwmac100_setup(priv->ioaddr); - } if (!mac) return -ENOMEM; diff --git a/trunk/drivers/net/ethernet/sun/sungem.c b/trunk/drivers/net/ethernet/sun/sungem.c index 4ba969096717..558409ff4058 100644 --- a/trunk/drivers/net/ethernet/sun/sungem.c +++ b/trunk/drivers/net/ethernet/sun/sungem.c @@ -2339,7 +2339,7 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state) netif_device_detach(dev); /* Switch off chip, remember WOL setting */ - gp->asleep_wol = !!gp->wake_on_lan; + gp->asleep_wol = gp->wake_on_lan; gem_do_stop(dev, gp->asleep_wol); /* Unlock the network stack */ diff --git a/trunk/drivers/net/ethernet/ti/davinci_emac.c b/trunk/drivers/net/ethernet/ti/davinci_emac.c index 08aff1a2087c..174a3348f676 100644 --- a/trunk/drivers/net/ethernet/ti/davinci_emac.c +++ b/trunk/drivers/net/ethernet/ti/davinci_emac.c @@ -1511,7 +1511,7 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd) static int match_first_device(struct device *dev, void *data) { - return !strncmp(dev_name(dev), "davinci_mdio", 12); + return 1; } /** diff --git a/trunk/drivers/net/ethernet/ti/davinci_mdio.c b/trunk/drivers/net/ethernet/ti/davinci_mdio.c index e4e47088e26b..2757c7d6e633 100644 --- a/trunk/drivers/net/ethernet/ti/davinci_mdio.c +++ b/trunk/drivers/net/ethernet/ti/davinci_mdio.c @@ -181,11 +181,6 @@ static inline int wait_for_user_access(struct davinci_mdio_data *data) __davinci_mdio_reset(data); return -EAGAIN; } - - reg = __raw_readl(®s->user[0].access); - if ((reg & USERACCESS_GO) == 0) - return 0; - dev_err(data->dev, "timed out waiting for user access\n"); return -ETIMEDOUT; } diff --git a/trunk/drivers/net/ethernet/ti/tlan.c b/trunk/drivers/net/ethernet/ti/tlan.c index efd36691ce54..817ad3bc4957 100644 --- a/trunk/drivers/net/ethernet/ti/tlan.c +++ b/trunk/drivers/net/ethernet/ti/tlan.c @@ -228,7 +228,7 @@ tlan_get_skb(const struct tlan_list *tag) unsigned long addr; addr = tag->buffer[9].address; - addr |= ((unsigned long) tag->buffer[8].address << 16) << 16; + addr |= (tag->buffer[8].address << 16) << 16; return (struct sk_buff *) addr; } diff --git a/trunk/drivers/net/ethernet/tile/tilepro.c b/trunk/drivers/net/ethernet/tile/tilepro.c index 3d501ec7fad7..261356c2dc99 100644 --- a/trunk/drivers/net/ethernet/tile/tilepro.c +++ b/trunk/drivers/net/ethernet/tile/tilepro.c @@ -342,21 +342,6 @@ inline int __netio_fastio1(u32 fastio_index, u32 arg0) } -static void tile_net_return_credit(struct tile_net_cpu *info) -{ - struct tile_netio_queue *queue = &info->queue; - netio_queue_user_impl_t *qup = &queue->__user_part; - - /* Return four credits after every fourth packet. */ - if (--qup->__receive_credit_remaining == 0) { - u32 interval = qup->__receive_credit_interval; - qup->__receive_credit_remaining = interval; - __netio_fastio_return_credits(qup->__fastio_index, interval); - } -} - - - /* * Provide a linux buffer to LIPP. */ @@ -448,7 +433,7 @@ static bool tile_net_provide_needed_buffer(struct tile_net_cpu *info, struct sk_buff **skb_ptr; /* Request 96 extra bytes for alignment purposes. */ - skb = netdev_alloc_skb(info->napi.dev, len + padding); + skb = netdev_alloc_skb(info->napi->dev, len + padding); if (skb == NULL) return false; @@ -879,11 +864,19 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index) stats->rx_packets++; stats->rx_bytes += len; + + if (small) + info->num_needed_small_buffers++; + else + info->num_needed_large_buffers++; } - /* ISSUE: It would be nice to defer this until the packet has */ - /* actually been processed. */ - tile_net_return_credit(info); + /* Return four credits after every fourth packet. */ + if (--qup->__receive_credit_remaining == 0) { + u32 interval = qup->__receive_credit_interval; + qup->__receive_credit_remaining = interval; + __netio_fastio_return_credits(qup->__fastio_index, interval); + } /* Consume this packet. */ qup->__packet_receive_read = index2; @@ -1550,7 +1543,7 @@ static int tile_net_drain_lipp_buffers(struct tile_net_priv *priv) /* Drain all the LIPP buffers. */ while (true) { - unsigned int buffer; + int buffer; /* NOTE: This should never fail. */ if (hv_dev_pread(priv->hv_devhdl, 0, (HV_VirtAddr)&buffer, @@ -1714,7 +1707,7 @@ static unsigned int tile_net_tx_frags(lepp_frag_t *frags, if (!hash_default) { void *va = pfn_to_kaddr(pfn) + f->page_offset; BUG_ON(PageHighMem(skb_frag_page(f))); - finv_buffer_remote(va, skb_frag_size(f), 0); + finv_buffer_remote(va, f->size, 0); } cpa = ((phys_addr_t)pfn << PAGE_SHIFT) + f->page_offset; @@ -1742,8 +1735,8 @@ static unsigned int tile_net_tx_frags(lepp_frag_t *frags, * Sometimes, if "sendfile()" requires copying, we will be called with * "data" containing the header and payload, with "frags" being empty. * - * Sometimes, for example when using NFS over TCP, a single segment can - * span 3 fragments, which must be handled carefully in LEPP. + * In theory, "sh->nr_frags" could be 3, but in practice, it seems + * that this will never actually happen. * * See "emulate_large_send_offload()" for some reference code, which * does not handle checksumming. @@ -1851,8 +1844,10 @@ static int tile_net_tx_tso(struct sk_buff *skb, struct net_device *dev) spin_lock_irqsave(&priv->eq_lock, irqflags); - /* Handle completions if needed to make room. */ - /* NOTE: Return NETDEV_TX_BUSY if there is still no room. */ + /* + * Handle completions if needed to make room. + * HACK: Spin until there is sufficient room. + */ if (lepp_num_free_comp_slots(eq) == 0) { nolds = tile_net_lepp_grab_comps(eq, olds, wanted, 0); if (nolds == 0) { @@ -1866,7 +1861,6 @@ static int tile_net_tx_tso(struct sk_buff *skb, struct net_device *dev) cmd_tail = eq->cmd_tail; /* Prepare to advance, detecting full queue. */ - /* NOTE: Return NETDEV_TX_BUSY if the queue is full. */ cmd_next = cmd_tail + cmd_size; if (cmd_tail < cmd_head && cmd_next >= cmd_head) goto busy; @@ -2029,8 +2023,10 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev) spin_lock_irqsave(&priv->eq_lock, irqflags); - /* Handle completions if needed to make room. */ - /* NOTE: Return NETDEV_TX_BUSY if there is still no room. */ + /* + * Handle completions if needed to make room. + * HACK: Spin until there is sufficient room. + */ if (lepp_num_free_comp_slots(eq) == 0) { nolds = tile_net_lepp_grab_comps(eq, olds, wanted, 0); if (nolds == 0) { @@ -2044,7 +2040,6 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev) cmd_tail = eq->cmd_tail; /* Copy the commands, or fail. */ - /* NOTE: Return NETDEV_TX_BUSY if the queue is full. */ for (i = 0; i < num_frags; i++) { /* Prepare to advance, detecting full queue. */ @@ -2266,23 +2261,6 @@ static int tile_net_get_mac(struct net_device *dev) return 0; } - -#ifdef CONFIG_NET_POLL_CONTROLLER -/* - * Polling 'interrupt' - used by things like netconsole to send skbs - * without having to re-enable interrupts. It's not called while - * the interrupt routine is executing. - */ -static void tile_net_netpoll(struct net_device *dev) -{ - struct tile_net_priv *priv = netdev_priv(dev); - disable_percpu_irq(priv->intr_id); - tile_net_handle_ingress_interrupt(priv->intr_id, dev); - enable_percpu_irq(priv->intr_id, 0); -} -#endif - - static const struct net_device_ops tile_net_ops = { .ndo_open = tile_net_open, .ndo_stop = tile_net_stop, @@ -2291,10 +2269,7 @@ static const struct net_device_ops tile_net_ops = { .ndo_get_stats = tile_net_get_stats, .ndo_change_mtu = tile_net_change_mtu, .ndo_tx_timeout = tile_net_tx_timeout, - .ndo_set_mac_address = tile_net_set_mac_address, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = tile_net_netpoll, -#endif + .ndo_set_mac_address = tile_net_set_mac_address }; @@ -2434,7 +2409,7 @@ static void tile_net_cleanup(void) */ static int tile_net_init_module(void) { - pr_info("Tilera Network Driver\n"); + pr_info("Tilera IPP Net Driver\n"); tile_net_devs[0] = tile_net_dev_init("xgbe0"); tile_net_devs[1] = tile_net_dev_init("xgbe1"); diff --git a/trunk/drivers/net/ethernet/via/via-rhine.c b/trunk/drivers/net/ethernet/via/via-rhine.c index fcfa01f7ceb6..39b8cf3dafcd 100644 --- a/trunk/drivers/net/ethernet/via/via-rhine.c +++ b/trunk/drivers/net/ethernet/via/via-rhine.c @@ -503,32 +503,30 @@ static int rhine_vlan_rx_add_vid(struct net_device *dev, unsigned short vid); static int rhine_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid); static void rhine_restart_tx(struct net_device *dev); -static void rhine_wait_bit(struct rhine_private *rp, u8 reg, u8 mask, bool low) +static void rhine_wait_bit(struct rhine_private *rp, u8 reg, u8 mask, bool high) { void __iomem *ioaddr = rp->base; int i; for (i = 0; i < 1024; i++) { - bool has_mask_bits = !!(ioread8(ioaddr + reg) & mask); - - if (low ^ has_mask_bits) + if (high ^ !!(ioread8(ioaddr + reg) & mask)) break; udelay(10); } if (i > 64) { netif_dbg(rp, hw, rp->dev, "%s bit wait (%02x/%02x) cycle " - "count: %04d\n", low ? "low" : "high", reg, mask, i); + "count: %04d\n", high ? "high" : "low", reg, mask, i); } } static void rhine_wait_bit_high(struct rhine_private *rp, u8 reg, u8 mask) { - rhine_wait_bit(rp, reg, mask, false); + rhine_wait_bit(rp, reg, mask, true); } static void rhine_wait_bit_low(struct rhine_private *rp, u8 reg, u8 mask) { - rhine_wait_bit(rp, reg, mask, true); + rhine_wait_bit(rp, reg, mask, false); } static u32 rhine_get_events(struct rhine_private *rp) diff --git a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet.h b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet.h index 44b8d2bad8c3..cc83af083fd7 100644 --- a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet.h +++ b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet.h @@ -2,7 +2,9 @@ * Definitions for Xilinx Axi Ethernet device driver. * * Copyright (c) 2009 Secret Lab Technologies, Ltd. - * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved. + * Copyright (c) 2010 Xilinx, Inc. All rights reserved. + * Copyright (c) 2012 Daniel Borkmann, + * Copyright (c) 2012 Ariane Keller, */ #ifndef XILINX_AXIENET_H diff --git a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 9c365e192a31..2fcbeba6814b 100644 --- a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -4,9 +4,9 @@ * Copyright (c) 2008 Nissin Systems Co., Ltd., Yoshio Kashiwagi * Copyright (c) 2005-2008 DLA Systems, David H. Lynch Jr. * Copyright (c) 2008-2009 Secret Lab Technologies Ltd. - * Copyright (c) 2010 - 2011 Michal Simek - * Copyright (c) 2010 - 2011 PetaLogix - * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved. + * Copyright (c) 2010 Xilinx, Inc. All rights reserved. + * Copyright (c) 2012 Daniel Borkmann, + * Copyright (c) 2012 Ariane Keller, * * This is a driver for the Xilinx Axi Ethernet which is used in the Virtex6 * and Spartan6. diff --git a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c index e90e1f46121e..d70b6e79f6c0 100644 --- a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c +++ b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c @@ -2,9 +2,9 @@ * MDIO bus driver for the Xilinx Axi Ethernet device * * Copyright (c) 2009 Secret Lab Technologies, Ltd. - * Copyright (c) 2010 - 2011 Michal Simek - * Copyright (c) 2010 - 2011 PetaLogix - * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved. + * Copyright (c) 2010 Xilinx, Inc. All rights reserved. + * Copyright (c) 2012 Daniel Borkmann, + * Copyright (c) 2012 Ariane Keller, */ #include diff --git a/trunk/drivers/net/hyperv/netvsc_drv.c b/trunk/drivers/net/hyperv/netvsc_drv.c index 2d59138db7f3..dd294783b5c5 100644 --- a/trunk/drivers/net/hyperv/netvsc_drv.c +++ b/trunk/drivers/net/hyperv/netvsc_drv.c @@ -44,7 +44,6 @@ struct net_device_context { /* point back to our device context */ struct hv_device *device_ctx; struct delayed_work dwork; - struct work_struct work; }; @@ -52,22 +51,30 @@ static int ring_size = 128; module_param(ring_size, int, S_IRUGO); MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); +struct set_multicast_work { + struct work_struct work; + struct net_device *net; +}; + static void do_set_multicast(struct work_struct *w) { - struct net_device_context *ndevctx = - container_of(w, struct net_device_context, work); + struct set_multicast_work *swk = + container_of(w, struct set_multicast_work, work); + struct net_device *net = swk->net; + + struct net_device_context *ndevctx = netdev_priv(net); struct netvsc_device *nvdev; struct rndis_device *rdev; nvdev = hv_get_drvdata(ndevctx->device_ctx); - if (nvdev == NULL || nvdev->ndev == NULL) - return; + if (nvdev == NULL) + goto out; rdev = nvdev->extension; if (rdev == NULL) - return; + goto out; - if (nvdev->ndev->flags & IFF_PROMISC) + if (net->flags & IFF_PROMISC) rndis_filter_set_packet_filter(rdev, NDIS_PACKET_TYPE_PROMISCUOUS); else @@ -75,13 +82,21 @@ static void do_set_multicast(struct work_struct *w) NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_ALL_MULTICAST | NDIS_PACKET_TYPE_DIRECTED); + +out: + kfree(w); } static void netvsc_set_multicast_list(struct net_device *net) { - struct net_device_context *net_device_ctx = netdev_priv(net); + struct set_multicast_work *swk = + kmalloc(sizeof(struct set_multicast_work), GFP_ATOMIC); + if (swk == NULL) + return; - schedule_work(&net_device_ctx->work); + swk->net = net; + INIT_WORK(&swk->work, do_set_multicast); + schedule_work(&swk->work); } static int netvsc_open(struct net_device *net) @@ -110,8 +125,6 @@ static int netvsc_close(struct net_device *net) netif_tx_disable(net); - /* Make sure netvsc_set_multicast_list doesn't re-enable filter! */ - cancel_work_sync(&net_device_ctx->work); ret = rndis_filter_close(device_obj); if (ret != 0) netdev_err(net, "unable to close device (ret %d).\n", ret); @@ -322,7 +335,6 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) nvdev->start_remove = true; cancel_delayed_work_sync(&ndevctx->dwork); - cancel_work_sync(&ndevctx->work); netif_tx_disable(ndev); rndis_filter_device_remove(hdev); @@ -391,7 +403,6 @@ static int netvsc_probe(struct hv_device *dev, net_device_ctx->device_ctx = dev; hv_set_drvdata(dev, net); INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp); - INIT_WORK(&net_device_ctx->work, do_set_multicast); net->netdev_ops = &device_ops; @@ -445,7 +456,6 @@ static int netvsc_remove(struct hv_device *dev) ndev_ctx = netdev_priv(net); cancel_delayed_work_sync(&ndev_ctx->dwork); - cancel_work_sync(&ndev_ctx->work); /* Stop outbound asap */ netif_tx_disable(net); diff --git a/trunk/drivers/net/irda/sa1100_ir.c b/trunk/drivers/net/irda/sa1100_ir.c index e25067552b20..a0d1913a58d3 100644 --- a/trunk/drivers/net/irda/sa1100_ir.c +++ b/trunk/drivers/net/irda/sa1100_ir.c @@ -147,7 +147,7 @@ static void sa1100_irda_dma_start(struct sa1100_buf *buf, struct dma_async_tx_descriptor *desc; struct dma_chan *chan = buf->chan; - desc = dmaengine_prep_slave_sg(chan, &buf->sg, 1, dir, + desc = chan->device->device_prep_slave_sg(chan, &buf->sg, 1, dir, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (desc) { desc->callback = cb; diff --git a/trunk/drivers/net/phy/icplus.c b/trunk/drivers/net/phy/icplus.c index 5ac46f5226f3..0856e1b7a849 100644 --- a/trunk/drivers/net/phy/icplus.c +++ b/trunk/drivers/net/phy/icplus.c @@ -40,7 +40,6 @@ MODULE_LICENSE("GPL"); #define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */ #define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ #define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */ -#define IP101A_G_IRQ_CONF_STATUS 0x11 /* Conf Info IRQ & Status Reg */ static int ip175c_config_init(struct phy_device *phydev) { @@ -163,8 +162,7 @@ static int ip101a_g_config_init(struct phy_device *phydev) /* Enable Auto Power Saving mode */ c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); c |= IP101A_G_APS_ON; - - return phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c); + return c; } static int ip175c_read_status(struct phy_device *phydev) @@ -186,15 +184,6 @@ static int ip175c_config_aneg(struct phy_device *phydev) return 0; } -static int ip101a_g_ack_interrupt(struct phy_device *phydev) -{ - int err = phy_read(phydev, IP101A_G_IRQ_CONF_STATUS); - if (err < 0) - return err; - - return 0; -} - static struct phy_driver ip175c_driver = { .phy_id = 0x02430d80, .name = "ICPlus IP175C", @@ -214,6 +203,7 @@ static struct phy_driver ip1001_driver = { .phy_id_mask = 0x0ffffff0, .features = PHY_GBIT_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause, + .flags = PHY_HAS_INTERRUPT, .config_init = &ip1001_config_init, .config_aneg = &genphy_config_aneg, .read_status = &genphy_read_status, @@ -229,7 +219,6 @@ static struct phy_driver ip101a_g_driver = { .features = PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause, .flags = PHY_HAS_INTERRUPT, - .ack_interrupt = ip101a_g_ack_interrupt, .config_init = &ip101a_g_config_init, .config_aneg = &genphy_config_aneg, .read_status = &genphy_read_status, diff --git a/trunk/drivers/net/ppp/ppp_generic.c b/trunk/drivers/net/ppp/ppp_generic.c index 21d7151fb0ab..159da2905fe9 100644 --- a/trunk/drivers/net/ppp/ppp_generic.c +++ b/trunk/drivers/net/ppp/ppp_generic.c @@ -968,6 +968,7 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev) proto = npindex_to_proto[npi]; put_unaligned_be16(proto, pp); + netif_stop_queue(dev); skb_queue_tail(&ppp->file.xq, skb); ppp_xmit_process(ppp); return NETDEV_TX_OK; @@ -1062,8 +1063,6 @@ ppp_xmit_process(struct ppp *ppp) code that we can accept some more. */ if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq)) netif_wake_queue(ppp->dev); - else - netif_stop_queue(ppp->dev); } ppp_xmit_unlock(ppp); } diff --git a/trunk/drivers/net/rionet.c b/trunk/drivers/net/rionet.c index 91d25888a1b9..a57f05726b57 100644 --- a/trunk/drivers/net/rionet.c +++ b/trunk/drivers/net/rionet.c @@ -375,8 +375,8 @@ static void rionet_remove(struct rio_dev *rdev) struct net_device *ndev = rio_get_drvdata(rdev); struct rionet_peer *peer, *tmp; - free_pages((unsigned long)rionet_active, get_order(sizeof(void *) * - RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size))); + free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ? + __fls(sizeof(void *)) + 4 : 0); unregister_netdev(ndev); free_netdev(ndev); @@ -432,16 +432,15 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev) int rc = 0; struct rionet_private *rnet; u16 device_id; - const size_t rionet_active_bytes = sizeof(void *) * - RIO_MAX_ROUTE_ENTRIES(mport->sys_size); rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL, - get_order(rionet_active_bytes)); + mport->sys_size ? __fls(sizeof(void *)) + 4 : 0); if (!rionet_active) { rc = -ENOMEM; goto out; } - memset((void *)rionet_active, 0, rionet_active_bytes); + memset((void *)rionet_active, 0, sizeof(void *) * + RIO_MAX_ROUTE_ENTRIES(mport->sys_size)); /* Set up private area */ rnet = netdev_priv(ndev); diff --git a/trunk/drivers/net/usb/asix.c b/trunk/drivers/net/usb/asix.c index 42b5151aa78a..5ee032cafade 100644 --- a/trunk/drivers/net/usb/asix.c +++ b/trunk/drivers/net/usb/asix.c @@ -355,7 +355,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, u32 packet_len; u32 padbytes = 0xffff0000; - padlen = ((skb->len + 4) & (dev->maxpacket - 1)) ? 0 : 4; + padlen = ((skb->len + 4) % 512) ? 0 : 4; if ((!skb_cloned(skb)) && ((headroom + tailroom) >= (4 + padlen))) { @@ -377,7 +377,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, cpu_to_le32s(&packet_len); skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len)); - if (padlen) { + if ((skb->len % 512) == 0) { cpu_to_le32s(&padbytes); memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes)); skb_put(skb, sizeof(padbytes)); diff --git a/trunk/drivers/net/usb/cdc-phonet.c b/trunk/drivers/net/usb/cdc-phonet.c index 3e41b00c6806..3886b30ed373 100644 --- a/trunk/drivers/net/usb/cdc-phonet.c +++ b/trunk/drivers/net/usb/cdc-phonet.c @@ -165,13 +165,13 @@ static void rx_complete(struct urb *req) memcpy(skb_put(skb, 1), page_address(page), 1); skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, 1, req->actual_length, - PAGE_SIZE); + req->actual_length); page = NULL; } } else { skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, 0, req->actual_length, - PAGE_SIZE); + req->actual_length); page = NULL; } if (req->actual_length < PAGE_SIZE) diff --git a/trunk/drivers/net/usb/cdc_eem.c b/trunk/drivers/net/usb/cdc_eem.c index 685a4e22c768..439690be519f 100644 --- a/trunk/drivers/net/usb/cdc_eem.c +++ b/trunk/drivers/net/usb/cdc_eem.c @@ -93,7 +93,6 @@ static int eem_bind(struct usbnet *dev, struct usb_interface *intf) /* no jumbogram (16K) support for now */ dev->net->hard_header_len += EEM_HEAD + ETH_FCS_LEN; - dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; return 0; } diff --git a/trunk/drivers/net/usb/qmi_wwan.c b/trunk/drivers/net/usb/qmi_wwan.c index d316503b35d4..552d24bf862e 100644 --- a/trunk/drivers/net/usb/qmi_wwan.c +++ b/trunk/drivers/net/usb/qmi_wwan.c @@ -365,27 +365,6 @@ static const struct driver_info qmi_wwan_force_int4 = { .data = BIT(4), /* interface whitelist bitmap */ }; -/* Sierra Wireless provide equally useless interface descriptors - * Devices in QMI mode can be switched between two different - * configurations: - * a) USB interface #8 is QMI/wwan - * b) USB interfaces #8, #19 and #20 are QMI/wwan - * - * Both configurations provide a number of other interfaces (serial++), - * some of which have the same endpoint configuration as we expect, so - * a whitelist or blacklist is necessary. - * - * FIXME: The below whitelist should include BIT(20). It does not - * because I cannot get it to work... - */ -static const struct driver_info qmi_wwan_sierra = { - .description = "Sierra Wireless wwan/QMI device", - .flags = FLAG_WWAN, - .bind = qmi_wwan_bind_gobi, - .unbind = qmi_wwan_unbind_shared, - .manage_power = qmi_wwan_manage_power, - .data = BIT(8) | BIT(19), /* interface whitelist bitmap */ -}; #define HUAWEI_VENDOR_ID 0x12D1 #define QMI_GOBI_DEVICE(vend, prod) \ @@ -466,15 +445,6 @@ static const struct usb_device_id products[] = { .bInterfaceProtocol = 0xff, .driver_info = (unsigned long)&qmi_wwan_force_int4, }, - { /* Sierra Wireless MC77xx in QMI mode */ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x1199, - .idProduct = 0x68a2, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0xff, - .bInterfaceProtocol = 0xff, - .driver_info = (unsigned long)&qmi_wwan_sierra, - }, {QMI_GOBI_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ {QMI_GOBI_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ {QMI_GOBI_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ diff --git a/trunk/drivers/net/usb/rtl8150.c b/trunk/drivers/net/usb/rtl8150.c index d363b31053da..6dda2fe5b15b 100644 --- a/trunk/drivers/net/usb/rtl8150.c +++ b/trunk/drivers/net/usb/rtl8150.c @@ -59,6 +59,32 @@ #define RTL8150_REQ_SET_REGS 0x05 +/* Transmit status register errors */ +#define TSR_ECOL (1<<5) +#define TSR_LCOL (1<<4) +#define TSR_LOSS_CRS (1<<3) +#define TSR_JBR (1<<2) +#define TSR_ERRORS (TSR_ECOL | TSR_LCOL | TSR_LOSS_CRS | TSR_JBR) +/* Receive status register errors */ +#define RSR_CRC (1<<2) +#define RSR_FAE (1<<1) +#define RSR_ERRORS (RSR_CRC | RSR_FAE) + +/* Media status register definitions */ +#define MSR_DUPLEX (1<<4) +#define MSR_SPEED (1<<3) +#define MSR_LINK (1<<2) + +/* Interrupt pipe data */ +#define INT_TSR 0x00 +#define INT_RSR 0x01 +#define INT_MSR 0x02 +#define INT_WAKSR 0x03 +#define INT_TXOK_CNT 0x04 +#define INT_RXLOST_CNT 0x05 +#define INT_CRERR_CNT 0x06 +#define INT_COL_CNT 0x07 + /* Transmit status register errors */ #define TSR_ECOL (1<<5) #define TSR_LCOL (1<<4) diff --git a/trunk/drivers/net/usb/smsc75xx.c b/trunk/drivers/net/usb/smsc75xx.c index 00103a8c5e04..187d01ccb973 100644 --- a/trunk/drivers/net/usb/smsc75xx.c +++ b/trunk/drivers/net/usb/smsc75xx.c @@ -98,7 +98,7 @@ static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index, if (unlikely(ret < 0)) netdev_warn(dev->net, - "Failed to read reg index 0x%08x: %d", index, ret); + "Failed to read register index 0x%08x", index); le32_to_cpus(buf); *data = *buf; @@ -128,7 +128,7 @@ static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index, if (unlikely(ret < 0)) netdev_warn(dev->net, - "Failed to write reg index 0x%08x: %d", index, ret); + "Failed to write register index 0x%08x", index); kfree(buf); @@ -171,7 +171,7 @@ static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx) idx &= dev->mii.reg_num_mask; addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR) | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) - | MII_ACCESS_READ | MII_ACCESS_BUSY; + | MII_ACCESS_READ; ret = smsc75xx_write_reg(dev, MII_ACCESS, addr); check_warn_goto_done(ret, "Error writing MII_ACCESS"); @@ -210,7 +210,7 @@ static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx, idx &= dev->mii.reg_num_mask; addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR) | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) - | MII_ACCESS_WRITE | MII_ACCESS_BUSY; + | MII_ACCESS_WRITE; ret = smsc75xx_write_reg(dev, MII_ACCESS, addr); check_warn_goto_done(ret, "Error writing MII_ACCESS"); @@ -508,10 +508,9 @@ static int smsc75xx_link_reset(struct usbnet *dev) u16 lcladv, rmtadv; int ret; - /* read and write to clear phy interrupt status */ + /* clear interrupt status */ ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC); check_warn_return(ret, "Error reading PHY_INT_SRC"); - smsc75xx_mdio_write(dev->net, mii->phy_id, PHY_INT_SRC, 0xffff); ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL); check_warn_return(ret, "Error writing INT_STS"); @@ -644,7 +643,7 @@ static int smsc75xx_set_mac_address(struct usbnet *dev) static int smsc75xx_phy_initialize(struct usbnet *dev) { - int bmcr, ret, timeout = 0; + int bmcr, timeout = 0; /* Initialize MII structure */ dev->mii.dev = dev->net; @@ -652,7 +651,6 @@ static int smsc75xx_phy_initialize(struct usbnet *dev) dev->mii.mdio_write = smsc75xx_mdio_write; dev->mii.phy_id_mask = 0x1f; dev->mii.reg_num_mask = 0x1f; - dev->mii.supports_gmii = 1; dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID; /* reset phy and wait for reset to complete */ @@ -663,7 +661,7 @@ static int smsc75xx_phy_initialize(struct usbnet *dev) bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR); check_warn_return(bmcr, "Error reading MII_BMCR"); timeout++; - } while ((bmcr & BMCR_RESET) && (timeout < 100)); + } while ((bmcr & MII_BMCR) && (timeout < 100)); if (timeout >= 100) { netdev_warn(dev->net, "timeout on PHY Reset"); @@ -673,13 +671,10 @@ static int smsc75xx_phy_initialize(struct usbnet *dev) smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); - smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000, - ADVERTISE_1000FULL); - /* read and write to clear phy interrupt status */ - ret = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC); - check_warn_return(ret, "Error reading PHY_INT_SRC"); - smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_SRC, 0xffff); + /* read to clear */ + smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC); + check_warn_return(bmcr, "Error reading PHY_INT_SRC"); smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK, PHY_INT_MASK_DEFAULT); @@ -951,14 +946,6 @@ static int smsc75xx_reset(struct usbnet *dev) ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf); check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret); - /* allow mac to detect speed and duplex from phy */ - ret = smsc75xx_read_reg(dev, MAC_CR, &buf); - check_warn_return(ret, "Failed to read MAC_CR: %d", ret); - - buf |= (MAC_CR_ADD | MAC_CR_ASD); - ret = smsc75xx_write_reg(dev, MAC_CR, buf); - check_warn_return(ret, "Failed to write MAC_CR: %d", ret); - ret = smsc75xx_read_reg(dev, MAC_TX, &buf); check_warn_return(ret, "Failed to read MAC_TX: %d", ret); @@ -1064,7 +1051,6 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->ethtool_ops = &smsc75xx_ethtool_ops; dev->net->flags |= IFF_MULTICAST; dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD; - dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; return 0; } @@ -1225,7 +1211,7 @@ static const struct driver_info smsc75xx_info = { .rx_fixup = smsc75xx_rx_fixup, .tx_fixup = smsc75xx_tx_fixup, .status = smsc75xx_status, - .flags = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR, + .flags = FLAG_ETHER | FLAG_SEND_ZLP, }; static const struct usb_device_id products[] = { diff --git a/trunk/drivers/net/usb/smsc95xx.c b/trunk/drivers/net/usb/smsc95xx.c index 94ae66999f59..5f19f84d3494 100644 --- a/trunk/drivers/net/usb/smsc95xx.c +++ b/trunk/drivers/net/usb/smsc95xx.c @@ -1017,7 +1017,6 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->ethtool_ops = &smsc95xx_ethtool_ops; dev->net->flags |= IFF_MULTICAST; dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD_CSUM; - dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; return 0; } @@ -1192,7 +1191,7 @@ static const struct driver_info smsc95xx_info = { .rx_fixup = smsc95xx_rx_fixup, .tx_fixup = smsc95xx_tx_fixup, .status = smsc95xx_status, - .flags = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR, + .flags = FLAG_ETHER | FLAG_SEND_ZLP, }; static const struct usb_device_id products[] = { diff --git a/trunk/drivers/net/usb/usbnet.c b/trunk/drivers/net/usb/usbnet.c index 2d927fb4adf4..b7b3f5b0d406 100644 --- a/trunk/drivers/net/usb/usbnet.c +++ b/trunk/drivers/net/usb/usbnet.c @@ -210,7 +210,6 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf) } else { usb_fill_int_urb(dev->interrupt, dev->udev, pipe, buf, maxp, intr_complete, dev, period); - dev->interrupt->transfer_flags |= URB_FREE_BUFFER; dev_dbg(&intf->dev, "status ep%din, %d bytes period %d\n", usb_pipeendpoint(pipe), maxp, period); @@ -1444,7 +1443,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) status = register_netdev (net); if (status) - goto out4; + goto out3; netif_info(dev, probe, dev->net, "register '%s' at usb-%s-%s, %s, %pM\n", udev->dev.driver->name, @@ -1462,8 +1461,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) return 0; -out4: - usb_free_urb(dev->interrupt); out3: if (info->unbind) info->unbind (dev, udev); diff --git a/trunk/drivers/net/usb/zaurus.c b/trunk/drivers/net/usb/zaurus.c index 34db195fb8b0..c3197ce0e2ad 100644 --- a/trunk/drivers/net/usb/zaurus.c +++ b/trunk/drivers/net/usb/zaurus.c @@ -337,11 +337,6 @@ static const struct usb_device_id products [] = { .driver_info = ZAURUS_PXA_INFO, }, { - /* Motorola Rokr E6 */ - USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6027, USB_CLASS_COMM, - USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), - .driver_info = (unsigned long) &bogus_mdlm_info, -}, { /* Motorola MOTOMAGX phones */ USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6425, USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), diff --git a/trunk/drivers/net/virtio_net.c b/trunk/drivers/net/virtio_net.c index af8acc85f4bb..019da012669f 100644 --- a/trunk/drivers/net/virtio_net.c +++ b/trunk/drivers/net/virtio_net.c @@ -625,16 +625,16 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) /* This can happen with OOM and indirect buffers. */ if (unlikely(capacity < 0)) { - if (likely(capacity == -ENOMEM)) { - if (net_ratelimit()) + if (net_ratelimit()) { + if (likely(capacity == -ENOMEM)) { dev_warn(&dev->dev, "TX queue failure: out of memory\n"); - } else { - dev->stats.tx_fifo_errors++; - if (net_ratelimit()) + } else { + dev->stats.tx_fifo_errors++; dev_warn(&dev->dev, "Unexpected TX queue failure: %d\n", capacity); + } } dev->stats.tx_dropped++; kfree_skb(skb); diff --git a/trunk/drivers/net/wan/Kconfig b/trunk/drivers/net/wan/Kconfig index d70ede7a7f96..423eb26386c8 100644 --- a/trunk/drivers/net/wan/Kconfig +++ b/trunk/drivers/net/wan/Kconfig @@ -290,8 +290,8 @@ config FARSYNC Frame Relay or X.25/LAPB. If you want the module to be automatically loaded when the interface - is referenced then you should add "alias hdlcX farsync" to a file - in /etc/modprobe.d/ for each interface, where X is 0, 1, 2, ..., or + is referenced then you should add "alias hdlcX farsync" to + /etc/modprobe.conf for each interface, where X is 0, 1, 2, ..., or simply use "alias hdlc* farsync" to indicate all of them. To compile this driver as a module, choose M here: the diff --git a/trunk/drivers/net/wan/farsync.c b/trunk/drivers/net/wan/farsync.c index 1a623183cbe5..ebb9f24eefb5 100644 --- a/trunk/drivers/net/wan/farsync.c +++ b/trunk/drivers/net/wan/farsync.c @@ -2483,7 +2483,6 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent) pr_err("Control memory remap failed\n"); pci_release_regions(pdev); pci_disable_device(pdev); - iounmap(card->mem); kfree(card); return -ENODEV; } diff --git a/trunk/drivers/net/wimax/i2400m/debugfs.c b/trunk/drivers/net/wimax/i2400m/debugfs.c index 4b66ab1d0e5c..129ba36bd04d 100644 --- a/trunk/drivers/net/wimax/i2400m/debugfs.c +++ b/trunk/drivers/net/wimax/i2400m/debugfs.c @@ -53,6 +53,17 @@ struct dentry *debugfs_create_netdev_queue_stopped( &fops_netdev_queue_stopped); } + +/* + * inode->i_private has the @data argument to debugfs_create_file() + */ +static +int i2400m_stats_open(struct inode *inode, struct file *filp) +{ + filp->private_data = inode->i_private; + return 0; +} + /* * We don't allow partial reads of this file, as then the reader would * get weirdly confused data as it is updated. @@ -106,7 +117,7 @@ ssize_t i2400m_rx_stats_write(struct file *filp, const char __user *buffer, static const struct file_operations i2400m_rx_stats_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = i2400m_stats_open, .read = i2400m_rx_stats_read, .write = i2400m_rx_stats_write, .llseek = default_llseek, @@ -159,7 +170,7 @@ ssize_t i2400m_tx_stats_write(struct file *filp, const char __user *buffer, static const struct file_operations i2400m_tx_stats_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = i2400m_stats_open, .read = i2400m_tx_stats_read, .write = i2400m_tx_stats_write, .llseek = default_llseek, diff --git a/trunk/drivers/net/wimax/i2400m/netdev.c b/trunk/drivers/net/wimax/i2400m/netdev.c index 1d76ae855f07..63e4b709efa9 100644 --- a/trunk/drivers/net/wimax/i2400m/netdev.c +++ b/trunk/drivers/net/wimax/i2400m/netdev.c @@ -597,8 +597,7 @@ static void i2400m_get_drvinfo(struct net_device *net_dev, struct i2400m *i2400m = net_dev_to_i2400m(net_dev); strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver) - 1); - strncpy(info->fw_version, - i2400m->fw_name ? : "", sizeof(info->fw_version) - 1); + strncpy(info->fw_version, i2400m->fw_name, sizeof(info->fw_version) - 1); if (net_dev->dev.parent) strncpy(info->bus_info, dev_name(net_dev->dev.parent), sizeof(info->bus_info) - 1); diff --git a/trunk/drivers/net/wimax/i2400m/usb.c b/trunk/drivers/net/wimax/i2400m/usb.c index 29b1e033a10b..2c1b8b687646 100644 --- a/trunk/drivers/net/wimax/i2400m/usb.c +++ b/trunk/drivers/net/wimax/i2400m/usb.c @@ -339,23 +339,6 @@ int i2400mu_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt) return result; } -static void i2400mu_get_drvinfo(struct net_device *net_dev, - struct ethtool_drvinfo *info) -{ - struct i2400m *i2400m = net_dev_to_i2400m(net_dev); - struct i2400mu *i2400mu = container_of(i2400m, struct i2400mu, i2400m); - struct usb_device *udev = i2400mu->usb_dev; - - strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver) - 1); - strncpy(info->fw_version, - i2400m->fw_name ? : "", sizeof(info->fw_version) - 1); - usb_make_path(udev, info->bus_info, sizeof(info->bus_info)); -} - -static const struct ethtool_ops i2400mu_ethtool_ops = { - .get_drvinfo = i2400mu_get_drvinfo, - .get_link = ethtool_op_get_link, -}; static void i2400mu_netdev_setup(struct net_device *net_dev) @@ -364,7 +347,6 @@ void i2400mu_netdev_setup(struct net_device *net_dev) struct i2400mu *i2400mu = container_of(i2400m, struct i2400mu, i2400m); i2400mu_init(i2400mu); i2400m_netdev_setup(net_dev); - net_dev->ethtool_ops = &i2400mu_ethtool_ops; } diff --git a/trunk/drivers/net/wireless/ath/ath5k/ahb.c b/trunk/drivers/net/wireless/ath/ath5k/ahb.c index aec33cc207fd..8faa129da5a0 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/ahb.c +++ b/trunk/drivers/net/wireless/ath/ath5k/ahb.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include "ath5k.h" #include "debug.h" @@ -120,7 +119,7 @@ static int ath_ahb_probe(struct platform_device *pdev) if (res == NULL) { dev_err(&pdev->dev, "no IRQ resource found\n"); ret = -ENXIO; - goto err_iounmap; + goto err_out; } irq = res->start; @@ -129,7 +128,7 @@ static int ath_ahb_probe(struct platform_device *pdev) if (hw == NULL) { dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); ret = -ENOMEM; - goto err_iounmap; + goto err_out; } ah = hw->priv; @@ -186,8 +185,6 @@ static int ath_ahb_probe(struct platform_device *pdev) err_free_hw: ieee80211_free_hw(hw); platform_set_drvdata(pdev, NULL); - err_iounmap: - iounmap(mem); err_out: return ret; } @@ -220,7 +217,6 @@ static int ath_ahb_remove(struct platform_device *pdev) } ath5k_deinit_ah(ah); - iounmap(ah->iobase); platform_set_drvdata(pdev, NULL); ieee80211_free_hw(hw); diff --git a/trunk/drivers/net/wireless/ath/ath5k/debug.c b/trunk/drivers/net/wireless/ath/ath5k/debug.c index e5e8f45d86ac..8c5ce8b0c734 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/debug.c +++ b/trunk/drivers/net/wireless/ath/ath5k/debug.c @@ -71,6 +71,13 @@ static unsigned int ath5k_debug; module_param_named(debug, ath5k_debug, uint, 0); +static int ath5k_debugfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + + /* debugfs: registers */ struct reg { @@ -258,7 +265,7 @@ static ssize_t write_file_beacon(struct file *file, static const struct file_operations fops_beacon = { .read = read_file_beacon, .write = write_file_beacon, - .open = simple_open, + .open = ath5k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -278,7 +285,7 @@ static ssize_t write_file_reset(struct file *file, static const struct file_operations fops_reset = { .write = write_file_reset, - .open = simple_open, + .open = ath5k_debugfs_open, .owner = THIS_MODULE, .llseek = noop_llseek, }; @@ -358,7 +365,7 @@ static ssize_t write_file_debug(struct file *file, static const struct file_operations fops_debug = { .read = read_file_debug, .write = write_file_debug, - .open = simple_open, + .open = ath5k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -470,7 +477,7 @@ static ssize_t write_file_antenna(struct file *file, static const struct file_operations fops_antenna = { .read = read_file_antenna, .write = write_file_antenna, - .open = simple_open, + .open = ath5k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -525,7 +532,7 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, static const struct file_operations fops_misc = { .read = read_file_misc, - .open = simple_open, + .open = ath5k_debugfs_open, .owner = THIS_MODULE, }; @@ -640,7 +647,7 @@ static ssize_t write_file_frameerrors(struct file *file, static const struct file_operations fops_frameerrors = { .read = read_file_frameerrors, .write = write_file_frameerrors, - .open = simple_open, + .open = ath5k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -803,7 +810,7 @@ static ssize_t write_file_ani(struct file *file, static const struct file_operations fops_ani = { .read = read_file_ani, .write = write_file_ani, - .open = simple_open, + .open = ath5k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -874,7 +881,7 @@ static ssize_t write_file_queue(struct file *file, static const struct file_operations fops_queue = { .read = read_file_queue, .write = write_file_queue, - .open = simple_open, + .open = ath5k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; diff --git a/trunk/drivers/net/wireless/ath/ath6kl/debug.c b/trunk/drivers/net/wireless/ath/ath6kl/debug.c index d01403a263ff..552adb3f80d0 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/debug.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/debug.c @@ -217,6 +217,12 @@ void dump_cred_dist_stats(struct htc_target *target) target->credit_info->cur_free_credits); } +static int ath6kl_debugfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war) { switch (war) { @@ -257,7 +263,7 @@ static ssize_t read_file_war_stats(struct file *file, char __user *user_buf, static const struct file_operations fops_war_stats = { .read = read_file_war_stats, - .open = simple_open, + .open = ath6kl_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -482,7 +488,7 @@ static ssize_t ath6kl_fwlog_mask_write(struct file *file, } static const struct file_operations fops_fwlog_mask = { - .open = simple_open, + .open = ath6kl_debugfs_open, .read = ath6kl_fwlog_mask_read, .write = ath6kl_fwlog_mask_write, .owner = THIS_MODULE, @@ -628,7 +634,7 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, static const struct file_operations fops_tgt_stats = { .read = read_file_tgt_stats, - .open = simple_open, + .open = ath6kl_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -693,7 +699,7 @@ static ssize_t read_file_credit_dist_stats(struct file *file, static const struct file_operations fops_credit_dist_stats = { .read = read_file_credit_dist_stats, - .open = simple_open, + .open = ath6kl_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -796,7 +802,7 @@ static ssize_t ath6kl_endpoint_stats_write(struct file *file, } static const struct file_operations fops_endpoint_stats = { - .open = simple_open, + .open = ath6kl_debugfs_open, .read = ath6kl_endpoint_stats_read, .write = ath6kl_endpoint_stats_write, .owner = THIS_MODULE, @@ -869,7 +875,7 @@ static ssize_t ath6kl_regread_write(struct file *file, static const struct file_operations fops_diag_reg_read = { .read = ath6kl_regread_read, .write = ath6kl_regread_write, - .open = simple_open, + .open = ath6kl_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -993,7 +999,7 @@ static ssize_t ath6kl_lrssi_roam_read(struct file *file, static const struct file_operations fops_lrssi_roam_threshold = { .read = ath6kl_lrssi_roam_read, .write = ath6kl_lrssi_roam_write, - .open = simple_open, + .open = ath6kl_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -1055,7 +1061,7 @@ static ssize_t ath6kl_regwrite_write(struct file *file, static const struct file_operations fops_diag_reg_write = { .read = ath6kl_regwrite_read, .write = ath6kl_regwrite_write, - .open = simple_open, + .open = ath6kl_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -1160,7 +1166,7 @@ static ssize_t ath6kl_roam_table_read(struct file *file, char __user *user_buf, static const struct file_operations fops_roam_table = { .read = ath6kl_roam_table_read, - .open = simple_open, + .open = ath6kl_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -1198,7 +1204,7 @@ static ssize_t ath6kl_force_roam_write(struct file *file, static const struct file_operations fops_force_roam = { .write = ath6kl_force_roam_write, - .open = simple_open, + .open = ath6kl_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -1238,7 +1244,7 @@ static ssize_t ath6kl_roam_mode_write(struct file *file, static const struct file_operations fops_roam_mode = { .write = ath6kl_roam_mode_write, - .open = simple_open, + .open = ath6kl_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -1280,7 +1286,7 @@ static ssize_t ath6kl_keepalive_write(struct file *file, } static const struct file_operations fops_keepalive = { - .open = simple_open, + .open = ath6kl_debugfs_open, .read = ath6kl_keepalive_read, .write = ath6kl_keepalive_write, .owner = THIS_MODULE, @@ -1325,7 +1331,7 @@ static ssize_t ath6kl_disconnect_timeout_write(struct file *file, } static const struct file_operations fops_disconnect_timeout = { - .open = simple_open, + .open = ath6kl_debugfs_open, .read = ath6kl_disconnect_timeout_read, .write = ath6kl_disconnect_timeout_write, .owner = THIS_MODULE, @@ -1506,7 +1512,7 @@ static ssize_t ath6kl_create_qos_write(struct file *file, static const struct file_operations fops_create_qos = { .write = ath6kl_create_qos_write, - .open = simple_open, + .open = ath6kl_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -1554,7 +1560,7 @@ static ssize_t ath6kl_delete_qos_write(struct file *file, static const struct file_operations fops_delete_qos = { .write = ath6kl_delete_qos_write, - .open = simple_open, + .open = ath6kl_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -1587,7 +1593,7 @@ static ssize_t ath6kl_bgscan_int_write(struct file *file, static const struct file_operations fops_bgscan_int = { .write = ath6kl_bgscan_int_write, - .open = simple_open, + .open = ath6kl_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -1645,7 +1651,7 @@ static ssize_t ath6kl_listen_int_read(struct file *file, static const struct file_operations fops_listen_int = { .read = ath6kl_listen_int_read, .write = ath6kl_listen_int_write, - .open = simple_open, + .open = ath6kl_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -1705,7 +1711,7 @@ static ssize_t ath6kl_power_params_write(struct file *file, static const struct file_operations fops_power_params = { .write = ath6kl_power_params_write, - .open = simple_open, + .open = ath6kl_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c index aba088005b22..d7d8e9199140 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -869,7 +869,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, ar5008_hw_set_channel_regs(ah, chan); ar5008_hw_init_chain_masks(ah); ath9k_olc_init(ah); - ath9k_hw_apply_txpower(ah, chan, false); + ath9k_hw_apply_txpower(ah, chan); /* Write analog registers */ if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 3d400e8d6535..59647a3ceb7f 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -54,7 +54,7 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val) if (val) { ah->paprd_table_write_done = true; - ath9k_hw_apply_txpower(ah, chan, false); + ath9k_hw_apply_txpower(ah, chan); } REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0, diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c index deb6cfb2959a..bc992b237ae5 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -694,7 +694,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, ar9003_hw_override_ini(ah); ar9003_hw_set_channel_regs(ah, chan); ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); - ath9k_hw_apply_txpower(ah, chan, false); + ath9k_hw_apply_txpower(ah, chan); if (AR_SREV_9462(ah)) { if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0, diff --git a/trunk/drivers/net/wireless/ath/ath9k/calib.c b/trunk/drivers/net/wireless/ath/ath9k/calib.c index e5cceb077574..2f4b48e6fb03 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/calib.c +++ b/trunk/drivers/net/wireless/ath/ath9k/calib.c @@ -20,6 +20,7 @@ /* Common calibration code */ +#define ATH9K_NF_TOO_HIGH -60 static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer) { @@ -345,10 +346,10 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf) "NF calibrated [%s] [chain %d] is %d\n", (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]); - if (nf[i] > limit->max) { + if (nf[i] > ATH9K_NF_TOO_HIGH) { ath_dbg(common, CALIBRATE, "NF[%d] (%d) > MAX (%d), correcting to MAX\n", - i, nf[i], limit->max); + i, nf[i], ATH9K_NF_TOO_HIGH); nf[i] = limit->max; } else if (nf[i] < limit->min) { ath_dbg(common, CALIBRATE, diff --git a/trunk/drivers/net/wireless/ath/ath9k/debug.c b/trunk/drivers/net/wireless/ath/ath9k/debug.c index ff47b32ecaf4..35d1c8e91d1c 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/debug.c +++ b/trunk/drivers/net/wireless/ath/ath9k/debug.c @@ -26,6 +26,11 @@ #define REG_READ_D(_ah, _reg) \ ath9k_hw_common(_ah)->ops->read((_ah), (_reg)) +static int ath9k_debugfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} static ssize_t ath9k_debugfs_read_buf(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -78,7 +83,7 @@ static ssize_t write_file_debug(struct file *file, const char __user *user_buf, static const struct file_operations fops_debug = { .read = read_file_debug, .write = write_file_debug, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -124,7 +129,7 @@ static ssize_t write_file_tx_chainmask(struct file *file, const char __user *use static const struct file_operations fops_tx_chainmask = { .read = read_file_tx_chainmask, .write = write_file_tx_chainmask, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -167,7 +172,7 @@ static ssize_t write_file_rx_chainmask(struct file *file, const char __user *use static const struct file_operations fops_rx_chainmask = { .read = read_file_rx_chainmask, .write = write_file_rx_chainmask, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -218,7 +223,7 @@ static ssize_t write_file_disable_ani(struct file *file, static const struct file_operations fops_disable_ani = { .read = read_file_disable_ani, .write = write_file_disable_ani, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -319,7 +324,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf, static const struct file_operations fops_dma = { .read = read_file_dma, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -441,7 +446,7 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, static const struct file_operations fops_interrupt = { .read = read_file_interrupt, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -847,28 +852,28 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, static const struct file_operations fops_xmit = { .read = read_file_xmit, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; static const struct file_operations fops_stations = { .read = read_file_stations, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; static const struct file_operations fops_misc = { .read = read_file_misc, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; static const struct file_operations fops_reset = { .read = read_file_reset, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -1011,7 +1016,7 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) static const struct file_operations fops_recv = { .read = read_file_recv, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -1050,7 +1055,7 @@ static ssize_t write_file_regidx(struct file *file, const char __user *user_buf, static const struct file_operations fops_regidx = { .read = read_file_regidx, .write = write_file_regidx, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -1097,7 +1102,7 @@ static ssize_t write_file_regval(struct file *file, const char __user *user_buf, static const struct file_operations fops_regval = { .read = read_file_regval, .write = write_file_regval, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -1186,7 +1191,7 @@ static ssize_t read_file_dump_nfcal(struct file *file, char __user *user_buf, static const struct file_operations fops_dump_nfcal = { .read = read_file_dump_nfcal, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -1214,7 +1219,7 @@ static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, static const struct file_operations fops_base_eeprom = { .read = read_file_base_eeprom, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -1242,7 +1247,7 @@ static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf, static const struct file_operations fops_modal_eeprom = { .read = read_file_modal_eeprom, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; diff --git a/trunk/drivers/net/wireless/ath/ath9k/dfs_debug.c b/trunk/drivers/net/wireless/ath/ath9k/dfs_debug.c index 4364c103ed33..106d031d834a 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/dfs_debug.c +++ b/trunk/drivers/net/wireless/ath/ath9k/dfs_debug.c @@ -60,9 +60,16 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf, return retval; } +static int ath9k_dfs_debugfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + + return 0; +} + static const struct file_operations fops_dfs_stats = { .read = read_file_dfs, - .open = simple_open, + .open = ath9k_dfs_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; diff --git a/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c index b34e8b2990b1..f272236d8053 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -824,8 +824,6 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, regulatory->max_power_level = ratesArray[i]; } - ath9k_hw_update_regulatory_maxpower(ah); - if (test) return; diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index 3035deb7a0cd..d3ff33c71aa5 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -16,6 +16,12 @@ #include "htc.h" +static int ath9k_debugfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -69,7 +75,7 @@ static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf, static const struct file_operations fops_tgt_int_stats = { .read = read_file_tgt_int_stats, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -139,7 +145,7 @@ static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf, static const struct file_operations fops_tgt_tx_stats = { .read = read_file_tgt_tx_stats, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -185,7 +191,7 @@ static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf, static const struct file_operations fops_tgt_rx_stats = { .read = read_file_tgt_rx_stats, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -237,7 +243,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, static const struct file_operations fops_xmit = { .read = read_file_xmit, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -358,7 +364,7 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, static const struct file_operations fops_recv = { .read = read_file_recv, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -393,7 +399,7 @@ static ssize_t read_file_slot(struct file *file, char __user *user_buf, static const struct file_operations fops_slot = { .read = read_file_slot, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -440,7 +446,7 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf, static const struct file_operations fops_queue = { .read = read_file_queue, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -481,7 +487,7 @@ static ssize_t write_file_debug(struct file *file, const char __user *user_buf, static const struct file_operations fops_debug = { .read = read_file_debug, .write = write_file_debug, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -630,7 +636,7 @@ static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, static const struct file_operations fops_base_eeprom = { .read = read_file_base_eeprom, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; @@ -911,7 +917,7 @@ static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf, static const struct file_operations fops_modal_eeprom = { .read = read_file_modal_eeprom, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE, .llseek = default_llseek, }; diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.c b/trunk/drivers/net/wireless/ath/ath9k/hw.c index fa84e37bf091..6c69e4e8b1cb 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.c @@ -1454,7 +1454,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, return false; } ath9k_hw_set_clockrate(ah); - ath9k_hw_apply_txpower(ah, chan, false); + ath9k_hw_apply_txpower(ah, chan); ath9k_hw_rfbus_done(ah); if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) @@ -2652,8 +2652,7 @@ static int get_antenna_gain(struct ath_hw *ah, struct ath9k_channel *chan) return ah->eep_ops->get_eeprom(ah, gain_param); } -void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan, - bool test) +void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan) { struct ath_regulatory *reg = ath9k_hw_regulatory(ah); struct ieee80211_channel *channel; @@ -2674,7 +2673,7 @@ void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan, ah->eep_ops->set_txpower(ah, chan, ath9k_regd_get_ctl(reg, chan), - ant_reduction, new_pwr, test); + ant_reduction, new_pwr, false); } void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) @@ -2687,7 +2686,7 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) if (test) channel->max_power = MAX_RATE_POWER / 2; - ath9k_hw_apply_txpower(ah, chan, test); + ath9k_hw_apply_txpower(ah, chan); if (test) channel->max_power = DIV_ROUND_UP(reg->max_power_level, 2); diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.h b/trunk/drivers/net/wireless/ath/ath9k/hw.h index e88f182ff45c..aa1680a0c7fd 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.h +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.h @@ -985,8 +985,7 @@ void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len); /* PHY */ void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, u32 *coef_mantissa, u32 *coef_exponent); -void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan, - bool test); +void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan); /* * Code Specific to AR5008, AR9001 or AR9002, diff --git a/trunk/drivers/net/wireless/ath/ath9k/init.c b/trunk/drivers/net/wireless/ath/ath9k/init.c index cb006458fc4b..60159f4ee532 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/init.c +++ b/trunk/drivers/net/wireless/ath/ath9k/init.c @@ -680,7 +680,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->queues = 4; hw->max_rates = 4; hw->channel_change_time = 5000; - hw->max_listen_interval = 1; + hw->max_listen_interval = 10; hw->max_rate_tries = 10; hw->sta_data_size = sizeof(struct ath_node); hw->vif_data_size = sizeof(struct ath_vif); diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index 798ea57252b4..38794850f005 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -118,13 +118,15 @@ void ath9k_ps_restore(struct ath_softc *sc) if (--sc->ps_usecount != 0) goto unlock; - if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK)) + if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) + goto unlock; + + if (sc->ps_idle) mode = ATH9K_PM_FULL_SLEEP; else if (sc->ps_enabled && !(sc->ps_flags & (PS_WAIT_FOR_BEACON | PS_WAIT_FOR_CAB | - PS_WAIT_FOR_PSPOLL_DATA | - PS_WAIT_FOR_TX_ACK))) + PS_WAIT_FOR_PSPOLL_DATA))) mode = ATH9K_PM_NETWORK_SLEEP; else goto unlock; @@ -638,7 +640,7 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, an->sta = sta; an->vif = vif; - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { + if (sta->ht_cap.ht_supported) { ath_tx_node_init(sc, an); an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + sta->ht_cap.ampdu_factor); @@ -657,7 +659,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) an->sta = NULL; #endif - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) + if (sta->ht_cap.ht_supported) ath_tx_node_cleanup(sc, an); } @@ -1548,7 +1550,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ieee80211_conf *conf = &hw->conf; - bool reset_channel = false; ath9k_ps_wakeup(sc); mutex_lock(&sc->mutex); @@ -1557,12 +1558,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); if (sc->ps_idle) ath_cancel_work(sc); - else - /* - * The chip needs a reset to properly wake up from - * full sleep - */ - reset_channel = ah->chip_fullsleep; } /* @@ -1591,7 +1586,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) } } - if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) { + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { struct ieee80211_channel *curchan = hw->conf.channel; int pos = curchan->hw_value; int old_pos = -1; diff --git a/trunk/drivers/net/wireless/ath/ath9k/rc.c b/trunk/drivers/net/wireless/ath/ath9k/rc.c index 08bb45532701..4f848493fece 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/rc.c +++ b/trunk/drivers/net/wireless/ath/ath9k/rc.c @@ -1480,6 +1480,12 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, #ifdef CONFIG_ATH9K_DEBUGFS +static int ath9k_debugfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -1547,7 +1553,7 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, static const struct file_operations fops_rcstat = { .read = read_file_rcstat, - .open = simple_open, + .open = ath9k_debugfs_open, .owner = THIS_MODULE }; diff --git a/trunk/drivers/net/wireless/ath/ath9k/recv.c b/trunk/drivers/net/wireless/ath/ath9k/recv.c index 1c4583c7ff7c..f4ae3ba994a8 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/recv.c +++ b/trunk/drivers/net/wireless/ath/ath9k/recv.c @@ -1913,13 +1913,13 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) if (sc->rx.frag) { int space = skb->len - skb_tailroom(hdr_skb); + sc->rx.frag = NULL; + if (pskb_expand_head(hdr_skb, 0, space, GFP_ATOMIC) < 0) { dev_kfree_skb(skb); goto requeue_drop_frag; } - sc->rx.frag = NULL; - skb_copy_from_linear_data(skb, skb_put(hdr_skb, skb->len), skb->len); dev_kfree_skb_any(skb); diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c index 23eaa1b26ebe..834e6bc45e8b 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c @@ -1820,7 +1820,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, struct ath_frame_info *fi = get_frame_info(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ath_buf *bf; - int fragno; u16 seqno; bf = ath_tx_get_buffer(sc); @@ -1832,16 +1831,9 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, ATH_TXBUF_RESET(bf); if (tid) { - fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; seqno = tid->seq_next; hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); - - if (fragno) - hdr->seq_ctrl |= cpu_to_le16(fragno); - - if (!ieee80211_has_morefrags(hdr->frame_control)) - INCR(tid->seq_next, IEEE80211_SEQ_MAX); - + INCR(tid->seq_next, IEEE80211_SEQ_MAX); bf->bf_state.seqno = seqno; } diff --git a/trunk/drivers/net/wireless/ath/carl9170/debug.c b/trunk/drivers/net/wireless/ath/carl9170/debug.c index 93fe6003a493..3c164226687f 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/debug.c +++ b/trunk/drivers/net/wireless/ath/carl9170/debug.c @@ -48,6 +48,11 @@ #define ADD(buf, off, max, fmt, args...) \ off += snprintf(&buf[off], max - off, fmt, ##args); +static int carl9170_debugfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} struct carl9170_debugfs_fops { unsigned int read_bufsize; @@ -173,7 +178,7 @@ static const struct carl9170_debugfs_fops carl_debugfs_##name ##_ops = {\ .attr = _attr, \ .req_dev_state = _dstate, \ .fops = { \ - .open = simple_open, \ + .open = carl9170_debugfs_open, \ .read = carl9170_debugfs_read, \ .write = carl9170_debugfs_write, \ .owner = THIS_MODULE \ diff --git a/trunk/drivers/net/wireless/b43/debugfs.c b/trunk/drivers/net/wireless/b43/debugfs.c index e807bd930647..e751fdee89b2 100644 --- a/trunk/drivers/net/wireless/b43/debugfs.c +++ b/trunk/drivers/net/wireless/b43/debugfs.c @@ -500,6 +500,12 @@ static ssize_t loctls_read_file(struct b43_wldev *dev, #undef fappend +static int b43_debugfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { @@ -618,7 +624,7 @@ static ssize_t b43_debugfs_write(struct file *file, .read = _read, \ .write = _write, \ .fops = { \ - .open = simple_open, \ + .open = b43_debugfs_open, \ .read = b43_debugfs_read, \ .write = b43_debugfs_write, \ .llseek = generic_file_llseek, \ diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index e4d6dc2e37d1..c79e6638c88d 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -4827,14 +4827,8 @@ static int b43_op_start(struct ieee80211_hw *hw) out_mutex_unlock: mutex_unlock(&wl->mutex); - /* - * Configuration may have been overwritten during initialization. - * Reload the configuration, but only if initialization was - * successful. Reloading the configuration after a failed init - * may hang the system. - */ - if (!err) - b43_op_config(hw, ~0); + /* reload configuration */ + b43_op_config(hw, ~0); return err; } diff --git a/trunk/drivers/net/wireless/b43legacy/debugfs.c b/trunk/drivers/net/wireless/b43legacy/debugfs.c index 1965edb765a2..5e28ad0d6d17 100644 --- a/trunk/drivers/net/wireless/b43legacy/debugfs.c +++ b/trunk/drivers/net/wireless/b43legacy/debugfs.c @@ -197,6 +197,12 @@ static int restart_write_file(struct b43legacy_wldev *dev, const char *buf, size #undef fappend +static int b43legacy_debugfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static ssize_t b43legacy_debugfs_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { @@ -325,7 +331,7 @@ static ssize_t b43legacy_debugfs_write(struct file *file, .read = _read, \ .write = _write, \ .fops = { \ - .open = simple_open, \ + .open = b43legacy_debugfs_open, \ .read = b43legacy_debugfs_read, \ .write = b43legacy_debugfs_write, \ .llseek = generic_file_llseek, \ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 758c115b556e..4688904908ec 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -108,15 +108,9 @@ static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev, sdio_release_host(sdfunc); } } else if (regaddr == SDIO_CCCR_ABORT) { - sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), - GFP_KERNEL); - if (!sdfunc) - return -ENOMEM; - sdfunc->num = 0; sdio_claim_host(sdfunc); sdio_writeb(sdfunc, *byte, regaddr, &err_ret); sdio_release_host(sdfunc); - kfree(sdfunc); } else if (regaddr < 0xF0) { brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr); err_ret = -EPERM; @@ -492,7 +486,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, kfree(bus_if); return -ENOMEM; } - sdiodev->func[0] = func; + sdiodev->func[0] = func->card->sdio_func[0]; sdiodev->func[1] = func; sdiodev->bus_if = bus_if; bus_if->bus_priv.sdio = sdiodev; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index eb3829b03cd3..2bf5dda29291 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -574,8 +574,6 @@ struct brcmf_sdio { struct task_struct *dpc_tsk; struct completion dpc_wait; - struct list_head dpc_tsklst; - spinlock_t dpc_tl_lock; struct semaphore sdsem; @@ -2596,58 +2594,29 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) return resched; } -static inline void brcmf_sdbrcm_adddpctsk(struct brcmf_sdio *bus) -{ - struct list_head *new_hd; - unsigned long flags; - - if (in_interrupt()) - new_hd = kzalloc(sizeof(struct list_head), GFP_ATOMIC); - else - new_hd = kzalloc(sizeof(struct list_head), GFP_KERNEL); - if (new_hd == NULL) - return; - - spin_lock_irqsave(&bus->dpc_tl_lock, flags); - list_add_tail(new_hd, &bus->dpc_tsklst); - spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); -} - static int brcmf_sdbrcm_dpc_thread(void *data) { struct brcmf_sdio *bus = (struct brcmf_sdio *) data; - struct list_head *cur_hd, *tmp_hd; - unsigned long flags; allow_signal(SIGTERM); /* Run until signal received */ while (1) { if (kthread_should_stop()) break; - - if (list_empty(&bus->dpc_tsklst)) - if (wait_for_completion_interruptible(&bus->dpc_wait)) - break; - - spin_lock_irqsave(&bus->dpc_tl_lock, flags); - list_for_each_safe(cur_hd, tmp_hd, &bus->dpc_tsklst) { - spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); - - if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) { + if (!wait_for_completion_interruptible(&bus->dpc_wait)) { + /* Call bus dpc unless it indicated down + (then clean stop) */ + if (bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN) { + if (brcmf_sdbrcm_dpc(bus)) + complete(&bus->dpc_wait); + } else { /* after stopping the bus, exit thread */ brcmf_sdbrcm_bus_stop(bus->sdiodev->dev); bus->dpc_tsk = NULL; break; } - - if (brcmf_sdbrcm_dpc(bus)) - brcmf_sdbrcm_adddpctsk(bus); - - spin_lock_irqsave(&bus->dpc_tl_lock, flags); - list_del(cur_hd); - kfree(cur_hd); - } - spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); + } else + break; } return 0; } @@ -2700,10 +2669,8 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) /* Schedule DPC if needed to send queued packet(s) */ if (!bus->dpc_sched) { bus->dpc_sched = true; - if (bus->dpc_tsk) { - brcmf_sdbrcm_adddpctsk(bus); + if (bus->dpc_tsk) complete(&bus->dpc_wait); - } } return ret; @@ -3547,10 +3514,8 @@ void brcmf_sdbrcm_isr(void *arg) brcmf_dbg(ERROR, "isr w/o interrupt configured!\n"); bus->dpc_sched = true; - if (bus->dpc_tsk) { - brcmf_sdbrcm_adddpctsk(bus); + if (bus->dpc_tsk) complete(&bus->dpc_wait); - } } static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) @@ -3594,10 +3559,8 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) bus->ipend = true; bus->dpc_sched = true; - if (bus->dpc_tsk) { - brcmf_sdbrcm_adddpctsk(bus); + if (bus->dpc_tsk) complete(&bus->dpc_wait); - } } } @@ -3934,8 +3897,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) } /* Initialize DPC thread */ init_completion(&bus->dpc_wait); - INIT_LIST_HEAD(&bus->dpc_tsklst); - spin_lock_init(&bus->dpc_tl_lock); bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread, bus, "brcmf_dpc"); if (IS_ERR(bus->dpc_tsk)) { diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c index b4d92792c502..231ddf4a674f 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -847,7 +847,8 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) */ if (!(txs->status & TX_STATUS_AMPDU) && (txs->status & TX_STATUS_INTERMEDIATE)) { - BCMMSG(wlc->wiphy, "INTERMEDIATE but not AMPDU\n"); + wiphy_err(wlc->wiphy, "%s: INTERMEDIATE but not AMPDU\n", + __func__); return false; } @@ -7613,7 +7614,6 @@ brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh, { int len_mpdu; struct ieee80211_rx_status rx_status; - struct ieee80211_hdr *hdr; memset(&rx_status, 0, sizeof(rx_status)); prep_mac80211_status(wlc, rxh, p, &rx_status); @@ -7623,13 +7623,6 @@ brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh, skb_pull(p, D11_PHY_HDR_LEN); __skb_trim(p, len_mpdu); - /* unmute transmit */ - if (wlc->hw->suspended_fifos) { - hdr = (struct ieee80211_hdr *)p->data; - if (ieee80211_is_beacon(hdr->frame_control)) - brcms_b_mute(wlc->hw, false); - } - memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status)); ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); } diff --git a/trunk/drivers/net/wireless/ipw2x00/ipw2200.c b/trunk/drivers/net/wireless/ipw2x00/ipw2200.c index 1779db3aa2b0..4fcdac63a300 100644 --- a/trunk/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/trunk/drivers/net/wireless/ipw2x00/ipw2200.c @@ -2191,7 +2191,6 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) { int rc = 0; unsigned long flags; - unsigned long now, end; spin_lock_irqsave(&priv->lock, flags); if (priv->status & STATUS_HCMD_ACTIVE) { @@ -2233,20 +2232,10 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) } spin_unlock_irqrestore(&priv->lock, flags); - now = jiffies; - end = now + HOST_COMPLETE_TIMEOUT; -again: rc = wait_event_interruptible_timeout(priv->wait_command_queue, !(priv-> status & STATUS_HCMD_ACTIVE), - end - now); - if (rc < 0) { - now = jiffies; - if (time_before(now, end)) - goto again; - rc = 0; - } - + HOST_COMPLETE_TIMEOUT); if (rc == 0) { spin_lock_irqsave(&priv->lock, flags); if (priv->status & STATUS_HCMD_ACTIVE) { @@ -11518,9 +11507,9 @@ static int ipw_wdev_init(struct net_device *dev) rc = -ENOMEM; goto out; } - /* translate geo->a to a_band.channels */ + /* translate geo->bg to a_band.channels */ for (i = 0; i < geo->a_channels; i++) { - a_band->channels[i].band = IEEE80211_BAND_5GHZ; + a_band->channels[i].band = IEEE80211_BAND_2GHZ; a_band->channels[i].center_freq = geo->a[i].freq; a_band->channels[i].hw_value = geo->a[i].channel; a_band->channels[i].max_power = geo->a[i].max_power; diff --git a/trunk/drivers/net/wireless/iwlegacy/3945-mac.c b/trunk/drivers/net/wireless/iwlegacy/3945-mac.c index faec40467208..0c1209390169 100644 --- a/trunk/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/trunk/drivers/net/wireless/iwlegacy/3945-mac.c @@ -2673,6 +2673,8 @@ il3945_bg_restart(struct work_struct *data) if (test_and_clear_bit(S_FW_ERROR, &il->status)) { mutex_lock(&il->mutex); + /* FIXME: vif can be dereferenced */ + il->vif = NULL; il->is_open = 0; mutex_unlock(&il->mutex); il3945_down(il); diff --git a/trunk/drivers/net/wireless/iwlegacy/3945-rs.c b/trunk/drivers/net/wireless/iwlegacy/3945-rs.c index 4b10157d8686..70bee1a4d876 100644 --- a/trunk/drivers/net/wireless/iwlegacy/3945-rs.c +++ b/trunk/drivers/net/wireless/iwlegacy/3945-rs.c @@ -821,6 +821,12 @@ il3945_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta, } #ifdef CONFIG_MAC80211_DEBUGFS +static int +il3945_open_file_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} static ssize_t il3945_sta_dbgfs_stats_table_read(struct file *file, char __user *user_buf, @@ -856,7 +862,7 @@ il3945_sta_dbgfs_stats_table_read(struct file *file, char __user *user_buf, static const struct file_operations rs_sta_dbgfs_stats_table_ops = { .read = il3945_sta_dbgfs_stats_table_read, - .open = simple_open, + .open = il3945_open_file_generic, .llseek = default_llseek, }; diff --git a/trunk/drivers/net/wireless/iwlegacy/4965-mac.c b/trunk/drivers/net/wireless/iwlegacy/4965-mac.c index c46275a92565..17f1c6853182 100644 --- a/trunk/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/trunk/drivers/net/wireless/iwlegacy/4965-mac.c @@ -5652,6 +5652,8 @@ il4965_bg_restart(struct work_struct *data) if (test_and_clear_bit(S_FW_ERROR, &il->status)) { mutex_lock(&il->mutex); + /* FIXME: do we dereference vif without mutex locked ? */ + il->vif = NULL; il->is_open = 0; __il4965_down(il); diff --git a/trunk/drivers/net/wireless/iwlegacy/4965-rs.c b/trunk/drivers/net/wireless/iwlegacy/4965-rs.c index 11ab1247fae1..d7e2856e41d3 100644 --- a/trunk/drivers/net/wireless/iwlegacy/4965-rs.c +++ b/trunk/drivers/net/wireless/iwlegacy/4965-rs.c @@ -2518,6 +2518,12 @@ il4965_rs_free_sta(void *il_r, struct ieee80211_sta *sta, void *il_sta) } #ifdef CONFIG_MAC80211_DEBUGFS +static int +il4965_open_file_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} static void il4965_rs_dbgfs_set_mcs(struct il_lq_sta *lq_sta, u32 * rate_n_flags, int idx) @@ -2689,7 +2695,7 @@ il4965_rs_sta_dbgfs_scale_table_read(struct file *file, char __user *user_buf, static const struct file_operations rs_sta_dbgfs_scale_table_ops = { .write = il4965_rs_sta_dbgfs_scale_table_write, .read = il4965_rs_sta_dbgfs_scale_table_read, - .open = simple_open, + .open = il4965_open_file_generic, .llseek = default_llseek, }; @@ -2734,7 +2740,7 @@ il4965_rs_sta_dbgfs_stats_table_read(struct file *file, char __user *user_buf, static const struct file_operations rs_sta_dbgfs_stats_table_ops = { .read = il4965_rs_sta_dbgfs_stats_table_read, - .open = simple_open, + .open = il4965_open_file_generic, .llseek = default_llseek, }; @@ -2762,7 +2768,7 @@ il4965_rs_sta_dbgfs_rate_scale_data_read(struct file *file, static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = { .read = il4965_rs_sta_dbgfs_rate_scale_data_read, - .open = simple_open, + .open = il4965_open_file_generic, .llseek = default_llseek, }; diff --git a/trunk/drivers/net/wireless/iwlegacy/common.c b/trunk/drivers/net/wireless/iwlegacy/common.c index eaf249452e51..e5ac04739bcc 100644 --- a/trunk/drivers/net/wireless/iwlegacy/common.c +++ b/trunk/drivers/net/wireless/iwlegacy/common.c @@ -4508,7 +4508,6 @@ il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct il_priv *il = hw->priv; int err; - bool reset; mutex_lock(&il->mutex); D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr); @@ -4519,12 +4518,7 @@ il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) goto out; } - /* - * We do not support multiple virtual interfaces, but on hardware reset - * we have to add the same interface again. - */ - reset = (il->vif == vif); - if (il->vif && !reset) { + if (il->vif) { err = -EOPNOTSUPP; goto out; } @@ -4534,11 +4528,8 @@ il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) err = il_set_mode(il); if (err) { - IL_WARN("Fail to set mode %d\n", vif->type); - if (!reset) { - il->vif = NULL; - il->iw_mode = NL80211_IFTYPE_STATION; - } + il->vif = NULL; + il->iw_mode = NL80211_IFTYPE_STATION; } out: @@ -5288,9 +5279,9 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, D_MAC80211("BSSID %pM\n", bss_conf->bssid); /* - * If there is currently a HW scan going on in the background, - * then we need to cancel it, otherwise sometimes we are not - * able to authenticate (FIXME: why ?) + * If there is currently a HW scan going on in the + * background then we need to cancel it else the RXON + * below/in post_associate will fail. */ if (il_scan_cancel_timeout(il, 100)) { D_MAC80211("leave - scan abort failed\n"); @@ -5299,10 +5290,14 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } /* mac80211 only sets assoc when in STATION mode */ - memcpy(il->staging.bssid_addr, bss_conf->bssid, ETH_ALEN); + if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) { + memcpy(il->staging.bssid_addr, bss_conf->bssid, + ETH_ALEN); - /* FIXME: currently needed in a few places */ - memcpy(il->bssid, bss_conf->bssid, ETH_ALEN); + /* currently needed in a few places */ + memcpy(il->bssid, bss_conf->bssid, ETH_ALEN); + } else + il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; } /* diff --git a/trunk/drivers/net/wireless/iwlegacy/debug.c b/trunk/drivers/net/wireless/iwlegacy/debug.c index eff26501d60a..229849150aac 100644 --- a/trunk/drivers/net/wireless/iwlegacy/debug.c +++ b/trunk/drivers/net/wireless/iwlegacy/debug.c @@ -160,12 +160,18 @@ static ssize_t il_dbgfs_##name##_write(struct file *file, \ const char __user *user_buf, \ size_t count, loff_t *ppos); +static int +il_dbgfs_open_file_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} #define DEBUGFS_READ_FILE_OPS(name) \ DEBUGFS_READ_FUNC(name); \ static const struct file_operations il_dbgfs_##name##_ops = { \ .read = il_dbgfs_##name##_read, \ - .open = simple_open, \ + .open = il_dbgfs_open_file_generic, \ .llseek = generic_file_llseek, \ }; @@ -173,7 +179,7 @@ static const struct file_operations il_dbgfs_##name##_ops = { \ DEBUGFS_WRITE_FUNC(name); \ static const struct file_operations il_dbgfs_##name##_ops = { \ .write = il_dbgfs_##name##_write, \ - .open = simple_open, \ + .open = il_dbgfs_open_file_generic, \ .llseek = generic_file_llseek, \ }; @@ -183,7 +189,7 @@ static const struct file_operations il_dbgfs_##name##_ops = { \ static const struct file_operations il_dbgfs_##name##_ops = { \ .write = il_dbgfs_##name##_write, \ .read = il_dbgfs_##name##_read, \ - .open = simple_open, \ + .open = il_dbgfs_open_file_generic, \ .llseek = generic_file_llseek, \ }; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c index 8d80e233bc7a..5b0d888f746b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -46,8 +46,8 @@ #include "iwl-prph.h" /* Highest firmware API version supported */ -#define IWL1000_UCODE_API_MAX 5 -#define IWL100_UCODE_API_MAX 5 +#define IWL1000_UCODE_API_MAX 6 +#define IWL100_UCODE_API_MAX 6 /* Oldest version we won't warn about */ #define IWL1000_UCODE_API_OK 5 @@ -226,5 +226,5 @@ const struct iwl_cfg iwl100_bg_cfg = { IWL_DEVICE_100, }; -MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_OK)); +MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_MAX)); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c index ea108622e0bd..5635b9e2c69e 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -51,10 +51,10 @@ #define IWL135_UCODE_API_MAX 6 /* Oldest version we won't warn about */ -#define IWL2030_UCODE_API_OK 6 -#define IWL2000_UCODE_API_OK 6 -#define IWL105_UCODE_API_OK 6 -#define IWL135_UCODE_API_OK 6 +#define IWL2030_UCODE_API_OK 5 +#define IWL2000_UCODE_API_OK 5 +#define IWL105_UCODE_API_OK 5 +#define IWL135_UCODE_API_OK 5 /* Lowest firmware API version supported */ #define IWL2030_UCODE_API_MIN 5 @@ -328,7 +328,7 @@ const struct iwl_cfg iwl135_bgn_cfg = { .ht_params = &iwl2000_ht_params, }; -MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_OK)); -MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_OK)); -MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_OK)); +MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_MAX)); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c index de0920c74cdd..a805e97b89af 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -51,10 +51,6 @@ #define IWL5000_UCODE_API_MAX 5 #define IWL5150_UCODE_API_MAX 2 -/* Oldest version we won't warn about */ -#define IWL5000_UCODE_API_OK 5 -#define IWL5150_UCODE_API_OK 2 - /* Lowest firmware API version supported */ #define IWL5000_UCODE_API_MIN 1 #define IWL5150_UCODE_API_MIN 1 @@ -330,7 +326,6 @@ static const struct iwl_ht_params iwl5000_ht_params = { #define IWL_DEVICE_5000 \ .fw_name_pre = IWL5000_FW_PRE, \ .ucode_api_max = IWL5000_UCODE_API_MAX, \ - .ucode_api_ok = IWL5000_UCODE_API_OK, \ .ucode_api_min = IWL5000_UCODE_API_MIN, \ .max_inst_size = IWLAGN_RTC_INST_SIZE, \ .max_data_size = IWLAGN_RTC_DATA_SIZE, \ @@ -376,7 +371,6 @@ const struct iwl_cfg iwl5350_agn_cfg = { .name = "Intel(R) WiMAX/WiFi Link 5350 AGN", .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, - .ucode_api_ok = IWL5000_UCODE_API_OK, .ucode_api_min = IWL5000_UCODE_API_MIN, .max_inst_size = IWLAGN_RTC_INST_SIZE, .max_data_size = IWLAGN_RTC_DATA_SIZE, @@ -392,7 +386,6 @@ const struct iwl_cfg iwl5350_agn_cfg = { #define IWL_DEVICE_5150 \ .fw_name_pre = IWL5150_FW_PRE, \ .ucode_api_max = IWL5150_UCODE_API_MAX, \ - .ucode_api_ok = IWL5150_UCODE_API_OK, \ .ucode_api_min = IWL5150_UCODE_API_MIN, \ .max_inst_size = IWLAGN_RTC_INST_SIZE, \ .max_data_size = IWLAGN_RTC_DATA_SIZE, \ @@ -416,5 +409,5 @@ const struct iwl_cfg iwl5150_abg_cfg = { IWL_DEVICE_5150, }; -MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_OK)); +MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX)); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c index f0c91505a7f7..64060cd738b5 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -53,8 +53,6 @@ /* Oldest version we won't warn about */ #define IWL6000_UCODE_API_OK 4 #define IWL6000G2_UCODE_API_OK 5 -#define IWL6050_UCODE_API_OK 5 -#define IWL6000G2B_UCODE_API_OK 6 /* Lowest firmware API version supported */ #define IWL6000_UCODE_API_MIN 4 @@ -390,7 +388,7 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = { #define IWL_DEVICE_6030 \ .fw_name_pre = IWL6030_FW_PRE, \ .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ - .ucode_api_ok = IWL6000G2B_UCODE_API_OK, \ + .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ @@ -559,6 +557,6 @@ const struct iwl_cfg iwl6000_3agn_cfg = { }; MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_OK)); -MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_OK)); -MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2B_UCODE_API_OK)); +MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 7e590b349dd7..53f8c51cfcdb 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -3083,6 +3083,11 @@ static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta, } #ifdef CONFIG_MAC80211_DEBUGFS +static int open_file_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, u32 *rate_n_flags, int index) { @@ -3221,7 +3226,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, static const struct file_operations rs_sta_dbgfs_scale_table_ops = { .write = rs_sta_dbgfs_scale_table_write, .read = rs_sta_dbgfs_scale_table_read, - .open = simple_open, + .open = open_file_generic, .llseek = default_llseek, }; static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file, @@ -3264,7 +3269,7 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file, static const struct file_operations rs_sta_dbgfs_stats_table_ops = { .read = rs_sta_dbgfs_stats_table_read, - .open = simple_open, + .open = open_file_generic, .llseek = default_llseek, }; @@ -3290,7 +3295,7 @@ static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file, static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = { .read = rs_sta_dbgfs_rate_scale_data_read, - .open = simple_open, + .open = open_file_generic, .llseek = default_llseek, }; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c index 2a9a16f901c3..f1226dbf789d 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -863,6 +863,7 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) void iwlagn_prepare_restart(struct iwl_priv *priv) { + struct iwl_rxon_context *ctx; bool bt_full_concurrent; u8 bt_ci_compliance; u8 bt_load; @@ -871,6 +872,8 @@ void iwlagn_prepare_restart(struct iwl_priv *priv) lockdep_assert_held(&priv->mutex); + for_each_context(priv, ctx) + ctx->vif = NULL; priv->is_open = 0; /* diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 2bbaebd99ad4..b7b1c04f2fba 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -84,11 +84,17 @@ static ssize_t iwl_dbgfs_##name##_write(struct file *file, \ size_t count, loff_t *ppos); +static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + #define DEBUGFS_READ_FILE_OPS(name) \ DEBUGFS_READ_FUNC(name); \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .read = iwl_dbgfs_##name##_read, \ - .open = simple_open, \ + .open = iwl_dbgfs_open_file_generic, \ .llseek = generic_file_llseek, \ }; @@ -96,7 +102,7 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ DEBUGFS_WRITE_FUNC(name); \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .write = iwl_dbgfs_##name##_write, \ - .open = simple_open, \ + .open = iwl_dbgfs_open_file_generic, \ .llseek = generic_file_llseek, \ }; @@ -107,7 +113,7 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .write = iwl_dbgfs_##name##_write, \ .read = iwl_dbgfs_##name##_read, \ - .open = simple_open, \ + .open = iwl_dbgfs_open_file_generic, \ .llseek = generic_file_llseek, \ }; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-fh.h b/trunk/drivers/net/wireless/iwlwifi/iwl-fh.h index 74bce97a8600..90208094b8eb 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -104,29 +104,15 @@ * (see struct iwl_tfd_frame). These 16 pointer registers are offset by 0x04 * bytes from one another. Each TFD circular buffer in DRAM must be 256-byte * aligned (address bits 0-7 must be 0). - * Later devices have 20 (5000 series) or 30 (higher) queues, but the registers - * for them are in different places. * * Bit fields in each pointer register: * 27-0: TFD CB physical base address [35:8], must be 256-byte aligned */ -#define FH_MEM_CBBC_0_15_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0x9D0) -#define FH_MEM_CBBC_0_15_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xA10) -#define FH_MEM_CBBC_16_19_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xBF0) -#define FH_MEM_CBBC_16_19_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xC00) -#define FH_MEM_CBBC_20_31_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xB20) -#define FH_MEM_CBBC_20_31_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xB80) - -/* Find TFD CB base pointer for given queue */ -static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) -{ - if (chnl < 16) - return FH_MEM_CBBC_0_15_LOWER_BOUND + 4 * chnl; - if (chnl < 20) - return FH_MEM_CBBC_16_19_LOWER_BOUND + 4 * (chnl - 16); - WARN_ON_ONCE(chnl >= 32); - return FH_MEM_CBBC_20_31_LOWER_BOUND + 4 * (chnl - 20); -} +#define FH_MEM_CBBC_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0x9D0) +#define FH_MEM_CBBC_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xA10) + +/* Find TFD CB base pointer for given queue (range 0-15). */ +#define FH_MEM_CBBC_QUEUE(x) (FH_MEM_CBBC_LOWER_BOUND + (x) * 0x4) /** diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c index c24a7134a6f9..b6805f8e9a01 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -1244,7 +1244,6 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, struct iwl_rxon_context *tmp, *ctx = NULL; int err; enum nl80211_iftype viftype = ieee80211_vif_type_p2p(vif); - bool reset = false; IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", viftype, vif->addr); @@ -1266,13 +1265,6 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, tmp->interface_modes | tmp->exclusive_interface_modes; if (tmp->vif) { - /* On reset we need to add the same interface again */ - if (tmp->vif == vif) { - reset = true; - ctx = tmp; - break; - } - /* check if this busy context is exclusive */ if (tmp->exclusive_interface_modes & BIT(tmp->vif->type)) { @@ -1299,7 +1291,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, ctx->vif = vif; err = iwl_setup_interface(priv, ctx); - if (!err || reset) + if (!err) goto out; ctx->vif = NULL; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-prph.h b/trunk/drivers/net/wireless/iwlwifi/iwl-prph.h index 3b1069290fa9..75dc20bd965b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -223,33 +223,12 @@ #define SCD_AIT (SCD_BASE + 0x0c) #define SCD_TXFACT (SCD_BASE + 0x10) #define SCD_ACTIVE (SCD_BASE + 0x14) +#define SCD_QUEUE_WRPTR(x) (SCD_BASE + 0x18 + (x) * 4) +#define SCD_QUEUE_RDPTR(x) (SCD_BASE + 0x68 + (x) * 4) #define SCD_QUEUECHAIN_SEL (SCD_BASE + 0xe8) #define SCD_AGGR_SEL (SCD_BASE + 0x248) #define SCD_INTERRUPT_MASK (SCD_BASE + 0x108) - -static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl) -{ - if (chnl < 20) - return SCD_BASE + 0x18 + chnl * 4; - WARN_ON_ONCE(chnl >= 32); - return SCD_BASE + 0x284 + (chnl - 20) * 4; -} - -static inline unsigned int SCD_QUEUE_RDPTR(unsigned int chnl) -{ - if (chnl < 20) - return SCD_BASE + 0x68 + chnl * 4; - WARN_ON_ONCE(chnl >= 32); - return SCD_BASE + 0x2B4 + (chnl - 20) * 4; -} - -static inline unsigned int SCD_QUEUE_STATUS_BITS(unsigned int chnl) -{ - if (chnl < 20) - return SCD_BASE + 0x10c + chnl * 4; - WARN_ON_ONCE(chnl >= 32); - return SCD_BASE + 0x384 + (chnl - 20) * 4; -} +#define SCD_QUEUE_STATUS_BITS(x) (SCD_BASE + 0x10c + (x) * 4) /*********************** END TX SCHEDULER *************************************/ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 4d7b30d3e648..b4f796c82e1e 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1898,11 +1898,17 @@ static ssize_t iwl_dbgfs_##name##_write(struct file *file, \ size_t count, loff_t *ppos); +static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + #define DEBUGFS_READ_FILE_OPS(name) \ DEBUGFS_READ_FUNC(name); \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .read = iwl_dbgfs_##name##_read, \ - .open = simple_open, \ + .open = iwl_dbgfs_open_file_generic, \ .llseek = generic_file_llseek, \ }; @@ -1910,7 +1916,7 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ DEBUGFS_WRITE_FUNC(name); \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .write = iwl_dbgfs_##name##_write, \ - .open = simple_open, \ + .open = iwl_dbgfs_open_file_generic, \ .llseek = generic_file_llseek, \ }; @@ -1920,7 +1926,7 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .write = iwl_dbgfs_##name##_write, \ .read = iwl_dbgfs_##name##_read, \ - .open = simple_open, \ + .open = iwl_dbgfs_open_file_generic, \ .llseek = generic_file_llseek, \ }; diff --git a/trunk/drivers/net/wireless/iwmc3200wifi/debugfs.c b/trunk/drivers/net/wireless/iwmc3200wifi/debugfs.c index b6199d124bb9..87eef5773a02 100644 --- a/trunk/drivers/net/wireless/iwmc3200wifi/debugfs.c +++ b/trunk/drivers/net/wireless/iwmc3200wifi/debugfs.c @@ -99,6 +99,12 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_iwm_dbg_modules, iwm_debugfs_u32_read, iwm_debugfs_dbg_modules_write, "%llu\n"); +static int iwm_generic_open(struct inode *inode, struct file *filp) +{ + filp->private_data = inode->i_private; + return 0; +} + static ssize_t iwm_debugfs_txq_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos) @@ -395,28 +401,28 @@ static ssize_t iwm_debugfs_fw_err_read(struct file *filp, static const struct file_operations iwm_debugfs_txq_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = iwm_generic_open, .read = iwm_debugfs_txq_read, .llseek = default_llseek, }; static const struct file_operations iwm_debugfs_tx_credit_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = iwm_generic_open, .read = iwm_debugfs_tx_credit_read, .llseek = default_llseek, }; static const struct file_operations iwm_debugfs_rx_ticket_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = iwm_generic_open, .read = iwm_debugfs_rx_ticket_read, .llseek = default_llseek, }; static const struct file_operations iwm_debugfs_fw_err_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = iwm_generic_open, .read = iwm_debugfs_fw_err_read, .llseek = default_llseek, }; diff --git a/trunk/drivers/net/wireless/iwmc3200wifi/sdio.c b/trunk/drivers/net/wireless/iwmc3200wifi/sdio.c index 0042f204b07f..764b40dd24ad 100644 --- a/trunk/drivers/net/wireless/iwmc3200wifi/sdio.c +++ b/trunk/drivers/net/wireless/iwmc3200wifi/sdio.c @@ -264,6 +264,13 @@ static int if_sdio_send_chunk(struct iwm_priv *iwm, u8 *buf, int count) return ret; } +/* debugfs hooks */ +static int iwm_debugfs_sdio_open(struct inode *inode, struct file *filp) +{ + filp->private_data = inode->i_private; + return 0; +} + static ssize_t iwm_debugfs_sdio_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos) { @@ -356,7 +363,7 @@ static ssize_t iwm_debugfs_sdio_read(struct file *filp, char __user *buffer, static const struct file_operations iwm_debugfs_sdio_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = iwm_debugfs_sdio_open, .read = iwm_debugfs_sdio_read, .llseek = default_llseek, }; diff --git a/trunk/drivers/net/wireless/libertas/cfg.c b/trunk/drivers/net/wireless/libertas/cfg.c index 2fa879b015b6..3fa1ecebadfd 100644 --- a/trunk/drivers/net/wireless/libertas/cfg.c +++ b/trunk/drivers/net/wireless/libertas/cfg.c @@ -103,7 +103,7 @@ static const u32 cipher_suites[] = { * Convert NL80211's auth_type to the one from Libertas, see chapter 5.9.1 * in the firmware spec */ -static int lbs_auth_to_authtype(enum nl80211_auth_type auth_type) +static u8 lbs_auth_to_authtype(enum nl80211_auth_type auth_type) { int ret = -ENOTSUPP; @@ -1411,12 +1411,7 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev, goto done; } - ret = lbs_set_authtype(priv, sme); - if (ret == -ENOTSUPP) { - wiphy_err(wiphy, "unsupported authtype 0x%x\n", sme->auth_type); - goto done; - } - + lbs_set_authtype(priv, sme); lbs_set_radio(priv, preamble, 1); /* Do the actual association */ diff --git a/trunk/drivers/net/wireless/libertas/debugfs.c b/trunk/drivers/net/wireless/libertas/debugfs.c index a06cc283e23d..c192671610fc 100644 --- a/trunk/drivers/net/wireless/libertas/debugfs.c +++ b/trunk/drivers/net/wireless/libertas/debugfs.c @@ -21,6 +21,12 @@ static char *szStates[] = { static void lbs_debug_init(struct lbs_private *priv); #endif +static int open_file_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static ssize_t write_file_dummy(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { @@ -690,7 +696,7 @@ static ssize_t lbs_wrrf_write(struct file *file, #define FOPS(fread, fwrite) { \ .owner = THIS_MODULE, \ - .open = simple_open, \ + .open = open_file_generic, \ .read = (fread), \ .write = (fwrite), \ .llseek = generic_file_llseek, \ @@ -956,7 +962,7 @@ static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf, static const struct file_operations lbs_debug_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = open_file_generic, .write = lbs_debugfs_write, .read = lbs_debugfs_read, .llseek = default_llseek, diff --git a/trunk/drivers/net/wireless/mwifiex/debugfs.c b/trunk/drivers/net/wireless/mwifiex/debugfs.c index 1a845074c52a..d26a78b6b3c4 100644 --- a/trunk/drivers/net/wireless/mwifiex/debugfs.c +++ b/trunk/drivers/net/wireless/mwifiex/debugfs.c @@ -139,6 +139,18 @@ static struct mwifiex_debug_data items[] = { static int num_of_items = ARRAY_SIZE(items); +/* + * Generic proc file open handler. + * + * This function is called every time a file is accessed for read or write. + */ +static int +mwifiex_open_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + /* * Proc info file read handler. * @@ -664,19 +676,19 @@ mwifiex_rdeeprom_read(struct file *file, char __user *ubuf, static const struct file_operations mwifiex_dfs_##name##_fops = { \ .read = mwifiex_##name##_read, \ .write = mwifiex_##name##_write, \ - .open = simple_open, \ + .open = mwifiex_open_generic, \ }; #define MWIFIEX_DFS_FILE_READ_OPS(name) \ static const struct file_operations mwifiex_dfs_##name##_fops = { \ .read = mwifiex_##name##_read, \ - .open = simple_open, \ + .open = mwifiex_open_generic, \ }; #define MWIFIEX_DFS_FILE_WRITE_OPS(name) \ static const struct file_operations mwifiex_dfs_##name##_fops = { \ .write = mwifiex_##name##_write, \ - .open = simple_open, \ + .open = mwifiex_open_generic, \ }; diff --git a/trunk/drivers/net/wireless/mwifiex/pcie.h b/trunk/drivers/net/wireless/mwifiex/pcie.h index 2f218f9a3fd3..445ff21772e2 100644 --- a/trunk/drivers/net/wireless/mwifiex/pcie.h +++ b/trunk/drivers/net/wireless/mwifiex/pcie.h @@ -48,15 +48,15 @@ #define PCIE_HOST_INT_STATUS_MASK 0xC3C #define PCIE_SCRATCH_2_REG 0xC40 #define PCIE_SCRATCH_3_REG 0xC44 -#define PCIE_SCRATCH_4_REG 0xCD0 -#define PCIE_SCRATCH_5_REG 0xCD4 -#define PCIE_SCRATCH_6_REG 0xCD8 -#define PCIE_SCRATCH_7_REG 0xCDC -#define PCIE_SCRATCH_8_REG 0xCE0 -#define PCIE_SCRATCH_9_REG 0xCE4 -#define PCIE_SCRATCH_10_REG 0xCE8 -#define PCIE_SCRATCH_11_REG 0xCEC -#define PCIE_SCRATCH_12_REG 0xCF0 +#define PCIE_SCRATCH_4_REG 0xCC0 +#define PCIE_SCRATCH_5_REG 0xCC4 +#define PCIE_SCRATCH_6_REG 0xCC8 +#define PCIE_SCRATCH_7_REG 0xCCC +#define PCIE_SCRATCH_8_REG 0xCD0 +#define PCIE_SCRATCH_9_REG 0xCD4 +#define PCIE_SCRATCH_10_REG 0xCD8 +#define PCIE_SCRATCH_11_REG 0xCDC +#define PCIE_SCRATCH_12_REG 0xCE0 #define CPU_INTR_DNLD_RDY BIT(0) #define CPU_INTR_DOOR_BELL BIT(1) diff --git a/trunk/drivers/net/wireless/orinoco/main.c b/trunk/drivers/net/wireless/orinoco/main.c index 88e3ad2d1db8..dd6c64ac406e 100644 --- a/trunk/drivers/net/wireless/orinoco/main.c +++ b/trunk/drivers/net/wireless/orinoco/main.c @@ -1336,10 +1336,6 @@ static void qbuf_scan(struct orinoco_private *priv, void *buf, unsigned long flags; sd = kmalloc(sizeof(*sd), GFP_ATOMIC); - if (!sd) { - printk(KERN_ERR "%s: failed to alloc memory\n", __func__); - return; - } sd->buf = buf; sd->len = len; sd->type = type; @@ -1357,10 +1353,6 @@ static void qabort_scan(struct orinoco_private *priv) unsigned long flags; sd = kmalloc(sizeof(*sd), GFP_ATOMIC); - if (!sd) { - printk(KERN_ERR "%s: failed to alloc memory\n", __func__); - return; - } sd->len = -1; /* Abort */ spin_lock_irqsave(&priv->scan_lock, flags); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c index 001735f7a661..cd490abced91 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c @@ -163,13 +163,7 @@ static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, /* Reschedule urb to read TX status again instantly */ return true; - } - - /* Check if there is any entry that timedout waiting on TX status */ - if (rt2800usb_txstatus_timeout(rt2x00dev)) - queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); - - if (rt2800usb_txstatus_pending(rt2x00dev)) { + } else if (rt2800usb_txstatus_pending(rt2x00dev)) { /* Read register after 250 us */ hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 250000), HRTIMER_MODE_REL); @@ -184,7 +178,7 @@ static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, * here again if status reading is needed. */ if (rt2800usb_txstatus_pending(rt2x00dev) && - !test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) + test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) return true; else return false; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c index 90cc5e772650..fc9901e027c1 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1062,6 +1062,11 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) set_bit(DEVICE_STATE_INITIALIZED, &rt2x00dev->flags); + /* + * Register the extra components. + */ + rt2x00rfkill_register(rt2x00dev); + return 0; } @@ -1205,7 +1210,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) rt2x00link_register(rt2x00dev); rt2x00leds_register(rt2x00dev); rt2x00debug_register(rt2x00dev); - rt2x00rfkill_register(rt2x00dev); return 0; diff --git a/trunk/drivers/net/wireless/rtlwifi/base.c b/trunk/drivers/net/wireless/rtlwifi/base.c index e54488db0e10..510023554e5f 100644 --- a/trunk/drivers/net/wireless/rtlwifi/base.c +++ b/trunk/drivers/net/wireless/rtlwifi/base.c @@ -838,10 +838,7 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, __le16 fc = hdr->frame_control; txrate = ieee80211_get_tx_rate(hw, info); - if (txrate) - tcb_desc->hw_rate = txrate->hw_value; - else - tcb_desc->hw_rate = 0; + tcb_desc->hw_rate = txrate->hw_value; if (ieee80211_is_data(fc)) { /* diff --git a/trunk/drivers/net/wireless/rtlwifi/pci.c b/trunk/drivers/net/wireless/rtlwifi/pci.c index cc15fdb36060..07dd38efe62a 100644 --- a/trunk/drivers/net/wireless/rtlwifi/pci.c +++ b/trunk/drivers/net/wireless/rtlwifi/pci.c @@ -912,13 +912,8 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); ring = &rtlpci->tx_ring[BEACON_QUEUE]; pskb = __skb_dequeue(&ring->queue); - if (pskb) { - struct rtl_tx_desc *entry = &ring->desc[ring->idx]; - pci_unmap_single(rtlpci->pdev, rtlpriv->cfg->ops->get_desc( - (u8 *) entry, true, HW_DESC_TXBUFF_ADDR), - pskb->len, PCI_DMA_TODEVICE); + if (pskb) kfree_skb(pskb); - } /*NB: the beacon data buffer must be 32-bit aligned. */ pskb = ieee80211_beacon_get(hw, mac->vif); @@ -1941,7 +1936,6 @@ void rtl_pci_disconnect(struct pci_dev *pdev) rtl_deinit_deferred_work(hw); rtlpriv->intf_ops->adapter_stop(hw); } - rtlpriv->cfg->ops->disable_interrupt(hw); /*deinit rfkill */ rtl_deinit_rfkill(hw); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index 4c016241f340..1eec3a06d1f3 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -1893,7 +1893,7 @@ void rtl92c_phy_set_io(struct ieee80211_hw *hw) break; case IO_CMD_PAUSE_DM_BY_SCAN: rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue; - dm_digtable.cur_igvalue = 0x37; + dm_digtable.cur_igvalue = 0x17; rtl92c_dm_write_dig(hw); break; default: diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 28fc5fb8057b..34591eeb8376 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -3077,7 +3077,7 @@ static void rtl92d_phy_set_io(struct ieee80211_hw *hw) break; case IO_CMD_PAUSE_DM_BY_SCAN: rtlphy->initgain_backup.xaagccore1 = de_digtable.cur_igvalue; - de_digtable.cur_igvalue = 0x37; + de_digtable.cur_igvalue = 0x17; rtl92d_dm_write_dig(hw); break; default: diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index 480862c07f92..4898c502974d 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -91,6 +91,7 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) u8 tid; struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + static int header_print; rtlpriv->dm.dm_initialgain_enable = true; rtlpriv->dm.dm_flag = 0; @@ -170,6 +171,10 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) for (tid = 0; tid < 8; tid++) skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]); + /* Only load firmware for first MAC */ + if (header_print) + return 0; + /* for firmware buf */ rtlpriv->rtlhal.pfirmware = vzalloc(0x8000); if (!rtlpriv->rtlhal.pfirmware) { @@ -181,6 +186,7 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->max_fw_size = 0x8000; pr_info("Driver for Realtek RTL8192DE WLAN interface\n"); pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); + header_print++; /* request fw */ err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, diff --git a/trunk/drivers/net/wireless/rtlwifi/usb.c b/trunk/drivers/net/wireless/rtlwifi/usb.c index d04dbda13f5a..2e1e352864bb 100644 --- a/trunk/drivers/net/wireless/rtlwifi/usb.c +++ b/trunk/drivers/net/wireless/rtlwifi/usb.c @@ -124,38 +124,46 @@ static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request, return status; } -static u32 _usb_read_sync(struct rtl_priv *rtlpriv, u32 addr, u16 len) +static u32 _usb_read_sync(struct usb_device *udev, u32 addr, u16 len) { - struct device *dev = rtlpriv->io.dev; - struct usb_device *udev = to_usb_device(dev); u8 request; u16 wvalue; u16 index; - __le32 *data = &rtlpriv->usb_data[rtlpriv->usb_data_index]; + u32 *data; + u32 ret; + data = kmalloc(sizeof(u32), GFP_KERNEL); + if (!data) + return -ENOMEM; request = REALTEK_USB_VENQT_CMD_REQ; index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */ wvalue = (u16)addr; _usbctrl_vendorreq_sync_read(udev, request, wvalue, index, data, len); - if (++rtlpriv->usb_data_index >= RTL_USB_MAX_RX_COUNT) - rtlpriv->usb_data_index = 0; - return le32_to_cpu(*data); + ret = le32_to_cpu(*data); + kfree(data); + return ret; } static u8 _usb_read8_sync(struct rtl_priv *rtlpriv, u32 addr) { - return (u8)_usb_read_sync(rtlpriv, addr, 1); + struct device *dev = rtlpriv->io.dev; + + return (u8)_usb_read_sync(to_usb_device(dev), addr, 1); } static u16 _usb_read16_sync(struct rtl_priv *rtlpriv, u32 addr) { - return (u16)_usb_read_sync(rtlpriv, addr, 2); + struct device *dev = rtlpriv->io.dev; + + return (u16)_usb_read_sync(to_usb_device(dev), addr, 2); } static u32 _usb_read32_sync(struct rtl_priv *rtlpriv, u32 addr) { - return _usb_read_sync(rtlpriv, addr, 4); + struct device *dev = rtlpriv->io.dev; + + return _usb_read_sync(to_usb_device(dev), addr, 4); } static void _usb_write_async(struct usb_device *udev, u32 addr, u32 val, @@ -947,11 +955,6 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, return -ENOMEM; } rtlpriv = hw->priv; - rtlpriv->usb_data = kzalloc(RTL_USB_MAX_RX_COUNT * sizeof(u32), - GFP_KERNEL); - if (!rtlpriv->usb_data) - return -ENOMEM; - rtlpriv->usb_data_index = 0; init_completion(&rtlpriv->firmware_loading_complete); SET_IEEE80211_DEV(hw, &intf->dev); udev = interface_to_usbdev(intf); @@ -1022,7 +1025,6 @@ void rtl_usb_disconnect(struct usb_interface *intf) /* rtl_deinit_rfkill(hw); */ rtl_usb_deinit(hw); rtl_deinit_core(hw); - kfree(rtlpriv->usb_data); rtlpriv->cfg->ops->deinit_sw_leds(hw); rtlpriv->cfg->ops->deinit_sw_vars(hw); _rtl_usb_io_handler_release(hw); diff --git a/trunk/drivers/net/wireless/rtlwifi/wifi.h b/trunk/drivers/net/wireless/rtlwifi/wifi.h index 28ebc69218a3..b591614c3b9b 100644 --- a/trunk/drivers/net/wireless/rtlwifi/wifi.h +++ b/trunk/drivers/net/wireless/rtlwifi/wifi.h @@ -67,7 +67,7 @@ #define QOS_QUEUE_NUM 4 #define RTL_MAC80211_NUM_QUEUE 5 #define REALTEK_USB_VENQT_MAX_BUF_SIZE 254 -#define RTL_USB_MAX_RX_COUNT 100 + #define QBSS_LOAD_SIZE 5 #define MAX_WMMELE_LENGTH 64 @@ -1629,10 +1629,6 @@ struct rtl_priv { interface or hardware */ unsigned long status; - /* data buffer pointer for USB reads */ - __le32 *usb_data; - int usb_data_index; - /*This must be the last item so that it points to the data allocated beyond this structure like: diff --git a/trunk/drivers/net/wireless/wl1251/debugfs.c b/trunk/drivers/net/wireless/wl1251/debugfs.c index 448da1f8c22f..6c274007d200 100644 --- a/trunk/drivers/net/wireless/wl1251/debugfs.c +++ b/trunk/drivers/net/wireless/wl1251/debugfs.c @@ -47,7 +47,7 @@ static ssize_t name## _read(struct file *file, char __user *userbuf, \ \ static const struct file_operations name## _ops = { \ .read = name## _read, \ - .open = simple_open, \ + .open = wl1251_open_file_generic, \ .llseek = generic_file_llseek, \ }; @@ -84,7 +84,7 @@ static ssize_t sub## _ ##name## _read(struct file *file, \ \ static const struct file_operations sub## _ ##name## _ops = { \ .read = sub## _ ##name## _read, \ - .open = simple_open, \ + .open = wl1251_open_file_generic, \ .llseek = generic_file_llseek, \ }; @@ -117,6 +117,12 @@ static void wl1251_debugfs_update_stats(struct wl1251 *wl) mutex_unlock(&wl->mutex); } +static int wl1251_open_file_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u"); DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u"); @@ -229,7 +235,7 @@ static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf, static const struct file_operations tx_queue_len_ops = { .read = tx_queue_len_read, - .open = simple_open, + .open = wl1251_open_file_generic, .llseek = generic_file_llseek, }; @@ -251,7 +257,7 @@ static ssize_t tx_queue_status_read(struct file *file, char __user *userbuf, static const struct file_operations tx_queue_status_ops = { .read = tx_queue_status_read, - .open = simple_open, + .open = wl1251_open_file_generic, .llseek = generic_file_llseek, }; diff --git a/trunk/drivers/net/wireless/wl1251/main.c b/trunk/drivers/net/wireless/wl1251/main.c index d1afb8e3b2ef..41302c7b1ad0 100644 --- a/trunk/drivers/net/wireless/wl1251/main.c +++ b/trunk/drivers/net/wireless/wl1251/main.c @@ -479,7 +479,6 @@ static void wl1251_op_stop(struct ieee80211_hw *hw) cancel_work_sync(&wl->irq_work); cancel_work_sync(&wl->tx_work); cancel_work_sync(&wl->filter_work); - cancel_delayed_work_sync(&wl->elp_work); mutex_lock(&wl->mutex); diff --git a/trunk/drivers/net/wireless/wl1251/sdio.c b/trunk/drivers/net/wireless/wl1251/sdio.c index 1b851f650e07..f78694295c39 100644 --- a/trunk/drivers/net/wireless/wl1251/sdio.c +++ b/trunk/drivers/net/wireless/wl1251/sdio.c @@ -315,8 +315,8 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func) if (wl->irq) free_irq(wl->irq, wl); - wl1251_free_hw(wl); kfree(wl_sdio); + wl1251_free_hw(wl); sdio_claim_host(func); sdio_release_irq(func); diff --git a/trunk/drivers/net/wireless/wl12xx/debugfs.c b/trunk/drivers/net/wireless/wl12xx/debugfs.c index 564d49575c94..e1cf72765965 100644 --- a/trunk/drivers/net/wireless/wl12xx/debugfs.c +++ b/trunk/drivers/net/wireless/wl12xx/debugfs.c @@ -63,7 +63,7 @@ static ssize_t name## _read(struct file *file, char __user *userbuf, \ \ static const struct file_operations name## _ops = { \ .read = name## _read, \ - .open = simple_open, \ + .open = wl1271_open_file_generic, \ .llseek = generic_file_llseek, \ }; @@ -96,7 +96,7 @@ static ssize_t sub## _ ##name## _read(struct file *file, \ \ static const struct file_operations sub## _ ##name## _ops = { \ .read = sub## _ ##name## _read, \ - .open = simple_open, \ + .open = wl1271_open_file_generic, \ .llseek = generic_file_llseek, \ }; @@ -126,6 +126,12 @@ static void wl1271_debugfs_update_stats(struct wl1271 *wl) mutex_unlock(&wl->mutex); } +static int wl1271_open_file_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, "%u"); DEBUGFS_FWSTATS_FILE(rx, out_of_mem, "%u"); @@ -237,7 +243,7 @@ static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf, static const struct file_operations tx_queue_len_ops = { .read = tx_queue_len_read, - .open = simple_open, + .open = wl1271_open_file_generic, .llseek = default_llseek, }; @@ -283,7 +289,7 @@ static ssize_t gpio_power_write(struct file *file, static const struct file_operations gpio_power_ops = { .read = gpio_power_read, .write = gpio_power_write, - .open = simple_open, + .open = wl1271_open_file_generic, .llseek = default_llseek, }; @@ -302,7 +308,7 @@ static ssize_t start_recovery_write(struct file *file, static const struct file_operations start_recovery_ops = { .write = start_recovery_write, - .open = simple_open, + .open = wl1271_open_file_generic, .llseek = default_llseek, }; @@ -366,7 +372,7 @@ static ssize_t dynamic_ps_timeout_write(struct file *file, static const struct file_operations dynamic_ps_timeout_ops = { .read = dynamic_ps_timeout_read, .write = dynamic_ps_timeout_write, - .open = simple_open, + .open = wl1271_open_file_generic, .llseek = default_llseek, }; @@ -435,7 +441,7 @@ static ssize_t forced_ps_write(struct file *file, static const struct file_operations forced_ps_ops = { .read = forced_ps_read, .write = forced_ps_write, - .open = simple_open, + .open = wl1271_open_file_generic, .llseek = default_llseek, }; @@ -477,7 +483,7 @@ static ssize_t split_scan_timeout_write(struct file *file, static const struct file_operations split_scan_timeout_ops = { .read = split_scan_timeout_read, .write = split_scan_timeout_write, - .open = simple_open, + .open = wl1271_open_file_generic, .llseek = default_llseek, }; @@ -560,7 +566,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf, static const struct file_operations driver_state_ops = { .read = driver_state_read, - .open = simple_open, + .open = wl1271_open_file_generic, .llseek = default_llseek, }; @@ -669,7 +675,7 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf, static const struct file_operations vifs_state_ops = { .read = vifs_state_read, - .open = simple_open, + .open = wl1271_open_file_generic, .llseek = default_llseek, }; @@ -727,7 +733,7 @@ static ssize_t dtim_interval_write(struct file *file, static const struct file_operations dtim_interval_ops = { .read = dtim_interval_read, .write = dtim_interval_write, - .open = simple_open, + .open = wl1271_open_file_generic, .llseek = default_llseek, }; @@ -785,7 +791,7 @@ static ssize_t suspend_dtim_interval_write(struct file *file, static const struct file_operations suspend_dtim_interval_ops = { .read = suspend_dtim_interval_read, .write = suspend_dtim_interval_write, - .open = simple_open, + .open = wl1271_open_file_generic, .llseek = default_llseek, }; @@ -843,7 +849,7 @@ static ssize_t beacon_interval_write(struct file *file, static const struct file_operations beacon_interval_ops = { .read = beacon_interval_read, .write = beacon_interval_write, - .open = simple_open, + .open = wl1271_open_file_generic, .llseek = default_llseek, }; @@ -898,7 +904,7 @@ static ssize_t rx_streaming_interval_read(struct file *file, static const struct file_operations rx_streaming_interval_ops = { .read = rx_streaming_interval_read, .write = rx_streaming_interval_write, - .open = simple_open, + .open = wl1271_open_file_generic, .llseek = default_llseek, }; @@ -953,7 +959,7 @@ static ssize_t rx_streaming_always_read(struct file *file, static const struct file_operations rx_streaming_always_ops = { .read = rx_streaming_always_read, .write = rx_streaming_always_write, - .open = simple_open, + .open = wl1271_open_file_generic, .llseek = default_llseek, }; @@ -997,7 +1003,7 @@ static ssize_t beacon_filtering_write(struct file *file, static const struct file_operations beacon_filtering_ops = { .write = beacon_filtering_write, - .open = simple_open, + .open = wl1271_open_file_generic, .llseek = default_llseek, }; diff --git a/trunk/drivers/net/xen-netfront.c b/trunk/drivers/net/xen-netfront.c index 0ebbb1906c30..663b32c2e931 100644 --- a/trunk/drivers/net/xen-netfront.c +++ b/trunk/drivers/net/xen-netfront.c @@ -1965,7 +1965,7 @@ static int __init netif_init(void) if (xen_initial_domain()) return 0; - if (xen_hvm_domain() && !xen_platform_pci_unplug) + if (!xen_platform_pci_unplug) return -ENODEV; printk(KERN_INFO "Initialising Xen virtual ethernet driver.\n"); diff --git a/trunk/drivers/of/gpio.c b/trunk/drivers/of/gpio.c index bf984b6dc477..bba81216b4db 100644 --- a/trunk/drivers/of/gpio.c +++ b/trunk/drivers/of/gpio.c @@ -140,7 +140,7 @@ int of_gpio_simple_xlate(struct gpio_chip *gc, if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells)) return -EINVAL; - if (gpiospec->args[0] >= gc->ngpio) + if (gpiospec->args[0] > gc->ngpio) return -EINVAL; if (flags) diff --git a/trunk/drivers/oprofile/oprofilefs.c b/trunk/drivers/oprofile/oprofilefs.c index 849357c1045c..ee8fd037bb53 100644 --- a/trunk/drivers/oprofile/oprofilefs.c +++ b/trunk/drivers/oprofile/oprofilefs.c @@ -117,17 +117,25 @@ static ssize_t ulong_write_file(struct file *file, char const __user *buf, size_ } +static int default_open(struct inode *inode, struct file *filp) +{ + if (inode->i_private) + filp->private_data = inode->i_private; + return 0; +} + + static const struct file_operations ulong_fops = { .read = ulong_read_file, .write = ulong_write_file, - .open = simple_open, + .open = default_open, .llseek = default_llseek, }; static const struct file_operations ulong_ro_fops = { .read = ulong_read_file, - .open = simple_open, + .open = default_open, .llseek = default_llseek, }; @@ -179,7 +187,7 @@ static ssize_t atomic_read_file(struct file *file, char __user *buf, size_t coun static const struct file_operations atomic_ro_fops = { .read = atomic_read_file, - .open = simple_open, + .open = default_open, .llseek = default_llseek, }; diff --git a/trunk/drivers/pci/Makefile b/trunk/drivers/pci/Makefile index 165274c064bc..083a49fee56a 100644 --- a/trunk/drivers/pci/Makefile +++ b/trunk/drivers/pci/Makefile @@ -42,7 +42,6 @@ obj-$(CONFIG_UNICORE32) += setup-bus.o setup-irq.o obj-$(CONFIG_PARISC) += setup-bus.o obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o obj-$(CONFIG_PPC) += setup-bus.o -obj-$(CONFIG_FRV) += setup-bus.o obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o obj-$(CONFIG_X86_VISWS) += setup-irq.o obj-$(CONFIG_MN10300) += setup-bus.o diff --git a/trunk/drivers/pci/pci-acpi.c b/trunk/drivers/pci/pci-acpi.c index 1929c0c63b75..060fd22a1103 100644 --- a/trunk/drivers/pci/pci-acpi.c +++ b/trunk/drivers/pci/pci-acpi.c @@ -200,7 +200,7 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) return PCI_D1; case ACPI_STATE_D2: return PCI_D2; - case ACPI_STATE_D3_HOT: + case ACPI_STATE_D3: return PCI_D3hot; case ACPI_STATE_D3_COLD: return PCI_D3cold; @@ -223,7 +223,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) [PCI_D0] = ACPI_STATE_D0, [PCI_D1] = ACPI_STATE_D1, [PCI_D2] = ACPI_STATE_D2, - [PCI_D3hot] = ACPI_STATE_D3_HOT, + [PCI_D3hot] = ACPI_STATE_D3, [PCI_D3cold] = ACPI_STATE_D3 }; int error = -EINVAL; @@ -277,6 +277,40 @@ static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable) return 0; } +/** + * acpi_dev_run_wake - Enable/disable wake-up for given device. + * @phys_dev: Device to enable/disable the platform to wake-up the system for. + * @enable: Whether enable or disable the wake-up functionality. + * + * Find the ACPI device object corresponding to @pci_dev and try to + * enable/disable the GPE associated with it. + */ +static int acpi_dev_run_wake(struct device *phys_dev, bool enable) +{ + struct acpi_device *dev; + acpi_handle handle; + + if (!device_run_wake(phys_dev)) + return -EINVAL; + + handle = DEVICE_ACPI_HANDLE(phys_dev); + if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) { + dev_dbg(phys_dev, "ACPI handle has no context in %s!\n", + __func__); + return -ENODEV; + } + + if (enable) { + acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0); + acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); + } else { + acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); + acpi_disable_wakeup_device_power(dev); + } + + return 0; +} + static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable) { while (bus->parent) { @@ -284,14 +318,14 @@ static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable) if (bridge->pme_interrupt) return; - if (!acpi_pm_device_run_wake(&bridge->dev, enable)) + if (!acpi_dev_run_wake(&bridge->dev, enable)) return; bus = bus->parent; } /* We have reached the root bus. */ if (bus->bridge) - acpi_pm_device_run_wake(bus->bridge, enable); + acpi_dev_run_wake(bus->bridge, enable); } static int acpi_pci_run_wake(struct pci_dev *dev, bool enable) @@ -299,7 +333,7 @@ static int acpi_pci_run_wake(struct pci_dev *dev, bool enable) if (dev->pme_interrupt) return 0; - if (!acpi_pm_device_run_wake(&dev->dev, enable)) + if (!acpi_dev_run_wake(&dev->dev, enable)) return 0; acpi_pci_propagate_run_wake(dev->bus, enable); diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index 111569ccab43..815674415267 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -967,59 +967,16 @@ pci_save_state(struct pci_dev *dev) return 0; } -static void pci_restore_config_dword(struct pci_dev *pdev, int offset, - u32 saved_val, int retry) -{ - u32 val; - - pci_read_config_dword(pdev, offset, &val); - if (val == saved_val) - return; - - for (;;) { - dev_dbg(&pdev->dev, "restoring config space at offset " - "%#x (was %#x, writing %#x)\n", offset, val, saved_val); - pci_write_config_dword(pdev, offset, saved_val); - if (retry-- <= 0) - return; - - pci_read_config_dword(pdev, offset, &val); - if (val == saved_val) - return; - - mdelay(1); - } -} - -static void pci_restore_config_space_range(struct pci_dev *pdev, - int start, int end, int retry) -{ - int index; - - for (index = end; index >= start; index--) - pci_restore_config_dword(pdev, 4 * index, - pdev->saved_config_space[index], - retry); -} - -static void pci_restore_config_space(struct pci_dev *pdev) -{ - if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL) { - pci_restore_config_space_range(pdev, 10, 15, 0); - /* Restore BARs before the command register. */ - pci_restore_config_space_range(pdev, 4, 9, 10); - pci_restore_config_space_range(pdev, 0, 3, 0); - } else { - pci_restore_config_space_range(pdev, 0, 15, 0); - } -} - /** * pci_restore_state - Restore the saved state of a PCI device * @dev: - PCI device that we're dealing with */ void pci_restore_state(struct pci_dev *dev) { + int i; + u32 val; + int tries; + if (!dev->state_saved) return; @@ -1027,8 +984,24 @@ void pci_restore_state(struct pci_dev *dev) pci_restore_pcie_state(dev); pci_restore_ats_state(dev); - pci_restore_config_space(dev); - + /* + * The Base Address register should be programmed before the command + * register(s) + */ + for (i = 15; i >= 0; i--) { + pci_read_config_dword(dev, i * 4, &val); + tries = 10; + while (tries && val != dev->saved_config_space[i]) { + dev_dbg(&dev->dev, "restoring config " + "space at offset %#x (was %#x, writing %#x)\n", + i, val, (int)dev->saved_config_space[i]); + pci_write_config_dword(dev,i * 4, + dev->saved_config_space[i]); + pci_read_config_dword(dev, i * 4, &val); + mdelay(10); + tries--; + } + } pci_restore_pcix_state(dev); pci_restore_msi_state(dev); pci_restore_iov_state(dev); diff --git a/trunk/drivers/pci/pcie/aspm.c b/trunk/drivers/pci/pcie/aspm.c index b500840a143b..4bdef24cd412 100644 --- a/trunk/drivers/pci/pcie/aspm.c +++ b/trunk/drivers/pci/pcie/aspm.c @@ -508,6 +508,9 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) int pos; u32 reg32; + if (aspm_disabled) + return 0; + /* * Some functions in a slot might not all be PCIe functions, * very strange. Disable ASPM for the whole slot @@ -516,16 +519,6 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) pos = pci_pcie_cap(child); if (!pos) return -EINVAL; - - /* - * If ASPM is disabled then we're not going to change - * the BIOS state. It's safe to continue even if it's a - * pre-1.1 device - */ - - if (aspm_disabled) - continue; - /* * Disable ASPM for pre-1.1 PCIe device, we follow MS to use * RBER bit to determine if a function is 1.1 version device diff --git a/trunk/drivers/pci/xen-pcifront.c b/trunk/drivers/pci/xen-pcifront.c index d6cc62cb4cf7..fd00ff02ab4d 100644 --- a/trunk/drivers/pci/xen-pcifront.c +++ b/trunk/drivers/pci/xen-pcifront.c @@ -290,7 +290,6 @@ static int pci_frontend_enable_msix(struct pci_dev *dev, } else { printk(KERN_DEBUG "enable msix get value %x\n", op.value); - err = op.value; } } else { dev_err(&dev->dev, "enable msix get err %x\n", err); diff --git a/trunk/drivers/pinctrl/core.c b/trunk/drivers/pinctrl/core.c index df6296c5f47b..ec3b8cc188af 100644 --- a/trunk/drivers/pinctrl/core.c +++ b/trunk/drivers/pinctrl/core.c @@ -908,6 +908,10 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) const struct pinctrl_ops *ops = pctldev->desc->pctlops; unsigned selector = 0; + /* No grouping */ + if (!ops) + return 0; + mutex_lock(&pinctrl_mutex); seq_puts(s, "registered pin groups:\n"); @@ -1221,19 +1225,6 @@ static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev) #endif -static int pinctrl_check_ops(struct pinctrl_dev *pctldev) -{ - const struct pinctrl_ops *ops = pctldev->desc->pctlops; - - if (!ops || - !ops->list_groups || - !ops->get_group_name || - !ops->get_group_pins) - return -EINVAL; - - return 0; -} - /** * pinctrl_register() - register a pin controller device * @pctldesc: descriptor for this pin controller @@ -1265,14 +1256,6 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, INIT_LIST_HEAD(&pctldev->gpio_ranges); pctldev->dev = dev; - /* check core ops for sanity */ - ret = pinctrl_check_ops(pctldev); - if (ret) { - pr_err("%s pinctrl ops lacks necessary functions\n", - pctldesc->name); - goto out_err; - } - /* If we're implementing pinmuxing, check the ops for sanity */ if (pctldesc->pmxops) { ret = pinmux_check_ops(pctldev); diff --git a/trunk/drivers/platform/x86/acerhdf.c b/trunk/drivers/platform/x86/acerhdf.c index 639db4d0aa76..bc8384c6f3eb 100644 --- a/trunk/drivers/platform/x86/acerhdf.c +++ b/trunk/drivers/platform/x86/acerhdf.c @@ -50,7 +50,7 @@ */ #undef START_IN_KERNEL_MODE -#define DRV_VER "0.5.26" +#define DRV_VER "0.5.24" /* * According to the Atom N270 datasheet, @@ -83,8 +83,8 @@ static int kernelmode; #endif static unsigned int interval = 10; -static unsigned int fanon = 60000; -static unsigned int fanoff = 53000; +static unsigned int fanon = 63000; +static unsigned int fanoff = 58000; static unsigned int verbose; static unsigned int fanstate = ACERHDF_FAN_AUTO; static char force_bios[16]; @@ -150,8 +150,6 @@ static const struct bios_settings_t bios_tbl[] = { {"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x00} }, {"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x00} }, {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x00} }, - /* LT1005u */ - {"Acer", "LT-10Q", "v0.3310", 0x55, 0x58, {0x20, 0x00} }, /* Acer 1410 */ {"Acer", "Aspire 1410", "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, {"Acer", "Aspire 1410", "v0.3113", 0x55, 0x58, {0x9e, 0x00} }, @@ -163,7 +161,6 @@ static const struct bios_settings_t bios_tbl[] = { {"Acer", "Aspire 1410", "v1.3303", 0x55, 0x58, {0x9e, 0x00} }, {"Acer", "Aspire 1410", "v1.3308", 0x55, 0x58, {0x9e, 0x00} }, {"Acer", "Aspire 1410", "v1.3310", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1410", "v1.3314", 0x55, 0x58, {0x9e, 0x00} }, /* Acer 1810xx */ {"Acer", "Aspire 1810TZ", "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, {"Acer", "Aspire 1810T", "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, @@ -186,44 +183,29 @@ static const struct bios_settings_t bios_tbl[] = { {"Acer", "Aspire 1810TZ", "v1.3310", 0x55, 0x58, {0x9e, 0x00} }, {"Acer", "Aspire 1810T", "v1.3310", 0x55, 0x58, {0x9e, 0x00} }, {"Acer", "Aspire 1810TZ", "v1.3314", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810T", "v1.3314", 0x55, 0x58, {0x9e, 0x00} }, /* Acer 531 */ - {"Acer", "AO531h", "v0.3104", 0x55, 0x58, {0x20, 0x00} }, {"Acer", "AO531h", "v0.3201", 0x55, 0x58, {0x20, 0x00} }, - {"Acer", "AO531h", "v0.3304", 0x55, 0x58, {0x20, 0x00} }, - /* Acer 751 */ - {"Acer", "AO751h", "V0.3212", 0x55, 0x58, {0x21, 0x00} }, - /* Acer 1825 */ - {"Acer", "Aspire 1825PTZ", "V1.3118", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1825PTZ", "V1.3127", 0x55, 0x58, {0x9e, 0x00} }, - /* Acer TravelMate 7730 */ - {"Acer", "TravelMate 7730G", "v0.3509", 0x55, 0x58, {0xaf, 0x00} }, /* Gateway */ - {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00} }, - {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00} }, - {"Gateway", "LT31", "v1.3103", 0x55, 0x58, {0x9e, 0x00} }, - {"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x9e, 0x00} }, - {"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x9e, 0x00} }, - {"Gateway", "LT31", "v1.3303t", 0x55, 0x58, {0x9e, 0x00} }, + {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00} }, + {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00} }, + {"Gateway", "LT31", "v1.3103", 0x55, 0x58, {0x9e, 0x00} }, + {"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x9e, 0x00} }, + {"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x9e, 0x00} }, /* Packard Bell */ - {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00} }, - {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} }, - {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00} }, - {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} }, - {"Packard Bell", "ENBFT", "V1.3118", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "ENBFT", "V1.3127", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v1.3303", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3120", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3113", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3115", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3117", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3119", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v1.3204", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMA", "v1.3201", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMA", "v1.3302", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMA", "v1.3303t", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTVR46", "v1.3308", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00} }, + {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} }, + {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00} }, + {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} }, + {"Packard Bell", "DOTMU", "v1.3303", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMU", "v0.3120", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMU", "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMU", "v0.3113", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMU", "v0.3115", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMU", "v0.3117", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMU", "v0.3119", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMU", "v1.3204", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMA", "v1.3201", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMA", "v1.3302", 0x55, 0x58, {0x9e, 0x00} }, /* pewpew-terminator */ {"", "", "", 0, 0, {0, 0} } }; @@ -719,20 +701,15 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Peter Feuerer"); MODULE_DESCRIPTION("Aspire One temperature and fan driver"); MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:"); -MODULE_ALIAS("dmi:*:*Acer*:pnAO751h*:"); MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1410*:"); MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1810*:"); -MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1825PTZ:"); MODULE_ALIAS("dmi:*:*Acer*:pnAO531*:"); -MODULE_ALIAS("dmi:*:*Acer*:TravelMate*7730G:"); MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:"); MODULE_ALIAS("dmi:*:*Gateway*:pnLT31*:"); MODULE_ALIAS("dmi:*:*Packard*Bell*:pnAOA*:"); MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOA*:"); MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMU*:"); -MODULE_ALIAS("dmi:*:*Packard*Bell*:pnENBFT*:"); MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMA*:"); -MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTVR46*:"); module_init(acerhdf_init); module_exit(acerhdf_exit); diff --git a/trunk/drivers/platform/x86/dell-laptop.c b/trunk/drivers/platform/x86/dell-laptop.c index e6c08ee8d46c..a05fc9c955d8 100644 --- a/trunk/drivers/platform/x86/dell-laptop.c +++ b/trunk/drivers/platform/x86/dell-laptop.c @@ -212,7 +212,6 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { }, .driver_data = &quirk_dell_vostro_v130, }, - { } }; static struct calling_interface_buffer *buffer; diff --git a/trunk/drivers/platform/x86/intel_ips.c b/trunk/drivers/platform/x86/intel_ips.c index 0ffdb3cde2bb..88a98cff5a44 100644 --- a/trunk/drivers/platform/x86/intel_ips.c +++ b/trunk/drivers/platform/x86/intel_ips.c @@ -609,16 +609,25 @@ static bool mcp_exceeded(struct ips_driver *ips) bool ret = false; u32 temp_limit; u32 avg_power; + const char *msg = "MCP limit exceeded: "; spin_lock_irqsave(&ips->turbo_status_lock, flags); temp_limit = ips->mcp_temp_limit * 100; - if (ips->mcp_avg_temp > temp_limit) + if (ips->mcp_avg_temp > temp_limit) { + dev_info(&ips->dev->dev, + "%sAvg temp %u, limit %u\n", msg, ips->mcp_avg_temp, + temp_limit); ret = true; + } avg_power = ips->cpu_avg_power + ips->mch_avg_power; - if (avg_power > ips->mcp_power_limit) + if (avg_power > ips->mcp_power_limit) { + dev_info(&ips->dev->dev, + "%sAvg power %u, limit %u\n", msg, avg_power, + ips->mcp_power_limit); ret = true; + } spin_unlock_irqrestore(&ips->turbo_status_lock, flags); @@ -1565,7 +1574,7 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) ips->poll_turbo_status = true; if (!ips_get_i915_syms(ips)) { - dev_info(&dev->dev, "failed to get i915 symbols, graphics turbo disabled until i915 loads\n"); + dev_err(&dev->dev, "failed to get i915 symbols, graphics turbo disabled\n"); ips->gpu_turbo_enabled = false; } else { dev_dbg(&dev->dev, "graphics turbo enabled\n"); diff --git a/trunk/drivers/platform/x86/intel_mid_powerbtn.c b/trunk/drivers/platform/x86/intel_mid_powerbtn.c index bcbad8452a6f..0a3594c7e912 100644 --- a/trunk/drivers/platform/x86/intel_mid_powerbtn.c +++ b/trunk/drivers/platform/x86/intel_mid_powerbtn.c @@ -78,7 +78,7 @@ static int __devinit mfld_pb_probe(struct platform_device *pdev) input_set_capability(input, EV_KEY, KEY_POWER); - error = request_threaded_irq(irq, NULL, mfld_pb_isr, IRQF_NO_SUSPEND, + error = request_threaded_irq(irq, NULL, mfld_pb_isr, 0, DRIVER_NAME, input); if (error) { dev_err(&pdev->dev, "Unable to request irq %d for mfld power" diff --git a/trunk/drivers/pnp/pnpacpi/core.c b/trunk/drivers/pnp/pnpacpi/core.c index d21e8f59c84e..b00c17612a89 100644 --- a/trunk/drivers/pnp/pnpacpi/core.c +++ b/trunk/drivers/pnp/pnpacpi/core.c @@ -321,14 +321,9 @@ static int __init acpi_pnp_match(struct device *dev, void *_pnp) { struct acpi_device *acpi = to_acpi_device(dev); struct pnp_dev *pnp = _pnp; - struct device *physical_device; - - physical_device = acpi_get_physical_device(acpi->handle); - if (physical_device) - put_device(physical_device); /* true means it matched */ - return !physical_device + return !acpi_get_physical_device(acpi->handle) && compare_pnp_id(pnp->id, acpi_device_hid(acpi)); } diff --git a/trunk/drivers/power/Kconfig b/trunk/drivers/power/Kconfig index 99dc29f2f2f2..459f66437fe9 100644 --- a/trunk/drivers/power/Kconfig +++ b/trunk/drivers/power/Kconfig @@ -249,7 +249,7 @@ config CHARGER_TWL4030 Say Y here to enable support for TWL4030 Battery Charge Interface. config CHARGER_LP8727 - tristate "TI/National Semiconductor LP8727 charger driver" + tristate "National Semiconductor LP8727 charger driver" depends on I2C help Say Y here to enable support for LP8727 Charger Driver. @@ -288,23 +288,4 @@ config CHARGER_MAX8998 Say Y to enable support for the battery charger control sysfs and platform data of MAX8998/LP3974 PMICs. -config CHARGER_SMB347 - tristate "Summit Microelectronics SMB347 Battery Charger" - depends on I2C - help - Say Y to include support for Summit Microelectronics SMB347 - Battery Charger. - -config AB8500_BM - bool "AB8500 Battery Management Driver" - depends on AB8500_CORE && AB8500_GPADC - help - Say Y to include support for AB5500 battery management. - -config AB8500_BATTERY_THERM_ON_BATCTRL - bool "Thermistor connected on BATCTRL ADC" - depends on AB8500_BM - help - Say Y to enable battery temperature measurements using - thermistor connected on BATCTRL ADC. endif # POWER_SUPPLY diff --git a/trunk/drivers/power/Makefile b/trunk/drivers/power/Makefile index b6b243416c0e..c590fa533406 100644 --- a/trunk/drivers/power/Makefile +++ b/trunk/drivers/power/Makefile @@ -34,7 +34,6 @@ obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o -obj-$(CONFIG_AB8500_BM) += ab8500_charger.o ab8500_btemp.o ab8500_fg.o abx500_chargalg.o obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o @@ -43,4 +42,3 @@ obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o -obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o diff --git a/trunk/drivers/power/ab8500_btemp.c b/trunk/drivers/power/ab8500_btemp.c deleted file mode 100644 index d8bb99394ac0..000000000000 --- a/trunk/drivers/power/ab8500_btemp.c +++ /dev/null @@ -1,1124 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2012 - * - * Battery temperature driver for AB8500 - * - * License Terms: GNU General Public License v2 - * Author: - * Johan Palsson - * Karl Komierowski - * Arun R Murthy - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define VTVOUT_V 1800 - -#define BTEMP_THERMAL_LOW_LIMIT -10 -#define BTEMP_THERMAL_MED_LIMIT 0 -#define BTEMP_THERMAL_HIGH_LIMIT_52 52 -#define BTEMP_THERMAL_HIGH_LIMIT_57 57 -#define BTEMP_THERMAL_HIGH_LIMIT_62 62 - -#define BTEMP_BATCTRL_CURR_SRC_7UA 7 -#define BTEMP_BATCTRL_CURR_SRC_20UA 20 - -#define to_ab8500_btemp_device_info(x) container_of((x), \ - struct ab8500_btemp, btemp_psy); - -/** - * struct ab8500_btemp_interrupts - ab8500 interrupts - * @name: name of the interrupt - * @isr function pointer to the isr - */ -struct ab8500_btemp_interrupts { - char *name; - irqreturn_t (*isr)(int irq, void *data); -}; - -struct ab8500_btemp_events { - bool batt_rem; - bool btemp_high; - bool btemp_medhigh; - bool btemp_lowmed; - bool btemp_low; - bool ac_conn; - bool usb_conn; -}; - -struct ab8500_btemp_ranges { - int btemp_high_limit; - int btemp_med_limit; - int btemp_low_limit; -}; - -/** - * struct ab8500_btemp - ab8500 BTEMP device information - * @dev: Pointer to the structure device - * @node: List of AB8500 BTEMPs, hence prepared for reentrance - * @curr_source: What current source we use, in uA - * @bat_temp: Battery temperature in degree Celcius - * @prev_bat_temp Last dispatched battery temperature - * @parent: Pointer to the struct ab8500 - * @gpadc: Pointer to the struct gpadc - * @fg: Pointer to the struct fg - * @pdata: Pointer to the abx500_btemp platform data - * @bat: Pointer to the abx500_bm platform data - * @btemp_psy: Structure for BTEMP specific battery properties - * @events: Structure for information about events triggered - * @btemp_ranges: Battery temperature range structure - * @btemp_wq: Work queue for measuring the temperature periodically - * @btemp_periodic_work: Work for measuring the temperature periodically - */ -struct ab8500_btemp { - struct device *dev; - struct list_head node; - int curr_source; - int bat_temp; - int prev_bat_temp; - struct ab8500 *parent; - struct ab8500_gpadc *gpadc; - struct ab8500_fg *fg; - struct abx500_btemp_platform_data *pdata; - struct abx500_bm_data *bat; - struct power_supply btemp_psy; - struct ab8500_btemp_events events; - struct ab8500_btemp_ranges btemp_ranges; - struct workqueue_struct *btemp_wq; - struct delayed_work btemp_periodic_work; -}; - -/* BTEMP power supply properties */ -static enum power_supply_property ab8500_btemp_props[] = { - POWER_SUPPLY_PROP_PRESENT, - POWER_SUPPLY_PROP_ONLINE, - POWER_SUPPLY_PROP_TECHNOLOGY, - POWER_SUPPLY_PROP_TEMP, -}; - -static LIST_HEAD(ab8500_btemp_list); - -/** - * ab8500_btemp_get() - returns a reference to the primary AB8500 BTEMP - * (i.e. the first BTEMP in the instance list) - */ -struct ab8500_btemp *ab8500_btemp_get(void) -{ - struct ab8500_btemp *btemp; - btemp = list_first_entry(&ab8500_btemp_list, struct ab8500_btemp, node); - - return btemp; -} - -/** - * ab8500_btemp_batctrl_volt_to_res() - convert batctrl voltage to resistance - * @di: pointer to the ab8500_btemp structure - * @v_batctrl: measured batctrl voltage - * @inst_curr: measured instant current - * - * This function returns the battery resistance that is - * derived from the BATCTRL voltage. - * Returns value in Ohms. - */ -static int ab8500_btemp_batctrl_volt_to_res(struct ab8500_btemp *di, - int v_batctrl, int inst_curr) -{ - int rbs; - - if (is_ab8500_1p1_or_earlier(di->parent)) { - /* - * For ABB cut1.0 and 1.1 BAT_CTRL is internally - * connected to 1.8V through a 450k resistor - */ - return (450000 * (v_batctrl)) / (1800 - v_batctrl); - } - - if (di->bat->adc_therm == ABx500_ADC_THERM_BATCTRL) { - /* - * If the battery has internal NTC, we use the current - * source to calculate the resistance, 7uA or 20uA - */ - rbs = (v_batctrl * 1000 - - di->bat->gnd_lift_resistance * inst_curr) - / di->curr_source; - } else { - /* - * BAT_CTRL is internally - * connected to 1.8V through a 80k resistor - */ - rbs = (80000 * (v_batctrl)) / (1800 - v_batctrl); - } - - return rbs; -} - -/** - * ab8500_btemp_read_batctrl_voltage() - measure batctrl voltage - * @di: pointer to the ab8500_btemp structure - * - * This function returns the voltage on BATCTRL. Returns value in mV. - */ -static int ab8500_btemp_read_batctrl_voltage(struct ab8500_btemp *di) -{ - int vbtemp; - static int prev; - - vbtemp = ab8500_gpadc_convert(di->gpadc, BAT_CTRL); - if (vbtemp < 0) { - dev_err(di->dev, - "%s gpadc conversion failed, using previous value", - __func__); - return prev; - } - prev = vbtemp; - return vbtemp; -} - -/** - * ab8500_btemp_curr_source_enable() - enable/disable batctrl current source - * @di: pointer to the ab8500_btemp structure - * @enable: enable or disable the current source - * - * Enable or disable the current sources for the BatCtrl AD channel - */ -static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di, - bool enable) -{ - int curr; - int ret = 0; - - /* - * BATCTRL current sources are included on AB8500 cut2.0 - * and future versions - */ - if (is_ab8500_1p1_or_earlier(di->parent)) - return 0; - - /* Only do this for batteries with internal NTC */ - if (di->bat->adc_therm == ABx500_ADC_THERM_BATCTRL && enable) { - if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_7UA) - curr = BAT_CTRL_7U_ENA; - else - curr = BAT_CTRL_20U_ENA; - - dev_dbg(di->dev, "Set BATCTRL %duA\n", di->curr_source); - - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, - FORCE_BAT_CTRL_CMP_HIGH, FORCE_BAT_CTRL_CMP_HIGH); - if (ret) { - dev_err(di->dev, "%s failed setting cmp_force\n", - __func__); - return ret; - } - - /* - * We have to wait one 32kHz cycle before enabling - * the current source, since ForceBatCtrlCmpHigh needs - * to be written in a separate cycle - */ - udelay(32); - - ret = abx500_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, - FORCE_BAT_CTRL_CMP_HIGH | curr); - if (ret) { - dev_err(di->dev, "%s failed enabling current source\n", - __func__); - goto disable_curr_source; - } - } else if (di->bat->adc_therm == ABx500_ADC_THERM_BATCTRL && !enable) { - dev_dbg(di->dev, "Disable BATCTRL curr source\n"); - - /* Write 0 to the curr bits */ - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, - BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA, - ~(BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA)); - if (ret) { - dev_err(di->dev, "%s failed disabling current source\n", - __func__); - goto disable_curr_source; - } - - /* Enable Pull-Up and comparator */ - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, - BAT_CTRL_PULL_UP_ENA | BAT_CTRL_CMP_ENA, - BAT_CTRL_PULL_UP_ENA | BAT_CTRL_CMP_ENA); - if (ret) { - dev_err(di->dev, "%s failed enabling PU and comp\n", - __func__); - goto enable_pu_comp; - } - - /* - * We have to wait one 32kHz cycle before disabling - * ForceBatCtrlCmpHigh since this needs to be written - * in a separate cycle - */ - udelay(32); - - /* Disable 'force comparator' */ - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, - FORCE_BAT_CTRL_CMP_HIGH, ~FORCE_BAT_CTRL_CMP_HIGH); - if (ret) { - dev_err(di->dev, "%s failed disabling force comp\n", - __func__); - goto disable_force_comp; - } - } - return ret; - - /* - * We have to try unsetting FORCE_BAT_CTRL_CMP_HIGH one more time - * if we got an error above - */ -disable_curr_source: - /* Write 0 to the curr bits */ - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, - BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA, - ~(BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA)); - if (ret) { - dev_err(di->dev, "%s failed disabling current source\n", - __func__); - return ret; - } -enable_pu_comp: - /* Enable Pull-Up and comparator */ - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, - BAT_CTRL_PULL_UP_ENA | BAT_CTRL_CMP_ENA, - BAT_CTRL_PULL_UP_ENA | BAT_CTRL_CMP_ENA); - if (ret) { - dev_err(di->dev, "%s failed enabling PU and comp\n", - __func__); - return ret; - } - -disable_force_comp: - /* - * We have to wait one 32kHz cycle before disabling - * ForceBatCtrlCmpHigh since this needs to be written - * in a separate cycle - */ - udelay(32); - - /* Disable 'force comparator' */ - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, - FORCE_BAT_CTRL_CMP_HIGH, ~FORCE_BAT_CTRL_CMP_HIGH); - if (ret) { - dev_err(di->dev, "%s failed disabling force comp\n", - __func__); - return ret; - } - - return ret; -} - -/** - * ab8500_btemp_get_batctrl_res() - get battery resistance - * @di: pointer to the ab8500_btemp structure - * - * This function returns the battery pack identification resistance. - * Returns value in Ohms. - */ -static int ab8500_btemp_get_batctrl_res(struct ab8500_btemp *di) -{ - int ret; - int batctrl = 0; - int res; - int inst_curr; - int i; - - /* - * BATCTRL current sources are included on AB8500 cut2.0 - * and future versions - */ - ret = ab8500_btemp_curr_source_enable(di, true); - if (ret) { - dev_err(di->dev, "%s curr source enabled failed\n", __func__); - return ret; - } - - if (!di->fg) - di->fg = ab8500_fg_get(); - if (!di->fg) { - dev_err(di->dev, "No fg found\n"); - return -EINVAL; - } - - ret = ab8500_fg_inst_curr_start(di->fg); - - if (ret) { - dev_err(di->dev, "Failed to start current measurement\n"); - return ret; - } - - /* - * Since there is no interrupt when current measurement is done, - * loop for over 250ms (250ms is one sample conversion time - * with 32.768 Khz RTC clock). Note that a stop time must be set - * since the ab8500_btemp_read_batctrl_voltage call can block and - * take an unknown amount of time to complete. - */ - i = 0; - - do { - batctrl += ab8500_btemp_read_batctrl_voltage(di); - i++; - msleep(20); - } while (!ab8500_fg_inst_curr_done(di->fg)); - batctrl /= i; - - ret = ab8500_fg_inst_curr_finalize(di->fg, &inst_curr); - if (ret) { - dev_err(di->dev, "Failed to finalize current measurement\n"); - return ret; - } - - res = ab8500_btemp_batctrl_volt_to_res(di, batctrl, inst_curr); - - ret = ab8500_btemp_curr_source_enable(di, false); - if (ret) { - dev_err(di->dev, "%s curr source disable failed\n", __func__); - return ret; - } - - dev_dbg(di->dev, "%s batctrl: %d res: %d inst_curr: %d samples: %d\n", - __func__, batctrl, res, inst_curr, i); - - return res; -} - -/** - * ab8500_btemp_res_to_temp() - resistance to temperature - * @di: pointer to the ab8500_btemp structure - * @tbl: pointer to the resiatance to temperature table - * @tbl_size: size of the resistance to temperature table - * @res: resistance to calculate the temperature from - * - * This function returns the battery temperature in degrees Celcius - * based on the NTC resistance. - */ -static int ab8500_btemp_res_to_temp(struct ab8500_btemp *di, - const struct abx500_res_to_temp *tbl, int tbl_size, int res) -{ - int i, temp; - /* - * Calculate the formula for the straight line - * Simple interpolation if we are within - * the resistance table limits, extrapolate - * if resistance is outside the limits. - */ - if (res > tbl[0].resist) - i = 0; - else if (res <= tbl[tbl_size - 1].resist) - i = tbl_size - 2; - else { - i = 0; - while (!(res <= tbl[i].resist && - res > tbl[i + 1].resist)) - i++; - } - - temp = tbl[i].temp + ((tbl[i + 1].temp - tbl[i].temp) * - (res - tbl[i].resist)) / (tbl[i + 1].resist - tbl[i].resist); - return temp; -} - -/** - * ab8500_btemp_measure_temp() - measure battery temperature - * @di: pointer to the ab8500_btemp structure - * - * Returns battery temperature (on success) else the previous temperature - */ -static int ab8500_btemp_measure_temp(struct ab8500_btemp *di) -{ - int temp; - static int prev; - int rbat, rntc, vntc; - u8 id; - - id = di->bat->batt_id; - - if (di->bat->adc_therm == ABx500_ADC_THERM_BATCTRL && - id != BATTERY_UNKNOWN) { - - rbat = ab8500_btemp_get_batctrl_res(di); - if (rbat < 0) { - dev_err(di->dev, "%s get batctrl res failed\n", - __func__); - /* - * Return out-of-range temperature so that - * charging is stopped - */ - return BTEMP_THERMAL_LOW_LIMIT; - } - - temp = ab8500_btemp_res_to_temp(di, - di->bat->bat_type[id].r_to_t_tbl, - di->bat->bat_type[id].n_temp_tbl_elements, rbat); - } else { - vntc = ab8500_gpadc_convert(di->gpadc, BTEMP_BALL); - if (vntc < 0) { - dev_err(di->dev, - "%s gpadc conversion failed," - " using previous value\n", __func__); - return prev; - } - /* - * The PCB NTC is sourced from VTVOUT via a 230kOhm - * resistor. - */ - rntc = 230000 * vntc / (VTVOUT_V - vntc); - - temp = ab8500_btemp_res_to_temp(di, - di->bat->bat_type[id].r_to_t_tbl, - di->bat->bat_type[id].n_temp_tbl_elements, rntc); - prev = temp; - } - dev_dbg(di->dev, "Battery temperature is %d\n", temp); - return temp; -} - -/** - * ab8500_btemp_id() - Identify the connected battery - * @di: pointer to the ab8500_btemp structure - * - * This function will try to identify the battery by reading the ID - * resistor. Some brands use a combined ID resistor with a NTC resistor to - * both be able to identify and to read the temperature of it. - */ -static int ab8500_btemp_id(struct ab8500_btemp *di) -{ - int res; - u8 i; - - di->curr_source = BTEMP_BATCTRL_CURR_SRC_7UA; - di->bat->batt_id = BATTERY_UNKNOWN; - - res = ab8500_btemp_get_batctrl_res(di); - if (res < 0) { - dev_err(di->dev, "%s get batctrl res failed\n", __func__); - return -ENXIO; - } - - /* BATTERY_UNKNOWN is defined on position 0, skip it! */ - for (i = BATTERY_UNKNOWN + 1; i < di->bat->n_btypes; i++) { - if ((res <= di->bat->bat_type[i].resis_high) && - (res >= di->bat->bat_type[i].resis_low)) { - dev_dbg(di->dev, "Battery detected on %s" - " low %d < res %d < high: %d" - " index: %d\n", - di->bat->adc_therm == ABx500_ADC_THERM_BATCTRL ? - "BATCTRL" : "BATTEMP", - di->bat->bat_type[i].resis_low, res, - di->bat->bat_type[i].resis_high, i); - - di->bat->batt_id = i; - break; - } - } - - if (di->bat->batt_id == BATTERY_UNKNOWN) { - dev_warn(di->dev, "Battery identified as unknown" - ", resistance %d Ohm\n", res); - return -ENXIO; - } - - /* - * We only have to change current source if the - * detected type is Type 1, else we use the 7uA source - */ - if (di->bat->adc_therm == ABx500_ADC_THERM_BATCTRL && - di->bat->batt_id == 1) { - dev_dbg(di->dev, "Set BATCTRL current source to 20uA\n"); - di->curr_source = BTEMP_BATCTRL_CURR_SRC_20UA; - } - - return di->bat->batt_id; -} - -/** - * ab8500_btemp_periodic_work() - Measuring the temperature periodically - * @work: pointer to the work_struct structure - * - * Work function for measuring the temperature periodically - */ -static void ab8500_btemp_periodic_work(struct work_struct *work) -{ - int interval; - struct ab8500_btemp *di = container_of(work, - struct ab8500_btemp, btemp_periodic_work.work); - - di->bat_temp = ab8500_btemp_measure_temp(di); - - if (di->bat_temp != di->prev_bat_temp) { - di->prev_bat_temp = di->bat_temp; - power_supply_changed(&di->btemp_psy); - } - - if (di->events.ac_conn || di->events.usb_conn) - interval = di->bat->temp_interval_chg; - else - interval = di->bat->temp_interval_nochg; - - /* Schedule a new measurement */ - queue_delayed_work(di->btemp_wq, - &di->btemp_periodic_work, - round_jiffies(interval * HZ)); -} - -/** - * ab8500_btemp_batctrlindb_handler() - battery removal detected - * @irq: interrupt number - * @_di: void pointer that has to address of ab8500_btemp - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_btemp_batctrlindb_handler(int irq, void *_di) -{ - struct ab8500_btemp *di = _di; - dev_err(di->dev, "Battery removal detected!\n"); - - di->events.batt_rem = true; - power_supply_changed(&di->btemp_psy); - - return IRQ_HANDLED; -} - -/** - * ab8500_btemp_templow_handler() - battery temp lower than 10 degrees - * @irq: interrupt number - * @_di: void pointer that has to address of ab8500_btemp - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_btemp_templow_handler(int irq, void *_di) -{ - struct ab8500_btemp *di = _di; - - if (is_ab8500_2p0_or_earlier(di->parent)) { - dev_dbg(di->dev, "Ignore false btemp low irq" - " for ABB cut 1.0, 1.1 and 2.0\n"); - } else { - dev_crit(di->dev, "Battery temperature lower than -10deg c\n"); - - di->events.btemp_low = true; - di->events.btemp_high = false; - di->events.btemp_medhigh = false; - di->events.btemp_lowmed = false; - power_supply_changed(&di->btemp_psy); - } - - return IRQ_HANDLED; -} - -/** - * ab8500_btemp_temphigh_handler() - battery temp higher than max temp - * @irq: interrupt number - * @_di: void pointer that has to address of ab8500_btemp - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_btemp_temphigh_handler(int irq, void *_di) -{ - struct ab8500_btemp *di = _di; - - dev_crit(di->dev, "Battery temperature is higher than MAX temp\n"); - - di->events.btemp_high = true; - di->events.btemp_medhigh = false; - di->events.btemp_lowmed = false; - di->events.btemp_low = false; - power_supply_changed(&di->btemp_psy); - - return IRQ_HANDLED; -} - -/** - * ab8500_btemp_lowmed_handler() - battery temp between low and medium - * @irq: interrupt number - * @_di: void pointer that has to address of ab8500_btemp - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_btemp_lowmed_handler(int irq, void *_di) -{ - struct ab8500_btemp *di = _di; - - dev_dbg(di->dev, "Battery temperature is between low and medium\n"); - - di->events.btemp_lowmed = true; - di->events.btemp_medhigh = false; - di->events.btemp_high = false; - di->events.btemp_low = false; - power_supply_changed(&di->btemp_psy); - - return IRQ_HANDLED; -} - -/** - * ab8500_btemp_medhigh_handler() - battery temp between medium and high - * @irq: interrupt number - * @_di: void pointer that has to address of ab8500_btemp - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_btemp_medhigh_handler(int irq, void *_di) -{ - struct ab8500_btemp *di = _di; - - dev_dbg(di->dev, "Battery temperature is between medium and high\n"); - - di->events.btemp_medhigh = true; - di->events.btemp_lowmed = false; - di->events.btemp_high = false; - di->events.btemp_low = false; - power_supply_changed(&di->btemp_psy); - - return IRQ_HANDLED; -} - -/** - * ab8500_btemp_periodic() - Periodic temperature measurements - * @di: pointer to the ab8500_btemp structure - * @enable: enable or disable periodic temperature measurements - * - * Starts of stops periodic temperature measurements. Periodic measurements - * should only be done when a charger is connected. - */ -static void ab8500_btemp_periodic(struct ab8500_btemp *di, - bool enable) -{ - dev_dbg(di->dev, "Enable periodic temperature measurements: %d\n", - enable); - /* - * Make sure a new measurement is done directly by cancelling - * any pending work - */ - cancel_delayed_work_sync(&di->btemp_periodic_work); - - if (enable) - queue_delayed_work(di->btemp_wq, &di->btemp_periodic_work, 0); -} - -/** - * ab8500_btemp_get_temp() - get battery temperature - * @di: pointer to the ab8500_btemp structure - * - * Returns battery temperature - */ -static int ab8500_btemp_get_temp(struct ab8500_btemp *di) -{ - int temp = 0; - - /* - * The BTEMP events are not reliabe on AB8500 cut2.0 - * and prior versions - */ - if (is_ab8500_2p0_or_earlier(di->parent)) { - temp = di->bat_temp * 10; - } else { - if (di->events.btemp_low) { - if (temp > di->btemp_ranges.btemp_low_limit) - temp = di->btemp_ranges.btemp_low_limit; - else - temp = di->bat_temp * 10; - } else if (di->events.btemp_high) { - if (temp < di->btemp_ranges.btemp_high_limit) - temp = di->btemp_ranges.btemp_high_limit; - else - temp = di->bat_temp * 10; - } else if (di->events.btemp_lowmed) { - if (temp > di->btemp_ranges.btemp_med_limit) - temp = di->btemp_ranges.btemp_med_limit; - else - temp = di->bat_temp * 10; - } else if (di->events.btemp_medhigh) { - if (temp < di->btemp_ranges.btemp_med_limit) - temp = di->btemp_ranges.btemp_med_limit; - else - temp = di->bat_temp * 10; - } else - temp = di->bat_temp * 10; - } - return temp; -} - -/** - * ab8500_btemp_get_batctrl_temp() - get the temperature - * @btemp: pointer to the btemp structure - * - * Returns the batctrl temperature in millidegrees - */ -int ab8500_btemp_get_batctrl_temp(struct ab8500_btemp *btemp) -{ - return btemp->bat_temp * 1000; -} - -/** - * ab8500_btemp_get_property() - get the btemp properties - * @psy: pointer to the power_supply structure - * @psp: pointer to the power_supply_property structure - * @val: pointer to the power_supply_propval union - * - * This function gets called when an application tries to get the btemp - * properties by reading the sysfs files. - * online: presence of the battery - * present: presence of the battery - * technology: battery technology - * temp: battery temperature - * Returns error code in case of failure else 0(on success) - */ -static int ab8500_btemp_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct ab8500_btemp *di; - - di = to_ab8500_btemp_device_info(psy); - - switch (psp) { - case POWER_SUPPLY_PROP_PRESENT: - case POWER_SUPPLY_PROP_ONLINE: - if (di->events.batt_rem) - val->intval = 0; - else - val->intval = 1; - break; - case POWER_SUPPLY_PROP_TECHNOLOGY: - val->intval = di->bat->bat_type[di->bat->batt_id].name; - break; - case POWER_SUPPLY_PROP_TEMP: - val->intval = ab8500_btemp_get_temp(di); - break; - default: - return -EINVAL; - } - return 0; -} - -static int ab8500_btemp_get_ext_psy_data(struct device *dev, void *data) -{ - struct power_supply *psy; - struct power_supply *ext; - struct ab8500_btemp *di; - union power_supply_propval ret; - int i, j; - bool psy_found = false; - - psy = (struct power_supply *)data; - ext = dev_get_drvdata(dev); - di = to_ab8500_btemp_device_info(psy); - - /* - * For all psy where the name of your driver - * appears in any supplied_to - */ - for (i = 0; i < ext->num_supplicants; i++) { - if (!strcmp(ext->supplied_to[i], psy->name)) - psy_found = true; - } - - if (!psy_found) - return 0; - - /* Go through all properties for the psy */ - for (j = 0; j < ext->num_properties; j++) { - enum power_supply_property prop; - prop = ext->properties[j]; - - if (ext->get_property(ext, prop, &ret)) - continue; - - switch (prop) { - case POWER_SUPPLY_PROP_PRESENT: - switch (ext->type) { - case POWER_SUPPLY_TYPE_MAINS: - /* AC disconnected */ - if (!ret.intval && di->events.ac_conn) { - di->events.ac_conn = false; - } - /* AC connected */ - else if (ret.intval && !di->events.ac_conn) { - di->events.ac_conn = true; - if (!di->events.usb_conn) - ab8500_btemp_periodic(di, true); - } - break; - case POWER_SUPPLY_TYPE_USB: - /* USB disconnected */ - if (!ret.intval && di->events.usb_conn) { - di->events.usb_conn = false; - } - /* USB connected */ - else if (ret.intval && !di->events.usb_conn) { - di->events.usb_conn = true; - if (!di->events.ac_conn) - ab8500_btemp_periodic(di, true); - } - break; - default: - break; - } - break; - default: - break; - } - } - return 0; -} - -/** - * ab8500_btemp_external_power_changed() - callback for power supply changes - * @psy: pointer to the structure power_supply - * - * This function is pointing to the function pointer external_power_changed - * of the structure power_supply. - * This function gets executed when there is a change in the external power - * supply to the btemp. - */ -static void ab8500_btemp_external_power_changed(struct power_supply *psy) -{ - struct ab8500_btemp *di = to_ab8500_btemp_device_info(psy); - - class_for_each_device(power_supply_class, NULL, - &di->btemp_psy, ab8500_btemp_get_ext_psy_data); -} - -/* ab8500 btemp driver interrupts and their respective isr */ -static struct ab8500_btemp_interrupts ab8500_btemp_irq[] = { - {"BAT_CTRL_INDB", ab8500_btemp_batctrlindb_handler}, - {"BTEMP_LOW", ab8500_btemp_templow_handler}, - {"BTEMP_HIGH", ab8500_btemp_temphigh_handler}, - {"BTEMP_LOW_MEDIUM", ab8500_btemp_lowmed_handler}, - {"BTEMP_MEDIUM_HIGH", ab8500_btemp_medhigh_handler}, -}; - -#if defined(CONFIG_PM) -static int ab8500_btemp_resume(struct platform_device *pdev) -{ - struct ab8500_btemp *di = platform_get_drvdata(pdev); - - ab8500_btemp_periodic(di, true); - - return 0; -} - -static int ab8500_btemp_suspend(struct platform_device *pdev, - pm_message_t state) -{ - struct ab8500_btemp *di = platform_get_drvdata(pdev); - - ab8500_btemp_periodic(di, false); - - return 0; -} -#else -#define ab8500_btemp_suspend NULL -#define ab8500_btemp_resume NULL -#endif - -static int __devexit ab8500_btemp_remove(struct platform_device *pdev) -{ - struct ab8500_btemp *di = platform_get_drvdata(pdev); - int i, irq; - - /* Disable interrupts */ - for (i = 0; i < ARRAY_SIZE(ab8500_btemp_irq); i++) { - irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name); - free_irq(irq, di); - } - - /* Delete the work queue */ - destroy_workqueue(di->btemp_wq); - - flush_scheduled_work(); - power_supply_unregister(&di->btemp_psy); - platform_set_drvdata(pdev, NULL); - kfree(di); - - return 0; -} - -static int __devinit ab8500_btemp_probe(struct platform_device *pdev) -{ - int irq, i, ret = 0; - u8 val; - struct abx500_bm_plat_data *plat_data; - - struct ab8500_btemp *di = - kzalloc(sizeof(struct ab8500_btemp), GFP_KERNEL); - if (!di) - return -ENOMEM; - - /* get parent data */ - di->dev = &pdev->dev; - di->parent = dev_get_drvdata(pdev->dev.parent); - di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); - - /* get btemp specific platform data */ - plat_data = pdev->dev.platform_data; - di->pdata = plat_data->btemp; - if (!di->pdata) { - dev_err(di->dev, "no btemp platform data supplied\n"); - ret = -EINVAL; - goto free_device_info; - } - - /* get battery specific platform data */ - di->bat = plat_data->battery; - if (!di->bat) { - dev_err(di->dev, "no battery platform data supplied\n"); - ret = -EINVAL; - goto free_device_info; - } - - /* BTEMP supply */ - di->btemp_psy.name = "ab8500_btemp"; - di->btemp_psy.type = POWER_SUPPLY_TYPE_BATTERY; - di->btemp_psy.properties = ab8500_btemp_props; - di->btemp_psy.num_properties = ARRAY_SIZE(ab8500_btemp_props); - di->btemp_psy.get_property = ab8500_btemp_get_property; - di->btemp_psy.supplied_to = di->pdata->supplied_to; - di->btemp_psy.num_supplicants = di->pdata->num_supplicants; - di->btemp_psy.external_power_changed = - ab8500_btemp_external_power_changed; - - - /* Create a work queue for the btemp */ - di->btemp_wq = - create_singlethread_workqueue("ab8500_btemp_wq"); - if (di->btemp_wq == NULL) { - dev_err(di->dev, "failed to create work queue\n"); - goto free_device_info; - } - - /* Init work for measuring temperature periodically */ - INIT_DELAYED_WORK_DEFERRABLE(&di->btemp_periodic_work, - ab8500_btemp_periodic_work); - - /* Identify the battery */ - if (ab8500_btemp_id(di) < 0) - dev_warn(di->dev, "failed to identify the battery\n"); - - /* Set BTEMP thermal limits. Low and Med are fixed */ - di->btemp_ranges.btemp_low_limit = BTEMP_THERMAL_LOW_LIMIT; - di->btemp_ranges.btemp_med_limit = BTEMP_THERMAL_MED_LIMIT; - - ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_BTEMP_HIGH_TH, &val); - if (ret < 0) { - dev_err(di->dev, "%s ab8500 read failed\n", __func__); - goto free_btemp_wq; - } - switch (val) { - case BTEMP_HIGH_TH_57_0: - case BTEMP_HIGH_TH_57_1: - di->btemp_ranges.btemp_high_limit = - BTEMP_THERMAL_HIGH_LIMIT_57; - break; - case BTEMP_HIGH_TH_52: - di->btemp_ranges.btemp_high_limit = - BTEMP_THERMAL_HIGH_LIMIT_52; - break; - case BTEMP_HIGH_TH_62: - di->btemp_ranges.btemp_high_limit = - BTEMP_THERMAL_HIGH_LIMIT_62; - break; - } - - /* Register BTEMP power supply class */ - ret = power_supply_register(di->dev, &di->btemp_psy); - if (ret) { - dev_err(di->dev, "failed to register BTEMP psy\n"); - goto free_btemp_wq; - } - - /* Register interrupts */ - for (i = 0; i < ARRAY_SIZE(ab8500_btemp_irq); i++) { - irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name); - ret = request_threaded_irq(irq, NULL, ab8500_btemp_irq[i].isr, - IRQF_SHARED | IRQF_NO_SUSPEND, - ab8500_btemp_irq[i].name, di); - - if (ret) { - dev_err(di->dev, "failed to request %s IRQ %d: %d\n" - , ab8500_btemp_irq[i].name, irq, ret); - goto free_irq; - } - dev_dbg(di->dev, "Requested %s IRQ %d: %d\n", - ab8500_btemp_irq[i].name, irq, ret); - } - - platform_set_drvdata(pdev, di); - - /* Kick off periodic temperature measurements */ - ab8500_btemp_periodic(di, true); - list_add_tail(&di->node, &ab8500_btemp_list); - - return ret; - -free_irq: - power_supply_unregister(&di->btemp_psy); - - /* We also have to free all successfully registered irqs */ - for (i = i - 1; i >= 0; i--) { - irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name); - free_irq(irq, di); - } -free_btemp_wq: - destroy_workqueue(di->btemp_wq); -free_device_info: - kfree(di); - - return ret; -} - -static struct platform_driver ab8500_btemp_driver = { - .probe = ab8500_btemp_probe, - .remove = __devexit_p(ab8500_btemp_remove), - .suspend = ab8500_btemp_suspend, - .resume = ab8500_btemp_resume, - .driver = { - .name = "ab8500-btemp", - .owner = THIS_MODULE, - }, -}; - -static int __init ab8500_btemp_init(void) -{ - return platform_driver_register(&ab8500_btemp_driver); -} - -static void __exit ab8500_btemp_exit(void) -{ - platform_driver_unregister(&ab8500_btemp_driver); -} - -subsys_initcall_sync(ab8500_btemp_init); -module_exit(ab8500_btemp_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Johan Palsson, Karl Komierowski, Arun R Murthy"); -MODULE_ALIAS("platform:ab8500-btemp"); -MODULE_DESCRIPTION("AB8500 battery temperature driver"); diff --git a/trunk/drivers/power/ab8500_charger.c b/trunk/drivers/power/ab8500_charger.c deleted file mode 100644 index e2b4accbec88..000000000000 --- a/trunk/drivers/power/ab8500_charger.c +++ /dev/null @@ -1,2789 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2012 - * - * Charger driver for AB8500 - * - * License Terms: GNU General Public License v2 - * Author: - * Johan Palsson - * Karl Komierowski - * Arun R Murthy - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Charger constants */ -#define NO_PW_CONN 0 -#define AC_PW_CONN 1 -#define USB_PW_CONN 2 - -#define MAIN_WDOG_ENA 0x01 -#define MAIN_WDOG_KICK 0x02 -#define MAIN_WDOG_DIS 0x00 -#define CHARG_WD_KICK 0x01 -#define MAIN_CH_ENA 0x01 -#define MAIN_CH_NO_OVERSHOOT_ENA_N 0x02 -#define USB_CH_ENA 0x01 -#define USB_CHG_NO_OVERSHOOT_ENA_N 0x02 -#define MAIN_CH_DET 0x01 -#define MAIN_CH_CV_ON 0x04 -#define USB_CH_CV_ON 0x08 -#define VBUS_DET_DBNC100 0x02 -#define VBUS_DET_DBNC1 0x01 -#define OTP_ENABLE_WD 0x01 - -#define MAIN_CH_INPUT_CURR_SHIFT 4 -#define VBUS_IN_CURR_LIM_SHIFT 4 - -#define LED_INDICATOR_PWM_ENA 0x01 -#define LED_INDICATOR_PWM_DIS 0x00 -#define LED_IND_CUR_5MA 0x04 -#define LED_INDICATOR_PWM_DUTY_252_256 0xBF - -/* HW failure constants */ -#define MAIN_CH_TH_PROT 0x02 -#define VBUS_CH_NOK 0x08 -#define USB_CH_TH_PROT 0x02 -#define VBUS_OVV_TH 0x01 -#define MAIN_CH_NOK 0x01 -#define VBUS_DET 0x80 - -/* UsbLineStatus register bit masks */ -#define AB8500_USB_LINK_STATUS 0x78 -#define AB8500_STD_HOST_SUSP 0x18 - -/* Watchdog timeout constant */ -#define WD_TIMER 0x30 /* 4min */ -#define WD_KICK_INTERVAL (60 * HZ) - -/* Lowest charger voltage is 3.39V -> 0x4E */ -#define LOW_VOLT_REG 0x4E - -/* UsbLineStatus register - usb types */ -enum ab8500_charger_link_status { - USB_STAT_NOT_CONFIGURED, - USB_STAT_STD_HOST_NC, - USB_STAT_STD_HOST_C_NS, - USB_STAT_STD_HOST_C_S, - USB_STAT_HOST_CHG_NM, - USB_STAT_HOST_CHG_HS, - USB_STAT_HOST_CHG_HS_CHIRP, - USB_STAT_DEDICATED_CHG, - USB_STAT_ACA_RID_A, - USB_STAT_ACA_RID_B, - USB_STAT_ACA_RID_C_NM, - USB_STAT_ACA_RID_C_HS, - USB_STAT_ACA_RID_C_HS_CHIRP, - USB_STAT_HM_IDGND, - USB_STAT_RESERVED, - USB_STAT_NOT_VALID_LINK, -}; - -enum ab8500_usb_state { - AB8500_BM_USB_STATE_RESET_HS, /* HighSpeed Reset */ - AB8500_BM_USB_STATE_RESET_FS, /* FullSpeed/LowSpeed Reset */ - AB8500_BM_USB_STATE_CONFIGURED, - AB8500_BM_USB_STATE_SUSPEND, - AB8500_BM_USB_STATE_RESUME, - AB8500_BM_USB_STATE_MAX, -}; - -/* VBUS input current limits supported in AB8500 in mA */ -#define USB_CH_IP_CUR_LVL_0P05 50 -#define USB_CH_IP_CUR_LVL_0P09 98 -#define USB_CH_IP_CUR_LVL_0P19 193 -#define USB_CH_IP_CUR_LVL_0P29 290 -#define USB_CH_IP_CUR_LVL_0P38 380 -#define USB_CH_IP_CUR_LVL_0P45 450 -#define USB_CH_IP_CUR_LVL_0P5 500 -#define USB_CH_IP_CUR_LVL_0P6 600 -#define USB_CH_IP_CUR_LVL_0P7 700 -#define USB_CH_IP_CUR_LVL_0P8 800 -#define USB_CH_IP_CUR_LVL_0P9 900 -#define USB_CH_IP_CUR_LVL_1P0 1000 -#define USB_CH_IP_CUR_LVL_1P1 1100 -#define USB_CH_IP_CUR_LVL_1P3 1300 -#define USB_CH_IP_CUR_LVL_1P4 1400 -#define USB_CH_IP_CUR_LVL_1P5 1500 - -#define VBAT_TRESH_IP_CUR_RED 3800 - -#define to_ab8500_charger_usb_device_info(x) container_of((x), \ - struct ab8500_charger, usb_chg) -#define to_ab8500_charger_ac_device_info(x) container_of((x), \ - struct ab8500_charger, ac_chg) - -/** - * struct ab8500_charger_interrupts - ab8500 interupts - * @name: name of the interrupt - * @isr function pointer to the isr - */ -struct ab8500_charger_interrupts { - char *name; - irqreturn_t (*isr)(int irq, void *data); -}; - -struct ab8500_charger_info { - int charger_connected; - int charger_online; - int charger_voltage; - int cv_active; - bool wd_expired; -}; - -struct ab8500_charger_event_flags { - bool mainextchnotok; - bool main_thermal_prot; - bool usb_thermal_prot; - bool vbus_ovv; - bool usbchargernotok; - bool chgwdexp; - bool vbus_collapse; -}; - -struct ab8500_charger_usb_state { - bool usb_changed; - int usb_current; - enum ab8500_usb_state state; - spinlock_t usb_lock; -}; - -/** - * struct ab8500_charger - ab8500 Charger device information - * @dev: Pointer to the structure device - * @max_usb_in_curr: Max USB charger input current - * @vbus_detected: VBUS detected - * @vbus_detected_start: - * VBUS detected during startup - * @ac_conn: This will be true when the AC charger has been plugged - * @vddadc_en_ac: Indicate if VDD ADC supply is enabled because AC - * charger is enabled - * @vddadc_en_usb: Indicate if VDD ADC supply is enabled because USB - * charger is enabled - * @vbat Battery voltage - * @old_vbat Previously measured battery voltage - * @autopower Indicate if we should have automatic pwron after pwrloss - * @parent: Pointer to the struct ab8500 - * @gpadc: Pointer to the struct gpadc - * @pdata: Pointer to the abx500_charger platform data - * @bat: Pointer to the abx500_bm platform data - * @flags: Structure for information about events triggered - * @usb_state: Structure for usb stack information - * @ac_chg: AC charger power supply - * @usb_chg: USB charger power supply - * @ac: Structure that holds the AC charger properties - * @usb: Structure that holds the USB charger properties - * @regu: Pointer to the struct regulator - * @charger_wq: Work queue for the IRQs and checking HW state - * @check_vbat_work Work for checking vbat threshold to adjust vbus current - * @check_hw_failure_work: Work for checking HW state - * @check_usbchgnotok_work: Work for checking USB charger not ok status - * @kick_wd_work: Work for kicking the charger watchdog in case - * of ABB rev 1.* due to the watchog logic bug - * @ac_work: Work for checking AC charger connection - * @detect_usb_type_work: Work for detecting the USB type connected - * @usb_link_status_work: Work for checking the new USB link status - * @usb_state_changed_work: Work for checking USB state - * @check_main_thermal_prot_work: - * Work for checking Main thermal status - * @check_usb_thermal_prot_work: - * Work for checking USB thermal status - */ -struct ab8500_charger { - struct device *dev; - int max_usb_in_curr; - bool vbus_detected; - bool vbus_detected_start; - bool ac_conn; - bool vddadc_en_ac; - bool vddadc_en_usb; - int vbat; - int old_vbat; - bool autopower; - struct ab8500 *parent; - struct ab8500_gpadc *gpadc; - struct abx500_charger_platform_data *pdata; - struct abx500_bm_data *bat; - struct ab8500_charger_event_flags flags; - struct ab8500_charger_usb_state usb_state; - struct ux500_charger ac_chg; - struct ux500_charger usb_chg; - struct ab8500_charger_info ac; - struct ab8500_charger_info usb; - struct regulator *regu; - struct workqueue_struct *charger_wq; - struct delayed_work check_vbat_work; - struct delayed_work check_hw_failure_work; - struct delayed_work check_usbchgnotok_work; - struct delayed_work kick_wd_work; - struct work_struct ac_work; - struct work_struct detect_usb_type_work; - struct work_struct usb_link_status_work; - struct work_struct usb_state_changed_work; - struct work_struct check_main_thermal_prot_work; - struct work_struct check_usb_thermal_prot_work; - struct usb_phy *usb_phy; - struct notifier_block nb; -}; - -/* AC properties */ -static enum power_supply_property ab8500_charger_ac_props[] = { - POWER_SUPPLY_PROP_HEALTH, - POWER_SUPPLY_PROP_PRESENT, - POWER_SUPPLY_PROP_ONLINE, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_VOLTAGE_AVG, - POWER_SUPPLY_PROP_CURRENT_NOW, -}; - -/* USB properties */ -static enum power_supply_property ab8500_charger_usb_props[] = { - POWER_SUPPLY_PROP_HEALTH, - POWER_SUPPLY_PROP_CURRENT_AVG, - POWER_SUPPLY_PROP_PRESENT, - POWER_SUPPLY_PROP_ONLINE, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_VOLTAGE_AVG, - POWER_SUPPLY_PROP_CURRENT_NOW, -}; - -/** - * ab8500_power_loss_handling - set how we handle powerloss. - * @di: pointer to the ab8500_charger structure - * - * Magic nummbers are from STE HW department. - */ -static void ab8500_power_loss_handling(struct ab8500_charger *di) -{ - u8 reg; - int ret; - - dev_dbg(di->dev, "Autopower : %d\n", di->autopower); - - /* read the autopower register */ - ret = abx500_get_register_interruptible(di->dev, 0x15, 0x00, ®); - if (ret) { - dev_err(di->dev, "%d write failed\n", __LINE__); - return; - } - - /* enable the OPT emulation registers */ - ret = abx500_set_register_interruptible(di->dev, 0x11, 0x00, 0x2); - if (ret) { - dev_err(di->dev, "%d write failed\n", __LINE__); - return; - } - - if (di->autopower) - reg |= 0x8; - else - reg &= ~0x8; - - /* write back the changed value to autopower reg */ - ret = abx500_set_register_interruptible(di->dev, 0x15, 0x00, reg); - if (ret) { - dev_err(di->dev, "%d write failed\n", __LINE__); - return; - } - - /* disable the set OTP registers again */ - ret = abx500_set_register_interruptible(di->dev, 0x11, 0x00, 0x0); - if (ret) { - dev_err(di->dev, "%d write failed\n", __LINE__); - return; - } -} - -/** - * ab8500_power_supply_changed - a wrapper with local extentions for - * power_supply_changed - * @di: pointer to the ab8500_charger structure - * @psy: pointer to power_supply_that have changed. - * - */ -static void ab8500_power_supply_changed(struct ab8500_charger *di, - struct power_supply *psy) -{ - if (di->pdata->autopower_cfg) { - if (!di->usb.charger_connected && - !di->ac.charger_connected && - di->autopower) { - di->autopower = false; - ab8500_power_loss_handling(di); - } else if (!di->autopower && - (di->ac.charger_connected || - di->usb.charger_connected)) { - di->autopower = true; - ab8500_power_loss_handling(di); - } - } - power_supply_changed(psy); -} - -static void ab8500_charger_set_usb_connected(struct ab8500_charger *di, - bool connected) -{ - if (connected != di->usb.charger_connected) { - dev_dbg(di->dev, "USB connected:%i\n", connected); - di->usb.charger_connected = connected; - sysfs_notify(&di->usb_chg.psy.dev->kobj, NULL, "present"); - } -} - -/** - * ab8500_charger_get_ac_voltage() - get ac charger voltage - * @di: pointer to the ab8500_charger structure - * - * Returns ac charger voltage (on success) - */ -static int ab8500_charger_get_ac_voltage(struct ab8500_charger *di) -{ - int vch; - - /* Only measure voltage if the charger is connected */ - if (di->ac.charger_connected) { - vch = ab8500_gpadc_convert(di->gpadc, MAIN_CHARGER_V); - if (vch < 0) - dev_err(di->dev, "%s gpadc conv failed,\n", __func__); - } else { - vch = 0; - } - return vch; -} - -/** - * ab8500_charger_ac_cv() - check if the main charger is in CV mode - * @di: pointer to the ab8500_charger structure - * - * Returns ac charger CV mode (on success) else error code - */ -static int ab8500_charger_ac_cv(struct ab8500_charger *di) -{ - u8 val; - int ret = 0; - - /* Only check CV mode if the charger is online */ - if (di->ac.charger_online) { - ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CH_STATUS1_REG, &val); - if (ret < 0) { - dev_err(di->dev, "%s ab8500 read failed\n", __func__); - return 0; - } - - if (val & MAIN_CH_CV_ON) - ret = 1; - else - ret = 0; - } - - return ret; -} - -/** - * ab8500_charger_get_vbus_voltage() - get vbus voltage - * @di: pointer to the ab8500_charger structure - * - * This function returns the vbus voltage. - * Returns vbus voltage (on success) - */ -static int ab8500_charger_get_vbus_voltage(struct ab8500_charger *di) -{ - int vch; - - /* Only measure voltage if the charger is connected */ - if (di->usb.charger_connected) { - vch = ab8500_gpadc_convert(di->gpadc, VBUS_V); - if (vch < 0) - dev_err(di->dev, "%s gpadc conv failed\n", __func__); - } else { - vch = 0; - } - return vch; -} - -/** - * ab8500_charger_get_usb_current() - get usb charger current - * @di: pointer to the ab8500_charger structure - * - * This function returns the usb charger current. - * Returns usb current (on success) and error code on failure - */ -static int ab8500_charger_get_usb_current(struct ab8500_charger *di) -{ - int ich; - - /* Only measure current if the charger is online */ - if (di->usb.charger_online) { - ich = ab8500_gpadc_convert(di->gpadc, USB_CHARGER_C); - if (ich < 0) - dev_err(di->dev, "%s gpadc conv failed\n", __func__); - } else { - ich = 0; - } - return ich; -} - -/** - * ab8500_charger_get_ac_current() - get ac charger current - * @di: pointer to the ab8500_charger structure - * - * This function returns the ac charger current. - * Returns ac current (on success) and error code on failure. - */ -static int ab8500_charger_get_ac_current(struct ab8500_charger *di) -{ - int ich; - - /* Only measure current if the charger is online */ - if (di->ac.charger_online) { - ich = ab8500_gpadc_convert(di->gpadc, MAIN_CHARGER_C); - if (ich < 0) - dev_err(di->dev, "%s gpadc conv failed\n", __func__); - } else { - ich = 0; - } - return ich; -} - -/** - * ab8500_charger_usb_cv() - check if the usb charger is in CV mode - * @di: pointer to the ab8500_charger structure - * - * Returns ac charger CV mode (on success) else error code - */ -static int ab8500_charger_usb_cv(struct ab8500_charger *di) -{ - int ret; - u8 val; - - /* Only check CV mode if the charger is online */ - if (di->usb.charger_online) { - ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CH_USBCH_STAT1_REG, &val); - if (ret < 0) { - dev_err(di->dev, "%s ab8500 read failed\n", __func__); - return 0; - } - - if (val & USB_CH_CV_ON) - ret = 1; - else - ret = 0; - } else { - ret = 0; - } - - return ret; -} - -/** - * ab8500_charger_detect_chargers() - Detect the connected chargers - * @di: pointer to the ab8500_charger structure - * - * Returns the type of charger connected. - * For USB it will not mean we can actually charge from it - * but that there is a USB cable connected that we have to - * identify. This is used during startup when we don't get - * interrupts of the charger detection - * - * Returns an integer value, that means, - * NO_PW_CONN no power supply is connected - * AC_PW_CONN if the AC power supply is connected - * USB_PW_CONN if the USB power supply is connected - * AC_PW_CONN + USB_PW_CONN if USB and AC power supplies are both connected - */ -static int ab8500_charger_detect_chargers(struct ab8500_charger *di) -{ - int result = NO_PW_CONN; - int ret; - u8 val; - - /* Check for AC charger */ - ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CH_STATUS1_REG, &val); - if (ret < 0) { - dev_err(di->dev, "%s ab8500 read failed\n", __func__); - return ret; - } - - if (val & MAIN_CH_DET) - result = AC_PW_CONN; - - /* Check for USB charger */ - ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CH_USBCH_STAT1_REG, &val); - if (ret < 0) { - dev_err(di->dev, "%s ab8500 read failed\n", __func__); - return ret; - } - - if ((val & VBUS_DET_DBNC1) && (val & VBUS_DET_DBNC100)) - result |= USB_PW_CONN; - - return result; -} - -/** - * ab8500_charger_max_usb_curr() - get the max curr for the USB type - * @di: pointer to the ab8500_charger structure - * @link_status: the identified USB type - * - * Get the maximum current that is allowed to be drawn from the host - * based on the USB type. - * Returns error code in case of failure else 0 on success - */ -static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, - enum ab8500_charger_link_status link_status) -{ - int ret = 0; - - switch (link_status) { - case USB_STAT_STD_HOST_NC: - case USB_STAT_STD_HOST_C_NS: - case USB_STAT_STD_HOST_C_S: - dev_dbg(di->dev, "USB Type - Standard host is " - "detected through USB driver\n"); - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P09; - break; - case USB_STAT_HOST_CHG_HS_CHIRP: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; - break; - case USB_STAT_HOST_CHG_HS: - case USB_STAT_ACA_RID_C_HS: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P9; - break; - case USB_STAT_ACA_RID_A: - /* - * Dedicated charger level minus maximum current accessory - * can consume (300mA). Closest level is 1100mA - */ - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P1; - break; - case USB_STAT_ACA_RID_B: - /* - * Dedicated charger level minus 120mA (20mA for ACA and - * 100mA for potential accessory). Closest level is 1300mA - */ - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P3; - break; - case USB_STAT_DEDICATED_CHG: - case USB_STAT_HOST_CHG_NM: - case USB_STAT_ACA_RID_C_HS_CHIRP: - case USB_STAT_ACA_RID_C_NM: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P5; - break; - case USB_STAT_RESERVED: - /* - * This state is used to indicate that VBUS has dropped below - * the detection level 4 times in a row. This is due to the - * charger output current is set to high making the charger - * voltage collapse. This have to be propagated through to - * chargalg. This is done using the property - * POWER_SUPPLY_PROP_CURRENT_AVG = 1 - */ - di->flags.vbus_collapse = true; - dev_dbg(di->dev, "USB Type - USB_STAT_RESERVED " - "VBUS has collapsed\n"); - ret = -1; - break; - case USB_STAT_HM_IDGND: - case USB_STAT_NOT_CONFIGURED: - case USB_STAT_NOT_VALID_LINK: - dev_err(di->dev, "USB Type - Charging not allowed\n"); - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05; - ret = -ENXIO; - break; - default: - dev_err(di->dev, "USB Type - Unknown\n"); - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05; - ret = -ENXIO; - break; - }; - - dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", - link_status, di->max_usb_in_curr); - - return ret; -} - -/** - * ab8500_charger_read_usb_type() - read the type of usb connected - * @di: pointer to the ab8500_charger structure - * - * Detect the type of the plugged USB - * Returns error code in case of failure else 0 on success - */ -static int ab8500_charger_read_usb_type(struct ab8500_charger *di) -{ - int ret; - u8 val; - - ret = abx500_get_register_interruptible(di->dev, - AB8500_INTERRUPT, AB8500_IT_SOURCE21_REG, &val); - if (ret < 0) { - dev_err(di->dev, "%s ab8500 read failed\n", __func__); - return ret; - } - ret = abx500_get_register_interruptible(di->dev, AB8500_USB, - AB8500_USB_LINE_STAT_REG, &val); - if (ret < 0) { - dev_err(di->dev, "%s ab8500 read failed\n", __func__); - return ret; - } - - /* get the USB type */ - val = (val & AB8500_USB_LINK_STATUS) >> 3; - ret = ab8500_charger_max_usb_curr(di, - (enum ab8500_charger_link_status) val); - - return ret; -} - -/** - * ab8500_charger_detect_usb_type() - get the type of usb connected - * @di: pointer to the ab8500_charger structure - * - * Detect the type of the plugged USB - * Returns error code in case of failure else 0 on success - */ -static int ab8500_charger_detect_usb_type(struct ab8500_charger *di) -{ - int i, ret; - u8 val; - - /* - * On getting the VBUS rising edge detect interrupt there - * is a 250ms delay after which the register UsbLineStatus - * is filled with valid data. - */ - for (i = 0; i < 10; i++) { - msleep(250); - ret = abx500_get_register_interruptible(di->dev, - AB8500_INTERRUPT, AB8500_IT_SOURCE21_REG, - &val); - if (ret < 0) { - dev_err(di->dev, "%s ab8500 read failed\n", __func__); - return ret; - } - ret = abx500_get_register_interruptible(di->dev, AB8500_USB, - AB8500_USB_LINE_STAT_REG, &val); - if (ret < 0) { - dev_err(di->dev, "%s ab8500 read failed\n", __func__); - return ret; - } - /* - * Until the IT source register is read the UsbLineStatus - * register is not updated, hence doing the same - * Revisit this: - */ - - /* get the USB type */ - val = (val & AB8500_USB_LINK_STATUS) >> 3; - if (val) - break; - } - ret = ab8500_charger_max_usb_curr(di, - (enum ab8500_charger_link_status) val); - - return ret; -} - -/* - * This array maps the raw hex value to charger voltage used by the AB8500 - * Values taken from the UM0836 - */ -static int ab8500_charger_voltage_map[] = { - 3500 , - 3525 , - 3550 , - 3575 , - 3600 , - 3625 , - 3650 , - 3675 , - 3700 , - 3725 , - 3750 , - 3775 , - 3800 , - 3825 , - 3850 , - 3875 , - 3900 , - 3925 , - 3950 , - 3975 , - 4000 , - 4025 , - 4050 , - 4060 , - 4070 , - 4080 , - 4090 , - 4100 , - 4110 , - 4120 , - 4130 , - 4140 , - 4150 , - 4160 , - 4170 , - 4180 , - 4190 , - 4200 , - 4210 , - 4220 , - 4230 , - 4240 , - 4250 , - 4260 , - 4270 , - 4280 , - 4290 , - 4300 , - 4310 , - 4320 , - 4330 , - 4340 , - 4350 , - 4360 , - 4370 , - 4380 , - 4390 , - 4400 , - 4410 , - 4420 , - 4430 , - 4440 , - 4450 , - 4460 , - 4470 , - 4480 , - 4490 , - 4500 , - 4510 , - 4520 , - 4530 , - 4540 , - 4550 , - 4560 , - 4570 , - 4580 , - 4590 , - 4600 , -}; - -/* - * This array maps the raw hex value to charger current used by the AB8500 - * Values taken from the UM0836 - */ -static int ab8500_charger_current_map[] = { - 100 , - 200 , - 300 , - 400 , - 500 , - 600 , - 700 , - 800 , - 900 , - 1000 , - 1100 , - 1200 , - 1300 , - 1400 , - 1500 , -}; - -/* - * This array maps the raw hex value to VBUS input current used by the AB8500 - * Values taken from the UM0836 - */ -static int ab8500_charger_vbus_in_curr_map[] = { - USB_CH_IP_CUR_LVL_0P05, - USB_CH_IP_CUR_LVL_0P09, - USB_CH_IP_CUR_LVL_0P19, - USB_CH_IP_CUR_LVL_0P29, - USB_CH_IP_CUR_LVL_0P38, - USB_CH_IP_CUR_LVL_0P45, - USB_CH_IP_CUR_LVL_0P5, - USB_CH_IP_CUR_LVL_0P6, - USB_CH_IP_CUR_LVL_0P7, - USB_CH_IP_CUR_LVL_0P8, - USB_CH_IP_CUR_LVL_0P9, - USB_CH_IP_CUR_LVL_1P0, - USB_CH_IP_CUR_LVL_1P1, - USB_CH_IP_CUR_LVL_1P3, - USB_CH_IP_CUR_LVL_1P4, - USB_CH_IP_CUR_LVL_1P5, -}; - -static int ab8500_voltage_to_regval(int voltage) -{ - int i; - - /* Special case for voltage below 3.5V */ - if (voltage < ab8500_charger_voltage_map[0]) - return LOW_VOLT_REG; - - for (i = 1; i < ARRAY_SIZE(ab8500_charger_voltage_map); i++) { - if (voltage < ab8500_charger_voltage_map[i]) - return i - 1; - } - - /* If not last element, return error */ - i = ARRAY_SIZE(ab8500_charger_voltage_map) - 1; - if (voltage == ab8500_charger_voltage_map[i]) - return i; - else - return -1; -} - -static int ab8500_current_to_regval(int curr) -{ - int i; - - if (curr < ab8500_charger_current_map[0]) - return 0; - - for (i = 0; i < ARRAY_SIZE(ab8500_charger_current_map); i++) { - if (curr < ab8500_charger_current_map[i]) - return i - 1; - } - - /* If not last element, return error */ - i = ARRAY_SIZE(ab8500_charger_current_map) - 1; - if (curr == ab8500_charger_current_map[i]) - return i; - else - return -1; -} - -static int ab8500_vbus_in_curr_to_regval(int curr) -{ - int i; - - if (curr < ab8500_charger_vbus_in_curr_map[0]) - return 0; - - for (i = 0; i < ARRAY_SIZE(ab8500_charger_vbus_in_curr_map); i++) { - if (curr < ab8500_charger_vbus_in_curr_map[i]) - return i - 1; - } - - /* If not last element, return error */ - i = ARRAY_SIZE(ab8500_charger_vbus_in_curr_map) - 1; - if (curr == ab8500_charger_vbus_in_curr_map[i]) - return i; - else - return -1; -} - -/** - * ab8500_charger_get_usb_cur() - get usb current - * @di: pointer to the ab8500_charger structre - * - * The usb stack provides the maximum current that can be drawn from - * the standard usb host. This will be in mA. - * This function converts current in mA to a value that can be written - * to the register. Returns -1 if charging is not allowed - */ -static int ab8500_charger_get_usb_cur(struct ab8500_charger *di) -{ - switch (di->usb_state.usb_current) { - case 100: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P09; - break; - case 200: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P19; - break; - case 300: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P29; - break; - case 400: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P38; - break; - case 500: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; - break; - default: - di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05; - return -1; - break; - }; - return 0; -} - -/** - * ab8500_charger_set_vbus_in_curr() - set VBUS input current limit - * @di: pointer to the ab8500_charger structure - * @ich_in: charger input current limit - * - * Sets the current that can be drawn from the USB host - * Returns error code in case of failure else 0(on success) - */ -static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di, - int ich_in) -{ - int ret; - int input_curr_index; - int min_value; - - /* We should always use to lowest current limit */ - min_value = min(di->bat->chg_params->usb_curr_max, ich_in); - - switch (min_value) { - case 100: - if (di->vbat < VBAT_TRESH_IP_CUR_RED) - min_value = USB_CH_IP_CUR_LVL_0P05; - break; - case 500: - if (di->vbat < VBAT_TRESH_IP_CUR_RED) - min_value = USB_CH_IP_CUR_LVL_0P45; - break; - default: - break; - } - - input_curr_index = ab8500_vbus_in_curr_to_regval(min_value); - if (input_curr_index < 0) { - dev_err(di->dev, "VBUS input current limit too high\n"); - return -ENXIO; - } - - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_USBCH_IPT_CRNTLVL_REG, - input_curr_index << VBUS_IN_CURR_LIM_SHIFT); - if (ret) - dev_err(di->dev, "%s write failed\n", __func__); - - return ret; -} - -/** - * ab8500_charger_led_en() - turn on/off chargign led - * @di: pointer to the ab8500_charger structure - * @on: flag to turn on/off the chargign led - * - * Power ON/OFF charging LED indication - * Returns error code in case of failure else 0(on success) - */ -static int ab8500_charger_led_en(struct ab8500_charger *di, int on) -{ - int ret; - - if (on) { - /* Power ON charging LED indicator, set LED current to 5mA */ - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_LED_INDICATOR_PWM_CTRL, - (LED_IND_CUR_5MA | LED_INDICATOR_PWM_ENA)); - if (ret) { - dev_err(di->dev, "Power ON LED failed\n"); - return ret; - } - /* LED indicator PWM duty cycle 252/256 */ - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_LED_INDICATOR_PWM_DUTY, - LED_INDICATOR_PWM_DUTY_252_256); - if (ret) { - dev_err(di->dev, "Set LED PWM duty cycle failed\n"); - return ret; - } - } else { - /* Power off charging LED indicator */ - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_LED_INDICATOR_PWM_CTRL, - LED_INDICATOR_PWM_DIS); - if (ret) { - dev_err(di->dev, "Power-off LED failed\n"); - return ret; - } - } - - return ret; -} - -/** - * ab8500_charger_ac_en() - enable or disable ac charging - * @di: pointer to the ab8500_charger structure - * @enable: enable/disable flag - * @vset: charging voltage - * @iset: charging current - * - * Enable/Disable AC/Mains charging and turns on/off the charging led - * respectively. - **/ -static int ab8500_charger_ac_en(struct ux500_charger *charger, - int enable, int vset, int iset) -{ - int ret; - int volt_index; - int curr_index; - int input_curr_index; - u8 overshoot = 0; - - struct ab8500_charger *di = to_ab8500_charger_ac_device_info(charger); - - if (enable) { - /* Check if AC is connected */ - if (!di->ac.charger_connected) { - dev_err(di->dev, "AC charger not connected\n"); - return -ENXIO; - } - - /* Enable AC charging */ - dev_dbg(di->dev, "Enable AC: %dmV %dmA\n", vset, iset); - - /* - * Due to a bug in AB8500, BTEMP_HIGH/LOW interrupts - * will be triggered everytime we enable the VDD ADC supply. - * This will turn off charging for a short while. - * It can be avoided by having the supply on when - * there is a charger enabled. Normally the VDD ADC supply - * is enabled everytime a GPADC conversion is triggered. We will - * force it to be enabled from this driver to have - * the GPADC module independant of the AB8500 chargers - */ - if (!di->vddadc_en_ac) { - regulator_enable(di->regu); - di->vddadc_en_ac = true; - } - - /* Check if the requested voltage or current is valid */ - volt_index = ab8500_voltage_to_regval(vset); - curr_index = ab8500_current_to_regval(iset); - input_curr_index = ab8500_current_to_regval( - di->bat->chg_params->ac_curr_max); - if (volt_index < 0 || curr_index < 0 || input_curr_index < 0) { - dev_err(di->dev, - "Charger voltage or current too high, " - "charging not started\n"); - return -ENXIO; - } - - /* ChVoltLevel: maximum battery charging voltage */ - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CH_VOLT_LVL_REG, (u8) volt_index); - if (ret) { - dev_err(di->dev, "%s write failed\n", __func__); - return ret; - } - /* MainChInputCurr: current that can be drawn from the charger*/ - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_MCH_IPT_CURLVL_REG, - input_curr_index << MAIN_CH_INPUT_CURR_SHIFT); - if (ret) { - dev_err(di->dev, "%s write failed\n", __func__); - return ret; - } - /* ChOutputCurentLevel: protected output current */ - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CH_OPT_CRNTLVL_REG, (u8) curr_index); - if (ret) { - dev_err(di->dev, "%s write failed\n", __func__); - return ret; - } - - /* Check if VBAT overshoot control should be enabled */ - if (!di->bat->enable_overshoot) - overshoot = MAIN_CH_NO_OVERSHOOT_ENA_N; - - /* Enable Main Charger */ - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_MCH_CTRL1, MAIN_CH_ENA | overshoot); - if (ret) { - dev_err(di->dev, "%s write failed\n", __func__); - return ret; - } - - /* Power on charging LED indication */ - ret = ab8500_charger_led_en(di, true); - if (ret < 0) - dev_err(di->dev, "failed to enable LED\n"); - - di->ac.charger_online = 1; - } else { - /* Disable AC charging */ - if (is_ab8500_1p1_or_earlier(di->parent)) { - /* - * For ABB revision 1.0 and 1.1 there is a bug in the - * watchdog logic. That means we have to continously - * kick the charger watchdog even when no charger is - * connected. This is only valid once the AC charger - * has been enabled. This is a bug that is not handled - * by the algorithm and the watchdog have to be kicked - * by the charger driver when the AC charger - * is disabled - */ - if (di->ac_conn) { - queue_delayed_work(di->charger_wq, - &di->kick_wd_work, - round_jiffies(WD_KICK_INTERVAL)); - } - - /* - * We can't turn off charging completely - * due to a bug in AB8500 cut1. - * If we do, charging will not start again. - * That is why we set the lowest voltage - * and current possible - */ - ret = abx500_set_register_interruptible(di->dev, - AB8500_CHARGER, - AB8500_CH_VOLT_LVL_REG, CH_VOL_LVL_3P5); - if (ret) { - dev_err(di->dev, - "%s write failed\n", __func__); - return ret; - } - - ret = abx500_set_register_interruptible(di->dev, - AB8500_CHARGER, - AB8500_CH_OPT_CRNTLVL_REG, CH_OP_CUR_LVL_0P1); - if (ret) { - dev_err(di->dev, - "%s write failed\n", __func__); - return ret; - } - } else { - ret = abx500_set_register_interruptible(di->dev, - AB8500_CHARGER, - AB8500_MCH_CTRL1, 0); - if (ret) { - dev_err(di->dev, - "%s write failed\n", __func__); - return ret; - } - } - - ret = ab8500_charger_led_en(di, false); - if (ret < 0) - dev_err(di->dev, "failed to disable LED\n"); - - di->ac.charger_online = 0; - di->ac.wd_expired = false; - - /* Disable regulator if enabled */ - if (di->vddadc_en_ac) { - regulator_disable(di->regu); - di->vddadc_en_ac = false; - } - - dev_dbg(di->dev, "%s Disabled AC charging\n", __func__); - } - ab8500_power_supply_changed(di, &di->ac_chg.psy); - - return ret; -} - -/** - * ab8500_charger_usb_en() - enable usb charging - * @di: pointer to the ab8500_charger structure - * @enable: enable/disable flag - * @vset: charging voltage - * @ich_out: charger output current - * - * Enable/Disable USB charging and turns on/off the charging led respectively. - * Returns error code in case of failure else 0(on success) - */ -static int ab8500_charger_usb_en(struct ux500_charger *charger, - int enable, int vset, int ich_out) -{ - int ret; - int volt_index; - int curr_index; - u8 overshoot = 0; - - struct ab8500_charger *di = to_ab8500_charger_usb_device_info(charger); - - if (enable) { - /* Check if USB is connected */ - if (!di->usb.charger_connected) { - dev_err(di->dev, "USB charger not connected\n"); - return -ENXIO; - } - - /* - * Due to a bug in AB8500, BTEMP_HIGH/LOW interrupts - * will be triggered everytime we enable the VDD ADC supply. - * This will turn off charging for a short while. - * It can be avoided by having the supply on when - * there is a charger enabled. Normally the VDD ADC supply - * is enabled everytime a GPADC conversion is triggered. We will - * force it to be enabled from this driver to have - * the GPADC module independant of the AB8500 chargers - */ - if (!di->vddadc_en_usb) { - regulator_enable(di->regu); - di->vddadc_en_usb = true; - } - - /* Enable USB charging */ - dev_dbg(di->dev, "Enable USB: %dmV %dmA\n", vset, ich_out); - - /* Check if the requested voltage or current is valid */ - volt_index = ab8500_voltage_to_regval(vset); - curr_index = ab8500_current_to_regval(ich_out); - if (volt_index < 0 || curr_index < 0) { - dev_err(di->dev, - "Charger voltage or current too high, " - "charging not started\n"); - return -ENXIO; - } - - /* ChVoltLevel: max voltage upto which battery can be charged */ - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CH_VOLT_LVL_REG, (u8) volt_index); - if (ret) { - dev_err(di->dev, "%s write failed\n", __func__); - return ret; - } - /* USBChInputCurr: current that can be drawn from the usb */ - ret = ab8500_charger_set_vbus_in_curr(di, di->max_usb_in_curr); - if (ret) { - dev_err(di->dev, "setting USBChInputCurr failed\n"); - return ret; - } - /* ChOutputCurentLevel: protected output current */ - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CH_OPT_CRNTLVL_REG, (u8) curr_index); - if (ret) { - dev_err(di->dev, "%s write failed\n", __func__); - return ret; - } - /* Check if VBAT overshoot control should be enabled */ - if (!di->bat->enable_overshoot) - overshoot = USB_CHG_NO_OVERSHOOT_ENA_N; - - /* Enable USB Charger */ - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_USBCH_CTRL1_REG, USB_CH_ENA | overshoot); - if (ret) { - dev_err(di->dev, "%s write failed\n", __func__); - return ret; - } - - /* If success power on charging LED indication */ - ret = ab8500_charger_led_en(di, true); - if (ret < 0) - dev_err(di->dev, "failed to enable LED\n"); - - queue_delayed_work(di->charger_wq, &di->check_vbat_work, HZ); - - di->usb.charger_online = 1; - } else { - /* Disable USB charging */ - ret = abx500_set_register_interruptible(di->dev, - AB8500_CHARGER, - AB8500_USBCH_CTRL1_REG, 0); - if (ret) { - dev_err(di->dev, - "%s write failed\n", __func__); - return ret; - } - - ret = ab8500_charger_led_en(di, false); - if (ret < 0) - dev_err(di->dev, "failed to disable LED\n"); - - di->usb.charger_online = 0; - di->usb.wd_expired = false; - - /* Disable regulator if enabled */ - if (di->vddadc_en_usb) { - regulator_disable(di->regu); - di->vddadc_en_usb = false; - } - - dev_dbg(di->dev, "%s Disabled USB charging\n", __func__); - - /* Cancel any pending Vbat check work */ - if (delayed_work_pending(&di->check_vbat_work)) - cancel_delayed_work(&di->check_vbat_work); - - } - ab8500_power_supply_changed(di, &di->usb_chg.psy); - - return ret; -} - -/** - * ab8500_charger_watchdog_kick() - kick charger watchdog - * @di: pointer to the ab8500_charger structure - * - * Kick charger watchdog - * Returns error code in case of failure else 0(on success) - */ -static int ab8500_charger_watchdog_kick(struct ux500_charger *charger) -{ - int ret; - struct ab8500_charger *di; - - if (charger->psy.type == POWER_SUPPLY_TYPE_MAINS) - di = to_ab8500_charger_ac_device_info(charger); - else if (charger->psy.type == POWER_SUPPLY_TYPE_USB) - di = to_ab8500_charger_usb_device_info(charger); - else - return -ENXIO; - - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CHARG_WD_CTRL, CHARG_WD_KICK); - if (ret) - dev_err(di->dev, "Failed to kick WD!\n"); - - return ret; -} - -/** - * ab8500_charger_update_charger_current() - update charger current - * @di: pointer to the ab8500_charger structure - * - * Update the charger output current for the specified charger - * Returns error code in case of failure else 0(on success) - */ -static int ab8500_charger_update_charger_current(struct ux500_charger *charger, - int ich_out) -{ - int ret; - int curr_index; - struct ab8500_charger *di; - - if (charger->psy.type == POWER_SUPPLY_TYPE_MAINS) - di = to_ab8500_charger_ac_device_info(charger); - else if (charger->psy.type == POWER_SUPPLY_TYPE_USB) - di = to_ab8500_charger_usb_device_info(charger); - else - return -ENXIO; - - curr_index = ab8500_current_to_regval(ich_out); - if (curr_index < 0) { - dev_err(di->dev, - "Charger current too high, " - "charging not started\n"); - return -ENXIO; - } - - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CH_OPT_CRNTLVL_REG, (u8) curr_index); - if (ret) { - dev_err(di->dev, "%s write failed\n", __func__); - return ret; - } - - /* Reset the main and usb drop input current measurement counter */ - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CHARGER_CTRL, - 0x1); - if (ret) { - dev_err(di->dev, "%s write failed\n", __func__); - return ret; - } - - return ret; -} - -static int ab8500_charger_get_ext_psy_data(struct device *dev, void *data) -{ - struct power_supply *psy; - struct power_supply *ext; - struct ab8500_charger *di; - union power_supply_propval ret; - int i, j; - bool psy_found = false; - struct ux500_charger *usb_chg; - - usb_chg = (struct ux500_charger *)data; - psy = &usb_chg->psy; - - di = to_ab8500_charger_usb_device_info(usb_chg); - - ext = dev_get_drvdata(dev); - - /* For all psy where the driver name appears in any supplied_to */ - for (i = 0; i < ext->num_supplicants; i++) { - if (!strcmp(ext->supplied_to[i], psy->name)) - psy_found = true; - } - - if (!psy_found) - return 0; - - /* Go through all properties for the psy */ - for (j = 0; j < ext->num_properties; j++) { - enum power_supply_property prop; - prop = ext->properties[j]; - - if (ext->get_property(ext, prop, &ret)) - continue; - - switch (prop) { - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - switch (ext->type) { - case POWER_SUPPLY_TYPE_BATTERY: - di->vbat = ret.intval / 1000; - break; - default: - break; - } - break; - default: - break; - } - } - return 0; -} - -/** - * ab8500_charger_check_vbat_work() - keep vbus current within spec - * @work pointer to the work_struct structure - * - * Due to a asic bug it is necessary to lower the input current to the vbus - * charger when charging with at some specific levels. This issue is only valid - * for below a certain battery voltage. This function makes sure that the - * the allowed current limit isn't exceeded. - */ -static void ab8500_charger_check_vbat_work(struct work_struct *work) -{ - int t = 10; - struct ab8500_charger *di = container_of(work, - struct ab8500_charger, check_vbat_work.work); - - class_for_each_device(power_supply_class, NULL, - &di->usb_chg.psy, ab8500_charger_get_ext_psy_data); - - /* First run old_vbat is 0. */ - if (di->old_vbat == 0) - di->old_vbat = di->vbat; - - if (!((di->old_vbat <= VBAT_TRESH_IP_CUR_RED && - di->vbat <= VBAT_TRESH_IP_CUR_RED) || - (di->old_vbat > VBAT_TRESH_IP_CUR_RED && - di->vbat > VBAT_TRESH_IP_CUR_RED))) { - - dev_dbg(di->dev, "Vbat did cross threshold, curr: %d, new: %d," - " old: %d\n", di->max_usb_in_curr, di->vbat, - di->old_vbat); - ab8500_charger_set_vbus_in_curr(di, di->max_usb_in_curr); - power_supply_changed(&di->usb_chg.psy); - } - - di->old_vbat = di->vbat; - - /* - * No need to check the battery voltage every second when not close to - * the threshold. - */ - if (di->vbat < (VBAT_TRESH_IP_CUR_RED + 100) && - (di->vbat > (VBAT_TRESH_IP_CUR_RED - 100))) - t = 1; - - queue_delayed_work(di->charger_wq, &di->check_vbat_work, t * HZ); -} - -/** - * ab8500_charger_check_hw_failure_work() - check main charger failure - * @work: pointer to the work_struct structure - * - * Work queue function for checking the main charger status - */ -static void ab8500_charger_check_hw_failure_work(struct work_struct *work) -{ - int ret; - u8 reg_value; - - struct ab8500_charger *di = container_of(work, - struct ab8500_charger, check_hw_failure_work.work); - - /* Check if the status bits for HW failure is still active */ - if (di->flags.mainextchnotok) { - ret = abx500_get_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_CH_STATUS2_REG, ®_value); - if (ret < 0) { - dev_err(di->dev, "%s ab8500 read failed\n", __func__); - return; - } - if (!(reg_value & MAIN_CH_NOK)) { - di->flags.mainextchnotok = false; - ab8500_power_supply_changed(di, &di->ac_chg.psy); - } - } - if (di->flags.vbus_ovv) { - ret = abx500_get_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_CH_USBCH_STAT2_REG, - ®_value); - if (ret < 0) { - dev_err(di->dev, "%s ab8500 read failed\n", __func__); - return; - } - if (!(reg_value & VBUS_OVV_TH)) { - di->flags.vbus_ovv = false; - ab8500_power_supply_changed(di, &di->usb_chg.psy); - } - } - /* If we still have a failure, schedule a new check */ - if (di->flags.mainextchnotok || di->flags.vbus_ovv) { - queue_delayed_work(di->charger_wq, - &di->check_hw_failure_work, round_jiffies(HZ)); - } -} - -/** - * ab8500_charger_kick_watchdog_work() - kick the watchdog - * @work: pointer to the work_struct structure - * - * Work queue function for kicking the charger watchdog. - * - * For ABB revision 1.0 and 1.1 there is a bug in the watchdog - * logic. That means we have to continously kick the charger - * watchdog even when no charger is connected. This is only - * valid once the AC charger has been enabled. This is - * a bug that is not handled by the algorithm and the - * watchdog have to be kicked by the charger driver - * when the AC charger is disabled - */ -static void ab8500_charger_kick_watchdog_work(struct work_struct *work) -{ - int ret; - - struct ab8500_charger *di = container_of(work, - struct ab8500_charger, kick_wd_work.work); - - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CHARG_WD_CTRL, CHARG_WD_KICK); - if (ret) - dev_err(di->dev, "Failed to kick WD!\n"); - - /* Schedule a new watchdog kick */ - queue_delayed_work(di->charger_wq, - &di->kick_wd_work, round_jiffies(WD_KICK_INTERVAL)); -} - -/** - * ab8500_charger_ac_work() - work to get and set main charger status - * @work: pointer to the work_struct structure - * - * Work queue function for checking the main charger status - */ -static void ab8500_charger_ac_work(struct work_struct *work) -{ - int ret; - - struct ab8500_charger *di = container_of(work, - struct ab8500_charger, ac_work); - - /* - * Since we can't be sure that the events are received - * synchronously, we have the check if the main charger is - * connected by reading the status register - */ - ret = ab8500_charger_detect_chargers(di); - if (ret < 0) - return; - - if (ret & AC_PW_CONN) { - di->ac.charger_connected = 1; - di->ac_conn = true; - } else { - di->ac.charger_connected = 0; - } - - ab8500_power_supply_changed(di, &di->ac_chg.psy); - sysfs_notify(&di->ac_chg.psy.dev->kobj, NULL, "present"); -} - -/** - * ab8500_charger_detect_usb_type_work() - work to detect USB type - * @work: Pointer to the work_struct structure - * - * Detect the type of USB plugged - */ -static void ab8500_charger_detect_usb_type_work(struct work_struct *work) -{ - int ret; - - struct ab8500_charger *di = container_of(work, - struct ab8500_charger, detect_usb_type_work); - - /* - * Since we can't be sure that the events are received - * synchronously, we have the check if is - * connected by reading the status register - */ - ret = ab8500_charger_detect_chargers(di); - if (ret < 0) - return; - - if (!(ret & USB_PW_CONN)) { - di->vbus_detected = 0; - ab8500_charger_set_usb_connected(di, false); - ab8500_power_supply_changed(di, &di->usb_chg.psy); - } else { - di->vbus_detected = 1; - - if (is_ab8500_1p1_or_earlier(di->parent)) { - ret = ab8500_charger_detect_usb_type(di); - if (!ret) { - ab8500_charger_set_usb_connected(di, true); - ab8500_power_supply_changed(di, - &di->usb_chg.psy); - } - } else { - /* For ABB cut2.0 and onwards we have an IRQ, - * USB_LINK_STATUS that will be triggered when the USB - * link status changes. The exception is USB connected - * during startup. Then we don't get a - * USB_LINK_STATUS IRQ - */ - if (di->vbus_detected_start) { - di->vbus_detected_start = false; - ret = ab8500_charger_detect_usb_type(di); - if (!ret) { - ab8500_charger_set_usb_connected(di, - true); - ab8500_power_supply_changed(di, - &di->usb_chg.psy); - } - } - } - } -} - -/** - * ab8500_charger_usb_link_status_work() - work to detect USB type - * @work: pointer to the work_struct structure - * - * Detect the type of USB plugged - */ -static void ab8500_charger_usb_link_status_work(struct work_struct *work) -{ - int ret; - - struct ab8500_charger *di = container_of(work, - struct ab8500_charger, usb_link_status_work); - - /* - * Since we can't be sure that the events are received - * synchronously, we have the check if is - * connected by reading the status register - */ - ret = ab8500_charger_detect_chargers(di); - if (ret < 0) - return; - - if (!(ret & USB_PW_CONN)) { - di->vbus_detected = 0; - ab8500_charger_set_usb_connected(di, false); - ab8500_power_supply_changed(di, &di->usb_chg.psy); - } else { - di->vbus_detected = 1; - ret = ab8500_charger_read_usb_type(di); - if (!ret) { - /* Update maximum input current */ - ret = ab8500_charger_set_vbus_in_curr(di, - di->max_usb_in_curr); - if (ret) - return; - - ab8500_charger_set_usb_connected(di, true); - ab8500_power_supply_changed(di, &di->usb_chg.psy); - } else if (ret == -ENXIO) { - /* No valid charger type detected */ - ab8500_charger_set_usb_connected(di, false); - ab8500_power_supply_changed(di, &di->usb_chg.psy); - } - } -} - -static void ab8500_charger_usb_state_changed_work(struct work_struct *work) -{ - int ret; - unsigned long flags; - - struct ab8500_charger *di = container_of(work, - struct ab8500_charger, usb_state_changed_work); - - if (!di->vbus_detected) - return; - - spin_lock_irqsave(&di->usb_state.usb_lock, flags); - di->usb_state.usb_changed = false; - spin_unlock_irqrestore(&di->usb_state.usb_lock, flags); - - /* - * wait for some time until you get updates from the usb stack - * and negotiations are completed - */ - msleep(250); - - if (di->usb_state.usb_changed) - return; - - dev_dbg(di->dev, "%s USB state: 0x%02x mA: %d\n", - __func__, di->usb_state.state, di->usb_state.usb_current); - - switch (di->usb_state.state) { - case AB8500_BM_USB_STATE_RESET_HS: - case AB8500_BM_USB_STATE_RESET_FS: - case AB8500_BM_USB_STATE_SUSPEND: - case AB8500_BM_USB_STATE_MAX: - ab8500_charger_set_usb_connected(di, false); - ab8500_power_supply_changed(di, &di->usb_chg.psy); - break; - - case AB8500_BM_USB_STATE_RESUME: - /* - * when suspend->resume there should be delay - * of 1sec for enabling charging - */ - msleep(1000); - /* Intentional fall through */ - case AB8500_BM_USB_STATE_CONFIGURED: - /* - * USB is configured, enable charging with the charging - * input current obtained from USB driver - */ - if (!ab8500_charger_get_usb_cur(di)) { - /* Update maximum input current */ - ret = ab8500_charger_set_vbus_in_curr(di, - di->max_usb_in_curr); - if (ret) - return; - - ab8500_charger_set_usb_connected(di, true); - ab8500_power_supply_changed(di, &di->usb_chg.psy); - } - break; - - default: - break; - }; -} - -/** - * ab8500_charger_check_usbchargernotok_work() - check USB chg not ok status - * @work: pointer to the work_struct structure - * - * Work queue function for checking the USB charger Not OK status - */ -static void ab8500_charger_check_usbchargernotok_work(struct work_struct *work) -{ - int ret; - u8 reg_value; - bool prev_status; - - struct ab8500_charger *di = container_of(work, - struct ab8500_charger, check_usbchgnotok_work.work); - - /* Check if the status bit for usbchargernotok is still active */ - ret = abx500_get_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_CH_USBCH_STAT2_REG, ®_value); - if (ret < 0) { - dev_err(di->dev, "%s ab8500 read failed\n", __func__); - return; - } - prev_status = di->flags.usbchargernotok; - - if (reg_value & VBUS_CH_NOK) { - di->flags.usbchargernotok = true; - /* Check again in 1sec */ - queue_delayed_work(di->charger_wq, - &di->check_usbchgnotok_work, HZ); - } else { - di->flags.usbchargernotok = false; - di->flags.vbus_collapse = false; - } - - if (prev_status != di->flags.usbchargernotok) - ab8500_power_supply_changed(di, &di->usb_chg.psy); -} - -/** - * ab8500_charger_check_main_thermal_prot_work() - check main thermal status - * @work: pointer to the work_struct structure - * - * Work queue function for checking the Main thermal prot status - */ -static void ab8500_charger_check_main_thermal_prot_work( - struct work_struct *work) -{ - int ret; - u8 reg_value; - - struct ab8500_charger *di = container_of(work, - struct ab8500_charger, check_main_thermal_prot_work); - - /* Check if the status bit for main_thermal_prot is still active */ - ret = abx500_get_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_CH_STATUS2_REG, ®_value); - if (ret < 0) { - dev_err(di->dev, "%s ab8500 read failed\n", __func__); - return; - } - if (reg_value & MAIN_CH_TH_PROT) - di->flags.main_thermal_prot = true; - else - di->flags.main_thermal_prot = false; - - ab8500_power_supply_changed(di, &di->ac_chg.psy); -} - -/** - * ab8500_charger_check_usb_thermal_prot_work() - check usb thermal status - * @work: pointer to the work_struct structure - * - * Work queue function for checking the USB thermal prot status - */ -static void ab8500_charger_check_usb_thermal_prot_work( - struct work_struct *work) -{ - int ret; - u8 reg_value; - - struct ab8500_charger *di = container_of(work, - struct ab8500_charger, check_usb_thermal_prot_work); - - /* Check if the status bit for usb_thermal_prot is still active */ - ret = abx500_get_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_CH_USBCH_STAT2_REG, ®_value); - if (ret < 0) { - dev_err(di->dev, "%s ab8500 read failed\n", __func__); - return; - } - if (reg_value & USB_CH_TH_PROT) - di->flags.usb_thermal_prot = true; - else - di->flags.usb_thermal_prot = false; - - ab8500_power_supply_changed(di, &di->usb_chg.psy); -} - -/** - * ab8500_charger_mainchunplugdet_handler() - main charger unplugged - * @irq: interrupt number - * @_di: pointer to the ab8500_charger structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_charger_mainchunplugdet_handler(int irq, void *_di) -{ - struct ab8500_charger *di = _di; - - dev_dbg(di->dev, "Main charger unplugged\n"); - queue_work(di->charger_wq, &di->ac_work); - - return IRQ_HANDLED; -} - -/** - * ab8500_charger_mainchplugdet_handler() - main charger plugged - * @irq: interrupt number - * @_di: pointer to the ab8500_charger structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_charger_mainchplugdet_handler(int irq, void *_di) -{ - struct ab8500_charger *di = _di; - - dev_dbg(di->dev, "Main charger plugged\n"); - queue_work(di->charger_wq, &di->ac_work); - - return IRQ_HANDLED; -} - -/** - * ab8500_charger_mainextchnotok_handler() - main charger not ok - * @irq: interrupt number - * @_di: pointer to the ab8500_charger structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_charger_mainextchnotok_handler(int irq, void *_di) -{ - struct ab8500_charger *di = _di; - - dev_dbg(di->dev, "Main charger not ok\n"); - di->flags.mainextchnotok = true; - ab8500_power_supply_changed(di, &di->ac_chg.psy); - - /* Schedule a new HW failure check */ - queue_delayed_work(di->charger_wq, &di->check_hw_failure_work, 0); - - return IRQ_HANDLED; -} - -/** - * ab8500_charger_mainchthprotr_handler() - Die temp is above main charger - * thermal protection threshold - * @irq: interrupt number - * @_di: pointer to the ab8500_charger structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_charger_mainchthprotr_handler(int irq, void *_di) -{ - struct ab8500_charger *di = _di; - - dev_dbg(di->dev, - "Die temp above Main charger thermal protection threshold\n"); - queue_work(di->charger_wq, &di->check_main_thermal_prot_work); - - return IRQ_HANDLED; -} - -/** - * ab8500_charger_mainchthprotf_handler() - Die temp is below main charger - * thermal protection threshold - * @irq: interrupt number - * @_di: pointer to the ab8500_charger structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_charger_mainchthprotf_handler(int irq, void *_di) -{ - struct ab8500_charger *di = _di; - - dev_dbg(di->dev, - "Die temp ok for Main charger thermal protection threshold\n"); - queue_work(di->charger_wq, &di->check_main_thermal_prot_work); - - return IRQ_HANDLED; -} - -/** - * ab8500_charger_vbusdetf_handler() - VBUS falling detected - * @irq: interrupt number - * @_di: pointer to the ab8500_charger structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_charger_vbusdetf_handler(int irq, void *_di) -{ - struct ab8500_charger *di = _di; - - dev_dbg(di->dev, "VBUS falling detected\n"); - queue_work(di->charger_wq, &di->detect_usb_type_work); - - return IRQ_HANDLED; -} - -/** - * ab8500_charger_vbusdetr_handler() - VBUS rising detected - * @irq: interrupt number - * @_di: pointer to the ab8500_charger structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_charger_vbusdetr_handler(int irq, void *_di) -{ - struct ab8500_charger *di = _di; - - di->vbus_detected = true; - dev_dbg(di->dev, "VBUS rising detected\n"); - queue_work(di->charger_wq, &di->detect_usb_type_work); - - return IRQ_HANDLED; -} - -/** - * ab8500_charger_usblinkstatus_handler() - USB link status has changed - * @irq: interrupt number - * @_di: pointer to the ab8500_charger structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_charger_usblinkstatus_handler(int irq, void *_di) -{ - struct ab8500_charger *di = _di; - - dev_dbg(di->dev, "USB link status changed\n"); - - queue_work(di->charger_wq, &di->usb_link_status_work); - - return IRQ_HANDLED; -} - -/** - * ab8500_charger_usbchthprotr_handler() - Die temp is above usb charger - * thermal protection threshold - * @irq: interrupt number - * @_di: pointer to the ab8500_charger structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_charger_usbchthprotr_handler(int irq, void *_di) -{ - struct ab8500_charger *di = _di; - - dev_dbg(di->dev, - "Die temp above USB charger thermal protection threshold\n"); - queue_work(di->charger_wq, &di->check_usb_thermal_prot_work); - - return IRQ_HANDLED; -} - -/** - * ab8500_charger_usbchthprotf_handler() - Die temp is below usb charger - * thermal protection threshold - * @irq: interrupt number - * @_di: pointer to the ab8500_charger structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_charger_usbchthprotf_handler(int irq, void *_di) -{ - struct ab8500_charger *di = _di; - - dev_dbg(di->dev, - "Die temp ok for USB charger thermal protection threshold\n"); - queue_work(di->charger_wq, &di->check_usb_thermal_prot_work); - - return IRQ_HANDLED; -} - -/** - * ab8500_charger_usbchargernotokr_handler() - USB charger not ok detected - * @irq: interrupt number - * @_di: pointer to the ab8500_charger structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_charger_usbchargernotokr_handler(int irq, void *_di) -{ - struct ab8500_charger *di = _di; - - dev_dbg(di->dev, "Not allowed USB charger detected\n"); - queue_delayed_work(di->charger_wq, &di->check_usbchgnotok_work, 0); - - return IRQ_HANDLED; -} - -/** - * ab8500_charger_chwdexp_handler() - Charger watchdog expired - * @irq: interrupt number - * @_di: pointer to the ab8500_charger structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_charger_chwdexp_handler(int irq, void *_di) -{ - struct ab8500_charger *di = _di; - - dev_dbg(di->dev, "Charger watchdog expired\n"); - - /* - * The charger that was online when the watchdog expired - * needs to be restarted for charging to start again - */ - if (di->ac.charger_online) { - di->ac.wd_expired = true; - ab8500_power_supply_changed(di, &di->ac_chg.psy); - } - if (di->usb.charger_online) { - di->usb.wd_expired = true; - ab8500_power_supply_changed(di, &di->usb_chg.psy); - } - - return IRQ_HANDLED; -} - -/** - * ab8500_charger_vbusovv_handler() - VBUS overvoltage detected - * @irq: interrupt number - * @_di: pointer to the ab8500_charger structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_charger_vbusovv_handler(int irq, void *_di) -{ - struct ab8500_charger *di = _di; - - dev_dbg(di->dev, "VBUS overvoltage detected\n"); - di->flags.vbus_ovv = true; - ab8500_power_supply_changed(di, &di->usb_chg.psy); - - /* Schedule a new HW failure check */ - queue_delayed_work(di->charger_wq, &di->check_hw_failure_work, 0); - - return IRQ_HANDLED; -} - -/** - * ab8500_charger_ac_get_property() - get the ac/mains properties - * @psy: pointer to the power_supply structure - * @psp: pointer to the power_supply_property structure - * @val: pointer to the power_supply_propval union - * - * This function gets called when an application tries to get the ac/mains - * properties by reading the sysfs files. - * AC/Mains properties are online, present and voltage. - * online: ac/mains charging is in progress or not - * present: presence of the ac/mains - * voltage: AC/Mains voltage - * Returns error code in case of failure else 0(on success) - */ -static int ab8500_charger_ac_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct ab8500_charger *di; - - di = to_ab8500_charger_ac_device_info(psy_to_ux500_charger(psy)); - - switch (psp) { - case POWER_SUPPLY_PROP_HEALTH: - if (di->flags.mainextchnotok) - val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; - else if (di->ac.wd_expired || di->usb.wd_expired) - val->intval = POWER_SUPPLY_HEALTH_DEAD; - else if (di->flags.main_thermal_prot) - val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; - else - val->intval = POWER_SUPPLY_HEALTH_GOOD; - break; - case POWER_SUPPLY_PROP_ONLINE: - val->intval = di->ac.charger_online; - break; - case POWER_SUPPLY_PROP_PRESENT: - val->intval = di->ac.charger_connected; - break; - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - di->ac.charger_voltage = ab8500_charger_get_ac_voltage(di); - val->intval = di->ac.charger_voltage * 1000; - break; - case POWER_SUPPLY_PROP_VOLTAGE_AVG: - /* - * This property is used to indicate when CV mode is entered - * for the AC charger - */ - di->ac.cv_active = ab8500_charger_ac_cv(di); - val->intval = di->ac.cv_active; - break; - case POWER_SUPPLY_PROP_CURRENT_NOW: - val->intval = ab8500_charger_get_ac_current(di) * 1000; - break; - default: - return -EINVAL; - } - return 0; -} - -/** - * ab8500_charger_usb_get_property() - get the usb properties - * @psy: pointer to the power_supply structure - * @psp: pointer to the power_supply_property structure - * @val: pointer to the power_supply_propval union - * - * This function gets called when an application tries to get the usb - * properties by reading the sysfs files. - * USB properties are online, present and voltage. - * online: usb charging is in progress or not - * present: presence of the usb - * voltage: vbus voltage - * Returns error code in case of failure else 0(on success) - */ -static int ab8500_charger_usb_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct ab8500_charger *di; - - di = to_ab8500_charger_usb_device_info(psy_to_ux500_charger(psy)); - - switch (psp) { - case POWER_SUPPLY_PROP_HEALTH: - if (di->flags.usbchargernotok) - val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; - else if (di->ac.wd_expired || di->usb.wd_expired) - val->intval = POWER_SUPPLY_HEALTH_DEAD; - else if (di->flags.usb_thermal_prot) - val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; - else if (di->flags.vbus_ovv) - val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; - else - val->intval = POWER_SUPPLY_HEALTH_GOOD; - break; - case POWER_SUPPLY_PROP_ONLINE: - val->intval = di->usb.charger_online; - break; - case POWER_SUPPLY_PROP_PRESENT: - val->intval = di->usb.charger_connected; - break; - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - di->usb.charger_voltage = ab8500_charger_get_vbus_voltage(di); - val->intval = di->usb.charger_voltage * 1000; - break; - case POWER_SUPPLY_PROP_VOLTAGE_AVG: - /* - * This property is used to indicate when CV mode is entered - * for the USB charger - */ - di->usb.cv_active = ab8500_charger_usb_cv(di); - val->intval = di->usb.cv_active; - break; - case POWER_SUPPLY_PROP_CURRENT_NOW: - val->intval = ab8500_charger_get_usb_current(di) * 1000; - break; - case POWER_SUPPLY_PROP_CURRENT_AVG: - /* - * This property is used to indicate when VBUS has collapsed - * due to too high output current from the USB charger - */ - if (di->flags.vbus_collapse) - val->intval = 1; - else - val->intval = 0; - break; - default: - return -EINVAL; - } - return 0; -} - -/** - * ab8500_charger_init_hw_registers() - Set up charger related registers - * @di: pointer to the ab8500_charger structure - * - * Set up charger OVV, watchdog and maximum voltage registers as well as - * charging of the backup battery - */ -static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) -{ - int ret = 0; - - /* Setup maximum charger current and voltage for ABB cut2.0 */ - if (!is_ab8500_1p1_or_earlier(di->parent)) { - ret = abx500_set_register_interruptible(di->dev, - AB8500_CHARGER, - AB8500_CH_VOLT_LVL_MAX_REG, CH_VOL_LVL_4P6); - if (ret) { - dev_err(di->dev, - "failed to set CH_VOLT_LVL_MAX_REG\n"); - goto out; - } - - ret = abx500_set_register_interruptible(di->dev, - AB8500_CHARGER, - AB8500_CH_OPT_CRNTLVL_MAX_REG, CH_OP_CUR_LVL_1P6); - if (ret) { - dev_err(di->dev, - "failed to set CH_OPT_CRNTLVL_MAX_REG\n"); - goto out; - } - } - - /* VBUS OVV set to 6.3V and enable automatic current limitiation */ - ret = abx500_set_register_interruptible(di->dev, - AB8500_CHARGER, - AB8500_USBCH_CTRL2_REG, - VBUS_OVV_SELECT_6P3V | VBUS_AUTO_IN_CURR_LIM_ENA); - if (ret) { - dev_err(di->dev, "failed to set VBUS OVV\n"); - goto out; - } - - /* Enable main watchdog in OTP */ - ret = abx500_set_register_interruptible(di->dev, - AB8500_OTP_EMUL, AB8500_OTP_CONF_15, OTP_ENABLE_WD); - if (ret) { - dev_err(di->dev, "failed to enable main WD in OTP\n"); - goto out; - } - - /* Enable main watchdog */ - ret = abx500_set_register_interruptible(di->dev, - AB8500_SYS_CTRL2_BLOCK, - AB8500_MAIN_WDOG_CTRL_REG, MAIN_WDOG_ENA); - if (ret) { - dev_err(di->dev, "faile to enable main watchdog\n"); - goto out; - } - - /* - * Due to internal synchronisation, Enable and Kick watchdog bits - * cannot be enabled in a single write. - * A minimum delay of 2*32 kHz period (62.5µs) must be inserted - * between writing Enable then Kick bits. - */ - udelay(63); - - /* Kick main watchdog */ - ret = abx500_set_register_interruptible(di->dev, - AB8500_SYS_CTRL2_BLOCK, - AB8500_MAIN_WDOG_CTRL_REG, - (MAIN_WDOG_ENA | MAIN_WDOG_KICK)); - if (ret) { - dev_err(di->dev, "failed to kick main watchdog\n"); - goto out; - } - - /* Disable main watchdog */ - ret = abx500_set_register_interruptible(di->dev, - AB8500_SYS_CTRL2_BLOCK, - AB8500_MAIN_WDOG_CTRL_REG, MAIN_WDOG_DIS); - if (ret) { - dev_err(di->dev, "failed to disable main watchdog\n"); - goto out; - } - - /* Set watchdog timeout */ - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CH_WD_TIMER_REG, WD_TIMER); - if (ret) { - dev_err(di->dev, "failed to set charger watchdog timeout\n"); - goto out; - } - - /* Backup battery voltage and current */ - ret = abx500_set_register_interruptible(di->dev, - AB8500_RTC, - AB8500_RTC_BACKUP_CHG_REG, - di->bat->bkup_bat_v | - di->bat->bkup_bat_i); - if (ret) { - dev_err(di->dev, "failed to setup backup battery charging\n"); - goto out; - } - - /* Enable backup battery charging */ - abx500_mask_and_set_register_interruptible(di->dev, - AB8500_RTC, AB8500_RTC_CTRL_REG, - RTC_BUP_CH_ENA, RTC_BUP_CH_ENA); - if (ret < 0) - dev_err(di->dev, "%s mask and set failed\n", __func__); - -out: - return ret; -} - -/* - * ab8500 charger driver interrupts and their respective isr - */ -static struct ab8500_charger_interrupts ab8500_charger_irq[] = { - {"MAIN_CH_UNPLUG_DET", ab8500_charger_mainchunplugdet_handler}, - {"MAIN_CHARGE_PLUG_DET", ab8500_charger_mainchplugdet_handler}, - {"MAIN_EXT_CH_NOT_OK", ab8500_charger_mainextchnotok_handler}, - {"MAIN_CH_TH_PROT_R", ab8500_charger_mainchthprotr_handler}, - {"MAIN_CH_TH_PROT_F", ab8500_charger_mainchthprotf_handler}, - {"VBUS_DET_F", ab8500_charger_vbusdetf_handler}, - {"VBUS_DET_R", ab8500_charger_vbusdetr_handler}, - {"USB_LINK_STATUS", ab8500_charger_usblinkstatus_handler}, - {"USB_CH_TH_PROT_R", ab8500_charger_usbchthprotr_handler}, - {"USB_CH_TH_PROT_F", ab8500_charger_usbchthprotf_handler}, - {"USB_CHARGER_NOT_OKR", ab8500_charger_usbchargernotokr_handler}, - {"VBUS_OVV", ab8500_charger_vbusovv_handler}, - {"CH_WD_EXP", ab8500_charger_chwdexp_handler}, -}; - -static int ab8500_charger_usb_notifier_call(struct notifier_block *nb, - unsigned long event, void *power) -{ - struct ab8500_charger *di = - container_of(nb, struct ab8500_charger, nb); - enum ab8500_usb_state bm_usb_state; - unsigned mA = *((unsigned *)power); - - if (event != USB_EVENT_VBUS) { - dev_dbg(di->dev, "not a standard host, returning\n"); - return NOTIFY_DONE; - } - - /* TODO: State is fabricate here. See if charger really needs USB - * state or if mA is enough - */ - if ((di->usb_state.usb_current == 2) && (mA > 2)) - bm_usb_state = AB8500_BM_USB_STATE_RESUME; - else if (mA == 0) - bm_usb_state = AB8500_BM_USB_STATE_RESET_HS; - else if (mA == 2) - bm_usb_state = AB8500_BM_USB_STATE_SUSPEND; - else if (mA >= 8) /* 8, 100, 500 */ - bm_usb_state = AB8500_BM_USB_STATE_CONFIGURED; - else /* Should never occur */ - bm_usb_state = AB8500_BM_USB_STATE_RESET_FS; - - dev_dbg(di->dev, "%s usb_state: 0x%02x mA: %d\n", - __func__, bm_usb_state, mA); - - spin_lock(&di->usb_state.usb_lock); - di->usb_state.usb_changed = true; - spin_unlock(&di->usb_state.usb_lock); - - di->usb_state.state = bm_usb_state; - di->usb_state.usb_current = mA; - - queue_work(di->charger_wq, &di->usb_state_changed_work); - - return NOTIFY_OK; -} - -#if defined(CONFIG_PM) -static int ab8500_charger_resume(struct platform_device *pdev) -{ - int ret; - struct ab8500_charger *di = platform_get_drvdata(pdev); - - /* - * For ABB revision 1.0 and 1.1 there is a bug in the watchdog - * logic. That means we have to continously kick the charger - * watchdog even when no charger is connected. This is only - * valid once the AC charger has been enabled. This is - * a bug that is not handled by the algorithm and the - * watchdog have to be kicked by the charger driver - * when the AC charger is disabled - */ - if (di->ac_conn && is_ab8500_1p1_or_earlier(di->parent)) { - ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, - AB8500_CHARG_WD_CTRL, CHARG_WD_KICK); - if (ret) - dev_err(di->dev, "Failed to kick WD!\n"); - - /* If not already pending start a new timer */ - if (!delayed_work_pending( - &di->kick_wd_work)) { - queue_delayed_work(di->charger_wq, &di->kick_wd_work, - round_jiffies(WD_KICK_INTERVAL)); - } - } - - /* If we still have a HW failure, schedule a new check */ - if (di->flags.mainextchnotok || di->flags.vbus_ovv) { - queue_delayed_work(di->charger_wq, - &di->check_hw_failure_work, 0); - } - - return 0; -} - -static int ab8500_charger_suspend(struct platform_device *pdev, - pm_message_t state) -{ - struct ab8500_charger *di = platform_get_drvdata(pdev); - - /* Cancel any pending HW failure check */ - if (delayed_work_pending(&di->check_hw_failure_work)) - cancel_delayed_work(&di->check_hw_failure_work); - - return 0; -} -#else -#define ab8500_charger_suspend NULL -#define ab8500_charger_resume NULL -#endif - -static int __devexit ab8500_charger_remove(struct platform_device *pdev) -{ - struct ab8500_charger *di = platform_get_drvdata(pdev); - int i, irq, ret; - - /* Disable AC charging */ - ab8500_charger_ac_en(&di->ac_chg, false, 0, 0); - - /* Disable USB charging */ - ab8500_charger_usb_en(&di->usb_chg, false, 0, 0); - - /* Disable interrupts */ - for (i = 0; i < ARRAY_SIZE(ab8500_charger_irq); i++) { - irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name); - free_irq(irq, di); - } - - /* disable the regulator */ - regulator_put(di->regu); - - /* Backup battery voltage and current disable */ - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_RTC, AB8500_RTC_CTRL_REG, RTC_BUP_CH_ENA, 0); - if (ret < 0) - dev_err(di->dev, "%s mask and set failed\n", __func__); - - usb_unregister_notifier(di->usb_phy, &di->nb); - usb_put_transceiver(di->usb_phy); - - /* Delete the work queue */ - destroy_workqueue(di->charger_wq); - - flush_scheduled_work(); - power_supply_unregister(&di->usb_chg.psy); - power_supply_unregister(&di->ac_chg.psy); - platform_set_drvdata(pdev, NULL); - kfree(di); - - return 0; -} - -static int __devinit ab8500_charger_probe(struct platform_device *pdev) -{ - int irq, i, charger_status, ret = 0; - struct abx500_bm_plat_data *plat_data; - - struct ab8500_charger *di = - kzalloc(sizeof(struct ab8500_charger), GFP_KERNEL); - if (!di) - return -ENOMEM; - - /* get parent data */ - di->dev = &pdev->dev; - di->parent = dev_get_drvdata(pdev->dev.parent); - di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); - - /* initialize lock */ - spin_lock_init(&di->usb_state.usb_lock); - - /* get charger specific platform data */ - plat_data = pdev->dev.platform_data; - di->pdata = plat_data->charger; - - if (!di->pdata) { - dev_err(di->dev, "no charger platform data supplied\n"); - ret = -EINVAL; - goto free_device_info; - } - - /* get battery specific platform data */ - di->bat = plat_data->battery; - if (!di->bat) { - dev_err(di->dev, "no battery platform data supplied\n"); - ret = -EINVAL; - goto free_device_info; - } - - di->autopower = false; - - /* AC supply */ - /* power_supply base class */ - di->ac_chg.psy.name = "ab8500_ac"; - di->ac_chg.psy.type = POWER_SUPPLY_TYPE_MAINS; - di->ac_chg.psy.properties = ab8500_charger_ac_props; - di->ac_chg.psy.num_properties = ARRAY_SIZE(ab8500_charger_ac_props); - di->ac_chg.psy.get_property = ab8500_charger_ac_get_property; - di->ac_chg.psy.supplied_to = di->pdata->supplied_to; - di->ac_chg.psy.num_supplicants = di->pdata->num_supplicants; - /* ux500_charger sub-class */ - di->ac_chg.ops.enable = &ab8500_charger_ac_en; - di->ac_chg.ops.kick_wd = &ab8500_charger_watchdog_kick; - di->ac_chg.ops.update_curr = &ab8500_charger_update_charger_current; - di->ac_chg.max_out_volt = ab8500_charger_voltage_map[ - ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; - di->ac_chg.max_out_curr = ab8500_charger_current_map[ - ARRAY_SIZE(ab8500_charger_current_map) - 1]; - - /* USB supply */ - /* power_supply base class */ - di->usb_chg.psy.name = "ab8500_usb"; - di->usb_chg.psy.type = POWER_SUPPLY_TYPE_USB; - di->usb_chg.psy.properties = ab8500_charger_usb_props; - di->usb_chg.psy.num_properties = ARRAY_SIZE(ab8500_charger_usb_props); - di->usb_chg.psy.get_property = ab8500_charger_usb_get_property; - di->usb_chg.psy.supplied_to = di->pdata->supplied_to; - di->usb_chg.psy.num_supplicants = di->pdata->num_supplicants; - /* ux500_charger sub-class */ - di->usb_chg.ops.enable = &ab8500_charger_usb_en; - di->usb_chg.ops.kick_wd = &ab8500_charger_watchdog_kick; - di->usb_chg.ops.update_curr = &ab8500_charger_update_charger_current; - di->usb_chg.max_out_volt = ab8500_charger_voltage_map[ - ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; - di->usb_chg.max_out_curr = ab8500_charger_current_map[ - ARRAY_SIZE(ab8500_charger_current_map) - 1]; - - - /* Create a work queue for the charger */ - di->charger_wq = - create_singlethread_workqueue("ab8500_charger_wq"); - if (di->charger_wq == NULL) { - dev_err(di->dev, "failed to create work queue\n"); - goto free_device_info; - } - - /* Init work for HW failure check */ - INIT_DELAYED_WORK_DEFERRABLE(&di->check_hw_failure_work, - ab8500_charger_check_hw_failure_work); - INIT_DELAYED_WORK_DEFERRABLE(&di->check_usbchgnotok_work, - ab8500_charger_check_usbchargernotok_work); - - /* - * For ABB revision 1.0 and 1.1 there is a bug in the watchdog - * logic. That means we have to continously kick the charger - * watchdog even when no charger is connected. This is only - * valid once the AC charger has been enabled. This is - * a bug that is not handled by the algorithm and the - * watchdog have to be kicked by the charger driver - * when the AC charger is disabled - */ - INIT_DELAYED_WORK_DEFERRABLE(&di->kick_wd_work, - ab8500_charger_kick_watchdog_work); - - INIT_DELAYED_WORK_DEFERRABLE(&di->check_vbat_work, - ab8500_charger_check_vbat_work); - - /* Init work for charger detection */ - INIT_WORK(&di->usb_link_status_work, - ab8500_charger_usb_link_status_work); - INIT_WORK(&di->ac_work, ab8500_charger_ac_work); - INIT_WORK(&di->detect_usb_type_work, - ab8500_charger_detect_usb_type_work); - - INIT_WORK(&di->usb_state_changed_work, - ab8500_charger_usb_state_changed_work); - - /* Init work for checking HW status */ - INIT_WORK(&di->check_main_thermal_prot_work, - ab8500_charger_check_main_thermal_prot_work); - INIT_WORK(&di->check_usb_thermal_prot_work, - ab8500_charger_check_usb_thermal_prot_work); - - /* - * VDD ADC supply needs to be enabled from this driver when there - * is a charger connected to avoid erroneous BTEMP_HIGH/LOW - * interrupts during charging - */ - di->regu = regulator_get(di->dev, "vddadc"); - if (IS_ERR(di->regu)) { - ret = PTR_ERR(di->regu); - dev_err(di->dev, "failed to get vddadc regulator\n"); - goto free_charger_wq; - } - - - /* Initialize OVV, and other registers */ - ret = ab8500_charger_init_hw_registers(di); - if (ret) { - dev_err(di->dev, "failed to initialize ABB registers\n"); - goto free_regulator; - } - - /* Register AC charger class */ - ret = power_supply_register(di->dev, &di->ac_chg.psy); - if (ret) { - dev_err(di->dev, "failed to register AC charger\n"); - goto free_regulator; - } - - /* Register USB charger class */ - ret = power_supply_register(di->dev, &di->usb_chg.psy); - if (ret) { - dev_err(di->dev, "failed to register USB charger\n"); - goto free_ac; - } - - di->usb_phy = usb_get_transceiver(); - if (!di->usb_phy) { - dev_err(di->dev, "failed to get usb transceiver\n"); - ret = -EINVAL; - goto free_usb; - } - di->nb.notifier_call = ab8500_charger_usb_notifier_call; - ret = usb_register_notifier(di->usb_phy, &di->nb); - if (ret) { - dev_err(di->dev, "failed to register usb notifier\n"); - goto put_usb_phy; - } - - /* Identify the connected charger types during startup */ - charger_status = ab8500_charger_detect_chargers(di); - if (charger_status & AC_PW_CONN) { - di->ac.charger_connected = 1; - di->ac_conn = true; - ab8500_power_supply_changed(di, &di->ac_chg.psy); - sysfs_notify(&di->ac_chg.psy.dev->kobj, NULL, "present"); - } - - if (charger_status & USB_PW_CONN) { - dev_dbg(di->dev, "VBUS Detect during startup\n"); - di->vbus_detected = true; - di->vbus_detected_start = true; - queue_work(di->charger_wq, - &di->detect_usb_type_work); - } - - /* Register interrupts */ - for (i = 0; i < ARRAY_SIZE(ab8500_charger_irq); i++) { - irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name); - ret = request_threaded_irq(irq, NULL, ab8500_charger_irq[i].isr, - IRQF_SHARED | IRQF_NO_SUSPEND, - ab8500_charger_irq[i].name, di); - - if (ret != 0) { - dev_err(di->dev, "failed to request %s IRQ %d: %d\n" - , ab8500_charger_irq[i].name, irq, ret); - goto free_irq; - } - dev_dbg(di->dev, "Requested %s IRQ %d: %d\n", - ab8500_charger_irq[i].name, irq, ret); - } - - platform_set_drvdata(pdev, di); - - return ret; - -free_irq: - usb_unregister_notifier(di->usb_phy, &di->nb); - - /* We also have to free all successfully registered irqs */ - for (i = i - 1; i >= 0; i--) { - irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name); - free_irq(irq, di); - } -put_usb_phy: - usb_put_transceiver(di->usb_phy); -free_usb: - power_supply_unregister(&di->usb_chg.psy); -free_ac: - power_supply_unregister(&di->ac_chg.psy); -free_regulator: - regulator_put(di->regu); -free_charger_wq: - destroy_workqueue(di->charger_wq); -free_device_info: - kfree(di); - - return ret; -} - -static struct platform_driver ab8500_charger_driver = { - .probe = ab8500_charger_probe, - .remove = __devexit_p(ab8500_charger_remove), - .suspend = ab8500_charger_suspend, - .resume = ab8500_charger_resume, - .driver = { - .name = "ab8500-charger", - .owner = THIS_MODULE, - }, -}; - -static int __init ab8500_charger_init(void) -{ - return platform_driver_register(&ab8500_charger_driver); -} - -static void __exit ab8500_charger_exit(void) -{ - platform_driver_unregister(&ab8500_charger_driver); -} - -subsys_initcall_sync(ab8500_charger_init); -module_exit(ab8500_charger_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Johan Palsson, Karl Komierowski, Arun R Murthy"); -MODULE_ALIAS("platform:ab8500-charger"); -MODULE_DESCRIPTION("AB8500 charger management driver"); diff --git a/trunk/drivers/power/ab8500_fg.c b/trunk/drivers/power/ab8500_fg.c deleted file mode 100644 index c22f2f05657e..000000000000 --- a/trunk/drivers/power/ab8500_fg.c +++ /dev/null @@ -1,2637 +0,0 @@ -/* - * Copyright (C) ST-Ericsson AB 2012 - * - * Main and Back-up battery management driver. - * - * Note: Backup battery management is required in case of Li-Ion battery and not - * for capacitive battery. HREF boards have capacitive battery and hence backup - * battery management is not used and the supported code is available in this - * driver. - * - * License Terms: GNU General Public License v2 - * Author: - * Johan Palsson - * Karl Komierowski - * Arun R Murthy - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MILLI_TO_MICRO 1000 -#define FG_LSB_IN_MA 1627 -#define QLSB_NANO_AMP_HOURS_X10 1129 -#define INS_CURR_TIMEOUT (3 * HZ) - -#define SEC_TO_SAMPLE(S) (S * 4) - -#define NBR_AVG_SAMPLES 20 - -#define LOW_BAT_CHECK_INTERVAL (2 * HZ) - -#define VALID_CAPACITY_SEC (45 * 60) /* 45 minutes */ -#define BATT_OK_MIN 2360 /* mV */ -#define BATT_OK_INCREMENT 50 /* mV */ -#define BATT_OK_MAX_NR_INCREMENTS 0xE - -/* FG constants */ -#define BATT_OVV 0x01 - -#define interpolate(x, x1, y1, x2, y2) \ - ((y1) + ((((y2) - (y1)) * ((x) - (x1))) / ((x2) - (x1)))); - -#define to_ab8500_fg_device_info(x) container_of((x), \ - struct ab8500_fg, fg_psy); - -/** - * struct ab8500_fg_interrupts - ab8500 fg interupts - * @name: name of the interrupt - * @isr function pointer to the isr - */ -struct ab8500_fg_interrupts { - char *name; - irqreturn_t (*isr)(int irq, void *data); -}; - -enum ab8500_fg_discharge_state { - AB8500_FG_DISCHARGE_INIT, - AB8500_FG_DISCHARGE_INITMEASURING, - AB8500_FG_DISCHARGE_INIT_RECOVERY, - AB8500_FG_DISCHARGE_RECOVERY, - AB8500_FG_DISCHARGE_READOUT_INIT, - AB8500_FG_DISCHARGE_READOUT, - AB8500_FG_DISCHARGE_WAKEUP, -}; - -static char *discharge_state[] = { - "DISCHARGE_INIT", - "DISCHARGE_INITMEASURING", - "DISCHARGE_INIT_RECOVERY", - "DISCHARGE_RECOVERY", - "DISCHARGE_READOUT_INIT", - "DISCHARGE_READOUT", - "DISCHARGE_WAKEUP", -}; - -enum ab8500_fg_charge_state { - AB8500_FG_CHARGE_INIT, - AB8500_FG_CHARGE_READOUT, -}; - -static char *charge_state[] = { - "CHARGE_INIT", - "CHARGE_READOUT", -}; - -enum ab8500_fg_calibration_state { - AB8500_FG_CALIB_INIT, - AB8500_FG_CALIB_WAIT, - AB8500_FG_CALIB_END, -}; - -struct ab8500_fg_avg_cap { - int avg; - int samples[NBR_AVG_SAMPLES]; - __kernel_time_t time_stamps[NBR_AVG_SAMPLES]; - int pos; - int nbr_samples; - int sum; -}; - -struct ab8500_fg_battery_capacity { - int max_mah_design; - int max_mah; - int mah; - int permille; - int level; - int prev_mah; - int prev_percent; - int prev_level; - int user_mah; -}; - -struct ab8500_fg_flags { - bool fg_enabled; - bool conv_done; - bool charging; - bool fully_charged; - bool force_full; - bool low_bat_delay; - bool low_bat; - bool bat_ovv; - bool batt_unknown; - bool calibrate; - bool user_cap; - bool batt_id_received; -}; - -struct inst_curr_result_list { - struct list_head list; - int *result; -}; - -/** - * struct ab8500_fg - ab8500 FG device information - * @dev: Pointer to the structure device - * @node: a list of AB8500 FGs, hence prepared for reentrance - * @irq holds the CCEOC interrupt number - * @vbat: Battery voltage in mV - * @vbat_nom: Nominal battery voltage in mV - * @inst_curr: Instantenous battery current in mA - * @avg_curr: Average battery current in mA - * @bat_temp battery temperature - * @fg_samples: Number of samples used in the FG accumulation - * @accu_charge: Accumulated charge from the last conversion - * @recovery_cnt: Counter for recovery mode - * @high_curr_cnt: Counter for high current mode - * @init_cnt: Counter for init mode - * @recovery_needed: Indicate if recovery is needed - * @high_curr_mode: Indicate if we're in high current mode - * @init_capacity: Indicate if initial capacity measuring should be done - * @turn_off_fg: True if fg was off before current measurement - * @calib_state State during offset calibration - * @discharge_state: Current discharge state - * @charge_state: Current charge state - * @ab8500_fg_complete Completion struct used for the instant current reading - * @flags: Structure for information about events triggered - * @bat_cap: Structure for battery capacity specific parameters - * @avg_cap: Average capacity filter - * @parent: Pointer to the struct ab8500 - * @gpadc: Pointer to the struct gpadc - * @pdata: Pointer to the abx500_fg platform data - * @bat: Pointer to the abx500_bm platform data - * @fg_psy: Structure that holds the FG specific battery properties - * @fg_wq: Work queue for running the FG algorithm - * @fg_periodic_work: Work to run the FG algorithm periodically - * @fg_low_bat_work: Work to check low bat condition - * @fg_reinit_work Work used to reset and reinitialise the FG algorithm - * @fg_work: Work to run the FG algorithm instantly - * @fg_acc_cur_work: Work to read the FG accumulator - * @fg_check_hw_failure_work: Work for checking HW state - * @cc_lock: Mutex for locking the CC - * @fg_kobject: Structure of type kobject - */ -struct ab8500_fg { - struct device *dev; - struct list_head node; - int irq; - int vbat; - int vbat_nom; - int inst_curr; - int avg_curr; - int bat_temp; - int fg_samples; - int accu_charge; - int recovery_cnt; - int high_curr_cnt; - int init_cnt; - bool recovery_needed; - bool high_curr_mode; - bool init_capacity; - bool turn_off_fg; - enum ab8500_fg_calibration_state calib_state; - enum ab8500_fg_discharge_state discharge_state; - enum ab8500_fg_charge_state charge_state; - struct completion ab8500_fg_complete; - struct ab8500_fg_flags flags; - struct ab8500_fg_battery_capacity bat_cap; - struct ab8500_fg_avg_cap avg_cap; - struct ab8500 *parent; - struct ab8500_gpadc *gpadc; - struct abx500_fg_platform_data *pdata; - struct abx500_bm_data *bat; - struct power_supply fg_psy; - struct workqueue_struct *fg_wq; - struct delayed_work fg_periodic_work; - struct delayed_work fg_low_bat_work; - struct delayed_work fg_reinit_work; - struct work_struct fg_work; - struct work_struct fg_acc_cur_work; - struct delayed_work fg_check_hw_failure_work; - struct mutex cc_lock; - struct kobject fg_kobject; -}; -static LIST_HEAD(ab8500_fg_list); - -/** - * ab8500_fg_get() - returns a reference to the primary AB8500 fuel gauge - * (i.e. the first fuel gauge in the instance list) - */ -struct ab8500_fg *ab8500_fg_get(void) -{ - struct ab8500_fg *fg; - - if (list_empty(&ab8500_fg_list)) - return NULL; - - fg = list_first_entry(&ab8500_fg_list, struct ab8500_fg, node); - return fg; -} - -/* Main battery properties */ -static enum power_supply_property ab8500_fg_props[] = { - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_CURRENT_NOW, - POWER_SUPPLY_PROP_CURRENT_AVG, - POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, - POWER_SUPPLY_PROP_ENERGY_FULL, - POWER_SUPPLY_PROP_ENERGY_NOW, - POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, - POWER_SUPPLY_PROP_CHARGE_FULL, - POWER_SUPPLY_PROP_CHARGE_NOW, - POWER_SUPPLY_PROP_CAPACITY, - POWER_SUPPLY_PROP_CAPACITY_LEVEL, -}; - -/* - * This array maps the raw hex value to lowbat voltage used by the AB8500 - * Values taken from the UM0836 - */ -static int ab8500_fg_lowbat_voltage_map[] = { - 2300 , - 2325 , - 2350 , - 2375 , - 2400 , - 2425 , - 2450 , - 2475 , - 2500 , - 2525 , - 2550 , - 2575 , - 2600 , - 2625 , - 2650 , - 2675 , - 2700 , - 2725 , - 2750 , - 2775 , - 2800 , - 2825 , - 2850 , - 2875 , - 2900 , - 2925 , - 2950 , - 2975 , - 3000 , - 3025 , - 3050 , - 3075 , - 3100 , - 3125 , - 3150 , - 3175 , - 3200 , - 3225 , - 3250 , - 3275 , - 3300 , - 3325 , - 3350 , - 3375 , - 3400 , - 3425 , - 3450 , - 3475 , - 3500 , - 3525 , - 3550 , - 3575 , - 3600 , - 3625 , - 3650 , - 3675 , - 3700 , - 3725 , - 3750 , - 3775 , - 3800 , - 3825 , - 3850 , - 3850 , -}; - -static u8 ab8500_volt_to_regval(int voltage) -{ - int i; - - if (voltage < ab8500_fg_lowbat_voltage_map[0]) - return 0; - - for (i = 0; i < ARRAY_SIZE(ab8500_fg_lowbat_voltage_map); i++) { - if (voltage < ab8500_fg_lowbat_voltage_map[i]) - return (u8) i - 1; - } - - /* If not captured above, return index of last element */ - return (u8) ARRAY_SIZE(ab8500_fg_lowbat_voltage_map) - 1; -} - -/** - * ab8500_fg_is_low_curr() - Low or high current mode - * @di: pointer to the ab8500_fg structure - * @curr: the current to base or our decision on - * - * Low current mode if the current consumption is below a certain threshold - */ -static int ab8500_fg_is_low_curr(struct ab8500_fg *di, int curr) -{ - /* - * We want to know if we're in low current mode - */ - if (curr > -di->bat->fg_params->high_curr_threshold) - return true; - else - return false; -} - -/** - * ab8500_fg_add_cap_sample() - Add capacity to average filter - * @di: pointer to the ab8500_fg structure - * @sample: the capacity in mAh to add to the filter - * - * A capacity is added to the filter and a new mean capacity is calculated and - * returned - */ -static int ab8500_fg_add_cap_sample(struct ab8500_fg *di, int sample) -{ - struct timespec ts; - struct ab8500_fg_avg_cap *avg = &di->avg_cap; - - getnstimeofday(&ts); - - do { - avg->sum += sample - avg->samples[avg->pos]; - avg->samples[avg->pos] = sample; - avg->time_stamps[avg->pos] = ts.tv_sec; - avg->pos++; - - if (avg->pos == NBR_AVG_SAMPLES) - avg->pos = 0; - - if (avg->nbr_samples < NBR_AVG_SAMPLES) - avg->nbr_samples++; - - /* - * Check the time stamp for each sample. If too old, - * replace with latest sample - */ - } while (ts.tv_sec - VALID_CAPACITY_SEC > avg->time_stamps[avg->pos]); - - avg->avg = avg->sum / avg->nbr_samples; - - return avg->avg; -} - -/** - * ab8500_fg_clear_cap_samples() - Clear average filter - * @di: pointer to the ab8500_fg structure - * - * The capacity filter is is reset to zero. - */ -static void ab8500_fg_clear_cap_samples(struct ab8500_fg *di) -{ - int i; - struct ab8500_fg_avg_cap *avg = &di->avg_cap; - - avg->pos = 0; - avg->nbr_samples = 0; - avg->sum = 0; - avg->avg = 0; - - for (i = 0; i < NBR_AVG_SAMPLES; i++) { - avg->samples[i] = 0; - avg->time_stamps[i] = 0; - } -} - -/** - * ab8500_fg_fill_cap_sample() - Fill average filter - * @di: pointer to the ab8500_fg structure - * @sample: the capacity in mAh to fill the filter with - * - * The capacity filter is filled with a capacity in mAh - */ -static void ab8500_fg_fill_cap_sample(struct ab8500_fg *di, int sample) -{ - int i; - struct timespec ts; - struct ab8500_fg_avg_cap *avg = &di->avg_cap; - - getnstimeofday(&ts); - - for (i = 0; i < NBR_AVG_SAMPLES; i++) { - avg->samples[i] = sample; - avg->time_stamps[i] = ts.tv_sec; - } - - avg->pos = 0; - avg->nbr_samples = NBR_AVG_SAMPLES; - avg->sum = sample * NBR_AVG_SAMPLES; - avg->avg = sample; -} - -/** - * ab8500_fg_coulomb_counter() - enable coulomb counter - * @di: pointer to the ab8500_fg structure - * @enable: enable/disable - * - * Enable/Disable coulomb counter. - * On failure returns negative value. - */ -static int ab8500_fg_coulomb_counter(struct ab8500_fg *di, bool enable) -{ - int ret = 0; - mutex_lock(&di->cc_lock); - if (enable) { - /* To be able to reprogram the number of samples, we have to - * first stop the CC and then enable it again */ - ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, - AB8500_RTC_CC_CONF_REG, 0x00); - if (ret) - goto cc_err; - - /* Program the samples */ - ret = abx500_set_register_interruptible(di->dev, - AB8500_GAS_GAUGE, AB8500_GASG_CC_NCOV_ACCU, - di->fg_samples); - if (ret) - goto cc_err; - - /* Start the CC */ - ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, - AB8500_RTC_CC_CONF_REG, - (CC_DEEP_SLEEP_ENA | CC_PWR_UP_ENA)); - if (ret) - goto cc_err; - - di->flags.fg_enabled = true; - } else { - /* Clear any pending read requests */ - ret = abx500_set_register_interruptible(di->dev, - AB8500_GAS_GAUGE, AB8500_GASG_CC_CTRL_REG, 0); - if (ret) - goto cc_err; - - ret = abx500_set_register_interruptible(di->dev, - AB8500_GAS_GAUGE, AB8500_GASG_CC_NCOV_ACCU_CTRL, 0); - if (ret) - goto cc_err; - - /* Stop the CC */ - ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, - AB8500_RTC_CC_CONF_REG, 0); - if (ret) - goto cc_err; - - di->flags.fg_enabled = false; - - } - dev_dbg(di->dev, " CC enabled: %d Samples: %d\n", - enable, di->fg_samples); - - mutex_unlock(&di->cc_lock); - - return ret; -cc_err: - dev_err(di->dev, "%s Enabling coulomb counter failed\n", __func__); - mutex_unlock(&di->cc_lock); - return ret; -} - -/** - * ab8500_fg_inst_curr_start() - start battery instantaneous current - * @di: pointer to the ab8500_fg structure - * - * Returns 0 or error code - * Note: This is part "one" and has to be called before - * ab8500_fg_inst_curr_finalize() - */ - int ab8500_fg_inst_curr_start(struct ab8500_fg *di) -{ - u8 reg_val; - int ret; - - mutex_lock(&di->cc_lock); - - ret = abx500_get_register_interruptible(di->dev, AB8500_RTC, - AB8500_RTC_CC_CONF_REG, ®_val); - if (ret < 0) - goto fail; - - if (!(reg_val & CC_PWR_UP_ENA)) { - dev_dbg(di->dev, "%s Enable FG\n", __func__); - di->turn_off_fg = true; - - /* Program the samples */ - ret = abx500_set_register_interruptible(di->dev, - AB8500_GAS_GAUGE, AB8500_GASG_CC_NCOV_ACCU, - SEC_TO_SAMPLE(10)); - if (ret) - goto fail; - - /* Start the CC */ - ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, - AB8500_RTC_CC_CONF_REG, - (CC_DEEP_SLEEP_ENA | CC_PWR_UP_ENA)); - if (ret) - goto fail; - } else { - di->turn_off_fg = false; - } - - /* Return and WFI */ - INIT_COMPLETION(di->ab8500_fg_complete); - enable_irq(di->irq); - - /* Note: cc_lock is still locked */ - return 0; -fail: - mutex_unlock(&di->cc_lock); - return ret; -} - -/** - * ab8500_fg_inst_curr_done() - check if fg conversion is done - * @di: pointer to the ab8500_fg structure - * - * Returns 1 if conversion done, 0 if still waiting - */ -int ab8500_fg_inst_curr_done(struct ab8500_fg *di) -{ - return completion_done(&di->ab8500_fg_complete); -} - -/** - * ab8500_fg_inst_curr_finalize() - battery instantaneous current - * @di: pointer to the ab8500_fg structure - * @res: battery instantenous current(on success) - * - * Returns 0 or an error code - * Note: This is part "two" and has to be called at earliest 250 ms - * after ab8500_fg_inst_curr_start() - */ -int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res) -{ - u8 low, high; - int val; - int ret; - int timeout; - - if (!completion_done(&di->ab8500_fg_complete)) { - timeout = wait_for_completion_timeout(&di->ab8500_fg_complete, - INS_CURR_TIMEOUT); - dev_dbg(di->dev, "Finalize time: %d ms\n", - ((INS_CURR_TIMEOUT - timeout) * 1000) / HZ); - if (!timeout) { - ret = -ETIME; - disable_irq(di->irq); - dev_err(di->dev, "completion timed out [%d]\n", - __LINE__); - goto fail; - } - } - - disable_irq(di->irq); - - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_GAS_GAUGE, AB8500_GASG_CC_CTRL_REG, - READ_REQ, READ_REQ); - - /* 100uS between read request and read is needed */ - usleep_range(100, 100); - - /* Read CC Sample conversion value Low and high */ - ret = abx500_get_register_interruptible(di->dev, AB8500_GAS_GAUGE, - AB8500_GASG_CC_SMPL_CNVL_REG, &low); - if (ret < 0) - goto fail; - - ret = abx500_get_register_interruptible(di->dev, AB8500_GAS_GAUGE, - AB8500_GASG_CC_SMPL_CNVH_REG, &high); - if (ret < 0) - goto fail; - - /* - * negative value for Discharging - * convert 2's compliment into decimal - */ - if (high & 0x10) - val = (low | (high << 8) | 0xFFFFE000); - else - val = (low | (high << 8)); - - /* - * Convert to unit value in mA - * Full scale input voltage is - * 66.660mV => LSB = 66.660mV/(4096*res) = 1.627mA - * Given a 250ms conversion cycle time the LSB corresponds - * to 112.9 nAh. Convert to current by dividing by the conversion - * time in hours (250ms = 1 / (3600 * 4)h) - * 112.9nAh assumes 10mOhm, but fg_res is in 0.1mOhm - */ - val = (val * QLSB_NANO_AMP_HOURS_X10 * 36 * 4) / - (1000 * di->bat->fg_res); - - if (di->turn_off_fg) { - dev_dbg(di->dev, "%s Disable FG\n", __func__); - - /* Clear any pending read requests */ - ret = abx500_set_register_interruptible(di->dev, - AB8500_GAS_GAUGE, AB8500_GASG_CC_CTRL_REG, 0); - if (ret) - goto fail; - - /* Stop the CC */ - ret = abx500_set_register_interruptible(di->dev, AB8500_RTC, - AB8500_RTC_CC_CONF_REG, 0); - if (ret) - goto fail; - } - mutex_unlock(&di->cc_lock); - (*res) = val; - - return 0; -fail: - mutex_unlock(&di->cc_lock); - return ret; -} - -/** - * ab8500_fg_inst_curr_blocking() - battery instantaneous current - * @di: pointer to the ab8500_fg structure - * @res: battery instantenous current(on success) - * - * Returns 0 else error code - */ -int ab8500_fg_inst_curr_blocking(struct ab8500_fg *di) -{ - int ret; - int res = 0; - - ret = ab8500_fg_inst_curr_start(di); - if (ret) { - dev_err(di->dev, "Failed to initialize fg_inst\n"); - return 0; - } - - ret = ab8500_fg_inst_curr_finalize(di, &res); - if (ret) { - dev_err(di->dev, "Failed to finalize fg_inst\n"); - return 0; - } - - return res; -} - -/** - * ab8500_fg_acc_cur_work() - average battery current - * @work: pointer to the work_struct structure - * - * Updated the average battery current obtained from the - * coulomb counter. - */ -static void ab8500_fg_acc_cur_work(struct work_struct *work) -{ - int val; - int ret; - u8 low, med, high; - - struct ab8500_fg *di = container_of(work, - struct ab8500_fg, fg_acc_cur_work); - - mutex_lock(&di->cc_lock); - ret = abx500_set_register_interruptible(di->dev, AB8500_GAS_GAUGE, - AB8500_GASG_CC_NCOV_ACCU_CTRL, RD_NCONV_ACCU_REQ); - if (ret) - goto exit; - - ret = abx500_get_register_interruptible(di->dev, AB8500_GAS_GAUGE, - AB8500_GASG_CC_NCOV_ACCU_LOW, &low); - if (ret < 0) - goto exit; - - ret = abx500_get_register_interruptible(di->dev, AB8500_GAS_GAUGE, - AB8500_GASG_CC_NCOV_ACCU_MED, &med); - if (ret < 0) - goto exit; - - ret = abx500_get_register_interruptible(di->dev, AB8500_GAS_GAUGE, - AB8500_GASG_CC_NCOV_ACCU_HIGH, &high); - if (ret < 0) - goto exit; - - /* Check for sign bit in case of negative value, 2's compliment */ - if (high & 0x10) - val = (low | (med << 8) | (high << 16) | 0xFFE00000); - else - val = (low | (med << 8) | (high << 16)); - - /* - * Convert to uAh - * Given a 250ms conversion cycle time the LSB corresponds - * to 112.9 nAh. - * 112.9nAh assumes 10mOhm, but fg_res is in 0.1mOhm - */ - di->accu_charge = (val * QLSB_NANO_AMP_HOURS_X10) / - (100 * di->bat->fg_res); - - /* - * Convert to unit value in mA - * Full scale input voltage is - * 66.660mV => LSB = 66.660mV/(4096*res) = 1.627mA - * Given a 250ms conversion cycle time the LSB corresponds - * to 112.9 nAh. Convert to current by dividing by the conversion - * time in hours (= samples / (3600 * 4)h) - * 112.9nAh assumes 10mOhm, but fg_res is in 0.1mOhm - */ - di->avg_curr = (val * QLSB_NANO_AMP_HOURS_X10 * 36) / - (1000 * di->bat->fg_res * (di->fg_samples / 4)); - - di->flags.conv_done = true; - - mutex_unlock(&di->cc_lock); - - queue_work(di->fg_wq, &di->fg_work); - - return; -exit: - dev_err(di->dev, - "Failed to read or write gas gauge registers\n"); - mutex_unlock(&di->cc_lock); - queue_work(di->fg_wq, &di->fg_work); -} - -/** - * ab8500_fg_bat_voltage() - get battery voltage - * @di: pointer to the ab8500_fg structure - * - * Returns battery voltage(on success) else error code - */ -static int ab8500_fg_bat_voltage(struct ab8500_fg *di) -{ - int vbat; - static int prev; - - vbat = ab8500_gpadc_convert(di->gpadc, MAIN_BAT_V); - if (vbat < 0) { - dev_err(di->dev, - "%s gpadc conversion failed, using previous value\n", - __func__); - return prev; - } - - prev = vbat; - return vbat; -} - -/** - * ab8500_fg_volt_to_capacity() - Voltage based capacity - * @di: pointer to the ab8500_fg structure - * @voltage: The voltage to convert to a capacity - * - * Returns battery capacity in per mille based on voltage - */ -static int ab8500_fg_volt_to_capacity(struct ab8500_fg *di, int voltage) -{ - int i, tbl_size; - struct abx500_v_to_cap *tbl; - int cap = 0; - - tbl = di->bat->bat_type[di->bat->batt_id].v_to_cap_tbl, - tbl_size = di->bat->bat_type[di->bat->batt_id].n_v_cap_tbl_elements; - - for (i = 0; i < tbl_size; ++i) { - if (voltage > tbl[i].voltage) - break; - } - - if ((i > 0) && (i < tbl_size)) { - cap = interpolate(voltage, - tbl[i].voltage, - tbl[i].capacity * 10, - tbl[i-1].voltage, - tbl[i-1].capacity * 10); - } else if (i == 0) { - cap = 1000; - } else { - cap = 0; - } - - dev_dbg(di->dev, "%s Vbat: %d, Cap: %d per mille", - __func__, voltage, cap); - - return cap; -} - -/** - * ab8500_fg_uncomp_volt_to_capacity() - Uncompensated voltage based capacity - * @di: pointer to the ab8500_fg structure - * - * Returns battery capacity based on battery voltage that is not compensated - * for the voltage drop due to the load - */ -static int ab8500_fg_uncomp_volt_to_capacity(struct ab8500_fg *di) -{ - di->vbat = ab8500_fg_bat_voltage(di); - return ab8500_fg_volt_to_capacity(di, di->vbat); -} - -/** - * ab8500_fg_battery_resistance() - Returns the battery inner resistance - * @di: pointer to the ab8500_fg structure - * - * Returns battery inner resistance added with the fuel gauge resistor value - * to get the total resistance in the whole link from gnd to bat+ node. - */ -static int ab8500_fg_battery_resistance(struct ab8500_fg *di) -{ - int i, tbl_size; - struct batres_vs_temp *tbl; - int resist = 0; - - tbl = di->bat->bat_type[di->bat->batt_id].batres_tbl; - tbl_size = di->bat->bat_type[di->bat->batt_id].n_batres_tbl_elements; - - for (i = 0; i < tbl_size; ++i) { - if (di->bat_temp / 10 > tbl[i].temp) - break; - } - - if ((i > 0) && (i < tbl_size)) { - resist = interpolate(di->bat_temp / 10, - tbl[i].temp, - tbl[i].resist, - tbl[i-1].temp, - tbl[i-1].resist); - } else if (i == 0) { - resist = tbl[0].resist; - } else { - resist = tbl[tbl_size - 1].resist; - } - - dev_dbg(di->dev, "%s Temp: %d battery internal resistance: %d" - " fg resistance %d, total: %d (mOhm)\n", - __func__, di->bat_temp, resist, di->bat->fg_res / 10, - (di->bat->fg_res / 10) + resist); - - /* fg_res variable is in 0.1mOhm */ - resist += di->bat->fg_res / 10; - - return resist; -} - -/** - * ab8500_fg_load_comp_volt_to_capacity() - Load compensated voltage based capacity - * @di: pointer to the ab8500_fg structure - * - * Returns battery capacity based on battery voltage that is load compensated - * for the voltage drop - */ -static int ab8500_fg_load_comp_volt_to_capacity(struct ab8500_fg *di) -{ - int vbat_comp, res; - int i = 0; - int vbat = 0; - - ab8500_fg_inst_curr_start(di); - - do { - vbat += ab8500_fg_bat_voltage(di); - i++; - msleep(5); - } while (!ab8500_fg_inst_curr_done(di)); - - ab8500_fg_inst_curr_finalize(di, &di->inst_curr); - - di->vbat = vbat / i; - res = ab8500_fg_battery_resistance(di); - - /* Use Ohms law to get the load compensated voltage */ - vbat_comp = di->vbat - (di->inst_curr * res) / 1000; - - dev_dbg(di->dev, "%s Measured Vbat: %dmV,Compensated Vbat %dmV, " - "R: %dmOhm, Current: %dmA Vbat Samples: %d\n", - __func__, di->vbat, vbat_comp, res, di->inst_curr, i); - - return ab8500_fg_volt_to_capacity(di, vbat_comp); -} - -/** - * ab8500_fg_convert_mah_to_permille() - Capacity in mAh to permille - * @di: pointer to the ab8500_fg structure - * @cap_mah: capacity in mAh - * - * Converts capacity in mAh to capacity in permille - */ -static int ab8500_fg_convert_mah_to_permille(struct ab8500_fg *di, int cap_mah) -{ - return (cap_mah * 1000) / di->bat_cap.max_mah_design; -} - -/** - * ab8500_fg_convert_permille_to_mah() - Capacity in permille to mAh - * @di: pointer to the ab8500_fg structure - * @cap_pm: capacity in permille - * - * Converts capacity in permille to capacity in mAh - */ -static int ab8500_fg_convert_permille_to_mah(struct ab8500_fg *di, int cap_pm) -{ - return cap_pm * di->bat_cap.max_mah_design / 1000; -} - -/** - * ab8500_fg_convert_mah_to_uwh() - Capacity in mAh to uWh - * @di: pointer to the ab8500_fg structure - * @cap_mah: capacity in mAh - * - * Converts capacity in mAh to capacity in uWh - */ -static int ab8500_fg_convert_mah_to_uwh(struct ab8500_fg *di, int cap_mah) -{ - u64 div_res; - u32 div_rem; - - div_res = ((u64) cap_mah) * ((u64) di->vbat_nom); - div_rem = do_div(div_res, 1000); - - /* Make sure to round upwards if necessary */ - if (div_rem >= 1000 / 2) - div_res++; - - return (int) div_res; -} - -/** - * ab8500_fg_calc_cap_charging() - Calculate remaining capacity while charging - * @di: pointer to the ab8500_fg structure - * - * Return the capacity in mAh based on previous calculated capcity and the FG - * accumulator register value. The filter is filled with this capacity - */ -static int ab8500_fg_calc_cap_charging(struct ab8500_fg *di) -{ - dev_dbg(di->dev, "%s cap_mah %d accu_charge %d\n", - __func__, - di->bat_cap.mah, - di->accu_charge); - - /* Capacity should not be less than 0 */ - if (di->bat_cap.mah + di->accu_charge > 0) - di->bat_cap.mah += di->accu_charge; - else - di->bat_cap.mah = 0; - /* - * We force capacity to 100% once when the algorithm - * reports that it's full. - */ - if (di->bat_cap.mah >= di->bat_cap.max_mah_design || - di->flags.force_full) { - di->bat_cap.mah = di->bat_cap.max_mah_design; - } - - ab8500_fg_fill_cap_sample(di, di->bat_cap.mah); - di->bat_cap.permille = - ab8500_fg_convert_mah_to_permille(di, di->bat_cap.mah); - - /* We need to update battery voltage and inst current when charging */ - di->vbat = ab8500_fg_bat_voltage(di); - di->inst_curr = ab8500_fg_inst_curr_blocking(di); - - return di->bat_cap.mah; -} - -/** - * ab8500_fg_calc_cap_discharge_voltage() - Capacity in discharge with voltage - * @di: pointer to the ab8500_fg structure - * @comp: if voltage should be load compensated before capacity calc - * - * Return the capacity in mAh based on the battery voltage. The voltage can - * either be load compensated or not. This value is added to the filter and a - * new mean value is calculated and returned. - */ -static int ab8500_fg_calc_cap_discharge_voltage(struct ab8500_fg *di, bool comp) -{ - int permille, mah; - - if (comp) - permille = ab8500_fg_load_comp_volt_to_capacity(di); - else - permille = ab8500_fg_uncomp_volt_to_capacity(di); - - mah = ab8500_fg_convert_permille_to_mah(di, permille); - - di->bat_cap.mah = ab8500_fg_add_cap_sample(di, mah); - di->bat_cap.permille = - ab8500_fg_convert_mah_to_permille(di, di->bat_cap.mah); - - return di->bat_cap.mah; -} - -/** - * ab8500_fg_calc_cap_discharge_fg() - Capacity in discharge with FG - * @di: pointer to the ab8500_fg structure - * - * Return the capacity in mAh based on previous calculated capcity and the FG - * accumulator register value. This value is added to the filter and a - * new mean value is calculated and returned. - */ -static int ab8500_fg_calc_cap_discharge_fg(struct ab8500_fg *di) -{ - int permille_volt, permille; - - dev_dbg(di->dev, "%s cap_mah %d accu_charge %d\n", - __func__, - di->bat_cap.mah, - di->accu_charge); - - /* Capacity should not be less than 0 */ - if (di->bat_cap.mah + di->accu_charge > 0) - di->bat_cap.mah += di->accu_charge; - else - di->bat_cap.mah = 0; - - if (di->bat_cap.mah >= di->bat_cap.max_mah_design) - di->bat_cap.mah = di->bat_cap.max_mah_design; - - /* - * Check against voltage based capacity. It can not be lower - * than what the uncompensated voltage says - */ - permille = ab8500_fg_convert_mah_to_permille(di, di->bat_cap.mah); - permille_volt = ab8500_fg_uncomp_volt_to_capacity(di); - - if (permille < permille_volt) { - di->bat_cap.permille = permille_volt; - di->bat_cap.mah = ab8500_fg_convert_permille_to_mah(di, - di->bat_cap.permille); - - dev_dbg(di->dev, "%s voltage based: perm %d perm_volt %d\n", - __func__, - permille, - permille_volt); - - ab8500_fg_fill_cap_sample(di, di->bat_cap.mah); - } else { - ab8500_fg_fill_cap_sample(di, di->bat_cap.mah); - di->bat_cap.permille = - ab8500_fg_convert_mah_to_permille(di, di->bat_cap.mah); - } - - return di->bat_cap.mah; -} - -/** - * ab8500_fg_capacity_level() - Get the battery capacity level - * @di: pointer to the ab8500_fg structure - * - * Get the battery capacity level based on the capacity in percent - */ -static int ab8500_fg_capacity_level(struct ab8500_fg *di) -{ - int ret, percent; - - percent = di->bat_cap.permille / 10; - - if (percent <= di->bat->cap_levels->critical || - di->flags.low_bat) - ret = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; - else if (percent <= di->bat->cap_levels->low) - ret = POWER_SUPPLY_CAPACITY_LEVEL_LOW; - else if (percent <= di->bat->cap_levels->normal) - ret = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; - else if (percent <= di->bat->cap_levels->high) - ret = POWER_SUPPLY_CAPACITY_LEVEL_HIGH; - else - ret = POWER_SUPPLY_CAPACITY_LEVEL_FULL; - - return ret; -} - -/** - * ab8500_fg_check_capacity_limits() - Check if capacity has changed - * @di: pointer to the ab8500_fg structure - * @init: capacity is allowed to go up in init mode - * - * Check if capacity or capacity limit has changed and notify the system - * about it using the power_supply framework - */ -static void ab8500_fg_check_capacity_limits(struct ab8500_fg *di, bool init) -{ - bool changed = false; - - di->bat_cap.level = ab8500_fg_capacity_level(di); - - if (di->bat_cap.level != di->bat_cap.prev_level) { - /* - * We do not allow reported capacity level to go up - * unless we're charging or if we're in init - */ - if (!(!di->flags.charging && di->bat_cap.level > - di->bat_cap.prev_level) || init) { - dev_dbg(di->dev, "level changed from %d to %d\n", - di->bat_cap.prev_level, - di->bat_cap.level); - di->bat_cap.prev_level = di->bat_cap.level; - changed = true; - } else { - dev_dbg(di->dev, "level not allowed to go up " - "since no charger is connected: %d to %d\n", - di->bat_cap.prev_level, - di->bat_cap.level); - } - } - - /* - * If we have received the LOW_BAT IRQ, set capacity to 0 to initiate - * shutdown - */ - if (di->flags.low_bat) { - dev_dbg(di->dev, "Battery low, set capacity to 0\n"); - di->bat_cap.prev_percent = 0; - di->bat_cap.permille = 0; - di->bat_cap.prev_mah = 0; - di->bat_cap.mah = 0; - changed = true; - } else if (di->flags.fully_charged) { - /* - * We report 100% if algorithm reported fully charged - * unless capacity drops too much - */ - if (di->flags.force_full) { - di->bat_cap.prev_percent = di->bat_cap.permille / 10; - di->bat_cap.prev_mah = di->bat_cap.mah; - } else if (!di->flags.force_full && - di->bat_cap.prev_percent != - (di->bat_cap.permille) / 10 && - (di->bat_cap.permille / 10) < - di->bat->fg_params->maint_thres) { - dev_dbg(di->dev, - "battery reported full " - "but capacity dropping: %d\n", - di->bat_cap.permille / 10); - di->bat_cap.prev_percent = di->bat_cap.permille / 10; - di->bat_cap.prev_mah = di->bat_cap.mah; - - changed = true; - } - } else if (di->bat_cap.prev_percent != di->bat_cap.permille / 10) { - if (di->bat_cap.permille / 10 == 0) { - /* - * We will not report 0% unless we've got - * the LOW_BAT IRQ, no matter what the FG - * algorithm says. - */ - di->bat_cap.prev_percent = 1; - di->bat_cap.permille = 1; - di->bat_cap.prev_mah = 1; - di->bat_cap.mah = 1; - - changed = true; - } else if (!(!di->flags.charging && - (di->bat_cap.permille / 10) > - di->bat_cap.prev_percent) || init) { - /* - * We do not allow reported capacity to go up - * unless we're charging or if we're in init - */ - dev_dbg(di->dev, - "capacity changed from %d to %d (%d)\n", - di->bat_cap.prev_percent, - di->bat_cap.permille / 10, - di->bat_cap.permille); - di->bat_cap.prev_percent = di->bat_cap.permille / 10; - di->bat_cap.prev_mah = di->bat_cap.mah; - - changed = true; - } else { - dev_dbg(di->dev, "capacity not allowed to go up since " - "no charger is connected: %d to %d (%d)\n", - di->bat_cap.prev_percent, - di->bat_cap.permille / 10, - di->bat_cap.permille); - } - } - - if (changed) { - power_supply_changed(&di->fg_psy); - if (di->flags.fully_charged && di->flags.force_full) { - dev_dbg(di->dev, "Battery full, notifying.\n"); - di->flags.force_full = false; - sysfs_notify(&di->fg_kobject, NULL, "charge_full"); - } - sysfs_notify(&di->fg_kobject, NULL, "charge_now"); - } -} - -static void ab8500_fg_charge_state_to(struct ab8500_fg *di, - enum ab8500_fg_charge_state new_state) -{ - dev_dbg(di->dev, "Charge state from %d [%s] to %d [%s]\n", - di->charge_state, - charge_state[di->charge_state], - new_state, - charge_state[new_state]); - - di->charge_state = new_state; -} - -static void ab8500_fg_discharge_state_to(struct ab8500_fg *di, - enum ab8500_fg_discharge_state new_state) -{ - dev_dbg(di->dev, "Disharge state from %d [%s] to %d [%s]\n", - di->discharge_state, - discharge_state[di->discharge_state], - new_state, - discharge_state[new_state]); - - di->discharge_state = new_state; -} - -/** - * ab8500_fg_algorithm_charging() - FG algorithm for when charging - * @di: pointer to the ab8500_fg structure - * - * Battery capacity calculation state machine for when we're charging - */ -static void ab8500_fg_algorithm_charging(struct ab8500_fg *di) -{ - /* - * If we change to discharge mode - * we should start with recovery - */ - if (di->discharge_state != AB8500_FG_DISCHARGE_INIT_RECOVERY) - ab8500_fg_discharge_state_to(di, - AB8500_FG_DISCHARGE_INIT_RECOVERY); - - switch (di->charge_state) { - case AB8500_FG_CHARGE_INIT: - di->fg_samples = SEC_TO_SAMPLE( - di->bat->fg_params->accu_charging); - - ab8500_fg_coulomb_counter(di, true); - ab8500_fg_charge_state_to(di, AB8500_FG_CHARGE_READOUT); - - break; - - case AB8500_FG_CHARGE_READOUT: - /* - * Read the FG and calculate the new capacity - */ - mutex_lock(&di->cc_lock); - if (!di->flags.conv_done) { - /* Wasn't the CC IRQ that got us here */ - mutex_unlock(&di->cc_lock); - dev_dbg(di->dev, "%s CC conv not done\n", - __func__); - - break; - } - di->flags.conv_done = false; - mutex_unlock(&di->cc_lock); - - ab8500_fg_calc_cap_charging(di); - - break; - - default: - break; - } - - /* Check capacity limits */ - ab8500_fg_check_capacity_limits(di, false); -} - -static void force_capacity(struct ab8500_fg *di) -{ - int cap; - - ab8500_fg_clear_cap_samples(di); - cap = di->bat_cap.user_mah; - if (cap > di->bat_cap.max_mah_design) { - dev_dbg(di->dev, "Remaining cap %d can't be bigger than total" - " %d\n", cap, di->bat_cap.max_mah_design); - cap = di->bat_cap.max_mah_design; - } - ab8500_fg_fill_cap_sample(di, di->bat_cap.user_mah); - di->bat_cap.permille = ab8500_fg_convert_mah_to_permille(di, cap); - di->bat_cap.mah = cap; - ab8500_fg_check_capacity_limits(di, true); -} - -static bool check_sysfs_capacity(struct ab8500_fg *di) -{ - int cap, lower, upper; - int cap_permille; - - cap = di->bat_cap.user_mah; - - cap_permille = ab8500_fg_convert_mah_to_permille(di, - di->bat_cap.user_mah); - - lower = di->bat_cap.permille - di->bat->fg_params->user_cap_limit * 10; - upper = di->bat_cap.permille + di->bat->fg_params->user_cap_limit * 10; - - if (lower < 0) - lower = 0; - /* 1000 is permille, -> 100 percent */ - if (upper > 1000) - upper = 1000; - - dev_dbg(di->dev, "Capacity limits:" - " (Lower: %d User: %d Upper: %d) [user: %d, was: %d]\n", - lower, cap_permille, upper, cap, di->bat_cap.mah); - - /* If within limits, use the saved capacity and exit estimation...*/ - if (cap_permille > lower && cap_permille < upper) { - dev_dbg(di->dev, "OK! Using users cap %d uAh now\n", cap); - force_capacity(di); - return true; - } - dev_dbg(di->dev, "Capacity from user out of limits, ignoring"); - return false; -} - -/** - * ab8500_fg_algorithm_discharging() - FG algorithm for when discharging - * @di: pointer to the ab8500_fg structure - * - * Battery capacity calculation state machine for when we're discharging - */ -static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di) -{ - int sleep_time; - - /* If we change to charge mode we should start with init */ - if (di->charge_state != AB8500_FG_CHARGE_INIT) - ab8500_fg_charge_state_to(di, AB8500_FG_CHARGE_INIT); - - switch (di->discharge_state) { - case AB8500_FG_DISCHARGE_INIT: - /* We use the FG IRQ to work on */ - di->init_cnt = 0; - di->fg_samples = SEC_TO_SAMPLE(di->bat->fg_params->init_timer); - ab8500_fg_coulomb_counter(di, true); - ab8500_fg_discharge_state_to(di, - AB8500_FG_DISCHARGE_INITMEASURING); - - /* Intentional fallthrough */ - case AB8500_FG_DISCHARGE_INITMEASURING: - /* - * Discard a number of samples during startup. - * After that, use compensated voltage for a few - * samples to get an initial capacity. - * Then go to READOUT - */ - sleep_time = di->bat->fg_params->init_timer; - - /* Discard the first [x] seconds */ - if (di->init_cnt > - di->bat->fg_params->init_discard_time) { - ab8500_fg_calc_cap_discharge_voltage(di, true); - - ab8500_fg_check_capacity_limits(di, true); - } - - di->init_cnt += sleep_time; - if (di->init_cnt > di->bat->fg_params->init_total_time) - ab8500_fg_discharge_state_to(di, - AB8500_FG_DISCHARGE_READOUT_INIT); - - break; - - case AB8500_FG_DISCHARGE_INIT_RECOVERY: - di->recovery_cnt = 0; - di->recovery_needed = true; - ab8500_fg_discharge_state_to(di, - AB8500_FG_DISCHARGE_RECOVERY); - - /* Intentional fallthrough */ - - case AB8500_FG_DISCHARGE_RECOVERY: - sleep_time = di->bat->fg_params->recovery_sleep_timer; - - /* - * We should check the power consumption - * If low, go to READOUT (after x min) or - * RECOVERY_SLEEP if time left. - * If high, go to READOUT - */ - di->inst_curr = ab8500_fg_inst_curr_blocking(di); - - if (ab8500_fg_is_low_curr(di, di->inst_curr)) { - if (di->recovery_cnt > - di->bat->fg_params->recovery_total_time) { - di->fg_samples = SEC_TO_SAMPLE( - di->bat->fg_params->accu_high_curr); - ab8500_fg_coulomb_counter(di, true); - ab8500_fg_discharge_state_to(di, - AB8500_FG_DISCHARGE_READOUT); - di->recovery_needed = false; - } else { - queue_delayed_work(di->fg_wq, - &di->fg_periodic_work, - sleep_time * HZ); - } - di->recovery_cnt += sleep_time; - } else { - di->fg_samples = SEC_TO_SAMPLE( - di->bat->fg_params->accu_high_curr); - ab8500_fg_coulomb_counter(di, true); - ab8500_fg_discharge_state_to(di, - AB8500_FG_DISCHARGE_READOUT); - } - break; - - case AB8500_FG_DISCHARGE_READOUT_INIT: - di->fg_samples = SEC_TO_SAMPLE( - di->bat->fg_params->accu_high_curr); - ab8500_fg_coulomb_counter(di, true); - ab8500_fg_discharge_state_to(di, - AB8500_FG_DISCHARGE_READOUT); - break; - - case AB8500_FG_DISCHARGE_READOUT: - di->inst_curr = ab8500_fg_inst_curr_blocking(di); - - if (ab8500_fg_is_low_curr(di, di->inst_curr)) { - /* Detect mode change */ - if (di->high_curr_mode) { - di->high_curr_mode = false; - di->high_curr_cnt = 0; - } - - if (di->recovery_needed) { - ab8500_fg_discharge_state_to(di, - AB8500_FG_DISCHARGE_RECOVERY); - - queue_delayed_work(di->fg_wq, - &di->fg_periodic_work, 0); - - break; - } - - ab8500_fg_calc_cap_discharge_voltage(di, true); - } else { - mutex_lock(&di->cc_lock); - if (!di->flags.conv_done) { - /* Wasn't the CC IRQ that got us here */ - mutex_unlock(&di->cc_lock); - dev_dbg(di->dev, "%s CC conv not done\n", - __func__); - - break; - } - di->flags.conv_done = false; - mutex_unlock(&di->cc_lock); - - /* Detect mode change */ - if (!di->high_curr_mode) { - di->high_curr_mode = true; - di->high_curr_cnt = 0; - } - - di->high_curr_cnt += - di->bat->fg_params->accu_high_curr; - if (di->high_curr_cnt > - di->bat->fg_params->high_curr_time) - di->recovery_needed = true; - - ab8500_fg_calc_cap_discharge_fg(di); - } - - ab8500_fg_check_capacity_limits(di, false); - - break; - - case AB8500_FG_DISCHARGE_WAKEUP: - ab8500_fg_coulomb_counter(di, true); - di->inst_curr = ab8500_fg_inst_curr_blocking(di); - - ab8500_fg_calc_cap_discharge_voltage(di, true); - - di->fg_samples = SEC_TO_SAMPLE( - di->bat->fg_params->accu_high_curr); - ab8500_fg_coulomb_counter(di, true); - ab8500_fg_discharge_state_to(di, - AB8500_FG_DISCHARGE_READOUT); - - ab8500_fg_check_capacity_limits(di, false); - - break; - - default: - break; - } -} - -/** - * ab8500_fg_algorithm_calibrate() - Internal columb counter offset calibration - * @di: pointer to the ab8500_fg structure - * - */ -static void ab8500_fg_algorithm_calibrate(struct ab8500_fg *di) -{ - int ret; - - switch (di->calib_state) { - case AB8500_FG_CALIB_INIT: - dev_dbg(di->dev, "Calibration ongoing...\n"); - - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_GAS_GAUGE, AB8500_GASG_CC_CTRL_REG, - CC_INT_CAL_N_AVG_MASK, CC_INT_CAL_SAMPLES_8); - if (ret < 0) - goto err; - - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_GAS_GAUGE, AB8500_GASG_CC_CTRL_REG, - CC_INTAVGOFFSET_ENA, CC_INTAVGOFFSET_ENA); - if (ret < 0) - goto err; - di->calib_state = AB8500_FG_CALIB_WAIT; - break; - case AB8500_FG_CALIB_END: - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_GAS_GAUGE, AB8500_GASG_CC_CTRL_REG, - CC_MUXOFFSET, CC_MUXOFFSET); - if (ret < 0) - goto err; - di->flags.calibrate = false; - dev_dbg(di->dev, "Calibration done...\n"); - queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); - break; - case AB8500_FG_CALIB_WAIT: - dev_dbg(di->dev, "Calibration WFI\n"); - default: - break; - } - return; -err: - /* Something went wrong, don't calibrate then */ - dev_err(di->dev, "failed to calibrate the CC\n"); - di->flags.calibrate = false; - di->calib_state = AB8500_FG_CALIB_INIT; - queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); -} - -/** - * ab8500_fg_algorithm() - Entry point for the FG algorithm - * @di: pointer to the ab8500_fg structure - * - * Entry point for the battery capacity calculation state machine - */ -static void ab8500_fg_algorithm(struct ab8500_fg *di) -{ - if (di->flags.calibrate) - ab8500_fg_algorithm_calibrate(di); - else { - if (di->flags.charging) - ab8500_fg_algorithm_charging(di); - else - ab8500_fg_algorithm_discharging(di); - } - - dev_dbg(di->dev, "[FG_DATA] %d %d %d %d %d %d %d %d %d " - "%d %d %d %d %d %d %d\n", - di->bat_cap.max_mah_design, - di->bat_cap.mah, - di->bat_cap.permille, - di->bat_cap.level, - di->bat_cap.prev_mah, - di->bat_cap.prev_percent, - di->bat_cap.prev_level, - di->vbat, - di->inst_curr, - di->avg_curr, - di->accu_charge, - di->flags.charging, - di->charge_state, - di->discharge_state, - di->high_curr_mode, - di->recovery_needed); -} - -/** - * ab8500_fg_periodic_work() - Run the FG state machine periodically - * @work: pointer to the work_struct structure - * - * Work queue function for periodic work - */ -static void ab8500_fg_periodic_work(struct work_struct *work) -{ - struct ab8500_fg *di = container_of(work, struct ab8500_fg, - fg_periodic_work.work); - - if (di->init_capacity) { - /* A dummy read that will return 0 */ - di->inst_curr = ab8500_fg_inst_curr_blocking(di); - /* Get an initial capacity calculation */ - ab8500_fg_calc_cap_discharge_voltage(di, true); - ab8500_fg_check_capacity_limits(di, true); - di->init_capacity = false; - - queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); - } else if (di->flags.user_cap) { - if (check_sysfs_capacity(di)) { - ab8500_fg_check_capacity_limits(di, true); - if (di->flags.charging) - ab8500_fg_charge_state_to(di, - AB8500_FG_CHARGE_INIT); - else - ab8500_fg_discharge_state_to(di, - AB8500_FG_DISCHARGE_READOUT_INIT); - } - di->flags.user_cap = false; - queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); - } else - ab8500_fg_algorithm(di); - -} - -/** - * ab8500_fg_check_hw_failure_work() - Check OVV_BAT condition - * @work: pointer to the work_struct structure - * - * Work queue function for checking the OVV_BAT condition - */ -static void ab8500_fg_check_hw_failure_work(struct work_struct *work) -{ - int ret; - u8 reg_value; - - struct ab8500_fg *di = container_of(work, struct ab8500_fg, - fg_check_hw_failure_work.work); - - /* - * If we have had a battery over-voltage situation, - * check ovv-bit to see if it should be reset. - */ - if (di->flags.bat_ovv) { - ret = abx500_get_register_interruptible(di->dev, - AB8500_CHARGER, AB8500_CH_STAT_REG, - ®_value); - if (ret < 0) { - dev_err(di->dev, "%s ab8500 read failed\n", __func__); - return; - } - if ((reg_value & BATT_OVV) != BATT_OVV) { - dev_dbg(di->dev, "Battery recovered from OVV\n"); - di->flags.bat_ovv = false; - power_supply_changed(&di->fg_psy); - return; - } - - /* Not yet recovered from ovv, reschedule this test */ - queue_delayed_work(di->fg_wq, &di->fg_check_hw_failure_work, - round_jiffies(HZ)); - } -} - -/** - * ab8500_fg_low_bat_work() - Check LOW_BAT condition - * @work: pointer to the work_struct structure - * - * Work queue function for checking the LOW_BAT condition - */ -static void ab8500_fg_low_bat_work(struct work_struct *work) -{ - int vbat; - - struct ab8500_fg *di = container_of(work, struct ab8500_fg, - fg_low_bat_work.work); - - vbat = ab8500_fg_bat_voltage(di); - - /* Check if LOW_BAT still fulfilled */ - if (vbat < di->bat->fg_params->lowbat_threshold) { - di->flags.low_bat = true; - dev_warn(di->dev, "Battery voltage still LOW\n"); - - /* - * We need to re-schedule this check to be able to detect - * if the voltage increases again during charging - */ - queue_delayed_work(di->fg_wq, &di->fg_low_bat_work, - round_jiffies(LOW_BAT_CHECK_INTERVAL)); - } else { - di->flags.low_bat = false; - dev_warn(di->dev, "Battery voltage OK again\n"); - } - - /* This is needed to dispatch LOW_BAT */ - ab8500_fg_check_capacity_limits(di, false); - - /* Set this flag to check if LOW_BAT IRQ still occurs */ - di->flags.low_bat_delay = false; -} - -/** - * ab8500_fg_battok_calc - calculate the bit pattern corresponding - * to the target voltage. - * @di: pointer to the ab8500_fg structure - * @target target voltage - * - * Returns bit pattern closest to the target voltage - * valid return values are 0-14. (0-BATT_OK_MAX_NR_INCREMENTS) - */ - -static int ab8500_fg_battok_calc(struct ab8500_fg *di, int target) -{ - if (target > BATT_OK_MIN + - (BATT_OK_INCREMENT * BATT_OK_MAX_NR_INCREMENTS)) - return BATT_OK_MAX_NR_INCREMENTS; - if (target < BATT_OK_MIN) - return 0; - return (target - BATT_OK_MIN) / BATT_OK_INCREMENT; -} - -/** - * ab8500_fg_battok_init_hw_register - init battok levels - * @di: pointer to the ab8500_fg structure - * - */ - -static int ab8500_fg_battok_init_hw_register(struct ab8500_fg *di) -{ - int selected; - int sel0; - int sel1; - int cbp_sel0; - int cbp_sel1; - int ret; - int new_val; - - sel0 = di->bat->fg_params->battok_falling_th_sel0; - sel1 = di->bat->fg_params->battok_raising_th_sel1; - - cbp_sel0 = ab8500_fg_battok_calc(di, sel0); - cbp_sel1 = ab8500_fg_battok_calc(di, sel1); - - selected = BATT_OK_MIN + cbp_sel0 * BATT_OK_INCREMENT; - - if (selected != sel0) - dev_warn(di->dev, "Invalid voltage step:%d, using %d %d\n", - sel0, selected, cbp_sel0); - - selected = BATT_OK_MIN + cbp_sel1 * BATT_OK_INCREMENT; - - if (selected != sel1) - dev_warn(di->dev, "Invalid voltage step:%d, using %d %d\n", - sel1, selected, cbp_sel1); - - new_val = cbp_sel0 | (cbp_sel1 << 4); - - dev_dbg(di->dev, "using: %x %d %d\n", new_val, cbp_sel0, cbp_sel1); - ret = abx500_set_register_interruptible(di->dev, AB8500_SYS_CTRL2_BLOCK, - AB8500_BATT_OK_REG, new_val); - return ret; -} - -/** - * ab8500_fg_instant_work() - Run the FG state machine instantly - * @work: pointer to the work_struct structure - * - * Work queue function for instant work - */ -static void ab8500_fg_instant_work(struct work_struct *work) -{ - struct ab8500_fg *di = container_of(work, struct ab8500_fg, fg_work); - - ab8500_fg_algorithm(di); -} - -/** - * ab8500_fg_cc_data_end_handler() - isr to get battery avg current. - * @irq: interrupt number - * @_di: pointer to the ab8500_fg structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_fg_cc_data_end_handler(int irq, void *_di) -{ - struct ab8500_fg *di = _di; - complete(&di->ab8500_fg_complete); - return IRQ_HANDLED; -} - -/** - * ab8500_fg_cc_convend_handler() - isr to get battery avg current. - * @irq: interrupt number - * @_di: pointer to the ab8500_fg structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_fg_cc_int_calib_handler(int irq, void *_di) -{ - struct ab8500_fg *di = _di; - di->calib_state = AB8500_FG_CALIB_END; - queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); - return IRQ_HANDLED; -} - -/** - * ab8500_fg_cc_convend_handler() - isr to get battery avg current. - * @irq: interrupt number - * @_di: pointer to the ab8500_fg structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_fg_cc_convend_handler(int irq, void *_di) -{ - struct ab8500_fg *di = _di; - - queue_work(di->fg_wq, &di->fg_acc_cur_work); - - return IRQ_HANDLED; -} - -/** - * ab8500_fg_batt_ovv_handler() - Battery OVV occured - * @irq: interrupt number - * @_di: pointer to the ab8500_fg structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_fg_batt_ovv_handler(int irq, void *_di) -{ - struct ab8500_fg *di = _di; - - dev_dbg(di->dev, "Battery OVV\n"); - di->flags.bat_ovv = true; - power_supply_changed(&di->fg_psy); - - /* Schedule a new HW failure check */ - queue_delayed_work(di->fg_wq, &di->fg_check_hw_failure_work, 0); - - return IRQ_HANDLED; -} - -/** - * ab8500_fg_lowbatf_handler() - Battery voltage is below LOW threshold - * @irq: interrupt number - * @_di: pointer to the ab8500_fg structure - * - * Returns IRQ status(IRQ_HANDLED) - */ -static irqreturn_t ab8500_fg_lowbatf_handler(int irq, void *_di) -{ - struct ab8500_fg *di = _di; - - if (!di->flags.low_bat_delay) { - dev_warn(di->dev, "Battery voltage is below LOW threshold\n"); - di->flags.low_bat_delay = true; - /* - * Start a timer to check LOW_BAT again after some time - * This is done to avoid shutdown on single voltage dips - */ - queue_delayed_work(di->fg_wq, &di->fg_low_bat_work, - round_jiffies(LOW_BAT_CHECK_INTERVAL)); - } - return IRQ_HANDLED; -} - -/** - * ab8500_fg_get_property() - get the fg properties - * @psy: pointer to the power_supply structure - * @psp: pointer to the power_supply_property structure - * @val: pointer to the power_supply_propval union - * - * This function gets called when an application tries to get the - * fg properties by reading the sysfs files. - * voltage_now: battery voltage - * current_now: battery instant current - * current_avg: battery average current - * charge_full_design: capacity where battery is considered full - * charge_now: battery capacity in nAh - * capacity: capacity in percent - * capacity_level: capacity level - * - * Returns error code in case of failure else 0 on success - */ -static int ab8500_fg_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct ab8500_fg *di; - - di = to_ab8500_fg_device_info(psy); - - /* - * If battery is identified as unknown and charging of unknown - * batteries is disabled, we always report 100% capacity and - * capacity level UNKNOWN, since we can't calculate - * remaining capacity - */ - - switch (psp) { - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - if (di->flags.bat_ovv) - val->intval = BATT_OVV_VALUE * 1000; - else - val->intval = di->vbat * 1000; - break; - case POWER_SUPPLY_PROP_CURRENT_NOW: - val->intval = di->inst_curr * 1000; - break; - case POWER_SUPPLY_PROP_CURRENT_AVG: - val->intval = di->avg_curr * 1000; - break; - case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: - val->intval = ab8500_fg_convert_mah_to_uwh(di, - di->bat_cap.max_mah_design); - break; - case POWER_SUPPLY_PROP_ENERGY_FULL: - val->intval = ab8500_fg_convert_mah_to_uwh(di, - di->bat_cap.max_mah); - break; - case POWER_SUPPLY_PROP_ENERGY_NOW: - if (di->flags.batt_unknown && !di->bat->chg_unknown_bat && - di->flags.batt_id_received) - val->intval = ab8500_fg_convert_mah_to_uwh(di, - di->bat_cap.max_mah); - else - val->intval = ab8500_fg_convert_mah_to_uwh(di, - di->bat_cap.prev_mah); - break; - case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: - val->intval = di->bat_cap.max_mah_design; - break; - case POWER_SUPPLY_PROP_CHARGE_FULL: - val->intval = di->bat_cap.max_mah; - break; - case POWER_SUPPLY_PROP_CHARGE_NOW: - if (di->flags.batt_unknown && !di->bat->chg_unknown_bat && - di->flags.batt_id_received) - val->intval = di->bat_cap.max_mah; - else - val->intval = di->bat_cap.prev_mah; - break; - case POWER_SUPPLY_PROP_CAPACITY: - if (di->flags.batt_unknown && !di->bat->chg_unknown_bat && - di->flags.batt_id_received) - val->intval = 100; - else - val->intval = di->bat_cap.prev_percent; - break; - case POWER_SUPPLY_PROP_CAPACITY_LEVEL: - if (di->flags.batt_unknown && !di->bat->chg_unknown_bat && - di->flags.batt_id_received) - val->intval = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN; - else - val->intval = di->bat_cap.prev_level; - break; - default: - return -EINVAL; - } - return 0; -} - -static int ab8500_fg_get_ext_psy_data(struct device *dev, void *data) -{ - struct power_supply *psy; - struct power_supply *ext; - struct ab8500_fg *di; - union power_supply_propval ret; - int i, j; - bool psy_found = false; - - psy = (struct power_supply *)data; - ext = dev_get_drvdata(dev); - di = to_ab8500_fg_device_info(psy); - - /* - * For all psy where the name of your driver - * appears in any supplied_to - */ - for (i = 0; i < ext->num_supplicants; i++) { - if (!strcmp(ext->supplied_to[i], psy->name)) - psy_found = true; - } - - if (!psy_found) - return 0; - - /* Go through all properties for the psy */ - for (j = 0; j < ext->num_properties; j++) { - enum power_supply_property prop; - prop = ext->properties[j]; - - if (ext->get_property(ext, prop, &ret)) - continue; - - switch (prop) { - case POWER_SUPPLY_PROP_STATUS: - switch (ext->type) { - case POWER_SUPPLY_TYPE_BATTERY: - switch (ret.intval) { - case POWER_SUPPLY_STATUS_UNKNOWN: - case POWER_SUPPLY_STATUS_DISCHARGING: - case POWER_SUPPLY_STATUS_NOT_CHARGING: - if (!di->flags.charging) - break; - di->flags.charging = false; - di->flags.fully_charged = false; - queue_work(di->fg_wq, &di->fg_work); - break; - case POWER_SUPPLY_STATUS_FULL: - if (di->flags.fully_charged) - break; - di->flags.fully_charged = true; - di->flags.force_full = true; - /* Save current capacity as maximum */ - di->bat_cap.max_mah = di->bat_cap.mah; - queue_work(di->fg_wq, &di->fg_work); - break; - case POWER_SUPPLY_STATUS_CHARGING: - if (di->flags.charging) - break; - di->flags.charging = true; - di->flags.fully_charged = false; - queue_work(di->fg_wq, &di->fg_work); - break; - }; - default: - break; - }; - break; - case POWER_SUPPLY_PROP_TECHNOLOGY: - switch (ext->type) { - case POWER_SUPPLY_TYPE_BATTERY: - if (!di->flags.batt_id_received) { - const struct abx500_battery_type *b; - - b = &(di->bat->bat_type[di->bat->batt_id]); - - di->flags.batt_id_received = true; - - di->bat_cap.max_mah_design = - MILLI_TO_MICRO * - b->charge_full_design; - - di->bat_cap.max_mah = - di->bat_cap.max_mah_design; - - di->vbat_nom = b->nominal_voltage; - } - - if (ret.intval) - di->flags.batt_unknown = false; - else - di->flags.batt_unknown = true; - break; - default: - break; - } - break; - case POWER_SUPPLY_PROP_TEMP: - switch (ext->type) { - case POWER_SUPPLY_TYPE_BATTERY: - if (di->flags.batt_id_received) - di->bat_temp = ret.intval; - break; - default: - break; - } - break; - default: - break; - } - } - return 0; -} - -/** - * ab8500_fg_init_hw_registers() - Set up FG related registers - * @di: pointer to the ab8500_fg structure - * - * Set up battery OVV, low battery voltage registers - */ -static int ab8500_fg_init_hw_registers(struct ab8500_fg *di) -{ - int ret; - - /* Set VBAT OVV threshold */ - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_CHARGER, - AB8500_BATT_OVV, - BATT_OVV_TH_4P75, - BATT_OVV_TH_4P75); - if (ret) { - dev_err(di->dev, "failed to set BATT_OVV\n"); - goto out; - } - - /* Enable VBAT OVV detection */ - ret = abx500_mask_and_set_register_interruptible(di->dev, - AB8500_CHARGER, - AB8500_BATT_OVV, - BATT_OVV_ENA, - BATT_OVV_ENA); - if (ret) { - dev_err(di->dev, "failed to enable BATT_OVV\n"); - goto out; - } - - /* Low Battery Voltage */ - ret = abx500_set_register_interruptible(di->dev, - AB8500_SYS_CTRL2_BLOCK, - AB8500_LOW_BAT_REG, - ab8500_volt_to_regval( - di->bat->fg_params->lowbat_threshold) << 1 | - LOW_BAT_ENABLE); - if (ret) { - dev_err(di->dev, "%s write failed\n", __func__); - goto out; - } - - /* Battery OK threshold */ - ret = ab8500_fg_battok_init_hw_register(di); - if (ret) { - dev_err(di->dev, "BattOk init write failed.\n"); - goto out; - } -out: - return ret; -} - -/** - * ab8500_fg_external_power_changed() - callback for power supply changes - * @psy: pointer to the structure power_supply - * - * This function is the entry point of the pointer external_power_changed - * of the structure power_supply. - * This function gets executed when there is a change in any external power - * supply that this driver needs to be notified of. - */ -static void ab8500_fg_external_power_changed(struct power_supply *psy) -{ - struct ab8500_fg *di = to_ab8500_fg_device_info(psy); - - class_for_each_device(power_supply_class, NULL, - &di->fg_psy, ab8500_fg_get_ext_psy_data); -} - -/** - * abab8500_fg_reinit_work() - work to reset the FG algorithm - * @work: pointer to the work_struct structure - * - * Used to reset the current battery capacity to be able to - * retrigger a new voltage base capacity calculation. For - * test and verification purpose. - */ -static void ab8500_fg_reinit_work(struct work_struct *work) -{ - struct ab8500_fg *di = container_of(work, struct ab8500_fg, - fg_reinit_work.work); - - if (di->flags.calibrate == false) { - dev_dbg(di->dev, "Resetting FG state machine to init.\n"); - ab8500_fg_clear_cap_samples(di); - ab8500_fg_calc_cap_discharge_voltage(di, true); - ab8500_fg_charge_state_to(di, AB8500_FG_CHARGE_INIT); - ab8500_fg_discharge_state_to(di, AB8500_FG_DISCHARGE_INIT); - queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); - - } else { - dev_err(di->dev, "Residual offset calibration ongoing " - "retrying..\n"); - /* Wait one second until next try*/ - queue_delayed_work(di->fg_wq, &di->fg_reinit_work, - round_jiffies(1)); - } -} - -/** - * ab8500_fg_reinit() - forces FG algorithm to reinitialize with current values - * - * This function can be used to force the FG algorithm to recalculate a new - * voltage based battery capacity. - */ -void ab8500_fg_reinit(void) -{ - struct ab8500_fg *di = ab8500_fg_get(); - /* User won't be notified if a null pointer returned. */ - if (di != NULL) - queue_delayed_work(di->fg_wq, &di->fg_reinit_work, 0); -} - -/* Exposure to the sysfs interface */ - -struct ab8500_fg_sysfs_entry { - struct attribute attr; - ssize_t (*show)(struct ab8500_fg *, char *); - ssize_t (*store)(struct ab8500_fg *, const char *, size_t); -}; - -static ssize_t charge_full_show(struct ab8500_fg *di, char *buf) -{ - return sprintf(buf, "%d\n", di->bat_cap.max_mah); -} - -static ssize_t charge_full_store(struct ab8500_fg *di, const char *buf, - size_t count) -{ - unsigned long charge_full; - ssize_t ret = -EINVAL; - - ret = strict_strtoul(buf, 10, &charge_full); - - dev_dbg(di->dev, "Ret %zd charge_full %lu", ret, charge_full); - - if (!ret) { - di->bat_cap.max_mah = (int) charge_full; - ret = count; - } - return ret; -} - -static ssize_t charge_now_show(struct ab8500_fg *di, char *buf) -{ - return sprintf(buf, "%d\n", di->bat_cap.prev_mah); -} - -static ssize_t charge_now_store(struct ab8500_fg *di, const char *buf, - size_t count) -{ - unsigned long charge_now; - ssize_t ret; - - ret = strict_strtoul(buf, 10, &charge_now); - - dev_dbg(di->dev, "Ret %zd charge_now %lu was %d", - ret, charge_now, di->bat_cap.prev_mah); - - if (!ret) { - di->bat_cap.user_mah = (int) charge_now; - di->flags.user_cap = true; - ret = count; - queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); - } - return ret; -} - -static struct ab8500_fg_sysfs_entry charge_full_attr = - __ATTR(charge_full, 0644, charge_full_show, charge_full_store); - -static struct ab8500_fg_sysfs_entry charge_now_attr = - __ATTR(charge_now, 0644, charge_now_show, charge_now_store); - -static ssize_t -ab8500_fg_show(struct kobject *kobj, struct attribute *attr, char *buf) -{ - struct ab8500_fg_sysfs_entry *entry; - struct ab8500_fg *di; - - entry = container_of(attr, struct ab8500_fg_sysfs_entry, attr); - di = container_of(kobj, struct ab8500_fg, fg_kobject); - - if (!entry->show) - return -EIO; - - return entry->show(di, buf); -} -static ssize_t -ab8500_fg_store(struct kobject *kobj, struct attribute *attr, const char *buf, - size_t count) -{ - struct ab8500_fg_sysfs_entry *entry; - struct ab8500_fg *di; - - entry = container_of(attr, struct ab8500_fg_sysfs_entry, attr); - di = container_of(kobj, struct ab8500_fg, fg_kobject); - - if (!entry->store) - return -EIO; - - return entry->store(di, buf, count); -} - -static const struct sysfs_ops ab8500_fg_sysfs_ops = { - .show = ab8500_fg_show, - .store = ab8500_fg_store, -}; - -static struct attribute *ab8500_fg_attrs[] = { - &charge_full_attr.attr, - &charge_now_attr.attr, - NULL, -}; - -static struct kobj_type ab8500_fg_ktype = { - .sysfs_ops = &ab8500_fg_sysfs_ops, - .default_attrs = ab8500_fg_attrs, -}; - -/** - * ab8500_chargalg_sysfs_exit() - de-init of sysfs entry - * @di: pointer to the struct ab8500_chargalg - * - * This function removes the entry in sysfs. - */ -static void ab8500_fg_sysfs_exit(struct ab8500_fg *di) -{ - kobject_del(&di->fg_kobject); -} - -/** - * ab8500_chargalg_sysfs_init() - init of sysfs entry - * @di: pointer to the struct ab8500_chargalg - * - * This function adds an entry in sysfs. - * Returns error code in case of failure else 0(on success) - */ -static int ab8500_fg_sysfs_init(struct ab8500_fg *di) -{ - int ret = 0; - - ret = kobject_init_and_add(&di->fg_kobject, - &ab8500_fg_ktype, - NULL, "battery"); - if (ret < 0) - dev_err(di->dev, "failed to create sysfs entry\n"); - - return ret; -} -/* Exposure to the sysfs interface <> */ - -#if defined(CONFIG_PM) -static int ab8500_fg_resume(struct platform_device *pdev) -{ - struct ab8500_fg *di = platform_get_drvdata(pdev); - - /* - * Change state if we're not charging. If we're charging we will wake - * up on the FG IRQ - */ - if (!di->flags.charging) { - ab8500_fg_discharge_state_to(di, AB8500_FG_DISCHARGE_WAKEUP); - queue_work(di->fg_wq, &di->fg_work); - } - - return 0; -} - -static int ab8500_fg_suspend(struct platform_device *pdev, - pm_message_t state) -{ - struct ab8500_fg *di = platform_get_drvdata(pdev); - - flush_delayed_work(&di->fg_periodic_work); - - /* - * If the FG is enabled we will disable it before going to suspend - * only if we're not charging - */ - if (di->flags.fg_enabled && !di->flags.charging) - ab8500_fg_coulomb_counter(di, false); - - return 0; -} -#else -#define ab8500_fg_suspend NULL -#define ab8500_fg_resume NULL -#endif - -static int __devexit ab8500_fg_remove(struct platform_device *pdev) -{ - int ret = 0; - struct ab8500_fg *di = platform_get_drvdata(pdev); - - list_del(&di->node); - - /* Disable coulomb counter */ - ret = ab8500_fg_coulomb_counter(di, false); - if (ret) - dev_err(di->dev, "failed to disable coulomb counter\n"); - - destroy_workqueue(di->fg_wq); - ab8500_fg_sysfs_exit(di); - - flush_scheduled_work(); - power_supply_unregister(&di->fg_psy); - platform_set_drvdata(pdev, NULL); - kfree(di); - return ret; -} - -/* ab8500 fg driver interrupts and their respective isr */ -static struct ab8500_fg_interrupts ab8500_fg_irq[] = { - {"NCONV_ACCU", ab8500_fg_cc_convend_handler}, - {"BATT_OVV", ab8500_fg_batt_ovv_handler}, - {"LOW_BAT_F", ab8500_fg_lowbatf_handler}, - {"CC_INT_CALIB", ab8500_fg_cc_int_calib_handler}, - {"CCEOC", ab8500_fg_cc_data_end_handler}, -}; - -static int __devinit ab8500_fg_probe(struct platform_device *pdev) -{ - int i, irq; - int ret = 0; - struct abx500_bm_plat_data *plat_data; - - struct ab8500_fg *di = - kzalloc(sizeof(struct ab8500_fg), GFP_KERNEL); - if (!di) - return -ENOMEM; - - mutex_init(&di->cc_lock); - - /* get parent data */ - di->dev = &pdev->dev; - di->parent = dev_get_drvdata(pdev->dev.parent); - di->gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); - - /* get fg specific platform data */ - plat_data = pdev->dev.platform_data; - di->pdata = plat_data->fg; - if (!di->pdata) { - dev_err(di->dev, "no fg platform data supplied\n"); - ret = -EINVAL; - goto free_device_info; - } - - /* get battery specific platform data */ - di->bat = plat_data->battery; - if (!di->bat) { - dev_err(di->dev, "no battery platform data supplied\n"); - ret = -EINVAL; - goto free_device_info; - } - - di->fg_psy.name = "ab8500_fg"; - di->fg_psy.type = POWER_SUPPLY_TYPE_BATTERY; - di->fg_psy.properties = ab8500_fg_props; - di->fg_psy.num_properties = ARRAY_SIZE(ab8500_fg_props); - di->fg_psy.get_property = ab8500_fg_get_property; - di->fg_psy.supplied_to = di->pdata->supplied_to; - di->fg_psy.num_supplicants = di->pdata->num_supplicants; - di->fg_psy.external_power_changed = ab8500_fg_external_power_changed; - - di->bat_cap.max_mah_design = MILLI_TO_MICRO * - di->bat->bat_type[di->bat->batt_id].charge_full_design; - - di->bat_cap.max_mah = di->bat_cap.max_mah_design; - - di->vbat_nom = di->bat->bat_type[di->bat->batt_id].nominal_voltage; - - di->init_capacity = true; - - ab8500_fg_charge_state_to(di, AB8500_FG_CHARGE_INIT); - ab8500_fg_discharge_state_to(di, AB8500_FG_DISCHARGE_INIT); - - /* Create a work queue for running the FG algorithm */ - di->fg_wq = create_singlethread_workqueue("ab8500_fg_wq"); - if (di->fg_wq == NULL) { - dev_err(di->dev, "failed to create work queue\n"); - goto free_device_info; - } - - /* Init work for running the fg algorithm instantly */ - INIT_WORK(&di->fg_work, ab8500_fg_instant_work); - - /* Init work for getting the battery accumulated current */ - INIT_WORK(&di->fg_acc_cur_work, ab8500_fg_acc_cur_work); - - /* Init work for reinitialising the fg algorithm */ - INIT_DELAYED_WORK_DEFERRABLE(&di->fg_reinit_work, - ab8500_fg_reinit_work); - - /* Work delayed Queue to run the state machine */ - INIT_DELAYED_WORK_DEFERRABLE(&di->fg_periodic_work, - ab8500_fg_periodic_work); - - /* Work to check low battery condition */ - INIT_DELAYED_WORK_DEFERRABLE(&di->fg_low_bat_work, - ab8500_fg_low_bat_work); - - /* Init work for HW failure check */ - INIT_DELAYED_WORK_DEFERRABLE(&di->fg_check_hw_failure_work, - ab8500_fg_check_hw_failure_work); - - /* Initialize OVV, and other registers */ - ret = ab8500_fg_init_hw_registers(di); - if (ret) { - dev_err(di->dev, "failed to initialize registers\n"); - goto free_inst_curr_wq; - } - - /* Consider battery unknown until we're informed otherwise */ - di->flags.batt_unknown = true; - di->flags.batt_id_received = false; - - /* Register FG power supply class */ - ret = power_supply_register(di->dev, &di->fg_psy); - if (ret) { - dev_err(di->dev, "failed to register FG psy\n"); - goto free_inst_curr_wq; - } - - di->fg_samples = SEC_TO_SAMPLE(di->bat->fg_params->init_timer); - ab8500_fg_coulomb_counter(di, true); - - /* Initialize completion used to notify completion of inst current */ - init_completion(&di->ab8500_fg_complete); - - /* Register interrupts */ - for (i = 0; i < ARRAY_SIZE(ab8500_fg_irq); i++) { - irq = platform_get_irq_byname(pdev, ab8500_fg_irq[i].name); - ret = request_threaded_irq(irq, NULL, ab8500_fg_irq[i].isr, - IRQF_SHARED | IRQF_NO_SUSPEND, - ab8500_fg_irq[i].name, di); - - if (ret != 0) { - dev_err(di->dev, "failed to request %s IRQ %d: %d\n" - , ab8500_fg_irq[i].name, irq, ret); - goto free_irq; - } - dev_dbg(di->dev, "Requested %s IRQ %d: %d\n", - ab8500_fg_irq[i].name, irq, ret); - } - di->irq = platform_get_irq_byname(pdev, "CCEOC"); - disable_irq(di->irq); - - platform_set_drvdata(pdev, di); - - ret = ab8500_fg_sysfs_init(di); - if (ret) { - dev_err(di->dev, "failed to create sysfs entry\n"); - goto free_irq; - } - - /* Calibrate the fg first time */ - di->flags.calibrate = true; - di->calib_state = AB8500_FG_CALIB_INIT; - - /* Use room temp as default value until we get an update from driver. */ - di->bat_temp = 210; - - /* Run the FG algorithm */ - queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); - - list_add_tail(&di->node, &ab8500_fg_list); - - return ret; - -free_irq: - power_supply_unregister(&di->fg_psy); - - /* We also have to free all successfully registered irqs */ - for (i = i - 1; i >= 0; i--) { - irq = platform_get_irq_byname(pdev, ab8500_fg_irq[i].name); - free_irq(irq, di); - } -free_inst_curr_wq: - destroy_workqueue(di->fg_wq); -free_device_info: - kfree(di); - - return ret; -} - -static struct platform_driver ab8500_fg_driver = { - .probe = ab8500_fg_probe, - .remove = __devexit_p(ab8500_fg_remove), - .suspend = ab8500_fg_suspend, - .resume = ab8500_fg_resume, - .driver = { - .name = "ab8500-fg", - .owner = THIS_MODULE, - }, -}; - -static int __init ab8500_fg_init(void) -{ - return platform_driver_register(&ab8500_fg_driver); -} - -static void __exit ab8500_fg_exit(void) -{ - platform_driver_unregister(&ab8500_fg_driver); -} - -subsys_initcall_sync(ab8500_fg_init); -module_exit(ab8500_fg_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Johan Palsson, Karl Komierowski"); -MODULE_ALIAS("platform:ab8500-fg"); -MODULE_DESCRIPTION("AB8500 Fuel Gauge driver"); diff --git a/trunk/drivers/power/abx500_chargalg.c b/trunk/drivers/power/abx500_chargalg.c deleted file mode 100644 index 804b88c760d6..000000000000 --- a/trunk/drivers/power/abx500_chargalg.c +++ /dev/null @@ -1,1921 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2012 - * - * Charging algorithm driver for abx500 variants - * - * License Terms: GNU General Public License v2 - * Authors: - * Johan Palsson - * Karl Komierowski - * Arun R Murthy - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Watchdog kick interval */ -#define CHG_WD_INTERVAL (6 * HZ) - -/* End-of-charge criteria counter */ -#define EOC_COND_CNT 10 - -/* Recharge criteria counter */ -#define RCH_COND_CNT 3 - -#define to_abx500_chargalg_device_info(x) container_of((x), \ - struct abx500_chargalg, chargalg_psy); - -enum abx500_chargers { - NO_CHG, - AC_CHG, - USB_CHG, -}; - -struct abx500_chargalg_charger_info { - enum abx500_chargers conn_chg; - enum abx500_chargers prev_conn_chg; - enum abx500_chargers online_chg; - enum abx500_chargers prev_online_chg; - enum abx500_chargers charger_type; - bool usb_chg_ok; - bool ac_chg_ok; - int usb_volt; - int usb_curr; - int ac_volt; - int ac_curr; - int usb_vset; - int usb_iset; - int ac_vset; - int ac_iset; -}; - -struct abx500_chargalg_suspension_status { - bool suspended_change; - bool ac_suspended; - bool usb_suspended; -}; - -struct abx500_chargalg_battery_data { - int temp; - int volt; - int avg_curr; - int inst_curr; - int percent; -}; - -enum abx500_chargalg_states { - STATE_HANDHELD_INIT, - STATE_HANDHELD, - STATE_CHG_NOT_OK_INIT, - STATE_CHG_NOT_OK, - STATE_HW_TEMP_PROTECT_INIT, - STATE_HW_TEMP_PROTECT, - STATE_NORMAL_INIT, - STATE_NORMAL, - STATE_WAIT_FOR_RECHARGE_INIT, - STATE_WAIT_FOR_RECHARGE, - STATE_MAINTENANCE_A_INIT, - STATE_MAINTENANCE_A, - STATE_MAINTENANCE_B_INIT, - STATE_MAINTENANCE_B, - STATE_TEMP_UNDEROVER_INIT, - STATE_TEMP_UNDEROVER, - STATE_TEMP_LOWHIGH_INIT, - STATE_TEMP_LOWHIGH, - STATE_SUSPENDED_INIT, - STATE_SUSPENDED, - STATE_OVV_PROTECT_INIT, - STATE_OVV_PROTECT, - STATE_SAFETY_TIMER_EXPIRED_INIT, - STATE_SAFETY_TIMER_EXPIRED, - STATE_BATT_REMOVED_INIT, - STATE_BATT_REMOVED, - STATE_WD_EXPIRED_INIT, - STATE_WD_EXPIRED, -}; - -static const char *states[] = { - "HANDHELD_INIT", - "HANDHELD", - "CHG_NOT_OK_INIT", - "CHG_NOT_OK", - "HW_TEMP_PROTECT_INIT", - "HW_TEMP_PROTECT", - "NORMAL_INIT", - "NORMAL", - "WAIT_FOR_RECHARGE_INIT", - "WAIT_FOR_RECHARGE", - "MAINTENANCE_A_INIT", - "MAINTENANCE_A", - "MAINTENANCE_B_INIT", - "MAINTENANCE_B", - "TEMP_UNDEROVER_INIT", - "TEMP_UNDEROVER", - "TEMP_LOWHIGH_INIT", - "TEMP_LOWHIGH", - "SUSPENDED_INIT", - "SUSPENDED", - "OVV_PROTECT_INIT", - "OVV_PROTECT", - "SAFETY_TIMER_EXPIRED_INIT", - "SAFETY_TIMER_EXPIRED", - "BATT_REMOVED_INIT", - "BATT_REMOVED", - "WD_EXPIRED_INIT", - "WD_EXPIRED", -}; - -struct abx500_chargalg_events { - bool batt_unknown; - bool mainextchnotok; - bool batt_ovv; - bool batt_rem; - bool btemp_underover; - bool btemp_lowhigh; - bool main_thermal_prot; - bool usb_thermal_prot; - bool main_ovv; - bool vbus_ovv; - bool usbchargernotok; - bool safety_timer_expired; - bool maintenance_timer_expired; - bool ac_wd_expired; - bool usb_wd_expired; - bool ac_cv_active; - bool usb_cv_active; - bool vbus_collapsed; -}; - -/** - * struct abx500_charge_curr_maximization - Charger maximization parameters - * @original_iset: the non optimized/maximised charger current - * @current_iset: the charging current used at this moment - * @test_delta_i: the delta between the current we want to charge and the - current that is really going into the battery - * @condition_cnt: number of iterations needed before a new charger current - is set - * @max_current: maximum charger current - * @wait_cnt: to avoid too fast current step down in case of charger - * voltage collapse, we insert this delay between step - * down - * @level: tells in how many steps the charging current has been - increased - */ -struct abx500_charge_curr_maximization { - int original_iset; - int current_iset; - int test_delta_i; - int condition_cnt; - int max_current; - int wait_cnt; - u8 level; -}; - -enum maxim_ret { - MAXIM_RET_NOACTION, - MAXIM_RET_CHANGE, - MAXIM_RET_IBAT_TOO_HIGH, -}; - -/** - * struct abx500_chargalg - abx500 Charging algorithm device information - * @dev: pointer to the structure device - * @charge_status: battery operating status - * @eoc_cnt: counter used to determine end-of_charge - * @rch_cnt: counter used to determine start of recharge - * @maintenance_chg: indicate if maintenance charge is active - * @t_hyst_norm temperature hysteresis when the temperature has been - * over or under normal limits - * @t_hyst_lowhigh temperature hysteresis when the temperature has been - * over or under the high or low limits - * @charge_state: current state of the charging algorithm - * @ccm charging current maximization parameters - * @chg_info: information about connected charger types - * @batt_data: data of the battery - * @susp_status: current charger suspension status - * @pdata: pointer to the abx500_chargalg platform data - * @bat: pointer to the abx500_bm platform data - * @chargalg_psy: structure that holds the battery properties exposed by - * the charging algorithm - * @events: structure for information about events triggered - * @chargalg_wq: work queue for running the charging algorithm - * @chargalg_periodic_work: work to run the charging algorithm periodically - * @chargalg_wd_work: work to kick the charger watchdog periodically - * @chargalg_work: work to run the charging algorithm instantly - * @safety_timer: charging safety timer - * @maintenance_timer: maintenance charging timer - * @chargalg_kobject: structure of type kobject - */ -struct abx500_chargalg { - struct device *dev; - int charge_status; - int eoc_cnt; - int rch_cnt; - bool maintenance_chg; - int t_hyst_norm; - int t_hyst_lowhigh; - enum abx500_chargalg_states charge_state; - struct abx500_charge_curr_maximization ccm; - struct abx500_chargalg_charger_info chg_info; - struct abx500_chargalg_battery_data batt_data; - struct abx500_chargalg_suspension_status susp_status; - struct abx500_chargalg_platform_data *pdata; - struct abx500_bm_data *bat; - struct power_supply chargalg_psy; - struct ux500_charger *ac_chg; - struct ux500_charger *usb_chg; - struct abx500_chargalg_events events; - struct workqueue_struct *chargalg_wq; - struct delayed_work chargalg_periodic_work; - struct delayed_work chargalg_wd_work; - struct work_struct chargalg_work; - struct timer_list safety_timer; - struct timer_list maintenance_timer; - struct kobject chargalg_kobject; -}; - -/* Main battery properties */ -static enum power_supply_property abx500_chargalg_props[] = { - POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_HEALTH, -}; - -/** - * abx500_chargalg_safety_timer_expired() - Expiration of the safety timer - * @data: pointer to the abx500_chargalg structure - * - * This function gets called when the safety timer for the charger - * expires - */ -static void abx500_chargalg_safety_timer_expired(unsigned long data) -{ - struct abx500_chargalg *di = (struct abx500_chargalg *) data; - dev_err(di->dev, "Safety timer expired\n"); - di->events.safety_timer_expired = true; - - /* Trigger execution of the algorithm instantly */ - queue_work(di->chargalg_wq, &di->chargalg_work); -} - -/** - * abx500_chargalg_maintenance_timer_expired() - Expiration of - * the maintenance timer - * @i: pointer to the abx500_chargalg structure - * - * This function gets called when the maintenence timer - * expires - */ -static void abx500_chargalg_maintenance_timer_expired(unsigned long data) -{ - - struct abx500_chargalg *di = (struct abx500_chargalg *) data; - dev_dbg(di->dev, "Maintenance timer expired\n"); - di->events.maintenance_timer_expired = true; - - /* Trigger execution of the algorithm instantly */ - queue_work(di->chargalg_wq, &di->chargalg_work); -} - -/** - * abx500_chargalg_state_to() - Change charge state - * @di: pointer to the abx500_chargalg structure - * - * This function gets called when a charge state change should occur - */ -static void abx500_chargalg_state_to(struct abx500_chargalg *di, - enum abx500_chargalg_states state) -{ - dev_dbg(di->dev, - "State changed: %s (From state: [%d] %s =to=> [%d] %s )\n", - di->charge_state == state ? "NO" : "YES", - di->charge_state, - states[di->charge_state], - state, - states[state]); - - di->charge_state = state; -} - -/** - * abx500_chargalg_check_charger_connection() - Check charger connection change - * @di: pointer to the abx500_chargalg structure - * - * This function will check if there is a change in the charger connection - * and change charge state accordingly. AC has precedence over USB. - */ -static int abx500_chargalg_check_charger_connection(struct abx500_chargalg *di) -{ - if (di->chg_info.conn_chg != di->chg_info.prev_conn_chg || - di->susp_status.suspended_change) { - /* - * Charger state changed or suspension - * has changed since last update - */ - if ((di->chg_info.conn_chg & AC_CHG) && - !di->susp_status.ac_suspended) { - dev_dbg(di->dev, "Charging source is AC\n"); - if (di->chg_info.charger_type != AC_CHG) { - di->chg_info.charger_type = AC_CHG; - abx500_chargalg_state_to(di, STATE_NORMAL_INIT); - } - } else if ((di->chg_info.conn_chg & USB_CHG) && - !di->susp_status.usb_suspended) { - dev_dbg(di->dev, "Charging source is USB\n"); - di->chg_info.charger_type = USB_CHG; - abx500_chargalg_state_to(di, STATE_NORMAL_INIT); - } else if (di->chg_info.conn_chg && - (di->susp_status.ac_suspended || - di->susp_status.usb_suspended)) { - dev_dbg(di->dev, "Charging is suspended\n"); - di->chg_info.charger_type = NO_CHG; - abx500_chargalg_state_to(di, STATE_SUSPENDED_INIT); - } else { - dev_dbg(di->dev, "Charging source is OFF\n"); - di->chg_info.charger_type = NO_CHG; - abx500_chargalg_state_to(di, STATE_HANDHELD_INIT); - } - di->chg_info.prev_conn_chg = di->chg_info.conn_chg; - di->susp_status.suspended_change = false; - } - return di->chg_info.conn_chg; -} - -/** - * abx500_chargalg_start_safety_timer() - Start charging safety timer - * @di: pointer to the abx500_chargalg structure - * - * The safety timer is used to avoid overcharging of old or bad batteries. - * There are different timers for AC and USB - */ -static void abx500_chargalg_start_safety_timer(struct abx500_chargalg *di) -{ - unsigned long timer_expiration = 0; - - switch (di->chg_info.charger_type) { - case AC_CHG: - timer_expiration = - round_jiffies(jiffies + - (di->bat->main_safety_tmr_h * 3600 * HZ)); - break; - - case USB_CHG: - timer_expiration = - round_jiffies(jiffies + - (di->bat->usb_safety_tmr_h * 3600 * HZ)); - break; - - default: - dev_err(di->dev, "Unknown charger to charge from\n"); - break; - } - - di->events.safety_timer_expired = false; - di->safety_timer.expires = timer_expiration; - if (!timer_pending(&di->safety_timer)) - add_timer(&di->safety_timer); - else - mod_timer(&di->safety_timer, timer_expiration); -} - -/** - * abx500_chargalg_stop_safety_timer() - Stop charging safety timer - * @di: pointer to the abx500_chargalg structure - * - * The safety timer is stopped whenever the NORMAL state is exited - */ -static void abx500_chargalg_stop_safety_timer(struct abx500_chargalg *di) -{ - di->events.safety_timer_expired = false; - del_timer(&di->safety_timer); -} - -/** - * abx500_chargalg_start_maintenance_timer() - Start charging maintenance timer - * @di: pointer to the abx500_chargalg structure - * @duration: duration of ther maintenance timer in hours - * - * The maintenance timer is used to maintain the charge in the battery once - * the battery is considered full. These timers are chosen to match the - * discharge curve of the battery - */ -static void abx500_chargalg_start_maintenance_timer(struct abx500_chargalg *di, - int duration) -{ - unsigned long timer_expiration; - - /* Convert from hours to jiffies */ - timer_expiration = round_jiffies(jiffies + (duration * 3600 * HZ)); - - di->events.maintenance_timer_expired = false; - di->maintenance_timer.expires = timer_expiration; - if (!timer_pending(&di->maintenance_timer)) - add_timer(&di->maintenance_timer); - else - mod_timer(&di->maintenance_timer, timer_expiration); -} - -/** - * abx500_chargalg_stop_maintenance_timer() - Stop maintenance timer - * @di: pointer to the abx500_chargalg structure - * - * The maintenance timer is stopped whenever maintenance ends or when another - * state is entered - */ -static void abx500_chargalg_stop_maintenance_timer(struct abx500_chargalg *di) -{ - di->events.maintenance_timer_expired = false; - del_timer(&di->maintenance_timer); -} - -/** - * abx500_chargalg_kick_watchdog() - Kick charger watchdog - * @di: pointer to the abx500_chargalg structure - * - * The charger watchdog have to be kicked periodically whenever the charger is - * on, else the ABB will reset the system - */ -static int abx500_chargalg_kick_watchdog(struct abx500_chargalg *di) -{ - /* Check if charger exists and kick watchdog if charging */ - if (di->ac_chg && di->ac_chg->ops.kick_wd && - di->chg_info.online_chg & AC_CHG) - return di->ac_chg->ops.kick_wd(di->ac_chg); - else if (di->usb_chg && di->usb_chg->ops.kick_wd && - di->chg_info.online_chg & USB_CHG) - return di->usb_chg->ops.kick_wd(di->usb_chg); - - return -ENXIO; -} - -/** - * abx500_chargalg_ac_en() - Turn on/off the AC charger - * @di: pointer to the abx500_chargalg structure - * @enable: charger on/off - * @vset: requested charger output voltage - * @iset: requested charger output current - * - * The AC charger will be turned on/off with the requested charge voltage and - * current - */ -static int abx500_chargalg_ac_en(struct abx500_chargalg *di, int enable, - int vset, int iset) -{ - if (!di->ac_chg || !di->ac_chg->ops.enable) - return -ENXIO; - - /* Select maximum of what both the charger and the battery supports */ - if (di->ac_chg->max_out_volt) - vset = min(vset, di->ac_chg->max_out_volt); - if (di->ac_chg->max_out_curr) - iset = min(iset, di->ac_chg->max_out_curr); - - di->chg_info.ac_iset = iset; - di->chg_info.ac_vset = vset; - - return di->ac_chg->ops.enable(di->ac_chg, enable, vset, iset); -} - -/** - * abx500_chargalg_usb_en() - Turn on/off the USB charger - * @di: pointer to the abx500_chargalg structure - * @enable: charger on/off - * @vset: requested charger output voltage - * @iset: requested charger output current - * - * The USB charger will be turned on/off with the requested charge voltage and - * current - */ -static int abx500_chargalg_usb_en(struct abx500_chargalg *di, int enable, - int vset, int iset) -{ - if (!di->usb_chg || !di->usb_chg->ops.enable) - return -ENXIO; - - /* Select maximum of what both the charger and the battery supports */ - if (di->usb_chg->max_out_volt) - vset = min(vset, di->usb_chg->max_out_volt); - if (di->usb_chg->max_out_curr) - iset = min(iset, di->usb_chg->max_out_curr); - - di->chg_info.usb_iset = iset; - di->chg_info.usb_vset = vset; - - return di->usb_chg->ops.enable(di->usb_chg, enable, vset, iset); -} - -/** - * abx500_chargalg_update_chg_curr() - Update charger current - * @di: pointer to the abx500_chargalg structure - * @iset: requested charger output current - * - * The charger output current will be updated for the charger - * that is currently in use - */ -static int abx500_chargalg_update_chg_curr(struct abx500_chargalg *di, - int iset) -{ - /* Check if charger exists and update current if charging */ - if (di->ac_chg && di->ac_chg->ops.update_curr && - di->chg_info.charger_type & AC_CHG) { - /* - * Select maximum of what both the charger - * and the battery supports - */ - if (di->ac_chg->max_out_curr) - iset = min(iset, di->ac_chg->max_out_curr); - - di->chg_info.ac_iset = iset; - - return di->ac_chg->ops.update_curr(di->ac_chg, iset); - } else if (di->usb_chg && di->usb_chg->ops.update_curr && - di->chg_info.charger_type & USB_CHG) { - /* - * Select maximum of what both the charger - * and the battery supports - */ - if (di->usb_chg->max_out_curr) - iset = min(iset, di->usb_chg->max_out_curr); - - di->chg_info.usb_iset = iset; - - return di->usb_chg->ops.update_curr(di->usb_chg, iset); - } - - return -ENXIO; -} - -/** - * abx500_chargalg_stop_charging() - Stop charging - * @di: pointer to the abx500_chargalg structure - * - * This function is called from any state where charging should be stopped. - * All charging is disabled and all status parameters and timers are changed - * accordingly - */ -static void abx500_chargalg_stop_charging(struct abx500_chargalg *di) -{ - abx500_chargalg_ac_en(di, false, 0, 0); - abx500_chargalg_usb_en(di, false, 0, 0); - abx500_chargalg_stop_safety_timer(di); - abx500_chargalg_stop_maintenance_timer(di); - di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING; - di->maintenance_chg = false; - cancel_delayed_work(&di->chargalg_wd_work); - power_supply_changed(&di->chargalg_psy); -} - -/** - * abx500_chargalg_hold_charging() - Pauses charging - * @di: pointer to the abx500_chargalg structure - * - * This function is called in the case where maintenance charging has been - * disabled and instead a battery voltage mode is entered to check when the - * battery voltage has reached a certain recharge voltage - */ -static void abx500_chargalg_hold_charging(struct abx500_chargalg *di) -{ - abx500_chargalg_ac_en(di, false, 0, 0); - abx500_chargalg_usb_en(di, false, 0, 0); - abx500_chargalg_stop_safety_timer(di); - abx500_chargalg_stop_maintenance_timer(di); - di->charge_status = POWER_SUPPLY_STATUS_CHARGING; - di->maintenance_chg = false; - cancel_delayed_work(&di->chargalg_wd_work); - power_supply_changed(&di->chargalg_psy); -} - -/** - * abx500_chargalg_start_charging() - Start the charger - * @di: pointer to the abx500_chargalg structure - * @vset: requested charger output voltage - * @iset: requested charger output current - * - * A charger will be enabled depending on the requested charger type that was - * detected previously. - */ -static void abx500_chargalg_start_charging(struct abx500_chargalg *di, - int vset, int iset) -{ - switch (di->chg_info.charger_type) { - case AC_CHG: - dev_dbg(di->dev, - "AC parameters: Vset %d, Ich %d\n", vset, iset); - abx500_chargalg_usb_en(di, false, 0, 0); - abx500_chargalg_ac_en(di, true, vset, iset); - break; - - case USB_CHG: - dev_dbg(di->dev, - "USB parameters: Vset %d, Ich %d\n", vset, iset); - abx500_chargalg_ac_en(di, false, 0, 0); - abx500_chargalg_usb_en(di, true, vset, iset); - break; - - default: - dev_err(di->dev, "Unknown charger to charge from\n"); - break; - } -} - -/** - * abx500_chargalg_check_temp() - Check battery temperature ranges - * @di: pointer to the abx500_chargalg structure - * - * The battery temperature is checked against the predefined limits and the - * charge state is changed accordingly - */ -static void abx500_chargalg_check_temp(struct abx500_chargalg *di) -{ - if (di->batt_data.temp > (di->bat->temp_low + di->t_hyst_norm) && - di->batt_data.temp < (di->bat->temp_high - di->t_hyst_norm)) { - /* Temp OK! */ - di->events.btemp_underover = false; - di->events.btemp_lowhigh = false; - di->t_hyst_norm = 0; - di->t_hyst_lowhigh = 0; - } else { - if (((di->batt_data.temp >= di->bat->temp_high) && - (di->batt_data.temp < - (di->bat->temp_over - di->t_hyst_lowhigh))) || - ((di->batt_data.temp > - (di->bat->temp_under + di->t_hyst_lowhigh)) && - (di->batt_data.temp <= di->bat->temp_low))) { - /* TEMP minor!!!!! */ - di->events.btemp_underover = false; - di->events.btemp_lowhigh = true; - di->t_hyst_norm = di->bat->temp_hysteresis; - di->t_hyst_lowhigh = 0; - } else if (di->batt_data.temp <= di->bat->temp_under || - di->batt_data.temp >= di->bat->temp_over) { - /* TEMP major!!!!! */ - di->events.btemp_underover = true; - di->events.btemp_lowhigh = false; - di->t_hyst_norm = 0; - di->t_hyst_lowhigh = di->bat->temp_hysteresis; - } else { - /* Within hysteresis */ - dev_dbg(di->dev, "Within hysteresis limit temp: %d " - "hyst_lowhigh %d, hyst normal %d\n", - di->batt_data.temp, di->t_hyst_lowhigh, - di->t_hyst_norm); - } - } -} - -/** - * abx500_chargalg_check_charger_voltage() - Check charger voltage - * @di: pointer to the abx500_chargalg structure - * - * Charger voltage is checked against maximum limit - */ -static void abx500_chargalg_check_charger_voltage(struct abx500_chargalg *di) -{ - if (di->chg_info.usb_volt > di->bat->chg_params->usb_volt_max) - di->chg_info.usb_chg_ok = false; - else - di->chg_info.usb_chg_ok = true; - - if (di->chg_info.ac_volt > di->bat->chg_params->ac_volt_max) - di->chg_info.ac_chg_ok = false; - else - di->chg_info.ac_chg_ok = true; - -} - -/** - * abx500_chargalg_end_of_charge() - Check if end-of-charge criteria is fulfilled - * @di: pointer to the abx500_chargalg structure - * - * End-of-charge criteria is fulfilled when the battery voltage is above a - * certain limit and the battery current is below a certain limit for a - * predefined number of consecutive seconds. If true, the battery is full - */ -static void abx500_chargalg_end_of_charge(struct abx500_chargalg *di) -{ - if (di->charge_status == POWER_SUPPLY_STATUS_CHARGING && - di->charge_state == STATE_NORMAL && - !di->maintenance_chg && (di->batt_data.volt >= - di->bat->bat_type[di->bat->batt_id].termination_vol || - di->events.usb_cv_active || di->events.ac_cv_active) && - di->batt_data.avg_curr < - di->bat->bat_type[di->bat->batt_id].termination_curr && - di->batt_data.avg_curr > 0) { - if (++di->eoc_cnt >= EOC_COND_CNT) { - di->eoc_cnt = 0; - di->charge_status = POWER_SUPPLY_STATUS_FULL; - di->maintenance_chg = true; - dev_dbg(di->dev, "EOC reached!\n"); - power_supply_changed(&di->chargalg_psy); - } else { - dev_dbg(di->dev, - " EOC limit reached for the %d" - " time, out of %d before EOC\n", - di->eoc_cnt, - EOC_COND_CNT); - } - } else { - di->eoc_cnt = 0; - } -} - -static void init_maxim_chg_curr(struct abx500_chargalg *di) -{ - di->ccm.original_iset = - di->bat->bat_type[di->bat->batt_id].normal_cur_lvl; - di->ccm.current_iset = - di->bat->bat_type[di->bat->batt_id].normal_cur_lvl; - di->ccm.test_delta_i = di->bat->maxi->charger_curr_step; - di->ccm.max_current = di->bat->maxi->chg_curr; - di->ccm.condition_cnt = di->bat->maxi->wait_cycles; - di->ccm.level = 0; -} - -/** - * abx500_chargalg_chg_curr_maxim - increases the charger current to - * compensate for the system load - * @di pointer to the abx500_chargalg structure - * - * This maximization function is used to raise the charger current to get the - * battery current as close to the optimal value as possible. The battery - * current during charging is affected by the system load - */ -static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di) -{ - int delta_i; - - if (!di->bat->maxi->ena_maxi) - return MAXIM_RET_NOACTION; - - delta_i = di->ccm.original_iset - di->batt_data.inst_curr; - - if (di->events.vbus_collapsed) { - dev_dbg(di->dev, "Charger voltage has collapsed %d\n", - di->ccm.wait_cnt); - if (di->ccm.wait_cnt == 0) { - dev_dbg(di->dev, "lowering current\n"); - di->ccm.wait_cnt++; - di->ccm.condition_cnt = di->bat->maxi->wait_cycles; - di->ccm.max_current = - di->ccm.current_iset - di->ccm.test_delta_i; - di->ccm.current_iset = di->ccm.max_current; - di->ccm.level--; - return MAXIM_RET_CHANGE; - } else { - dev_dbg(di->dev, "waiting\n"); - /* Let's go in here twice before lowering curr again */ - di->ccm.wait_cnt = (di->ccm.wait_cnt + 1) % 3; - return MAXIM_RET_NOACTION; - } - } - - di->ccm.wait_cnt = 0; - - if ((di->batt_data.inst_curr > di->ccm.original_iset)) { - dev_dbg(di->dev, " Maximization Ibat (%dmA) too high" - " (limit %dmA) (current iset: %dmA)!\n", - di->batt_data.inst_curr, di->ccm.original_iset, - di->ccm.current_iset); - - if (di->ccm.current_iset == di->ccm.original_iset) - return MAXIM_RET_NOACTION; - - di->ccm.condition_cnt = di->bat->maxi->wait_cycles; - di->ccm.current_iset = di->ccm.original_iset; - di->ccm.level = 0; - - return MAXIM_RET_IBAT_TOO_HIGH; - } - - if (delta_i > di->ccm.test_delta_i && - (di->ccm.current_iset + di->ccm.test_delta_i) < - di->ccm.max_current) { - if (di->ccm.condition_cnt-- == 0) { - /* Increse the iset with cco.test_delta_i */ - di->ccm.condition_cnt = di->bat->maxi->wait_cycles; - di->ccm.current_iset += di->ccm.test_delta_i; - di->ccm.level++; - dev_dbg(di->dev, " Maximization needed, increase" - " with %d mA to %dmA (Optimal ibat: %d)" - " Level %d\n", - di->ccm.test_delta_i, - di->ccm.current_iset, - di->ccm.original_iset, - di->ccm.level); - return MAXIM_RET_CHANGE; - } else { - return MAXIM_RET_NOACTION; - } - } else { - di->ccm.condition_cnt = di->bat->maxi->wait_cycles; - return MAXIM_RET_NOACTION; - } -} - -static void handle_maxim_chg_curr(struct abx500_chargalg *di) -{ - enum maxim_ret ret; - int result; - - ret = abx500_chargalg_chg_curr_maxim(di); - switch (ret) { - case MAXIM_RET_CHANGE: - result = abx500_chargalg_update_chg_curr(di, - di->ccm.current_iset); - if (result) - dev_err(di->dev, "failed to set chg curr\n"); - break; - case MAXIM_RET_IBAT_TOO_HIGH: - result = abx500_chargalg_update_chg_curr(di, - di->bat->bat_type[di->bat->batt_id].normal_cur_lvl); - if (result) - dev_err(di->dev, "failed to set chg curr\n"); - break; - - case MAXIM_RET_NOACTION: - default: - /* Do nothing..*/ - break; - } -} - -static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data) -{ - struct power_supply *psy; - struct power_supply *ext; - struct abx500_chargalg *di; - union power_supply_propval ret; - int i, j; - bool psy_found = false; - - psy = (struct power_supply *)data; - ext = dev_get_drvdata(dev); - di = to_abx500_chargalg_device_info(psy); - /* For all psy where the driver name appears in any supplied_to */ - for (i = 0; i < ext->num_supplicants; i++) { - if (!strcmp(ext->supplied_to[i], psy->name)) - psy_found = true; - } - if (!psy_found) - return 0; - - /* Go through all properties for the psy */ - for (j = 0; j < ext->num_properties; j++) { - enum power_supply_property prop; - prop = ext->properties[j]; - - /* Initialize chargers if not already done */ - if (!di->ac_chg && - ext->type == POWER_SUPPLY_TYPE_MAINS) - di->ac_chg = psy_to_ux500_charger(ext); - else if (!di->usb_chg && - ext->type == POWER_SUPPLY_TYPE_USB) - di->usb_chg = psy_to_ux500_charger(ext); - - if (ext->get_property(ext, prop, &ret)) - continue; - switch (prop) { - case POWER_SUPPLY_PROP_PRESENT: - switch (ext->type) { - case POWER_SUPPLY_TYPE_BATTERY: - /* Battery present */ - if (ret.intval) - di->events.batt_rem = false; - /* Battery removed */ - else - di->events.batt_rem = true; - break; - case POWER_SUPPLY_TYPE_MAINS: - /* AC disconnected */ - if (!ret.intval && - (di->chg_info.conn_chg & AC_CHG)) { - di->chg_info.prev_conn_chg = - di->chg_info.conn_chg; - di->chg_info.conn_chg &= ~AC_CHG; - } - /* AC connected */ - else if (ret.intval && - !(di->chg_info.conn_chg & AC_CHG)) { - di->chg_info.prev_conn_chg = - di->chg_info.conn_chg; - di->chg_info.conn_chg |= AC_CHG; - } - break; - case POWER_SUPPLY_TYPE_USB: - /* USB disconnected */ - if (!ret.intval && - (di->chg_info.conn_chg & USB_CHG)) { - di->chg_info.prev_conn_chg = - di->chg_info.conn_chg; - di->chg_info.conn_chg &= ~USB_CHG; - } - /* USB connected */ - else if (ret.intval && - !(di->chg_info.conn_chg & USB_CHG)) { - di->chg_info.prev_conn_chg = - di->chg_info.conn_chg; - di->chg_info.conn_chg |= USB_CHG; - } - break; - default: - break; - } - break; - - case POWER_SUPPLY_PROP_ONLINE: - switch (ext->type) { - case POWER_SUPPLY_TYPE_BATTERY: - break; - case POWER_SUPPLY_TYPE_MAINS: - /* AC offline */ - if (!ret.intval && - (di->chg_info.online_chg & AC_CHG)) { - di->chg_info.prev_online_chg = - di->chg_info.online_chg; - di->chg_info.online_chg &= ~AC_CHG; - } - /* AC online */ - else if (ret.intval && - !(di->chg_info.online_chg & AC_CHG)) { - di->chg_info.prev_online_chg = - di->chg_info.online_chg; - di->chg_info.online_chg |= AC_CHG; - queue_delayed_work(di->chargalg_wq, - &di->chargalg_wd_work, 0); - } - break; - case POWER_SUPPLY_TYPE_USB: - /* USB offline */ - if (!ret.intval && - (di->chg_info.online_chg & USB_CHG)) { - di->chg_info.prev_online_chg = - di->chg_info.online_chg; - di->chg_info.online_chg &= ~USB_CHG; - } - /* USB online */ - else if (ret.intval && - !(di->chg_info.online_chg & USB_CHG)) { - di->chg_info.prev_online_chg = - di->chg_info.online_chg; - di->chg_info.online_chg |= USB_CHG; - queue_delayed_work(di->chargalg_wq, - &di->chargalg_wd_work, 0); - } - break; - default: - break; - } - break; - - case POWER_SUPPLY_PROP_HEALTH: - switch (ext->type) { - case POWER_SUPPLY_TYPE_BATTERY: - break; - case POWER_SUPPLY_TYPE_MAINS: - switch (ret.intval) { - case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE: - di->events.mainextchnotok = true; - di->events.main_thermal_prot = false; - di->events.main_ovv = false; - di->events.ac_wd_expired = false; - break; - case POWER_SUPPLY_HEALTH_DEAD: - di->events.ac_wd_expired = true; - di->events.mainextchnotok = false; - di->events.main_ovv = false; - di->events.main_thermal_prot = false; - break; - case POWER_SUPPLY_HEALTH_COLD: - case POWER_SUPPLY_HEALTH_OVERHEAT: - di->events.main_thermal_prot = true; - di->events.mainextchnotok = false; - di->events.main_ovv = false; - di->events.ac_wd_expired = false; - break; - case POWER_SUPPLY_HEALTH_OVERVOLTAGE: - di->events.main_ovv = true; - di->events.mainextchnotok = false; - di->events.main_thermal_prot = false; - di->events.ac_wd_expired = false; - break; - case POWER_SUPPLY_HEALTH_GOOD: - di->events.main_thermal_prot = false; - di->events.mainextchnotok = false; - di->events.main_ovv = false; - di->events.ac_wd_expired = false; - break; - default: - break; - } - break; - - case POWER_SUPPLY_TYPE_USB: - switch (ret.intval) { - case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE: - di->events.usbchargernotok = true; - di->events.usb_thermal_prot = false; - di->events.vbus_ovv = false; - di->events.usb_wd_expired = false; - break; - case POWER_SUPPLY_HEALTH_DEAD: - di->events.usb_wd_expired = true; - di->events.usbchargernotok = false; - di->events.usb_thermal_prot = false; - di->events.vbus_ovv = false; - break; - case POWER_SUPPLY_HEALTH_COLD: - case POWER_SUPPLY_HEALTH_OVERHEAT: - di->events.usb_thermal_prot = true; - di->events.usbchargernotok = false; - di->events.vbus_ovv = false; - di->events.usb_wd_expired = false; - break; - case POWER_SUPPLY_HEALTH_OVERVOLTAGE: - di->events.vbus_ovv = true; - di->events.usbchargernotok = false; - di->events.usb_thermal_prot = false; - di->events.usb_wd_expired = false; - break; - case POWER_SUPPLY_HEALTH_GOOD: - di->events.usbchargernotok = false; - di->events.usb_thermal_prot = false; - di->events.vbus_ovv = false; - di->events.usb_wd_expired = false; - break; - default: - break; - } - default: - break; - } - break; - - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - switch (ext->type) { - case POWER_SUPPLY_TYPE_BATTERY: - di->batt_data.volt = ret.intval / 1000; - break; - case POWER_SUPPLY_TYPE_MAINS: - di->chg_info.ac_volt = ret.intval / 1000; - break; - case POWER_SUPPLY_TYPE_USB: - di->chg_info.usb_volt = ret.intval / 1000; - break; - default: - break; - } - break; - - case POWER_SUPPLY_PROP_VOLTAGE_AVG: - switch (ext->type) { - case POWER_SUPPLY_TYPE_MAINS: - /* AVG is used to indicate when we are - * in CV mode */ - if (ret.intval) - di->events.ac_cv_active = true; - else - di->events.ac_cv_active = false; - - break; - case POWER_SUPPLY_TYPE_USB: - /* AVG is used to indicate when we are - * in CV mode */ - if (ret.intval) - di->events.usb_cv_active = true; - else - di->events.usb_cv_active = false; - - break; - default: - break; - } - break; - - case POWER_SUPPLY_PROP_TECHNOLOGY: - switch (ext->type) { - case POWER_SUPPLY_TYPE_BATTERY: - if (ret.intval) - di->events.batt_unknown = false; - else - di->events.batt_unknown = true; - - break; - default: - break; - } - break; - - case POWER_SUPPLY_PROP_TEMP: - di->batt_data.temp = ret.intval / 10; - break; - - case POWER_SUPPLY_PROP_CURRENT_NOW: - switch (ext->type) { - case POWER_SUPPLY_TYPE_MAINS: - di->chg_info.ac_curr = - ret.intval / 1000; - break; - case POWER_SUPPLY_TYPE_USB: - di->chg_info.usb_curr = - ret.intval / 1000; - break; - case POWER_SUPPLY_TYPE_BATTERY: - di->batt_data.inst_curr = ret.intval / 1000; - break; - default: - break; - } - break; - - case POWER_SUPPLY_PROP_CURRENT_AVG: - switch (ext->type) { - case POWER_SUPPLY_TYPE_BATTERY: - di->batt_data.avg_curr = ret.intval / 1000; - break; - case POWER_SUPPLY_TYPE_USB: - if (ret.intval) - di->events.vbus_collapsed = true; - else - di->events.vbus_collapsed = false; - break; - default: - break; - } - break; - case POWER_SUPPLY_PROP_CAPACITY: - di->batt_data.percent = ret.intval; - break; - default: - break; - } - } - return 0; -} - -/** - * abx500_chargalg_external_power_changed() - callback for power supply changes - * @psy: pointer to the structure power_supply - * - * This function is the entry point of the pointer external_power_changed - * of the structure power_supply. - * This function gets executed when there is a change in any external power - * supply that this driver needs to be notified of. - */ -static void abx500_chargalg_external_power_changed(struct power_supply *psy) -{ - struct abx500_chargalg *di = to_abx500_chargalg_device_info(psy); - - /* - * Trigger execution of the algorithm instantly and read - * all power_supply properties there instead - */ - queue_work(di->chargalg_wq, &di->chargalg_work); -} - -/** - * abx500_chargalg_algorithm() - Main function for the algorithm - * @di: pointer to the abx500_chargalg structure - * - * This is the main control function for the charging algorithm. - * It is called periodically or when something happens that will - * trigger a state change - */ -static void abx500_chargalg_algorithm(struct abx500_chargalg *di) -{ - int charger_status; - - /* Collect data from all power_supply class devices */ - class_for_each_device(power_supply_class, NULL, - &di->chargalg_psy, abx500_chargalg_get_ext_psy_data); - - abx500_chargalg_end_of_charge(di); - abx500_chargalg_check_temp(di); - abx500_chargalg_check_charger_voltage(di); - - charger_status = abx500_chargalg_check_charger_connection(di); - /* - * First check if we have a charger connected. - * Also we don't allow charging of unknown batteries if configured - * this way - */ - if (!charger_status || - (di->events.batt_unknown && !di->bat->chg_unknown_bat)) { - if (di->charge_state != STATE_HANDHELD) { - di->events.safety_timer_expired = false; - abx500_chargalg_state_to(di, STATE_HANDHELD_INIT); - } - } - - /* If suspended, we should not continue checking the flags */ - else if (di->charge_state == STATE_SUSPENDED_INIT || - di->charge_state == STATE_SUSPENDED) { - /* We don't do anything here, just don,t continue */ - } - - /* Safety timer expiration */ - else if (di->events.safety_timer_expired) { - if (di->charge_state != STATE_SAFETY_TIMER_EXPIRED) - abx500_chargalg_state_to(di, - STATE_SAFETY_TIMER_EXPIRED_INIT); - } - /* - * Check if any interrupts has occured - * that will prevent us from charging - */ - - /* Battery removed */ - else if (di->events.batt_rem) { - if (di->charge_state != STATE_BATT_REMOVED) - abx500_chargalg_state_to(di, STATE_BATT_REMOVED_INIT); - } - /* Main or USB charger not ok. */ - else if (di->events.mainextchnotok || di->events.usbchargernotok) { - /* - * If vbus_collapsed is set, we have to lower the charger - * current, which is done in the normal state below - */ - if (di->charge_state != STATE_CHG_NOT_OK && - !di->events.vbus_collapsed) - abx500_chargalg_state_to(di, STATE_CHG_NOT_OK_INIT); - } - /* VBUS, Main or VBAT OVV. */ - else if (di->events.vbus_ovv || - di->events.main_ovv || - di->events.batt_ovv || - !di->chg_info.usb_chg_ok || - !di->chg_info.ac_chg_ok) { - if (di->charge_state != STATE_OVV_PROTECT) - abx500_chargalg_state_to(di, STATE_OVV_PROTECT_INIT); - } - /* USB Thermal, stop charging */ - else if (di->events.main_thermal_prot || - di->events.usb_thermal_prot) { - if (di->charge_state != STATE_HW_TEMP_PROTECT) - abx500_chargalg_state_to(di, - STATE_HW_TEMP_PROTECT_INIT); - } - /* Battery temp over/under */ - else if (di->events.btemp_underover) { - if (di->charge_state != STATE_TEMP_UNDEROVER) - abx500_chargalg_state_to(di, - STATE_TEMP_UNDEROVER_INIT); - } - /* Watchdog expired */ - else if (di->events.ac_wd_expired || - di->events.usb_wd_expired) { - if (di->charge_state != STATE_WD_EXPIRED) - abx500_chargalg_state_to(di, STATE_WD_EXPIRED_INIT); - } - /* Battery temp high/low */ - else if (di->events.btemp_lowhigh) { - if (di->charge_state != STATE_TEMP_LOWHIGH) - abx500_chargalg_state_to(di, STATE_TEMP_LOWHIGH_INIT); - } - - dev_dbg(di->dev, - "[CHARGALG] Vb %d Ib_avg %d Ib_inst %d Tb %d Cap %d Maint %d " - "State %s Active_chg %d Chg_status %d AC %d USB %d " - "AC_online %d USB_online %d AC_CV %d USB_CV %d AC_I %d " - "USB_I %d AC_Vset %d AC_Iset %d USB_Vset %d USB_Iset %d\n", - di->batt_data.volt, - di->batt_data.avg_curr, - di->batt_data.inst_curr, - di->batt_data.temp, - di->batt_data.percent, - di->maintenance_chg, - states[di->charge_state], - di->chg_info.charger_type, - di->charge_status, - di->chg_info.conn_chg & AC_CHG, - di->chg_info.conn_chg & USB_CHG, - di->chg_info.online_chg & AC_CHG, - di->chg_info.online_chg & USB_CHG, - di->events.ac_cv_active, - di->events.usb_cv_active, - di->chg_info.ac_curr, - di->chg_info.usb_curr, - di->chg_info.ac_vset, - di->chg_info.ac_iset, - di->chg_info.usb_vset, - di->chg_info.usb_iset); - - switch (di->charge_state) { - case STATE_HANDHELD_INIT: - abx500_chargalg_stop_charging(di); - di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING; - abx500_chargalg_state_to(di, STATE_HANDHELD); - /* Intentional fallthrough */ - - case STATE_HANDHELD: - break; - - case STATE_SUSPENDED_INIT: - if (di->susp_status.ac_suspended) - abx500_chargalg_ac_en(di, false, 0, 0); - if (di->susp_status.usb_suspended) - abx500_chargalg_usb_en(di, false, 0, 0); - abx500_chargalg_stop_safety_timer(di); - abx500_chargalg_stop_maintenance_timer(di); - di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING; - di->maintenance_chg = false; - abx500_chargalg_state_to(di, STATE_SUSPENDED); - power_supply_changed(&di->chargalg_psy); - /* Intentional fallthrough */ - - case STATE_SUSPENDED: - /* CHARGING is suspended */ - break; - - case STATE_BATT_REMOVED_INIT: - abx500_chargalg_stop_charging(di); - abx500_chargalg_state_to(di, STATE_BATT_REMOVED); - /* Intentional fallthrough */ - - case STATE_BATT_REMOVED: - if (!di->events.batt_rem) - abx500_chargalg_state_to(di, STATE_NORMAL_INIT); - break; - - case STATE_HW_TEMP_PROTECT_INIT: - abx500_chargalg_stop_charging(di); - abx500_chargalg_state_to(di, STATE_HW_TEMP_PROTECT); - /* Intentional fallthrough */ - - case STATE_HW_TEMP_PROTECT: - if (!di->events.main_thermal_prot && - !di->events.usb_thermal_prot) - abx500_chargalg_state_to(di, STATE_NORMAL_INIT); - break; - - case STATE_OVV_PROTECT_INIT: - abx500_chargalg_stop_charging(di); - abx500_chargalg_state_to(di, STATE_OVV_PROTECT); - /* Intentional fallthrough */ - - case STATE_OVV_PROTECT: - if (!di->events.vbus_ovv && - !di->events.main_ovv && - !di->events.batt_ovv && - di->chg_info.usb_chg_ok && - di->chg_info.ac_chg_ok) - abx500_chargalg_state_to(di, STATE_NORMAL_INIT); - break; - - case STATE_CHG_NOT_OK_INIT: - abx500_chargalg_stop_charging(di); - abx500_chargalg_state_to(di, STATE_CHG_NOT_OK); - /* Intentional fallthrough */ - - case STATE_CHG_NOT_OK: - if (!di->events.mainextchnotok && - !di->events.usbchargernotok) - abx500_chargalg_state_to(di, STATE_NORMAL_INIT); - break; - - case STATE_SAFETY_TIMER_EXPIRED_INIT: - abx500_chargalg_stop_charging(di); - abx500_chargalg_state_to(di, STATE_SAFETY_TIMER_EXPIRED); - /* Intentional fallthrough */ - - case STATE_SAFETY_TIMER_EXPIRED: - /* We exit this state when charger is removed */ - break; - - case STATE_NORMAL_INIT: - abx500_chargalg_start_charging(di, - di->bat->bat_type[di->bat->batt_id].normal_vol_lvl, - di->bat->bat_type[di->bat->batt_id].normal_cur_lvl); - abx500_chargalg_state_to(di, STATE_NORMAL); - abx500_chargalg_start_safety_timer(di); - abx500_chargalg_stop_maintenance_timer(di); - init_maxim_chg_curr(di); - di->charge_status = POWER_SUPPLY_STATUS_CHARGING; - di->eoc_cnt = 0; - di->maintenance_chg = false; - power_supply_changed(&di->chargalg_psy); - - break; - - case STATE_NORMAL: - handle_maxim_chg_curr(di); - if (di->charge_status == POWER_SUPPLY_STATUS_FULL && - di->maintenance_chg) { - if (di->bat->no_maintenance) - abx500_chargalg_state_to(di, - STATE_WAIT_FOR_RECHARGE_INIT); - else - abx500_chargalg_state_to(di, - STATE_MAINTENANCE_A_INIT); - } - break; - - /* This state will be used when the maintenance state is disabled */ - case STATE_WAIT_FOR_RECHARGE_INIT: - abx500_chargalg_hold_charging(di); - abx500_chargalg_state_to(di, STATE_WAIT_FOR_RECHARGE); - di->rch_cnt = RCH_COND_CNT; - /* Intentional fallthrough */ - - case STATE_WAIT_FOR_RECHARGE: - if (di->batt_data.volt <= - di->bat->bat_type[di->bat->batt_id].recharge_vol) { - if (di->rch_cnt-- == 0) - abx500_chargalg_state_to(di, STATE_NORMAL_INIT); - } else - di->rch_cnt = RCH_COND_CNT; - break; - - case STATE_MAINTENANCE_A_INIT: - abx500_chargalg_stop_safety_timer(di); - abx500_chargalg_start_maintenance_timer(di, - di->bat->bat_type[ - di->bat->batt_id].maint_a_chg_timer_h); - abx500_chargalg_start_charging(di, - di->bat->bat_type[ - di->bat->batt_id].maint_a_vol_lvl, - di->bat->bat_type[ - di->bat->batt_id].maint_a_cur_lvl); - abx500_chargalg_state_to(di, STATE_MAINTENANCE_A); - power_supply_changed(&di->chargalg_psy); - /* Intentional fallthrough*/ - - case STATE_MAINTENANCE_A: - if (di->events.maintenance_timer_expired) { - abx500_chargalg_stop_maintenance_timer(di); - abx500_chargalg_state_to(di, STATE_MAINTENANCE_B_INIT); - } - break; - - case STATE_MAINTENANCE_B_INIT: - abx500_chargalg_start_maintenance_timer(di, - di->bat->bat_type[ - di->bat->batt_id].maint_b_chg_timer_h); - abx500_chargalg_start_charging(di, - di->bat->bat_type[ - di->bat->batt_id].maint_b_vol_lvl, - di->bat->bat_type[ - di->bat->batt_id].maint_b_cur_lvl); - abx500_chargalg_state_to(di, STATE_MAINTENANCE_B); - power_supply_changed(&di->chargalg_psy); - /* Intentional fallthrough*/ - - case STATE_MAINTENANCE_B: - if (di->events.maintenance_timer_expired) { - abx500_chargalg_stop_maintenance_timer(di); - abx500_chargalg_state_to(di, STATE_NORMAL_INIT); - } - break; - - case STATE_TEMP_LOWHIGH_INIT: - abx500_chargalg_start_charging(di, - di->bat->bat_type[ - di->bat->batt_id].low_high_vol_lvl, - di->bat->bat_type[ - di->bat->batt_id].low_high_cur_lvl); - abx500_chargalg_stop_maintenance_timer(di); - di->charge_status = POWER_SUPPLY_STATUS_CHARGING; - abx500_chargalg_state_to(di, STATE_TEMP_LOWHIGH); - power_supply_changed(&di->chargalg_psy); - /* Intentional fallthrough */ - - case STATE_TEMP_LOWHIGH: - if (!di->events.btemp_lowhigh) - abx500_chargalg_state_to(di, STATE_NORMAL_INIT); - break; - - case STATE_WD_EXPIRED_INIT: - abx500_chargalg_stop_charging(di); - abx500_chargalg_state_to(di, STATE_WD_EXPIRED); - /* Intentional fallthrough */ - - case STATE_WD_EXPIRED: - if (!di->events.ac_wd_expired && - !di->events.usb_wd_expired) - abx500_chargalg_state_to(di, STATE_NORMAL_INIT); - break; - - case STATE_TEMP_UNDEROVER_INIT: - abx500_chargalg_stop_charging(di); - abx500_chargalg_state_to(di, STATE_TEMP_UNDEROVER); - /* Intentional fallthrough */ - - case STATE_TEMP_UNDEROVER: - if (!di->events.btemp_underover) - abx500_chargalg_state_to(di, STATE_NORMAL_INIT); - break; - } - - /* Start charging directly if the new state is a charge state */ - if (di->charge_state == STATE_NORMAL_INIT || - di->charge_state == STATE_MAINTENANCE_A_INIT || - di->charge_state == STATE_MAINTENANCE_B_INIT) - queue_work(di->chargalg_wq, &di->chargalg_work); -} - -/** - * abx500_chargalg_periodic_work() - Periodic work for the algorithm - * @work: pointer to the work_struct structure - * - * Work queue function for the charging algorithm - */ -static void abx500_chargalg_periodic_work(struct work_struct *work) -{ - struct abx500_chargalg *di = container_of(work, - struct abx500_chargalg, chargalg_periodic_work.work); - - abx500_chargalg_algorithm(di); - - /* - * If a charger is connected then the battery has to be monitored - * frequently, else the work can be delayed. - */ - if (di->chg_info.conn_chg) - queue_delayed_work(di->chargalg_wq, - &di->chargalg_periodic_work, - di->bat->interval_charging * HZ); - else - queue_delayed_work(di->chargalg_wq, - &di->chargalg_periodic_work, - di->bat->interval_not_charging * HZ); -} - -/** - * abx500_chargalg_wd_work() - periodic work to kick the charger watchdog - * @work: pointer to the work_struct structure - * - * Work queue function for kicking the charger watchdog - */ -static void abx500_chargalg_wd_work(struct work_struct *work) -{ - int ret; - struct abx500_chargalg *di = container_of(work, - struct abx500_chargalg, chargalg_wd_work.work); - - dev_dbg(di->dev, "abx500_chargalg_wd_work\n"); - - ret = abx500_chargalg_kick_watchdog(di); - if (ret < 0) - dev_err(di->dev, "failed to kick watchdog\n"); - - queue_delayed_work(di->chargalg_wq, - &di->chargalg_wd_work, CHG_WD_INTERVAL); -} - -/** - * abx500_chargalg_work() - Work to run the charging algorithm instantly - * @work: pointer to the work_struct structure - * - * Work queue function for calling the charging algorithm - */ -static void abx500_chargalg_work(struct work_struct *work) -{ - struct abx500_chargalg *di = container_of(work, - struct abx500_chargalg, chargalg_work); - - abx500_chargalg_algorithm(di); -} - -/** - * abx500_chargalg_get_property() - get the chargalg properties - * @psy: pointer to the power_supply structure - * @psp: pointer to the power_supply_property structure - * @val: pointer to the power_supply_propval union - * - * This function gets called when an application tries to get the - * chargalg properties by reading the sysfs files. - * status: charging/discharging/full/unknown - * health: health of the battery - * Returns error code in case of failure else 0 on success - */ -static int abx500_chargalg_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct abx500_chargalg *di; - - di = to_abx500_chargalg_device_info(psy); - - switch (psp) { - case POWER_SUPPLY_PROP_STATUS: - val->intval = di->charge_status; - break; - case POWER_SUPPLY_PROP_HEALTH: - if (di->events.batt_ovv) { - val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; - } else if (di->events.btemp_underover) { - if (di->batt_data.temp <= di->bat->temp_under) - val->intval = POWER_SUPPLY_HEALTH_COLD; - else - val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; - } else { - val->intval = POWER_SUPPLY_HEALTH_GOOD; - } - break; - default: - return -EINVAL; - } - return 0; -} - -/* Exposure to the sysfs interface */ - -/** - * abx500_chargalg_sysfs_charger() - sysfs store operations - * @kobj: pointer to the struct kobject - * @attr: pointer to the struct attribute - * @buf: buffer that holds the parameter passed from userspace - * @length: length of the parameter passed - * - * Returns length of the buffer(input taken from user space) on success - * else error code on failure - * The operation to be performed on passing the parameters from the user space. - */ -static ssize_t abx500_chargalg_sysfs_charger(struct kobject *kobj, - struct attribute *attr, const char *buf, size_t length) -{ - struct abx500_chargalg *di = container_of(kobj, - struct abx500_chargalg, chargalg_kobject); - long int param; - int ac_usb; - int ret; - char entry = *attr->name; - - switch (entry) { - case 'c': - ret = strict_strtol(buf, 10, ¶m); - if (ret < 0) - return ret; - - ac_usb = param; - switch (ac_usb) { - case 0: - /* Disable charging */ - di->susp_status.ac_suspended = true; - di->susp_status.usb_suspended = true; - di->susp_status.suspended_change = true; - /* Trigger a state change */ - queue_work(di->chargalg_wq, - &di->chargalg_work); - break; - case 1: - /* Enable AC Charging */ - di->susp_status.ac_suspended = false; - di->susp_status.suspended_change = true; - /* Trigger a state change */ - queue_work(di->chargalg_wq, - &di->chargalg_work); - break; - case 2: - /* Enable USB charging */ - di->susp_status.usb_suspended = false; - di->susp_status.suspended_change = true; - /* Trigger a state change */ - queue_work(di->chargalg_wq, - &di->chargalg_work); - break; - default: - dev_info(di->dev, "Wrong input\n" - "Enter 0. Disable AC/USB Charging\n" - "1. Enable AC charging\n" - "2. Enable USB Charging\n"); - }; - break; - }; - return strlen(buf); -} - -static struct attribute abx500_chargalg_en_charger = \ -{ - .name = "chargalg", - .mode = S_IWUGO, -}; - -static struct attribute *abx500_chargalg_chg[] = { - &abx500_chargalg_en_charger, - NULL -}; - -static const struct sysfs_ops abx500_chargalg_sysfs_ops = { - .store = abx500_chargalg_sysfs_charger, -}; - -static struct kobj_type abx500_chargalg_ktype = { - .sysfs_ops = &abx500_chargalg_sysfs_ops, - .default_attrs = abx500_chargalg_chg, -}; - -/** - * abx500_chargalg_sysfs_exit() - de-init of sysfs entry - * @di: pointer to the struct abx500_chargalg - * - * This function removes the entry in sysfs. - */ -static void abx500_chargalg_sysfs_exit(struct abx500_chargalg *di) -{ - kobject_del(&di->chargalg_kobject); -} - -/** - * abx500_chargalg_sysfs_init() - init of sysfs entry - * @di: pointer to the struct abx500_chargalg - * - * This function adds an entry in sysfs. - * Returns error code in case of failure else 0(on success) - */ -static int abx500_chargalg_sysfs_init(struct abx500_chargalg *di) -{ - int ret = 0; - - ret = kobject_init_and_add(&di->chargalg_kobject, - &abx500_chargalg_ktype, - NULL, "abx500_chargalg"); - if (ret < 0) - dev_err(di->dev, "failed to create sysfs entry\n"); - - return ret; -} -/* Exposure to the sysfs interface <> */ - -#if defined(CONFIG_PM) -static int abx500_chargalg_resume(struct platform_device *pdev) -{ - struct abx500_chargalg *di = platform_get_drvdata(pdev); - - /* Kick charger watchdog if charging (any charger online) */ - if (di->chg_info.online_chg) - queue_delayed_work(di->chargalg_wq, &di->chargalg_wd_work, 0); - - /* - * Run the charging algorithm directly to be sure we don't - * do it too seldom - */ - queue_delayed_work(di->chargalg_wq, &di->chargalg_periodic_work, 0); - - return 0; -} - -static int abx500_chargalg_suspend(struct platform_device *pdev, - pm_message_t state) -{ - struct abx500_chargalg *di = platform_get_drvdata(pdev); - - if (di->chg_info.online_chg) - cancel_delayed_work_sync(&di->chargalg_wd_work); - - cancel_delayed_work_sync(&di->chargalg_periodic_work); - - return 0; -} -#else -#define abx500_chargalg_suspend NULL -#define abx500_chargalg_resume NULL -#endif - -static int __devexit abx500_chargalg_remove(struct platform_device *pdev) -{ - struct abx500_chargalg *di = platform_get_drvdata(pdev); - - /* sysfs interface to enable/disbale charging from user space */ - abx500_chargalg_sysfs_exit(di); - - /* Delete the work queue */ - destroy_workqueue(di->chargalg_wq); - - flush_scheduled_work(); - power_supply_unregister(&di->chargalg_psy); - platform_set_drvdata(pdev, NULL); - kfree(di); - - return 0; -} - -static int __devinit abx500_chargalg_probe(struct platform_device *pdev) -{ - struct abx500_bm_plat_data *plat_data; - int ret = 0; - - struct abx500_chargalg *di = - kzalloc(sizeof(struct abx500_chargalg), GFP_KERNEL); - if (!di) - return -ENOMEM; - - /* get device struct */ - di->dev = &pdev->dev; - - plat_data = pdev->dev.platform_data; - di->pdata = plat_data->chargalg; - di->bat = plat_data->battery; - - /* chargalg supply */ - di->chargalg_psy.name = "abx500_chargalg"; - di->chargalg_psy.type = POWER_SUPPLY_TYPE_BATTERY; - di->chargalg_psy.properties = abx500_chargalg_props; - di->chargalg_psy.num_properties = ARRAY_SIZE(abx500_chargalg_props); - di->chargalg_psy.get_property = abx500_chargalg_get_property; - di->chargalg_psy.supplied_to = di->pdata->supplied_to; - di->chargalg_psy.num_supplicants = di->pdata->num_supplicants; - di->chargalg_psy.external_power_changed = - abx500_chargalg_external_power_changed; - - /* Initilialize safety timer */ - init_timer(&di->safety_timer); - di->safety_timer.function = abx500_chargalg_safety_timer_expired; - di->safety_timer.data = (unsigned long) di; - - /* Initilialize maintenance timer */ - init_timer(&di->maintenance_timer); - di->maintenance_timer.function = - abx500_chargalg_maintenance_timer_expired; - di->maintenance_timer.data = (unsigned long) di; - - /* Create a work queue for the chargalg */ - di->chargalg_wq = - create_singlethread_workqueue("abx500_chargalg_wq"); - if (di->chargalg_wq == NULL) { - dev_err(di->dev, "failed to create work queue\n"); - goto free_device_info; - } - - /* Init work for chargalg */ - INIT_DELAYED_WORK_DEFERRABLE(&di->chargalg_periodic_work, - abx500_chargalg_periodic_work); - INIT_DELAYED_WORK_DEFERRABLE(&di->chargalg_wd_work, - abx500_chargalg_wd_work); - - /* Init work for chargalg */ - INIT_WORK(&di->chargalg_work, abx500_chargalg_work); - - /* To detect charger at startup */ - di->chg_info.prev_conn_chg = -1; - - /* Register chargalg power supply class */ - ret = power_supply_register(di->dev, &di->chargalg_psy); - if (ret) { - dev_err(di->dev, "failed to register chargalg psy\n"); - goto free_chargalg_wq; - } - - platform_set_drvdata(pdev, di); - - /* sysfs interface to enable/disable charging from user space */ - ret = abx500_chargalg_sysfs_init(di); - if (ret) { - dev_err(di->dev, "failed to create sysfs entry\n"); - goto free_psy; - } - - /* Run the charging algorithm */ - queue_delayed_work(di->chargalg_wq, &di->chargalg_periodic_work, 0); - - dev_info(di->dev, "probe success\n"); - return ret; - -free_psy: - power_supply_unregister(&di->chargalg_psy); -free_chargalg_wq: - destroy_workqueue(di->chargalg_wq); -free_device_info: - kfree(di); - - return ret; -} - -static struct platform_driver abx500_chargalg_driver = { - .probe = abx500_chargalg_probe, - .remove = __devexit_p(abx500_chargalg_remove), - .suspend = abx500_chargalg_suspend, - .resume = abx500_chargalg_resume, - .driver = { - .name = "abx500-chargalg", - .owner = THIS_MODULE, - }, -}; - -static int __init abx500_chargalg_init(void) -{ - return platform_driver_register(&abx500_chargalg_driver); -} - -static void __exit abx500_chargalg_exit(void) -{ - platform_driver_unregister(&abx500_chargalg_driver); -} - -module_init(abx500_chargalg_init); -module_exit(abx500_chargalg_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Johan Palsson, Karl Komierowski"); -MODULE_ALIAS("platform:abx500-chargalg"); -MODULE_DESCRIPTION("abx500 battery charging algorithm"); diff --git a/trunk/drivers/power/charger-manager.c b/trunk/drivers/power/charger-manager.c index 9eca9f1ff0ea..88fd9710bda2 100644 --- a/trunk/drivers/power/charger-manager.c +++ b/trunk/drivers/power/charger-manager.c @@ -134,11 +134,12 @@ static int get_batt_uV(struct charger_manager *cm, int *uV) union power_supply_propval val; int ret; - if (!cm->fuel_gauge) + if (cm->fuel_gauge) + ret = cm->fuel_gauge->get_property(cm->fuel_gauge, + POWER_SUPPLY_PROP_VOLTAGE_NOW, &val); + else return -ENODEV; - ret = cm->fuel_gauge->get_property(cm->fuel_gauge, - POWER_SUPPLY_PROP_VOLTAGE_NOW, &val); if (ret) return ret; @@ -244,7 +245,9 @@ static int try_charger_enable(struct charger_manager *cm, bool enable) struct charger_desc *desc = cm->desc; /* Ignore if it's redundent command */ - if (enable == cm->charger_enabled) + if (enable && cm->charger_enabled) + return 0; + if (!enable && !cm->charger_enabled) return 0; if (enable) { @@ -306,7 +309,9 @@ static void uevent_notify(struct charger_manager *cm, const char *event) if (!strncmp(env_str_save, event, UEVENT_BUF_SIZE)) return; /* Duplicated. */ - strncpy(env_str_save, event, UEVENT_BUF_SIZE); + else + strncpy(env_str_save, event, UEVENT_BUF_SIZE); + return; } @@ -382,10 +387,8 @@ static bool cm_monitor(void) mutex_lock(&cm_list_mtx); - list_for_each_entry(cm, &cm_list, entry) { - if (_cm_monitor(cm)) - stop = true; - } + list_for_each_entry(cm, &cm_list, entry) + stop = stop || _cm_monitor(cm); mutex_unlock(&cm_list_mtx); @@ -399,8 +402,7 @@ static int charger_get_property(struct power_supply *psy, struct charger_manager *cm = container_of(psy, struct charger_manager, charger_psy); struct charger_desc *desc = cm->desc; - int ret = 0; - int uV; + int i, ret = 0, uV; switch (psp) { case POWER_SUPPLY_PROP_STATUS: @@ -426,7 +428,8 @@ static int charger_get_property(struct power_supply *psy, val->intval = 0; break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: - ret = get_batt_uV(cm, &val->intval); + ret = get_batt_uV(cm, &i); + val->intval = i; break; case POWER_SUPPLY_PROP_CURRENT_NOW: ret = cm->fuel_gauge->get_property(cm->fuel_gauge, @@ -694,10 +697,8 @@ bool cm_suspend_again(void) mutex_lock(&cm_list_mtx); list_for_each_entry(cm, &cm_list, entry) { if (cm->status_save_ext_pwr_inserted != is_ext_pwr_online(cm) || - cm->status_save_batt != is_batt_present(cm)) { + cm->status_save_batt != is_batt_present(cm)) ret = false; - break; - } } mutex_unlock(&cm_list_mtx); @@ -854,10 +855,11 @@ static int charger_manager_probe(struct platform_device *pdev) platform_set_drvdata(pdev, cm); - memcpy(&cm->charger_psy, &psy_default, sizeof(psy_default)); - + memcpy(&cm->charger_psy, &psy_default, + sizeof(psy_default)); if (!desc->psy_name) { - strncpy(cm->psy_name_buf, psy_default.name, PSY_NAME_MAX); + strncpy(cm->psy_name_buf, psy_default.name, + PSY_NAME_MAX); } else { strncpy(cm->psy_name_buf, desc->psy_name, PSY_NAME_MAX); } @@ -892,14 +894,14 @@ static int charger_manager_probe(struct platform_device *pdev) POWER_SUPPLY_PROP_CURRENT_NOW; cm->charger_psy.num_properties++; } - - if (desc->measure_battery_temp) { + if (!desc->measure_battery_temp) { cm->charger_psy.properties[cm->charger_psy.num_properties] = - POWER_SUPPLY_PROP_TEMP; + POWER_SUPPLY_PROP_TEMP_AMBIENT; cm->charger_psy.num_properties++; - } else { + } + if (desc->measure_battery_temp) { cm->charger_psy.properties[cm->charger_psy.num_properties] = - POWER_SUPPLY_PROP_TEMP_AMBIENT; + POWER_SUPPLY_PROP_TEMP; cm->charger_psy.num_properties++; } @@ -931,8 +933,9 @@ static int charger_manager_probe(struct platform_device *pdev) return 0; err_chg_enable: - regulator_bulk_free(desc->num_charger_regulators, - desc->charger_regulators); + if (desc->charger_regulators) + regulator_bulk_free(desc->num_charger_regulators, + desc->charger_regulators); err_bulk_get: power_supply_unregister(&cm->charger_psy); err_register: @@ -958,8 +961,10 @@ static int __devexit charger_manager_remove(struct platform_device *pdev) list_del(&cm->entry); mutex_unlock(&cm_list_mtx); - regulator_bulk_free(desc->num_charger_regulators, - desc->charger_regulators); + if (desc->charger_regulators) + regulator_bulk_free(desc->num_charger_regulators, + desc->charger_regulators); + power_supply_unregister(&cm->charger_psy); kfree(cm->charger_psy.properties); kfree(cm->charger_stat); @@ -977,7 +982,9 @@ MODULE_DEVICE_TABLE(platform, charger_manager_id); static int cm_suspend_prepare(struct device *dev) { - struct charger_manager *cm = dev_get_drvdata(dev); + struct platform_device *pdev = container_of(dev, struct platform_device, + dev); + struct charger_manager *cm = platform_get_drvdata(pdev); if (!cm_suspended) { if (rtc_dev) { @@ -1013,7 +1020,9 @@ static int cm_suspend_prepare(struct device *dev) static void cm_suspend_complete(struct device *dev) { - struct charger_manager *cm = dev_get_drvdata(dev); + struct platform_device *pdev = container_of(dev, struct platform_device, + dev); + struct charger_manager *cm = platform_get_drvdata(pdev); if (cm_suspended) { if (rtc_dev) { diff --git a/trunk/drivers/power/da9052-battery.c b/trunk/drivers/power/da9052-battery.c index a5f6a0ec1572..e8ea47a53dee 100644 --- a/trunk/drivers/power/da9052-battery.c +++ b/trunk/drivers/power/da9052-battery.c @@ -612,7 +612,6 @@ static s32 __devinit da9052_bat_probe(struct platform_device *pdev) if (ret) goto err; - platform_set_drvdata(pdev, bat); return 0; err: @@ -634,7 +633,6 @@ static int __devexit da9052_bat_remove(struct platform_device *pdev) free_irq(bat->da9052->irq_base + irq, bat); } power_supply_unregister(&bat->psy); - kfree(bat); return 0; } @@ -647,7 +645,18 @@ static struct platform_driver da9052_bat_driver = { .owner = THIS_MODULE, }, }; -module_platform_driver(da9052_bat_driver); + +static int __init da9052_bat_init(void) +{ + return platform_driver_register(&da9052_bat_driver); +} +module_init(da9052_bat_init); + +static void __exit da9052_bat_exit(void) +{ + platform_driver_unregister(&da9052_bat_driver); +} +module_exit(da9052_bat_exit); MODULE_DESCRIPTION("DA9052 BAT Device Driver"); MODULE_AUTHOR("David Dajun Chen "); diff --git a/trunk/drivers/power/ds2782_battery.c b/trunk/drivers/power/ds2782_battery.c index 6bb6e2f5ea81..bfbce5de49da 100644 --- a/trunk/drivers/power/ds2782_battery.c +++ b/trunk/drivers/power/ds2782_battery.c @@ -403,7 +403,18 @@ static struct i2c_driver ds278x_battery_driver = { .remove = ds278x_battery_remove, .id_table = ds278x_id, }; -module_i2c_driver(ds278x_battery_driver); + +static int __init ds278x_init(void) +{ + return i2c_add_driver(&ds278x_battery_driver); +} +module_init(ds278x_init); + +static void __exit ds278x_exit(void) +{ + i2c_del_driver(&ds278x_battery_driver); +} +module_exit(ds278x_exit); MODULE_AUTHOR("Ryan Mallon"); MODULE_DESCRIPTION("Maxim/Dallas DS2782 Stand-Alone Fuel Gauage IC driver"); diff --git a/trunk/drivers/power/isp1704_charger.c b/trunk/drivers/power/isp1704_charger.c index 39eb50f35f09..1289a5f790a1 100644 --- a/trunk/drivers/power/isp1704_charger.c +++ b/trunk/drivers/power/isp1704_charger.c @@ -480,7 +480,6 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to register isp1704 with error %d\n", ret); - isp1704_charger_set_power(isp, 0); return ret; } diff --git a/trunk/drivers/power/lp8727_charger.c b/trunk/drivers/power/lp8727_charger.c index d8b75780bfef..c53dd1292f81 100644 --- a/trunk/drivers/power/lp8727_charger.c +++ b/trunk/drivers/power/lp8727_charger.c @@ -1,7 +1,6 @@ /* - * Driver for LP8727 Micro/Mini USB IC with integrated charger + * Driver for LP8727 Micro/Mini USB IC with intergrated charger * - * Copyright (C) 2011 Texas Instruments * Copyright (C) 2011 National Semiconductor * * This program is free software; you can redistribute it and/or modify @@ -26,7 +25,7 @@ #define INT1 0x4 #define INT2 0x5 #define STATUS1 0x6 -#define STATUS2 0x7 +#define STATUS2 0x7 #define CHGCTRL2 0x9 /* CTRL1 register */ @@ -92,7 +91,7 @@ struct lp8727_chg { enum lp8727_dev_id devid; }; -static int lp8727_read_bytes(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len) +static int lp8727_i2c_read(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len) { s32 ret; @@ -103,22 +102,29 @@ static int lp8727_read_bytes(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len) return (ret != len) ? -EIO : 0; } -static inline int lp8727_read_byte(struct lp8727_chg *pchg, u8 reg, u8 *data) +static int lp8727_i2c_write(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len) { - return lp8727_read_bytes(pchg, reg, data, 1); -} - -static int lp8727_write_byte(struct lp8727_chg *pchg, u8 reg, u8 data) -{ - int ret; + s32 ret; mutex_lock(&pchg->xfer_lock); - ret = i2c_smbus_write_byte_data(pchg->client, reg, data); + ret = i2c_smbus_write_i2c_block_data(pchg->client, reg, len, data); mutex_unlock(&pchg->xfer_lock); return ret; } +static inline int lp8727_i2c_read_byte(struct lp8727_chg *pchg, u8 reg, + u8 *data) +{ + return lp8727_i2c_read(pchg, reg, data, 1); +} + +static inline int lp8727_i2c_write_byte(struct lp8727_chg *pchg, u8 reg, + u8 *data) +{ + return lp8727_i2c_write(pchg, reg, data, 1); +} + static int lp8727_is_charger_attached(const char *name, int id) { if (name) { @@ -131,41 +137,37 @@ static int lp8727_is_charger_attached(const char *name, int id) return (id >= ID_TA && id <= ID_USB_CHG) ? 1 : 0; } -static int lp8727_init_device(struct lp8727_chg *pchg) +static void lp8727_init_device(struct lp8727_chg *pchg) { u8 val; - int ret; val = ID200_EN | ADC_EN | CP_EN; - ret = lp8727_write_byte(pchg, CTRL1, val); - if (ret) - return ret; + if (lp8727_i2c_write_byte(pchg, CTRL1, &val)) + dev_err(pchg->dev, "i2c write err : addr=0x%.2x\n", CTRL1); val = INT_EN | CHGDET_EN; - ret = lp8727_write_byte(pchg, CTRL2, val); - if (ret) - return ret; - - return 0; + if (lp8727_i2c_write_byte(pchg, CTRL2, &val)) + dev_err(pchg->dev, "i2c write err : addr=0x%.2x\n", CTRL2); } static int lp8727_is_dedicated_charger(struct lp8727_chg *pchg) { u8 val; - lp8727_read_byte(pchg, STATUS1, &val); - return val & DCPORT; + lp8727_i2c_read_byte(pchg, STATUS1, &val); + return (val & DCPORT); } static int lp8727_is_usb_charger(struct lp8727_chg *pchg) { u8 val; - lp8727_read_byte(pchg, STATUS1, &val); - return val & CHPORT; + lp8727_i2c_read_byte(pchg, STATUS1, &val); + return (val & CHPORT); } static void lp8727_ctrl_switch(struct lp8727_chg *pchg, u8 sw) { - lp8727_write_byte(pchg, SWCTRL, sw); + u8 val = sw; + lp8727_i2c_write_byte(pchg, SWCTRL, &val); } static void lp8727_id_detection(struct lp8727_chg *pchg, u8 id, int vbusin) @@ -205,9 +207,9 @@ static void lp8727_enable_chgdet(struct lp8727_chg *pchg) { u8 val; - lp8727_read_byte(pchg, CTRL2, &val); + lp8727_i2c_read_byte(pchg, CTRL2, &val); val |= CHGDET_EN; - lp8727_write_byte(pchg, CTRL2, val); + lp8727_i2c_write_byte(pchg, CTRL2, &val); } static void lp8727_delayed_func(struct work_struct *_work) @@ -216,7 +218,7 @@ static void lp8727_delayed_func(struct work_struct *_work) struct lp8727_chg *pchg = container_of(_work, struct lp8727_chg, work.work); - if (lp8727_read_bytes(pchg, INT1, intstat, 2)) { + if (lp8727_i2c_read(pchg, INT1, intstat, 2)) { dev_err(pchg->dev, "can not read INT registers\n"); return; } @@ -242,22 +244,20 @@ static irqreturn_t lp8727_isr_func(int irq, void *ptr) return IRQ_HANDLED; } -static int lp8727_intr_config(struct lp8727_chg *pchg) +static void lp8727_intr_config(struct lp8727_chg *pchg) { INIT_DELAYED_WORK(&pchg->work, lp8727_delayed_func); pchg->irqthread = create_singlethread_workqueue("lp8727-irqthd"); - if (!pchg->irqthread) { + if (!pchg->irqthread) dev_err(pchg->dev, "can not create thread for lp8727\n"); - return -ENOMEM; - } - return request_threaded_irq(pchg->client->irq, - NULL, - lp8727_isr_func, - IRQF_TRIGGER_FALLING, - "lp8727_irq", - pchg); + if (request_threaded_irq(pchg->client->irq, + NULL, + lp8727_isr_func, + IRQF_TRIGGER_FALLING, "lp8727_irq", pchg)) { + dev_err(pchg->dev, "lp8727 irq can not be registered\n"); + } } static enum power_supply_property lp8727_charger_prop[] = { @@ -300,7 +300,7 @@ static int lp8727_battery_get_property(struct power_supply *psy, switch (psp) { case POWER_SUPPLY_PROP_STATUS: if (lp8727_is_charger_attached(psy->name, pchg->devid)) { - lp8727_read_byte(pchg, STATUS1, &read); + lp8727_i2c_read_byte(pchg, STATUS1, &read); if (((read & CHGSTAT) >> 4) == EOC) val->intval = POWER_SUPPLY_STATUS_FULL; else @@ -310,7 +310,7 @@ static int lp8727_battery_get_property(struct power_supply *psy, } break; case POWER_SUPPLY_PROP_HEALTH: - lp8727_read_byte(pchg, STATUS2, &read); + lp8727_i2c_read_byte(pchg, STATUS2, &read); read = (read & TEMP_STAT) >> 5; if (read >= 0x1 && read <= 0x3) val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; @@ -351,7 +351,7 @@ static void lp8727_charger_changed(struct power_supply *psy) eoc_level = pchg->chg_parm->eoc_level; ichg = pchg->chg_parm->ichg; val = (ichg << 4) | eoc_level; - lp8727_write_byte(pchg, CHGCTRL2, val); + lp8727_i2c_write_byte(pchg, CHGCTRL2, &val); } } } @@ -439,29 +439,15 @@ static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id) mutex_init(&pchg->xfer_lock); - ret = lp8727_init_device(pchg); - if (ret) { - dev_err(pchg->dev, "i2c communication err: %d", ret); - goto error; - } - - ret = lp8727_intr_config(pchg); - if (ret) { - dev_err(pchg->dev, "irq handler err: %d", ret); - goto error; - } + lp8727_init_device(pchg); + lp8727_intr_config(pchg); ret = lp8727_register_psy(pchg); - if (ret) { - dev_err(pchg->dev, "power supplies register err: %d", ret); - goto error; - } + if (ret) + dev_err(pchg->dev, + "can not register power supplies. err=%d", ret); return 0; - -error: - kfree(pchg); - return ret; } static int __devexit lp8727_remove(struct i2c_client *cl) @@ -480,7 +466,6 @@ static const struct i2c_device_id lp8727_ids[] = { {"lp8727", 0}, { } }; -MODULE_DEVICE_TABLE(i2c, lp8727_ids); static struct i2c_driver lp8727_driver = { .driver = { @@ -490,9 +475,21 @@ static struct i2c_driver lp8727_driver = { .remove = __devexit_p(lp8727_remove), .id_table = lp8727_ids, }; -module_i2c_driver(lp8727_driver); -MODULE_DESCRIPTION("TI/National Semiconductor LP8727 charger driver"); -MODULE_AUTHOR("Woogyom Kim , " - "Daniel Jeong "); +static int __init lp8727_init(void) +{ + return i2c_add_driver(&lp8727_driver); +} + +static void __exit lp8727_exit(void) +{ + i2c_del_driver(&lp8727_driver); +} + +module_init(lp8727_init); +module_exit(lp8727_exit); + +MODULE_DESCRIPTION("National Semiconductor LP8727 charger driver"); +MODULE_AUTHOR + ("Woogyom Kim , Daniel Jeong "); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/power/max17040_battery.c b/trunk/drivers/power/max17040_battery.c index c284143cfcd7..2f2f9a6f54fa 100644 --- a/trunk/drivers/power/max17040_battery.c +++ b/trunk/drivers/power/max17040_battery.c @@ -290,7 +290,18 @@ static struct i2c_driver max17040_i2c_driver = { .resume = max17040_resume, .id_table = max17040_id, }; -module_i2c_driver(max17040_i2c_driver); + +static int __init max17040_init(void) +{ + return i2c_add_driver(&max17040_i2c_driver); +} +module_init(max17040_init); + +static void __exit max17040_exit(void) +{ + i2c_del_driver(&max17040_i2c_driver); +} +module_exit(max17040_exit); MODULE_AUTHOR("Minkyu Kang "); MODULE_DESCRIPTION("MAX17040 Fuel Gauge"); diff --git a/trunk/drivers/power/max17042_battery.c b/trunk/drivers/power/max17042_battery.c index 04620c2cb388..86acee2f9889 100644 --- a/trunk/drivers/power/max17042_battery.c +++ b/trunk/drivers/power/max17042_battery.c @@ -26,47 +26,14 @@ #include #include #include -#include -#include #include #include #include -#include - -/* Status register bits */ -#define STATUS_POR_BIT (1 << 1) -#define STATUS_BST_BIT (1 << 3) -#define STATUS_VMN_BIT (1 << 8) -#define STATUS_TMN_BIT (1 << 9) -#define STATUS_SMN_BIT (1 << 10) -#define STATUS_BI_BIT (1 << 11) -#define STATUS_VMX_BIT (1 << 12) -#define STATUS_TMX_BIT (1 << 13) -#define STATUS_SMX_BIT (1 << 14) -#define STATUS_BR_BIT (1 << 15) - -/* Interrupt mask bits */ -#define CONFIG_ALRT_BIT_ENBL (1 << 2) -#define STATUS_INTR_SOCMIN_BIT (1 << 10) -#define STATUS_INTR_SOCMAX_BIT (1 << 14) - -#define VFSOC0_LOCK 0x0000 -#define VFSOC0_UNLOCK 0x0080 -#define MODEL_UNLOCK1 0X0059 -#define MODEL_UNLOCK2 0X00C4 -#define MODEL_LOCK1 0X0000 -#define MODEL_LOCK2 0X0000 - -#define dQ_ACC_DIV 0x4 -#define dP_ACC_100 0x1900 -#define dP_ACC_200 0x3200 struct max17042_chip { struct i2c_client *client; struct power_supply battery; struct max17042_platform_data *pdata; - struct work_struct work; - int init_complete; }; static int max17042_write_reg(struct i2c_client *client, u8 reg, u16 value) @@ -120,9 +87,6 @@ static int max17042_get_property(struct power_supply *psy, struct max17042_chip, battery); int ret; - if (!chip->init_complete) - return -EAGAIN; - switch (psp) { case POWER_SUPPLY_PROP_PRESENT: ret = max17042_read_reg(chip->client, MAX17042_STATUS); @@ -172,18 +136,21 @@ static int max17042_get_property(struct power_supply *psy, val->intval = ret * 625 / 8; break; case POWER_SUPPLY_PROP_CAPACITY: - ret = max17042_read_reg(chip->client, MAX17042_RepSOC); + ret = max17042_read_reg(chip->client, MAX17042_SOC); if (ret < 0) return ret; val->intval = ret >> 8; break; case POWER_SUPPLY_PROP_CHARGE_FULL: - ret = max17042_read_reg(chip->client, MAX17042_FullCAP); + ret = max17042_read_reg(chip->client, MAX17042_RepSOC); if (ret < 0) return ret; - val->intval = ret * 1000 / 2; + if ((ret >> 8) >= MAX17042_BATTERY_FULL) + val->intval = 1; + else if (ret >= 0) + val->intval = 0; break; case POWER_SUPPLY_PROP_TEMP: ret = max17042_read_reg(chip->client, MAX17042_TEMP); @@ -243,419 +210,22 @@ static int max17042_get_property(struct power_supply *psy, return 0; } -static int max17042_write_verify_reg(struct i2c_client *client, - u8 reg, u16 value) -{ - int retries = 8; - int ret; - u16 read_value; - - do { - ret = i2c_smbus_write_word_data(client, reg, value); - read_value = max17042_read_reg(client, reg); - if (read_value != value) { - ret = -EIO; - retries--; - } - } while (retries && read_value != value); - - if (ret < 0) - dev_err(&client->dev, "%s: err %d\n", __func__, ret); - - return ret; -} - -static inline void max17042_override_por( - struct i2c_client *client, u8 reg, u16 value) -{ - if (value) - max17042_write_reg(client, reg, value); -} - -static inline void max10742_unlock_model(struct max17042_chip *chip) -{ - struct i2c_client *client = chip->client; - max17042_write_reg(client, MAX17042_MLOCKReg1, MODEL_UNLOCK1); - max17042_write_reg(client, MAX17042_MLOCKReg2, MODEL_UNLOCK2); -} - -static inline void max10742_lock_model(struct max17042_chip *chip) -{ - struct i2c_client *client = chip->client; - max17042_write_reg(client, MAX17042_MLOCKReg1, MODEL_LOCK1); - max17042_write_reg(client, MAX17042_MLOCKReg2, MODEL_LOCK2); -} - -static inline void max17042_write_model_data(struct max17042_chip *chip, - u8 addr, int size) -{ - struct i2c_client *client = chip->client; - int i; - for (i = 0; i < size; i++) - max17042_write_reg(client, addr + i, - chip->pdata->config_data->cell_char_tbl[i]); -} - -static inline void max17042_read_model_data(struct max17042_chip *chip, - u8 addr, u16 *data, int size) -{ - struct i2c_client *client = chip->client; - int i; - - for (i = 0; i < size; i++) - data[i] = max17042_read_reg(client, addr + i); -} - -static inline int max17042_model_data_compare(struct max17042_chip *chip, - u16 *data1, u16 *data2, int size) -{ - int i; - - if (memcmp(data1, data2, size)) { - dev_err(&chip->client->dev, "%s compare failed\n", __func__); - for (i = 0; i < size; i++) - dev_info(&chip->client->dev, "0x%x, 0x%x", - data1[i], data2[i]); - dev_info(&chip->client->dev, "\n"); - return -EINVAL; - } - return 0; -} - -static int max17042_init_model(struct max17042_chip *chip) -{ - int ret; - int table_size = - sizeof(chip->pdata->config_data->cell_char_tbl)/sizeof(u16); - u16 *temp_data; - - temp_data = kzalloc(table_size, GFP_KERNEL); - if (!temp_data) - return -ENOMEM; - - max10742_unlock_model(chip); - max17042_write_model_data(chip, MAX17042_MODELChrTbl, - table_size); - max17042_read_model_data(chip, MAX17042_MODELChrTbl, temp_data, - table_size); - - ret = max17042_model_data_compare( - chip, - chip->pdata->config_data->cell_char_tbl, - temp_data, - table_size); - - max10742_lock_model(chip); - kfree(temp_data); - - return ret; -} - -static int max17042_verify_model_lock(struct max17042_chip *chip) -{ - int i; - int table_size = - sizeof(chip->pdata->config_data->cell_char_tbl); - u16 *temp_data; - int ret = 0; - - temp_data = kzalloc(table_size, GFP_KERNEL); - if (!temp_data) - return -ENOMEM; - - max17042_read_model_data(chip, MAX17042_MODELChrTbl, temp_data, - table_size); - for (i = 0; i < table_size; i++) - if (temp_data[i]) - ret = -EINVAL; - - kfree(temp_data); - return ret; -} - -static void max17042_write_config_regs(struct max17042_chip *chip) -{ - struct max17042_config_data *config = chip->pdata->config_data; - - max17042_write_reg(chip->client, MAX17042_CONFIG, config->config); - max17042_write_reg(chip->client, MAX17042_LearnCFG, config->learn_cfg); - max17042_write_reg(chip->client, MAX17042_FilterCFG, - config->filter_cfg); - max17042_write_reg(chip->client, MAX17042_RelaxCFG, config->relax_cfg); -} - -static void max17042_write_custom_regs(struct max17042_chip *chip) -{ - struct max17042_config_data *config = chip->pdata->config_data; - - max17042_write_verify_reg(chip->client, MAX17042_RCOMP0, - config->rcomp0); - max17042_write_verify_reg(chip->client, MAX17042_TempCo, - config->tcompc0); - max17042_write_reg(chip->client, MAX17042_EmptyTempCo, - config->empty_tempco); - max17042_write_verify_reg(chip->client, MAX17042_K_empty0, - config->kempty0); - max17042_write_verify_reg(chip->client, MAX17042_ICHGTerm, - config->ichgt_term); -} - -static void max17042_update_capacity_regs(struct max17042_chip *chip) -{ - struct max17042_config_data *config = chip->pdata->config_data; - - max17042_write_verify_reg(chip->client, MAX17042_FullCAP, - config->fullcap); - max17042_write_reg(chip->client, MAX17042_DesignCap, - config->design_cap); - max17042_write_verify_reg(chip->client, MAX17042_FullCAPNom, - config->fullcapnom); -} - -static void max17042_reset_vfsoc0_reg(struct max17042_chip *chip) -{ - u16 vfSoc; - - vfSoc = max17042_read_reg(chip->client, MAX17042_VFSOC); - max17042_write_reg(chip->client, MAX17042_VFSOC0Enable, VFSOC0_UNLOCK); - max17042_write_verify_reg(chip->client, MAX17042_VFSOC0, vfSoc); - max17042_write_reg(chip->client, MAX17042_VFSOC0Enable, VFSOC0_LOCK); -} - -static void max17042_load_new_capacity_params(struct max17042_chip *chip) -{ - u16 full_cap0, rep_cap, dq_acc, vfSoc; - u32 rem_cap; - - struct max17042_config_data *config = chip->pdata->config_data; - - full_cap0 = max17042_read_reg(chip->client, MAX17042_FullCAP0); - vfSoc = max17042_read_reg(chip->client, MAX17042_VFSOC); - - /* fg_vfSoc needs to shifted by 8 bits to get the - * perc in 1% accuracy, to get the right rem_cap multiply - * full_cap0, fg_vfSoc and devide by 100 - */ - rem_cap = ((vfSoc >> 8) * full_cap0) / 100; - max17042_write_verify_reg(chip->client, MAX17042_RemCap, (u16)rem_cap); - - rep_cap = (u16)rem_cap; - max17042_write_verify_reg(chip->client, MAX17042_RepCap, rep_cap); - - /* Write dQ_acc to 200% of Capacity and dP_acc to 200% */ - dq_acc = config->fullcap / dQ_ACC_DIV; - max17042_write_verify_reg(chip->client, MAX17042_dQacc, dq_acc); - max17042_write_verify_reg(chip->client, MAX17042_dPacc, dP_ACC_200); - - max17042_write_verify_reg(chip->client, MAX17042_FullCAP, - config->fullcap); - max17042_write_reg(chip->client, MAX17042_DesignCap, - config->design_cap); - max17042_write_verify_reg(chip->client, MAX17042_FullCAPNom, - config->fullcapnom); -} - -/* - * Block write all the override values coming from platform data. - * This function MUST be called before the POR initialization proceedure - * specified by maxim. - */ -static inline void max17042_override_por_values(struct max17042_chip *chip) -{ - struct i2c_client *client = chip->client; - struct max17042_config_data *config = chip->pdata->config_data; - - max17042_override_por(client, MAX17042_TGAIN, config->tgain); - max17042_override_por(client, MAx17042_TOFF, config->toff); - max17042_override_por(client, MAX17042_CGAIN, config->cgain); - max17042_override_por(client, MAX17042_COFF, config->coff); - - max17042_override_por(client, MAX17042_VALRT_Th, config->valrt_thresh); - max17042_override_por(client, MAX17042_TALRT_Th, config->talrt_thresh); - max17042_override_por(client, MAX17042_SALRT_Th, - config->soc_alrt_thresh); - max17042_override_por(client, MAX17042_CONFIG, config->config); - max17042_override_por(client, MAX17042_SHDNTIMER, config->shdntimer); - - max17042_override_por(client, MAX17042_DesignCap, config->design_cap); - max17042_override_por(client, MAX17042_ICHGTerm, config->ichgt_term); - - max17042_override_por(client, MAX17042_AtRate, config->at_rate); - max17042_override_por(client, MAX17042_LearnCFG, config->learn_cfg); - max17042_override_por(client, MAX17042_FilterCFG, config->filter_cfg); - max17042_override_por(client, MAX17042_RelaxCFG, config->relax_cfg); - max17042_override_por(client, MAX17042_MiscCFG, config->misc_cfg); - max17042_override_por(client, MAX17042_MaskSOC, config->masksoc); - - max17042_override_por(client, MAX17042_FullCAP, config->fullcap); - max17042_override_por(client, MAX17042_FullCAPNom, config->fullcapnom); - max17042_override_por(client, MAX17042_SOC_empty, config->socempty); - max17042_override_por(client, MAX17042_LAvg_empty, config->lavg_empty); - max17042_override_por(client, MAX17042_dQacc, config->dqacc); - max17042_override_por(client, MAX17042_dPacc, config->dpacc); - - max17042_override_por(client, MAX17042_V_empty, config->vempty); - max17042_override_por(client, MAX17042_TempNom, config->temp_nom); - max17042_override_por(client, MAX17042_TempLim, config->temp_lim); - max17042_override_por(client, MAX17042_FCTC, config->fctc); - max17042_override_por(client, MAX17042_RCOMP0, config->rcomp0); - max17042_override_por(client, MAX17042_TempCo, config->tcompc0); - max17042_override_por(client, MAX17042_EmptyTempCo, - config->empty_tempco); - max17042_override_por(client, MAX17042_K_empty0, config->kempty0); -} - -static int max17042_init_chip(struct max17042_chip *chip) -{ - int ret; - int val; - - max17042_override_por_values(chip); - /* After Power up, the MAX17042 requires 500mS in order - * to perform signal debouncing and initial SOC reporting - */ - msleep(500); - - /* Initialize configaration */ - max17042_write_config_regs(chip); - - /* write cell characterization data */ - ret = max17042_init_model(chip); - if (ret) { - dev_err(&chip->client->dev, "%s init failed\n", - __func__); - return -EIO; - } - max17042_verify_model_lock(chip); - if (ret) { - dev_err(&chip->client->dev, "%s lock verify failed\n", - __func__); - return -EIO; - } - /* write custom parameters */ - max17042_write_custom_regs(chip); - - /* update capacity params */ - max17042_update_capacity_regs(chip); - - /* delay must be atleast 350mS to allow VFSOC - * to be calculated from the new configuration - */ - msleep(350); - - /* reset vfsoc0 reg */ - max17042_reset_vfsoc0_reg(chip); - - /* load new capacity params */ - max17042_load_new_capacity_params(chip); - - /* Init complete, Clear the POR bit */ - val = max17042_read_reg(chip->client, MAX17042_STATUS); - max17042_write_reg(chip->client, MAX17042_STATUS, - val & (~STATUS_POR_BIT)); - return 0; -} - -static void max17042_set_soc_threshold(struct max17042_chip *chip, u16 off) -{ - u16 soc, soc_tr; - - /* program interrupt thesholds such that we should - * get interrupt for every 'off' perc change in the soc - */ - soc = max17042_read_reg(chip->client, MAX17042_RepSOC) >> 8; - soc_tr = (soc + off) << 8; - soc_tr |= (soc - off); - max17042_write_reg(chip->client, MAX17042_SALRT_Th, soc_tr); -} - -static irqreturn_t max17042_thread_handler(int id, void *dev) -{ - struct max17042_chip *chip = dev; - u16 val; - - val = max17042_read_reg(chip->client, MAX17042_STATUS); - if ((val & STATUS_INTR_SOCMIN_BIT) || - (val & STATUS_INTR_SOCMAX_BIT)) { - dev_info(&chip->client->dev, "SOC threshold INTR\n"); - max17042_set_soc_threshold(chip, 1); - } - - power_supply_changed(&chip->battery); - return IRQ_HANDLED; -} - -static void max17042_init_worker(struct work_struct *work) -{ - struct max17042_chip *chip = container_of(work, - struct max17042_chip, work); - int ret; - - /* Initialize registers according to values from the platform data */ - if (chip->pdata->enable_por_init && chip->pdata->config_data) { - ret = max17042_init_chip(chip); - if (ret) - return; - } - - chip->init_complete = 1; -} - -#ifdef CONFIG_OF -static struct max17042_platform_data * -max17042_get_pdata(struct device *dev) -{ - struct device_node *np = dev->of_node; - u32 prop; - struct max17042_platform_data *pdata; - - if (!np) - return dev->platform_data; - - pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return NULL; - - /* - * Require current sense resistor value to be specified for - * current-sense functionality to be enabled at all. - */ - if (of_property_read_u32(np, "maxim,rsns-microohm", &prop) == 0) { - pdata->r_sns = prop; - pdata->enable_current_sense = true; - } - - return pdata; -} -#else -static struct max17042_platform_data * -max17042_get_pdata(struct device *dev) -{ - return dev->platform_data; -} -#endif - static int __devinit max17042_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct max17042_chip *chip; int ret; - int reg; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) return -EIO; - chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); + chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM; chip->client = client; - chip->pdata = max17042_get_pdata(&client->dev); - if (!chip->pdata) { - dev_err(&client->dev, "no platform data provided\n"); - return -EINVAL; - } + chip->pdata = client->dev.platform_data; i2c_set_clientdata(client, chip); @@ -673,9 +243,17 @@ static int __devinit max17042_probe(struct i2c_client *client, if (chip->pdata->r_sns == 0) chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR; + ret = power_supply_register(&client->dev, &chip->battery); + if (ret) { + dev_err(&client->dev, "failed: power supply register\n"); + kfree(chip); + return ret; + } + + /* Initialize registers according to values from the platform data */ if (chip->pdata->init_data) max17042_set_reg(client, chip->pdata->init_data, - chip->pdata->num_init_data); + chip->pdata->num_init_data); if (!chip->pdata->enable_current_sense) { max17042_write_reg(client, MAX17042_CGAIN, 0x0000); @@ -683,34 +261,7 @@ static int __devinit max17042_probe(struct i2c_client *client, max17042_write_reg(client, MAX17042_LearnCFG, 0x0007); } - if (client->irq) { - ret = request_threaded_irq(client->irq, NULL, - max17042_thread_handler, - IRQF_TRIGGER_FALLING, - chip->battery.name, chip); - if (!ret) { - reg = max17042_read_reg(client, MAX17042_CONFIG); - reg |= CONFIG_ALRT_BIT_ENBL; - max17042_write_reg(client, MAX17042_CONFIG, reg); - max17042_set_soc_threshold(chip, 1); - } else - dev_err(&client->dev, "%s(): cannot get IRQ\n", - __func__); - } - - reg = max17042_read_reg(chip->client, MAX17042_STATUS); - - if (reg & STATUS_POR_BIT) { - INIT_WORK(&chip->work, max17042_init_worker); - schedule_work(&chip->work); - } else { - chip->init_complete = 1; - } - - ret = power_supply_register(&client->dev, &chip->battery); - if (ret) - dev_err(&client->dev, "failed: power supply register\n"); - return ret; + return 0; } static int __devexit max17042_remove(struct i2c_client *client) @@ -718,17 +269,10 @@ static int __devexit max17042_remove(struct i2c_client *client) struct max17042_chip *chip = i2c_get_clientdata(client); power_supply_unregister(&chip->battery); + kfree(chip); return 0; } -#ifdef CONFIG_OF -static const struct of_device_id max17042_dt_match[] = { - { .compatible = "maxim,max17042" }, - { }, -}; -MODULE_DEVICE_TABLE(of, max17042_dt_match); -#endif - static const struct i2c_device_id max17042_id[] = { { "max17042", 0 }, { } @@ -738,13 +282,23 @@ MODULE_DEVICE_TABLE(i2c, max17042_id); static struct i2c_driver max17042_i2c_driver = { .driver = { .name = "max17042", - .of_match_table = of_match_ptr(max17042_dt_match), }, .probe = max17042_probe, .remove = __devexit_p(max17042_remove), .id_table = max17042_id, }; -module_i2c_driver(max17042_i2c_driver); + +static int __init max17042_init(void) +{ + return i2c_add_driver(&max17042_i2c_driver); +} +module_init(max17042_init); + +static void __exit max17042_exit(void) +{ + i2c_del_driver(&max17042_i2c_driver); +} +module_exit(max17042_exit); MODULE_AUTHOR("MyungJoo Ham "); MODULE_DESCRIPTION("MAX17042 Fuel Gauge"); diff --git a/trunk/drivers/power/sbs-battery.c b/trunk/drivers/power/sbs-battery.c index 06b659d91790..9ff8af069da6 100644 --- a/trunk/drivers/power/sbs-battery.c +++ b/trunk/drivers/power/sbs-battery.c @@ -852,7 +852,18 @@ static struct i2c_driver sbs_battery_driver = { .of_match_table = sbs_dt_ids, }, }; -module_i2c_driver(sbs_battery_driver); + +static int __init sbs_battery_init(void) +{ + return i2c_add_driver(&sbs_battery_driver); +} +module_init(sbs_battery_init); + +static void __exit sbs_battery_exit(void) +{ + i2c_del_driver(&sbs_battery_driver); +} +module_exit(sbs_battery_exit); MODULE_DESCRIPTION("SBS battery monitor driver"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/power/smb347-charger.c b/trunk/drivers/power/smb347-charger.c deleted file mode 100644 index ce1694d1a365..000000000000 --- a/trunk/drivers/power/smb347-charger.c +++ /dev/null @@ -1,1294 +0,0 @@ -/* - * Summit Microelectronics SMB347 Battery Charger Driver - * - * Copyright (C) 2011, Intel Corporation - * - * Authors: Bruce E. Robertson - * Mika Westerberg - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Configuration registers. These are mirrored to volatile RAM and can be - * written once %CMD_A_ALLOW_WRITE is set in %CMD_A register. They will be - * reloaded from non-volatile registers after POR. - */ -#define CFG_CHARGE_CURRENT 0x00 -#define CFG_CHARGE_CURRENT_FCC_MASK 0xe0 -#define CFG_CHARGE_CURRENT_FCC_SHIFT 5 -#define CFG_CHARGE_CURRENT_PCC_MASK 0x18 -#define CFG_CHARGE_CURRENT_PCC_SHIFT 3 -#define CFG_CHARGE_CURRENT_TC_MASK 0x07 -#define CFG_CURRENT_LIMIT 0x01 -#define CFG_CURRENT_LIMIT_DC_MASK 0xf0 -#define CFG_CURRENT_LIMIT_DC_SHIFT 4 -#define CFG_CURRENT_LIMIT_USB_MASK 0x0f -#define CFG_FLOAT_VOLTAGE 0x03 -#define CFG_FLOAT_VOLTAGE_THRESHOLD_MASK 0xc0 -#define CFG_FLOAT_VOLTAGE_THRESHOLD_SHIFT 6 -#define CFG_STAT 0x05 -#define CFG_STAT_DISABLED BIT(5) -#define CFG_STAT_ACTIVE_HIGH BIT(7) -#define CFG_PIN 0x06 -#define CFG_PIN_EN_CTRL_MASK 0x60 -#define CFG_PIN_EN_CTRL_ACTIVE_HIGH 0x40 -#define CFG_PIN_EN_CTRL_ACTIVE_LOW 0x60 -#define CFG_PIN_EN_APSD_IRQ BIT(1) -#define CFG_PIN_EN_CHARGER_ERROR BIT(2) -#define CFG_THERM 0x07 -#define CFG_THERM_SOFT_HOT_COMPENSATION_MASK 0x03 -#define CFG_THERM_SOFT_HOT_COMPENSATION_SHIFT 0 -#define CFG_THERM_SOFT_COLD_COMPENSATION_MASK 0x0c -#define CFG_THERM_SOFT_COLD_COMPENSATION_SHIFT 2 -#define CFG_THERM_MONITOR_DISABLED BIT(4) -#define CFG_SYSOK 0x08 -#define CFG_SYSOK_SUSPEND_HARD_LIMIT_DISABLED BIT(2) -#define CFG_OTHER 0x09 -#define CFG_OTHER_RID_MASK 0xc0 -#define CFG_OTHER_RID_ENABLED_AUTO_OTG 0xc0 -#define CFG_OTG 0x0a -#define CFG_OTG_TEMP_THRESHOLD_MASK 0x30 -#define CFG_OTG_TEMP_THRESHOLD_SHIFT 4 -#define CFG_OTG_CC_COMPENSATION_MASK 0xc0 -#define CFG_OTG_CC_COMPENSATION_SHIFT 6 -#define CFG_TEMP_LIMIT 0x0b -#define CFG_TEMP_LIMIT_SOFT_HOT_MASK 0x03 -#define CFG_TEMP_LIMIT_SOFT_HOT_SHIFT 0 -#define CFG_TEMP_LIMIT_SOFT_COLD_MASK 0x0c -#define CFG_TEMP_LIMIT_SOFT_COLD_SHIFT 2 -#define CFG_TEMP_LIMIT_HARD_HOT_MASK 0x30 -#define CFG_TEMP_LIMIT_HARD_HOT_SHIFT 4 -#define CFG_TEMP_LIMIT_HARD_COLD_MASK 0xc0 -#define CFG_TEMP_LIMIT_HARD_COLD_SHIFT 6 -#define CFG_FAULT_IRQ 0x0c -#define CFG_FAULT_IRQ_DCIN_UV BIT(2) -#define CFG_STATUS_IRQ 0x0d -#define CFG_STATUS_IRQ_TERMINATION_OR_TAPER BIT(4) -#define CFG_ADDRESS 0x0e - -/* Command registers */ -#define CMD_A 0x30 -#define CMD_A_CHG_ENABLED BIT(1) -#define CMD_A_SUSPEND_ENABLED BIT(2) -#define CMD_A_ALLOW_WRITE BIT(7) -#define CMD_B 0x31 -#define CMD_C 0x33 - -/* Interrupt Status registers */ -#define IRQSTAT_A 0x35 -#define IRQSTAT_C 0x37 -#define IRQSTAT_C_TERMINATION_STAT BIT(0) -#define IRQSTAT_C_TERMINATION_IRQ BIT(1) -#define IRQSTAT_C_TAPER_IRQ BIT(3) -#define IRQSTAT_E 0x39 -#define IRQSTAT_E_USBIN_UV_STAT BIT(0) -#define IRQSTAT_E_USBIN_UV_IRQ BIT(1) -#define IRQSTAT_E_DCIN_UV_STAT BIT(4) -#define IRQSTAT_E_DCIN_UV_IRQ BIT(5) -#define IRQSTAT_F 0x3a - -/* Status registers */ -#define STAT_A 0x3b -#define STAT_A_FLOAT_VOLTAGE_MASK 0x3f -#define STAT_B 0x3c -#define STAT_C 0x3d -#define STAT_C_CHG_ENABLED BIT(0) -#define STAT_C_CHG_MASK 0x06 -#define STAT_C_CHG_SHIFT 1 -#define STAT_C_CHARGER_ERROR BIT(6) -#define STAT_E 0x3f - -/** - * struct smb347_charger - smb347 charger instance - * @lock: protects concurrent access to online variables - * @client: pointer to i2c client - * @mains: power_supply instance for AC/DC power - * @usb: power_supply instance for USB power - * @battery: power_supply instance for battery - * @mains_online: is AC/DC input connected - * @usb_online: is USB input connected - * @charging_enabled: is charging enabled - * @dentry: for debugfs - * @pdata: pointer to platform data - */ -struct smb347_charger { - struct mutex lock; - struct i2c_client *client; - struct power_supply mains; - struct power_supply usb; - struct power_supply battery; - bool mains_online; - bool usb_online; - bool charging_enabled; - struct dentry *dentry; - const struct smb347_charger_platform_data *pdata; -}; - -/* Fast charge current in uA */ -static const unsigned int fcc_tbl[] = { - 700000, - 900000, - 1200000, - 1500000, - 1800000, - 2000000, - 2200000, - 2500000, -}; - -/* Pre-charge current in uA */ -static const unsigned int pcc_tbl[] = { - 100000, - 150000, - 200000, - 250000, -}; - -/* Termination current in uA */ -static const unsigned int tc_tbl[] = { - 37500, - 50000, - 100000, - 150000, - 200000, - 250000, - 500000, - 600000, -}; - -/* Input current limit in uA */ -static const unsigned int icl_tbl[] = { - 300000, - 500000, - 700000, - 900000, - 1200000, - 1500000, - 1800000, - 2000000, - 2200000, - 2500000, -}; - -/* Charge current compensation in uA */ -static const unsigned int ccc_tbl[] = { - 250000, - 700000, - 900000, - 1200000, -}; - -/* Convert register value to current using lookup table */ -static int hw_to_current(const unsigned int *tbl, size_t size, unsigned int val) -{ - if (val >= size) - return -EINVAL; - return tbl[val]; -} - -/* Convert current to register value using lookup table */ -static int current_to_hw(const unsigned int *tbl, size_t size, unsigned int val) -{ - size_t i; - - for (i = 0; i < size; i++) - if (val < tbl[i]) - break; - return i > 0 ? i - 1 : -EINVAL; -} - -static int smb347_read(struct smb347_charger *smb, u8 reg) -{ - int ret; - - ret = i2c_smbus_read_byte_data(smb->client, reg); - if (ret < 0) - dev_warn(&smb->client->dev, "failed to read reg 0x%x: %d\n", - reg, ret); - return ret; -} - -static int smb347_write(struct smb347_charger *smb, u8 reg, u8 val) -{ - int ret; - - ret = i2c_smbus_write_byte_data(smb->client, reg, val); - if (ret < 0) - dev_warn(&smb->client->dev, "failed to write reg 0x%x: %d\n", - reg, ret); - return ret; -} - -/** - * smb347_update_status - updates the charging status - * @smb: pointer to smb347 charger instance - * - * Function checks status of the charging and updates internal state - * accordingly. Returns %0 if there is no change in status, %1 if the - * status has changed and negative errno in case of failure. - */ -static int smb347_update_status(struct smb347_charger *smb) -{ - bool usb = false; - bool dc = false; - int ret; - - ret = smb347_read(smb, IRQSTAT_E); - if (ret < 0) - return ret; - - /* - * Dc and usb are set depending on whether they are enabled in - * platform data _and_ whether corresponding undervoltage is set. - */ - if (smb->pdata->use_mains) - dc = !(ret & IRQSTAT_E_DCIN_UV_STAT); - if (smb->pdata->use_usb) - usb = !(ret & IRQSTAT_E_USBIN_UV_STAT); - - mutex_lock(&smb->lock); - ret = smb->mains_online != dc || smb->usb_online != usb; - smb->mains_online = dc; - smb->usb_online = usb; - mutex_unlock(&smb->lock); - - return ret; -} - -/* - * smb347_is_online - returns whether input power source is connected - * @smb: pointer to smb347 charger instance - * - * Returns %true if input power source is connected. Note that this is - * dependent on what platform has configured for usable power sources. For - * example if USB is disabled, this will return %false even if the USB - * cable is connected. - */ -static bool smb347_is_online(struct smb347_charger *smb) -{ - bool ret; - - mutex_lock(&smb->lock); - ret = smb->usb_online || smb->mains_online; - mutex_unlock(&smb->lock); - - return ret; -} - -/** - * smb347_charging_status - returns status of charging - * @smb: pointer to smb347 charger instance - * - * Function returns charging status. %0 means no charging is in progress, - * %1 means pre-charging, %2 fast-charging and %3 taper-charging. - */ -static int smb347_charging_status(struct smb347_charger *smb) -{ - int ret; - - if (!smb347_is_online(smb)) - return 0; - - ret = smb347_read(smb, STAT_C); - if (ret < 0) - return 0; - - return (ret & STAT_C_CHG_MASK) >> STAT_C_CHG_SHIFT; -} - -static int smb347_charging_set(struct smb347_charger *smb, bool enable) -{ - int ret = 0; - - if (smb->pdata->enable_control != SMB347_CHG_ENABLE_SW) { - dev_dbg(&smb->client->dev, - "charging enable/disable in SW disabled\n"); - return 0; - } - - mutex_lock(&smb->lock); - if (smb->charging_enabled != enable) { - ret = smb347_read(smb, CMD_A); - if (ret < 0) - goto out; - - smb->charging_enabled = enable; - - if (enable) - ret |= CMD_A_CHG_ENABLED; - else - ret &= ~CMD_A_CHG_ENABLED; - - ret = smb347_write(smb, CMD_A, ret); - } -out: - mutex_unlock(&smb->lock); - return ret; -} - -static inline int smb347_charging_enable(struct smb347_charger *smb) -{ - return smb347_charging_set(smb, true); -} - -static inline int smb347_charging_disable(struct smb347_charger *smb) -{ - return smb347_charging_set(smb, false); -} - -static int smb347_update_online(struct smb347_charger *smb) -{ - int ret; - - /* - * Depending on whether valid power source is connected or not, we - * disable or enable the charging. We do it manually because it - * depends on how the platform has configured the valid inputs. - */ - if (smb347_is_online(smb)) { - ret = smb347_charging_enable(smb); - if (ret < 0) - dev_err(&smb->client->dev, - "failed to enable charging\n"); - } else { - ret = smb347_charging_disable(smb); - if (ret < 0) - dev_err(&smb->client->dev, - "failed to disable charging\n"); - } - - return ret; -} - -static int smb347_set_charge_current(struct smb347_charger *smb) -{ - int ret, val; - - ret = smb347_read(smb, CFG_CHARGE_CURRENT); - if (ret < 0) - return ret; - - if (smb->pdata->max_charge_current) { - val = current_to_hw(fcc_tbl, ARRAY_SIZE(fcc_tbl), - smb->pdata->max_charge_current); - if (val < 0) - return val; - - ret &= ~CFG_CHARGE_CURRENT_FCC_MASK; - ret |= val << CFG_CHARGE_CURRENT_FCC_SHIFT; - } - - if (smb->pdata->pre_charge_current) { - val = current_to_hw(pcc_tbl, ARRAY_SIZE(pcc_tbl), - smb->pdata->pre_charge_current); - if (val < 0) - return val; - - ret &= ~CFG_CHARGE_CURRENT_PCC_MASK; - ret |= val << CFG_CHARGE_CURRENT_PCC_SHIFT; - } - - if (smb->pdata->termination_current) { - val = current_to_hw(tc_tbl, ARRAY_SIZE(tc_tbl), - smb->pdata->termination_current); - if (val < 0) - return val; - - ret &= ~CFG_CHARGE_CURRENT_TC_MASK; - ret |= val; - } - - return smb347_write(smb, CFG_CHARGE_CURRENT, ret); -} - -static int smb347_set_current_limits(struct smb347_charger *smb) -{ - int ret, val; - - ret = smb347_read(smb, CFG_CURRENT_LIMIT); - if (ret < 0) - return ret; - - if (smb->pdata->mains_current_limit) { - val = current_to_hw(icl_tbl, ARRAY_SIZE(icl_tbl), - smb->pdata->mains_current_limit); - if (val < 0) - return val; - - ret &= ~CFG_CURRENT_LIMIT_DC_MASK; - ret |= val << CFG_CURRENT_LIMIT_DC_SHIFT; - } - - if (smb->pdata->usb_hc_current_limit) { - val = current_to_hw(icl_tbl, ARRAY_SIZE(icl_tbl), - smb->pdata->usb_hc_current_limit); - if (val < 0) - return val; - - ret &= ~CFG_CURRENT_LIMIT_USB_MASK; - ret |= val; - } - - return smb347_write(smb, CFG_CURRENT_LIMIT, ret); -} - -static int smb347_set_voltage_limits(struct smb347_charger *smb) -{ - int ret, val; - - ret = smb347_read(smb, CFG_FLOAT_VOLTAGE); - if (ret < 0) - return ret; - - if (smb->pdata->pre_to_fast_voltage) { - val = smb->pdata->pre_to_fast_voltage; - - /* uV */ - val = clamp_val(val, 2400000, 3000000) - 2400000; - val /= 200000; - - ret &= ~CFG_FLOAT_VOLTAGE_THRESHOLD_MASK; - ret |= val << CFG_FLOAT_VOLTAGE_THRESHOLD_SHIFT; - } - - if (smb->pdata->max_charge_voltage) { - val = smb->pdata->max_charge_voltage; - - /* uV */ - val = clamp_val(val, 3500000, 4500000) - 3500000; - val /= 20000; - - ret |= val; - } - - return smb347_write(smb, CFG_FLOAT_VOLTAGE, ret); -} - -static int smb347_set_temp_limits(struct smb347_charger *smb) -{ - bool enable_therm_monitor = false; - int ret, val; - - if (smb->pdata->chip_temp_threshold) { - val = smb->pdata->chip_temp_threshold; - - /* degree C */ - val = clamp_val(val, 100, 130) - 100; - val /= 10; - - ret = smb347_read(smb, CFG_OTG); - if (ret < 0) - return ret; - - ret &= ~CFG_OTG_TEMP_THRESHOLD_MASK; - ret |= val << CFG_OTG_TEMP_THRESHOLD_SHIFT; - - ret = smb347_write(smb, CFG_OTG, ret); - if (ret < 0) - return ret; - } - - ret = smb347_read(smb, CFG_TEMP_LIMIT); - if (ret < 0) - return ret; - - if (smb->pdata->soft_cold_temp_limit != SMB347_TEMP_USE_DEFAULT) { - val = smb->pdata->soft_cold_temp_limit; - - val = clamp_val(val, 0, 15); - val /= 5; - /* this goes from higher to lower so invert the value */ - val = ~val & 0x3; - - ret &= ~CFG_TEMP_LIMIT_SOFT_COLD_MASK; - ret |= val << CFG_TEMP_LIMIT_SOFT_COLD_SHIFT; - - enable_therm_monitor = true; - } - - if (smb->pdata->soft_hot_temp_limit != SMB347_TEMP_USE_DEFAULT) { - val = smb->pdata->soft_hot_temp_limit; - - val = clamp_val(val, 40, 55) - 40; - val /= 5; - - ret &= ~CFG_TEMP_LIMIT_SOFT_HOT_MASK; - ret |= val << CFG_TEMP_LIMIT_SOFT_HOT_SHIFT; - - enable_therm_monitor = true; - } - - if (smb->pdata->hard_cold_temp_limit != SMB347_TEMP_USE_DEFAULT) { - val = smb->pdata->hard_cold_temp_limit; - - val = clamp_val(val, -5, 10) + 5; - val /= 5; - /* this goes from higher to lower so invert the value */ - val = ~val & 0x3; - - ret &= ~CFG_TEMP_LIMIT_HARD_COLD_MASK; - ret |= val << CFG_TEMP_LIMIT_HARD_COLD_SHIFT; - - enable_therm_monitor = true; - } - - if (smb->pdata->hard_hot_temp_limit != SMB347_TEMP_USE_DEFAULT) { - val = smb->pdata->hard_hot_temp_limit; - - val = clamp_val(val, 50, 65) - 50; - val /= 5; - - ret &= ~CFG_TEMP_LIMIT_HARD_HOT_MASK; - ret |= val << CFG_TEMP_LIMIT_HARD_HOT_SHIFT; - - enable_therm_monitor = true; - } - - ret = smb347_write(smb, CFG_TEMP_LIMIT, ret); - if (ret < 0) - return ret; - - /* - * If any of the temperature limits are set, we also enable the - * thermistor monitoring. - * - * When soft limits are hit, the device will start to compensate - * current and/or voltage depending on the configuration. - * - * When hard limit is hit, the device will suspend charging - * depending on the configuration. - */ - if (enable_therm_monitor) { - ret = smb347_read(smb, CFG_THERM); - if (ret < 0) - return ret; - - ret &= ~CFG_THERM_MONITOR_DISABLED; - - ret = smb347_write(smb, CFG_THERM, ret); - if (ret < 0) - return ret; - } - - if (smb->pdata->suspend_on_hard_temp_limit) { - ret = smb347_read(smb, CFG_SYSOK); - if (ret < 0) - return ret; - - ret &= ~CFG_SYSOK_SUSPEND_HARD_LIMIT_DISABLED; - - ret = smb347_write(smb, CFG_SYSOK, ret); - if (ret < 0) - return ret; - } - - if (smb->pdata->soft_temp_limit_compensation != - SMB347_SOFT_TEMP_COMPENSATE_DEFAULT) { - val = smb->pdata->soft_temp_limit_compensation & 0x3; - - ret = smb347_read(smb, CFG_THERM); - if (ret < 0) - return ret; - - ret &= ~CFG_THERM_SOFT_HOT_COMPENSATION_MASK; - ret |= val << CFG_THERM_SOFT_HOT_COMPENSATION_SHIFT; - - ret &= ~CFG_THERM_SOFT_COLD_COMPENSATION_MASK; - ret |= val << CFG_THERM_SOFT_COLD_COMPENSATION_SHIFT; - - ret = smb347_write(smb, CFG_THERM, ret); - if (ret < 0) - return ret; - } - - if (smb->pdata->charge_current_compensation) { - val = current_to_hw(ccc_tbl, ARRAY_SIZE(ccc_tbl), - smb->pdata->charge_current_compensation); - if (val < 0) - return val; - - ret = smb347_read(smb, CFG_OTG); - if (ret < 0) - return ret; - - ret &= ~CFG_OTG_CC_COMPENSATION_MASK; - ret |= (val & 0x3) << CFG_OTG_CC_COMPENSATION_SHIFT; - - ret = smb347_write(smb, CFG_OTG, ret); - if (ret < 0) - return ret; - } - - return ret; -} - -/* - * smb347_set_writable - enables/disables writing to non-volatile registers - * @smb: pointer to smb347 charger instance - * - * You can enable/disable writing to the non-volatile configuration - * registers by calling this function. - * - * Returns %0 on success and negative errno in case of failure. - */ -static int smb347_set_writable(struct smb347_charger *smb, bool writable) -{ - int ret; - - ret = smb347_read(smb, CMD_A); - if (ret < 0) - return ret; - - if (writable) - ret |= CMD_A_ALLOW_WRITE; - else - ret &= ~CMD_A_ALLOW_WRITE; - - return smb347_write(smb, CMD_A, ret); -} - -static int smb347_hw_init(struct smb347_charger *smb) -{ - int ret; - - ret = smb347_set_writable(smb, true); - if (ret < 0) - return ret; - - /* - * Program the platform specific configuration values to the device - * first. - */ - ret = smb347_set_charge_current(smb); - if (ret < 0) - goto fail; - - ret = smb347_set_current_limits(smb); - if (ret < 0) - goto fail; - - ret = smb347_set_voltage_limits(smb); - if (ret < 0) - goto fail; - - ret = smb347_set_temp_limits(smb); - if (ret < 0) - goto fail; - - /* If USB charging is disabled we put the USB in suspend mode */ - if (!smb->pdata->use_usb) { - ret = smb347_read(smb, CMD_A); - if (ret < 0) - goto fail; - - ret |= CMD_A_SUSPEND_ENABLED; - - ret = smb347_write(smb, CMD_A, ret); - if (ret < 0) - goto fail; - } - - ret = smb347_read(smb, CFG_OTHER); - if (ret < 0) - goto fail; - - /* - * If configured by platform data, we enable hardware Auto-OTG - * support for driving VBUS. Otherwise we disable it. - */ - ret &= ~CFG_OTHER_RID_MASK; - if (smb->pdata->use_usb_otg) - ret |= CFG_OTHER_RID_ENABLED_AUTO_OTG; - - ret = smb347_write(smb, CFG_OTHER, ret); - if (ret < 0) - goto fail; - - ret = smb347_read(smb, CFG_PIN); - if (ret < 0) - goto fail; - - /* - * Make the charging functionality controllable by a write to the - * command register unless pin control is specified in the platform - * data. - */ - ret &= ~CFG_PIN_EN_CTRL_MASK; - - switch (smb->pdata->enable_control) { - case SMB347_CHG_ENABLE_SW: - /* Do nothing, 0 means i2c control */ - break; - case SMB347_CHG_ENABLE_PIN_ACTIVE_LOW: - ret |= CFG_PIN_EN_CTRL_ACTIVE_LOW; - break; - case SMB347_CHG_ENABLE_PIN_ACTIVE_HIGH: - ret |= CFG_PIN_EN_CTRL_ACTIVE_HIGH; - break; - } - - /* Disable Automatic Power Source Detection (APSD) interrupt. */ - ret &= ~CFG_PIN_EN_APSD_IRQ; - - ret = smb347_write(smb, CFG_PIN, ret); - if (ret < 0) - goto fail; - - ret = smb347_update_status(smb); - if (ret < 0) - goto fail; - - ret = smb347_update_online(smb); - -fail: - smb347_set_writable(smb, false); - return ret; -} - -static irqreturn_t smb347_interrupt(int irq, void *data) -{ - struct smb347_charger *smb = data; - int stat_c, irqstat_e, irqstat_c; - irqreturn_t ret = IRQ_NONE; - - stat_c = smb347_read(smb, STAT_C); - if (stat_c < 0) { - dev_warn(&smb->client->dev, "reading STAT_C failed\n"); - return IRQ_NONE; - } - - irqstat_c = smb347_read(smb, IRQSTAT_C); - if (irqstat_c < 0) { - dev_warn(&smb->client->dev, "reading IRQSTAT_C failed\n"); - return IRQ_NONE; - } - - irqstat_e = smb347_read(smb, IRQSTAT_E); - if (irqstat_e < 0) { - dev_warn(&smb->client->dev, "reading IRQSTAT_E failed\n"); - return IRQ_NONE; - } - - /* - * If we get charger error we report the error back to user and - * disable charging. - */ - if (stat_c & STAT_C_CHARGER_ERROR) { - dev_err(&smb->client->dev, - "error in charger, disabling charging\n"); - - smb347_charging_disable(smb); - power_supply_changed(&smb->battery); - - ret = IRQ_HANDLED; - } - - /* - * If we reached the termination current the battery is charged and - * we can update the status now. Charging is automatically - * disabled by the hardware. - */ - if (irqstat_c & (IRQSTAT_C_TERMINATION_IRQ | IRQSTAT_C_TAPER_IRQ)) { - if (irqstat_c & IRQSTAT_C_TERMINATION_STAT) - power_supply_changed(&smb->battery); - ret = IRQ_HANDLED; - } - - /* - * If we got an under voltage interrupt it means that AC/USB input - * was connected or disconnected. - */ - if (irqstat_e & (IRQSTAT_E_USBIN_UV_IRQ | IRQSTAT_E_DCIN_UV_IRQ)) { - if (smb347_update_status(smb) > 0) { - smb347_update_online(smb); - power_supply_changed(&smb->mains); - power_supply_changed(&smb->usb); - } - ret = IRQ_HANDLED; - } - - return ret; -} - -static int smb347_irq_set(struct smb347_charger *smb, bool enable) -{ - int ret; - - ret = smb347_set_writable(smb, true); - if (ret < 0) - return ret; - - /* - * Enable/disable interrupts for: - * - under voltage - * - termination current reached - * - charger error - */ - if (enable) { - ret = smb347_write(smb, CFG_FAULT_IRQ, CFG_FAULT_IRQ_DCIN_UV); - if (ret < 0) - goto fail; - - ret = smb347_write(smb, CFG_STATUS_IRQ, - CFG_STATUS_IRQ_TERMINATION_OR_TAPER); - if (ret < 0) - goto fail; - - ret = smb347_read(smb, CFG_PIN); - if (ret < 0) - goto fail; - - ret |= CFG_PIN_EN_CHARGER_ERROR; - - ret = smb347_write(smb, CFG_PIN, ret); - } else { - ret = smb347_write(smb, CFG_FAULT_IRQ, 0); - if (ret < 0) - goto fail; - - ret = smb347_write(smb, CFG_STATUS_IRQ, 0); - if (ret < 0) - goto fail; - - ret = smb347_read(smb, CFG_PIN); - if (ret < 0) - goto fail; - - ret &= ~CFG_PIN_EN_CHARGER_ERROR; - - ret = smb347_write(smb, CFG_PIN, ret); - } - -fail: - smb347_set_writable(smb, false); - return ret; -} - -static inline int smb347_irq_enable(struct smb347_charger *smb) -{ - return smb347_irq_set(smb, true); -} - -static inline int smb347_irq_disable(struct smb347_charger *smb) -{ - return smb347_irq_set(smb, false); -} - -static int smb347_irq_init(struct smb347_charger *smb) -{ - const struct smb347_charger_platform_data *pdata = smb->pdata; - int ret, irq = gpio_to_irq(pdata->irq_gpio); - - ret = gpio_request_one(pdata->irq_gpio, GPIOF_IN, smb->client->name); - if (ret < 0) - goto fail; - - ret = request_threaded_irq(irq, NULL, smb347_interrupt, - IRQF_TRIGGER_FALLING, smb->client->name, - smb); - if (ret < 0) - goto fail_gpio; - - ret = smb347_set_writable(smb, true); - if (ret < 0) - goto fail_irq; - - /* - * Configure the STAT output to be suitable for interrupts: disable - * all other output (except interrupts) and make it active low. - */ - ret = smb347_read(smb, CFG_STAT); - if (ret < 0) - goto fail_readonly; - - ret &= ~CFG_STAT_ACTIVE_HIGH; - ret |= CFG_STAT_DISABLED; - - ret = smb347_write(smb, CFG_STAT, ret); - if (ret < 0) - goto fail_readonly; - - ret = smb347_irq_enable(smb); - if (ret < 0) - goto fail_readonly; - - smb347_set_writable(smb, false); - smb->client->irq = irq; - return 0; - -fail_readonly: - smb347_set_writable(smb, false); -fail_irq: - free_irq(irq, smb); -fail_gpio: - gpio_free(pdata->irq_gpio); -fail: - smb->client->irq = 0; - return ret; -} - -static int smb347_mains_get_property(struct power_supply *psy, - enum power_supply_property prop, - union power_supply_propval *val) -{ - struct smb347_charger *smb = - container_of(psy, struct smb347_charger, mains); - - if (prop == POWER_SUPPLY_PROP_ONLINE) { - val->intval = smb->mains_online; - return 0; - } - return -EINVAL; -} - -static enum power_supply_property smb347_mains_properties[] = { - POWER_SUPPLY_PROP_ONLINE, -}; - -static int smb347_usb_get_property(struct power_supply *psy, - enum power_supply_property prop, - union power_supply_propval *val) -{ - struct smb347_charger *smb = - container_of(psy, struct smb347_charger, usb); - - if (prop == POWER_SUPPLY_PROP_ONLINE) { - val->intval = smb->usb_online; - return 0; - } - return -EINVAL; -} - -static enum power_supply_property smb347_usb_properties[] = { - POWER_SUPPLY_PROP_ONLINE, -}; - -static int smb347_battery_get_property(struct power_supply *psy, - enum power_supply_property prop, - union power_supply_propval *val) -{ - struct smb347_charger *smb = - container_of(psy, struct smb347_charger, battery); - const struct smb347_charger_platform_data *pdata = smb->pdata; - int ret; - - ret = smb347_update_status(smb); - if (ret < 0) - return ret; - - switch (prop) { - case POWER_SUPPLY_PROP_STATUS: - if (!smb347_is_online(smb)) { - val->intval = POWER_SUPPLY_STATUS_DISCHARGING; - break; - } - if (smb347_charging_status(smb)) - val->intval = POWER_SUPPLY_STATUS_CHARGING; - else - val->intval = POWER_SUPPLY_STATUS_FULL; - break; - - case POWER_SUPPLY_PROP_CHARGE_TYPE: - if (!smb347_is_online(smb)) - return -ENODATA; - - /* - * We handle trickle and pre-charging the same, and taper - * and none the same. - */ - switch (smb347_charging_status(smb)) { - case 1: - val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; - break; - case 2: - val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; - break; - default: - val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; - break; - } - break; - - case POWER_SUPPLY_PROP_TECHNOLOGY: - val->intval = pdata->battery_info.technology; - break; - - case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: - val->intval = pdata->battery_info.voltage_min_design; - break; - - case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: - val->intval = pdata->battery_info.voltage_max_design; - break; - - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - if (!smb347_is_online(smb)) - return -ENODATA; - ret = smb347_read(smb, STAT_A); - if (ret < 0) - return ret; - - ret &= STAT_A_FLOAT_VOLTAGE_MASK; - if (ret > 0x3d) - ret = 0x3d; - - val->intval = 3500000 + ret * 20000; - break; - - case POWER_SUPPLY_PROP_CURRENT_NOW: - if (!smb347_is_online(smb)) - return -ENODATA; - - ret = smb347_read(smb, STAT_B); - if (ret < 0) - return ret; - - /* - * The current value is composition of FCC and PCC values - * and we can detect which table to use from bit 5. - */ - if (ret & 0x20) { - val->intval = hw_to_current(fcc_tbl, - ARRAY_SIZE(fcc_tbl), - ret & 7); - } else { - ret >>= 3; - val->intval = hw_to_current(pcc_tbl, - ARRAY_SIZE(pcc_tbl), - ret & 7); - } - break; - - case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: - val->intval = pdata->battery_info.charge_full_design; - break; - - case POWER_SUPPLY_PROP_MODEL_NAME: - val->strval = pdata->battery_info.name; - break; - - default: - return -EINVAL; - } - - return 0; -} - -static enum power_supply_property smb347_battery_properties[] = { - POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_CHARGE_TYPE, - POWER_SUPPLY_PROP_TECHNOLOGY, - POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, - POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_CURRENT_NOW, - POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, - POWER_SUPPLY_PROP_MODEL_NAME, -}; - -static int smb347_debugfs_show(struct seq_file *s, void *data) -{ - struct smb347_charger *smb = s->private; - int ret; - u8 reg; - - seq_printf(s, "Control registers:\n"); - seq_printf(s, "==================\n"); - for (reg = CFG_CHARGE_CURRENT; reg <= CFG_ADDRESS; reg++) { - ret = smb347_read(smb, reg); - seq_printf(s, "0x%02x:\t0x%02x\n", reg, ret); - } - seq_printf(s, "\n"); - - seq_printf(s, "Command registers:\n"); - seq_printf(s, "==================\n"); - ret = smb347_read(smb, CMD_A); - seq_printf(s, "0x%02x:\t0x%02x\n", CMD_A, ret); - ret = smb347_read(smb, CMD_B); - seq_printf(s, "0x%02x:\t0x%02x\n", CMD_B, ret); - ret = smb347_read(smb, CMD_C); - seq_printf(s, "0x%02x:\t0x%02x\n", CMD_C, ret); - seq_printf(s, "\n"); - - seq_printf(s, "Interrupt status registers:\n"); - seq_printf(s, "===========================\n"); - for (reg = IRQSTAT_A; reg <= IRQSTAT_F; reg++) { - ret = smb347_read(smb, reg); - seq_printf(s, "0x%02x:\t0x%02x\n", reg, ret); - } - seq_printf(s, "\n"); - - seq_printf(s, "Status registers:\n"); - seq_printf(s, "=================\n"); - for (reg = STAT_A; reg <= STAT_E; reg++) { - ret = smb347_read(smb, reg); - seq_printf(s, "0x%02x:\t0x%02x\n", reg, ret); - } - - return 0; -} - -static int smb347_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, smb347_debugfs_show, inode->i_private); -} - -static const struct file_operations smb347_debugfs_fops = { - .open = smb347_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int smb347_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - static char *battery[] = { "smb347-battery" }; - const struct smb347_charger_platform_data *pdata; - struct device *dev = &client->dev; - struct smb347_charger *smb; - int ret; - - pdata = dev->platform_data; - if (!pdata) - return -EINVAL; - - if (!pdata->use_mains && !pdata->use_usb) - return -EINVAL; - - smb = devm_kzalloc(dev, sizeof(*smb), GFP_KERNEL); - if (!smb) - return -ENOMEM; - - i2c_set_clientdata(client, smb); - - mutex_init(&smb->lock); - smb->client = client; - smb->pdata = pdata; - - ret = smb347_hw_init(smb); - if (ret < 0) - return ret; - - smb->mains.name = "smb347-mains"; - smb->mains.type = POWER_SUPPLY_TYPE_MAINS; - smb->mains.get_property = smb347_mains_get_property; - smb->mains.properties = smb347_mains_properties; - smb->mains.num_properties = ARRAY_SIZE(smb347_mains_properties); - smb->mains.supplied_to = battery; - smb->mains.num_supplicants = ARRAY_SIZE(battery); - - smb->usb.name = "smb347-usb"; - smb->usb.type = POWER_SUPPLY_TYPE_USB; - smb->usb.get_property = smb347_usb_get_property; - smb->usb.properties = smb347_usb_properties; - smb->usb.num_properties = ARRAY_SIZE(smb347_usb_properties); - smb->usb.supplied_to = battery; - smb->usb.num_supplicants = ARRAY_SIZE(battery); - - smb->battery.name = "smb347-battery"; - smb->battery.type = POWER_SUPPLY_TYPE_BATTERY; - smb->battery.get_property = smb347_battery_get_property; - smb->battery.properties = smb347_battery_properties; - smb->battery.num_properties = ARRAY_SIZE(smb347_battery_properties); - - ret = power_supply_register(dev, &smb->mains); - if (ret < 0) - return ret; - - ret = power_supply_register(dev, &smb->usb); - if (ret < 0) { - power_supply_unregister(&smb->mains); - return ret; - } - - ret = power_supply_register(dev, &smb->battery); - if (ret < 0) { - power_supply_unregister(&smb->usb); - power_supply_unregister(&smb->mains); - return ret; - } - - /* - * Interrupt pin is optional. If it is connected, we setup the - * interrupt support here. - */ - if (pdata->irq_gpio >= 0) { - ret = smb347_irq_init(smb); - if (ret < 0) { - dev_warn(dev, "failed to initialize IRQ: %d\n", ret); - dev_warn(dev, "disabling IRQ support\n"); - } - } - - smb->dentry = debugfs_create_file("smb347-regs", S_IRUSR, NULL, smb, - &smb347_debugfs_fops); - return 0; -} - -static int smb347_remove(struct i2c_client *client) -{ - struct smb347_charger *smb = i2c_get_clientdata(client); - - if (!IS_ERR_OR_NULL(smb->dentry)) - debugfs_remove(smb->dentry); - - if (client->irq) { - smb347_irq_disable(smb); - free_irq(client->irq, smb); - gpio_free(smb->pdata->irq_gpio); - } - - power_supply_unregister(&smb->battery); - power_supply_unregister(&smb->usb); - power_supply_unregister(&smb->mains); - return 0; -} - -static const struct i2c_device_id smb347_id[] = { - { "smb347", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, smb347_id); - -static struct i2c_driver smb347_driver = { - .driver = { - .name = "smb347", - }, - .probe = smb347_probe, - .remove = __devexit_p(smb347_remove), - .id_table = smb347_id, -}; - -static int __init smb347_init(void) -{ - return i2c_add_driver(&smb347_driver); -} -module_init(smb347_init); - -static void __exit smb347_exit(void) -{ - i2c_del_driver(&smb347_driver); -} -module_exit(smb347_exit); - -MODULE_AUTHOR("Bruce E. Robertson "); -MODULE_AUTHOR("Mika Westerberg "); -MODULE_DESCRIPTION("SMB347 battery charger driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("i2c:smb347"); diff --git a/trunk/drivers/power/z2_battery.c b/trunk/drivers/power/z2_battery.c index 8c9a607ea77a..636ebb2a0e80 100644 --- a/trunk/drivers/power/z2_battery.c +++ b/trunk/drivers/power/z2_battery.c @@ -316,7 +316,19 @@ static struct i2c_driver z2_batt_driver = { .remove = __devexit_p(z2_batt_remove), .id_table = z2_batt_id, }; -module_i2c_driver(z2_batt_driver); + +static int __init z2_batt_init(void) +{ + return i2c_add_driver(&z2_batt_driver); +} + +static void __exit z2_batt_exit(void) +{ + i2c_del_driver(&z2_batt_driver); +} + +module_init(z2_batt_init); +module_exit(z2_batt_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Peter Edwards "); diff --git a/trunk/drivers/regulator/anatop-regulator.c b/trunk/drivers/regulator/anatop-regulator.c index 81fd606e47bc..17499a55113d 100644 --- a/trunk/drivers/regulator/anatop-regulator.c +++ b/trunk/drivers/regulator/anatop-regulator.c @@ -138,10 +138,9 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev) rdesc->type = REGULATOR_VOLTAGE; rdesc->owner = THIS_MODULE; sreg->mfd = anatopmfd; - ret = of_property_read_u32(np, "anatop-reg-offset", - &sreg->control_reg); + ret = of_property_read_u32(np, "reg", &sreg->control_reg); if (ret) { - dev_err(dev, "no anatop-reg-offset property set\n"); + dev_err(dev, "no reg property set\n"); goto anatop_probe_end; } ret = of_property_read_u32(np, "anatop-vol-bit-width", @@ -214,7 +213,7 @@ static struct of_device_id __devinitdata of_anatop_regulator_match_tbl[] = { { /* end */ } }; -static struct platform_driver anatop_regulator_driver = { +static struct platform_driver anatop_regulator = { .driver = { .name = "anatop_regulator", .owner = THIS_MODULE, @@ -226,13 +225,13 @@ static struct platform_driver anatop_regulator_driver = { static int __init anatop_regulator_init(void) { - return platform_driver_register(&anatop_regulator_driver); + return platform_driver_register(&anatop_regulator); } postcore_initcall(anatop_regulator_init); static void __exit anatop_regulator_exit(void) { - platform_driver_unregister(&anatop_regulator_driver); + platform_driver_unregister(&anatop_regulator); } module_exit(anatop_regulator_exit); diff --git a/trunk/drivers/regulator/core.c b/trunk/drivers/regulator/core.c index e70dd382a009..c056abd7562a 100644 --- a/trunk/drivers/regulator/core.c +++ b/trunk/drivers/regulator/core.c @@ -2992,14 +2992,14 @@ void regulator_unregister(struct regulator_dev *rdev) if (rdev == NULL) return; - if (rdev->supply) - regulator_put(rdev->supply); mutex_lock(®ulator_list_mutex); debugfs_remove_recursive(rdev->debugfs); flush_work_sync(&rdev->disable_work.work); WARN_ON(rdev->open_count); unset_regulator_supplies(rdev); list_del(&rdev->list); + if (rdev->supply) + regulator_put(rdev->supply); kfree(rdev->constraints); device_unregister(&rdev->dev); mutex_unlock(®ulator_list_mutex); diff --git a/trunk/drivers/regulator/fixed-helper.c b/trunk/drivers/regulator/fixed-helper.c index cacd33c9d042..30d0a15b8949 100644 --- a/trunk/drivers/regulator/fixed-helper.c +++ b/trunk/drivers/regulator/fixed-helper.c @@ -18,6 +18,7 @@ static void regulator_fixed_release(struct device *dev) /** * regulator_register_fixed - register a no-op fixed regulator + * @name: supply name * @id: platform device id * @supplies: consumers for this regulator * @num_supplies: number of consumers @@ -31,7 +32,7 @@ struct platform_device *regulator_register_fixed(int id, if (!data) return NULL; - data->cfg.supply_name = "fixed-dummy"; + data->cfg.supply_name = "dummy"; data->cfg.microvolts = 0; data->cfg.gpio = -EINVAL; data->cfg.enabled_at_boot = 1; diff --git a/trunk/drivers/regulator/mc13892-regulator.c b/trunk/drivers/regulator/mc13892-regulator.c index 845aa2263b8a..e8cfc99dd8f0 100644 --- a/trunk/drivers/regulator/mc13892-regulator.c +++ b/trunk/drivers/regulator/mc13892-regulator.c @@ -552,7 +552,7 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev) mc13xxx_lock(mc13892); ret = mc13xxx_reg_read(mc13892, MC13892_REVISION, &val); if (ret) - goto err_unlock; + goto err_free; /* enable switch auto mode */ if ((val & 0x0000FFFF) == 0x45d0) { @@ -562,7 +562,7 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev) MC13892_SWITCHERS4_SW1MODE_AUTO | MC13892_SWITCHERS4_SW2MODE_AUTO); if (ret) - goto err_unlock; + goto err_free; ret = mc13xxx_reg_rmw(mc13892, MC13892_SWITCHERS5, MC13892_SWITCHERS5_SW3MODE_M | @@ -570,7 +570,7 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev) MC13892_SWITCHERS5_SW3MODE_AUTO | MC13892_SWITCHERS5_SW4MODE_AUTO); if (ret) - goto err_unlock; + goto err_free; } mc13xxx_unlock(mc13892); @@ -612,10 +612,10 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev) err: while (--i >= 0) regulator_unregister(priv->regulators[i]); - return ret; -err_unlock: +err_free: mc13xxx_unlock(mc13892); + return ret; } diff --git a/trunk/drivers/regulator/s5m8767.c b/trunk/drivers/regulator/s5m8767.c index 4ca2db059004..58447db15de1 100644 --- a/trunk/drivers/regulator/s5m8767.c +++ b/trunk/drivers/regulator/s5m8767.c @@ -311,7 +311,8 @@ static int s5m8767_set_voltage(struct regulator_dev *rdev, struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); const struct s5m_voltage_desc *desc; int reg_id = rdev_get_id(rdev); - int sel, reg, mask, ret; + int reg, mask, ret; + int i; u8 val; switch (reg_id) { @@ -332,20 +333,19 @@ static int s5m8767_set_voltage(struct regulator_dev *rdev, desc = reg_voltage_map[reg_id]; - sel = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV); - if (sel < 0) - return sel; + i = s5m8767_convert_voltage_to_sel(desc, min_uV, max_uV); + if (i < 0) + return i; ret = s5m8767_get_voltage_register(rdev, ®); if (ret) return ret; s5m_reg_read(s5m8767->iodev, reg, &val); - val &= ~mask; - val |= sel; + val = val & mask; ret = s5m_reg_write(s5m8767->iodev, reg, val); - *selector = sel; + *selector = i; return ret; } diff --git a/trunk/drivers/regulator/tps6586x-regulator.c b/trunk/drivers/regulator/tps6586x-regulator.c index cfc1f16f7771..29b615ce3aff 100644 --- a/trunk/drivers/regulator/tps6586x-regulator.c +++ b/trunk/drivers/regulator/tps6586x-regulator.c @@ -79,11 +79,6 @@ static int tps6586x_ldo_list_voltage(struct regulator_dev *rdev, unsigned selector) { struct tps6586x_regulator *info = rdev_get_drvdata(rdev); - int rid = rdev_get_id(rdev); - - /* LDO0 has minimal voltage 1.2V rather than 1.25V */ - if ((rid == TPS6586X_ID_LDO_0) && (selector == 0)) - return (info->voltages[0] - 50) * 1000; return info->voltages[selector] * 1000; } diff --git a/trunk/drivers/regulator/wm831x-dcdc.c b/trunk/drivers/regulator/wm831x-dcdc.c index ff810e787eac..4904a40b0d46 100644 --- a/trunk/drivers/regulator/wm831x-dcdc.c +++ b/trunk/drivers/regulator/wm831x-dcdc.c @@ -380,15 +380,13 @@ static int wm831x_buckv_set_current_limit(struct regulator_dev *rdev, int i; for (i = 0; i < ARRAY_SIZE(wm831x_dcdc_ilim); i++) { - if ((min_uA <= wm831x_dcdc_ilim[i]) && - (wm831x_dcdc_ilim[i] <= max_uA)) + if (max_uA <= wm831x_dcdc_ilim[i]) break; } if (i == ARRAY_SIZE(wm831x_dcdc_ilim)) return -EINVAL; - return wm831x_set_bits(wm831x, reg, WM831X_DC1_HC_THR_MASK, - i << WM831X_DC1_HC_THR_SHIFT); + return wm831x_set_bits(wm831x, reg, WM831X_DC1_HC_THR_MASK, i); } static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev) @@ -402,8 +400,7 @@ static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev) if (val < 0) return val; - val = (val & WM831X_DC1_HC_THR_MASK) >> WM831X_DC1_HC_THR_SHIFT; - return wm831x_dcdc_ilim[val]; + return wm831x_dcdc_ilim[val & WM831X_DC1_HC_THR_MASK]; } static struct regulator_ops wm831x_buckv_ops = { diff --git a/trunk/drivers/regulator/wm831x-isink.c b/trunk/drivers/regulator/wm831x-isink.c index b414e09c5620..634aac3f2d5f 100644 --- a/trunk/drivers/regulator/wm831x-isink.c +++ b/trunk/drivers/regulator/wm831x-isink.c @@ -101,7 +101,7 @@ static int wm831x_isink_set_current(struct regulator_dev *rdev, for (i = 0; i < ARRAY_SIZE(wm831x_isinkv_values); i++) { int val = wm831x_isinkv_values[i]; - if (min_uA <= val && val <= max_uA) { + if (min_uA >= val && val <= max_uA) { ret = wm831x_set_bits(wm831x, isink->reg, WM831X_CS1_ISEL_MASK, i); return ret; diff --git a/trunk/drivers/regulator/wm831x-ldo.c b/trunk/drivers/regulator/wm831x-ldo.c index 641e9f6499d1..f1e4ab0f9fda 100644 --- a/trunk/drivers/regulator/wm831x-ldo.c +++ b/trunk/drivers/regulator/wm831x-ldo.c @@ -506,19 +506,22 @@ static int wm831x_aldo_set_mode(struct regulator_dev *rdev, { struct wm831x_ldo *ldo = rdev_get_drvdata(rdev); struct wm831x *wm831x = ldo->wm831x; + int ctrl_reg = ldo->base + WM831X_LDO_CONTROL; int on_reg = ldo->base + WM831X_LDO_ON_CONTROL; int ret; switch (mode) { case REGULATOR_MODE_NORMAL: - ret = wm831x_set_bits(wm831x, on_reg, WM831X_LDO7_ON_MODE, 0); + ret = wm831x_set_bits(wm831x, on_reg, + WM831X_LDO7_ON_MODE, 0); if (ret < 0) return ret; break; case REGULATOR_MODE_IDLE: - ret = wm831x_set_bits(wm831x, on_reg, WM831X_LDO7_ON_MODE, + ret = wm831x_set_bits(wm831x, ctrl_reg, + WM831X_LDO7_ON_MODE, WM831X_LDO7_ON_MODE); if (ret < 0) return ret; diff --git a/trunk/drivers/regulator/wm8350-regulator.c b/trunk/drivers/regulator/wm8350-regulator.c index 05ecfb872319..ab1e183a74b5 100644 --- a/trunk/drivers/regulator/wm8350-regulator.c +++ b/trunk/drivers/regulator/wm8350-regulator.c @@ -99,7 +99,7 @@ static int get_isink_val(int min_uA, int max_uA, u16 *setting) { int i; - for (i = 0; i < ARRAY_SIZE(isink_cur); i++) { + for (i = ARRAY_SIZE(isink_cur) - 1; i >= 0; i--) { if (min_uA <= isink_cur[i] && max_uA >= isink_cur[i]) { *setting = i; return 0; @@ -186,7 +186,7 @@ static int wm8350_isink_get_current(struct regulator_dev *rdev) return 0; } - return isink_cur[val]; + return DIV_ROUND_CLOSEST(isink_cur[val], 100); } /* turn on ISINK followed by DCDC */ @@ -495,25 +495,25 @@ static int wm8350_dcdc_set_suspend_enable(struct regulator_dev *rdev) val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER) & ~WM8350_DCDC_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC1_LOW_POWER, - val | wm8350->pmic.dcdc1_hib_mode); + wm8350->pmic.dcdc1_hib_mode); break; case WM8350_DCDC_3: val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER) & ~WM8350_DCDC_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC3_LOW_POWER, - val | wm8350->pmic.dcdc3_hib_mode); + wm8350->pmic.dcdc3_hib_mode); break; case WM8350_DCDC_4: val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER) & ~WM8350_DCDC_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC4_LOW_POWER, - val | wm8350->pmic.dcdc4_hib_mode); + wm8350->pmic.dcdc4_hib_mode); break; case WM8350_DCDC_6: val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER) & ~WM8350_DCDC_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC6_LOW_POWER, - val | wm8350->pmic.dcdc6_hib_mode); + wm8350->pmic.dcdc6_hib_mode); break; case WM8350_DCDC_2: case WM8350_DCDC_5: @@ -535,25 +535,25 @@ static int wm8350_dcdc_set_suspend_disable(struct regulator_dev *rdev) val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER); wm8350->pmic.dcdc1_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC1_LOW_POWER, - val | WM8350_DCDC_HIB_MODE_DIS); + WM8350_DCDC_HIB_MODE_DIS); break; case WM8350_DCDC_3: val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER); wm8350->pmic.dcdc3_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC3_LOW_POWER, - val | WM8350_DCDC_HIB_MODE_DIS); + WM8350_DCDC_HIB_MODE_DIS); break; case WM8350_DCDC_4: val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER); wm8350->pmic.dcdc4_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC4_LOW_POWER, - val | WM8350_DCDC_HIB_MODE_DIS); + WM8350_DCDC_HIB_MODE_DIS); break; case WM8350_DCDC_6: val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER); wm8350->pmic.dcdc6_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC6_LOW_POWER, - val | WM8350_DCDC_HIB_MODE_DIS); + WM8350_DCDC_HIB_MODE_DIS); break; case WM8350_DCDC_2: case WM8350_DCDC_5: @@ -575,13 +575,13 @@ static int wm8350_dcdc25_set_suspend_enable(struct regulator_dev *rdev) val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL) & ~WM8350_DC2_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val | - (WM8350_DC2_HIB_MODE_ACTIVE << WM8350_DC2_HIB_MODE_SHIFT)); + WM8350_DC2_HIB_MODE_ACTIVE); break; case WM8350_DCDC_5: val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL) - & ~WM8350_DC5_HIB_MODE_MASK; + & ~WM8350_DC2_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val | - (WM8350_DC5_HIB_MODE_ACTIVE << WM8350_DC5_HIB_MODE_SHIFT)); + WM8350_DC5_HIB_MODE_ACTIVE); break; default: return -EINVAL; @@ -600,13 +600,13 @@ static int wm8350_dcdc25_set_suspend_disable(struct regulator_dev *rdev) val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL) & ~WM8350_DC2_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val | - (WM8350_DC2_HIB_MODE_DISABLE << WM8350_DC2_HIB_MODE_SHIFT)); + WM8350_DC2_HIB_MODE_DISABLE); break; case WM8350_DCDC_5: val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL) - & ~WM8350_DC5_HIB_MODE_MASK; + & ~WM8350_DC2_HIB_MODE_MASK; wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val | - (WM8350_DC5_HIB_MODE_DISABLE << WM8350_DC5_HIB_MODE_SHIFT)); + WM8350_DC2_HIB_MODE_DISABLE); break; default: return -EINVAL; @@ -749,7 +749,7 @@ static int wm8350_ldo_set_suspend_disable(struct regulator_dev *rdev) /* all LDOs have same mV bits */ val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_HIB_MODE_MASK; - wm8350_reg_write(wm8350, volt_reg, val | WM8350_LDO1_HIB_MODE_DIS); + wm8350_reg_write(wm8350, volt_reg, WM8350_LDO1_HIB_MODE_DIS); return 0; } diff --git a/trunk/drivers/remoteproc/remoteproc_debugfs.c b/trunk/drivers/remoteproc/remoteproc_debugfs.c index 85d31a69e117..70277a530133 100644 --- a/trunk/drivers/remoteproc/remoteproc_debugfs.c +++ b/trunk/drivers/remoteproc/remoteproc_debugfs.c @@ -50,9 +50,16 @@ static ssize_t rproc_trace_read(struct file *filp, char __user *userbuf, return simple_read_from_buffer(userbuf, count, ppos, trace->va, len); } +static int rproc_open_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + + return 0; +} + static const struct file_operations trace_rproc_ops = { .read = rproc_trace_read, - .open = simple_open, + .open = rproc_open_generic, .llseek = generic_file_llseek, }; @@ -87,7 +94,7 @@ static ssize_t rproc_state_read(struct file *filp, char __user *userbuf, static const struct file_operations rproc_state_ops = { .read = rproc_state_read, - .open = simple_open, + .open = rproc_open_generic, .llseek = generic_file_llseek, }; @@ -107,7 +114,7 @@ static ssize_t rproc_name_read(struct file *filp, char __user *userbuf, static const struct file_operations rproc_name_ops = { .read = rproc_name_read, - .open = simple_open, + .open = rproc_open_generic, .llseek = generic_file_llseek, }; diff --git a/trunk/drivers/rtc/rtc-88pm860x.c b/trunk/drivers/rtc/rtc-88pm860x.c index feddefc42109..afee0e8ae714 100644 --- a/trunk/drivers/rtc/rtc-88pm860x.c +++ b/trunk/drivers/rtc/rtc-88pm860x.c @@ -72,9 +72,9 @@ static int pm860x_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) struct pm860x_rtc_info *info = dev_get_drvdata(dev); if (enabled) - pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM_EN, ALARM_EN); + pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM, ALARM); else - pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM_EN, 0); + pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM, 0); return 0; } diff --git a/trunk/drivers/rtc/rtc-ds1307.c b/trunk/drivers/rtc/rtc-ds1307.c index c293d0cdb104..cd188ab72f79 100644 --- a/trunk/drivers/rtc/rtc-ds1307.c +++ b/trunk/drivers/rtc/rtc-ds1307.c @@ -902,7 +902,6 @@ static int __devinit ds1307_probe(struct i2c_client *client, } ds1307->nvram->attr.name = "nvram"; ds1307->nvram->attr.mode = S_IRUGO | S_IWUSR; - sysfs_bin_attr_init(ds1307->nvram); ds1307->nvram->read = ds1307_nvram_read, ds1307->nvram->write = ds1307_nvram_write, ds1307->nvram->size = chip->nvram_size; diff --git a/trunk/drivers/rtc/rtc-efi.c b/trunk/drivers/rtc/rtc-efi.c index c9f890b088da..550292304b0f 100644 --- a/trunk/drivers/rtc/rtc-efi.c +++ b/trunk/drivers/rtc/rtc-efi.c @@ -213,6 +213,7 @@ static struct platform_driver efi_rtc_driver = { .name = "rtc-efi", .owner = THIS_MODULE, }, + .probe = efi_rtc_probe, .remove = __exit_p(efi_rtc_remove), }; diff --git a/trunk/drivers/rtc/rtc-mpc5121.c b/trunk/drivers/rtc/rtc-mpc5121.c index 029e421baaed..42f5f829b3ee 100644 --- a/trunk/drivers/rtc/rtc-mpc5121.c +++ b/trunk/drivers/rtc/rtc-mpc5121.c @@ -360,11 +360,12 @@ static int __devinit mpc5121_rtc_probe(struct platform_device *op) &mpc5200_rtc_ops, THIS_MODULE); } + rtc->rtc->uie_unsupported = 1; + if (IS_ERR(rtc->rtc)) { err = PTR_ERR(rtc->rtc); goto out_free_irq; } - rtc->rtc->uie_unsupported = 1; return 0; diff --git a/trunk/drivers/rtc/rtc-pl031.c b/trunk/drivers/rtc/rtc-pl031.c index 684ef4bbfce4..692de7360e94 100644 --- a/trunk/drivers/rtc/rtc-pl031.c +++ b/trunk/drivers/rtc/rtc-pl031.c @@ -339,7 +339,8 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) dev_dbg(&adev->dev, "revision = 0x%01x\n", ldata->hw_revision); /* Enable the clockwatch on ST Variants */ - if (ldata->hw_designer == AMBA_VENDOR_ST) + if ((ldata->hw_designer == AMBA_VENDOR_ST) && + (ldata->hw_revision > 1)) writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN, ldata->base + RTC_CR); diff --git a/trunk/drivers/rtc/rtc-r9701.c b/trunk/drivers/rtc/rtc-r9701.c index 33b6ba0afa0d..7f8e6c247935 100644 --- a/trunk/drivers/rtc/rtc-r9701.c +++ b/trunk/drivers/rtc/rtc-r9701.c @@ -122,7 +122,6 @@ static const struct rtc_class_ops r9701_rtc_ops = { static int __devinit r9701_probe(struct spi_device *spi) { struct rtc_device *rtc; - struct rtc_time dt; unsigned char tmp; int res; @@ -133,27 +132,6 @@ static int __devinit r9701_probe(struct spi_device *spi) return -ENODEV; } - /* - * The device seems to be present. Now check if the registers - * contain invalid values. If so, try to write a default date: - * 2000/1/1 00:00:00 - */ - r9701_get_datetime(&spi->dev, &dt); - if (rtc_valid_tm(&dt)) { - dev_info(&spi->dev, "trying to repair invalid date/time\n"); - dt.tm_sec = 0; - dt.tm_min = 0; - dt.tm_hour = 0; - dt.tm_mday = 1; - dt.tm_mon = 0; - dt.tm_year = 100; - - if (r9701_set_datetime(&spi->dev, &dt)) { - dev_err(&spi->dev, "cannot repair RTC register\n"); - return -ENODEV; - } - } - rtc = rtc_device_register("r9701", &spi->dev, &r9701_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) diff --git a/trunk/drivers/rtc/rtc-s3c.c b/trunk/drivers/rtc/rtc-s3c.c index 3f3a29752369..9ccea134a996 100644 --- a/trunk/drivers/rtc/rtc-s3c.c +++ b/trunk/drivers/rtc/rtc-s3c.c @@ -40,10 +40,6 @@ enum s3c_cpu_type { TYPE_S3C64XX, }; -struct s3c_rtc_drv_data { - int cpu_type; -}; - /* I have yet to find an S3C implementation with more than one * of these rtc blocks in */ @@ -450,12 +446,10 @@ static const struct of_device_id s3c_rtc_dt_match[]; static inline int s3c_rtc_get_driver_data(struct platform_device *pdev) { #ifdef CONFIG_OF - struct s3c_rtc_drv_data *data; if (pdev->dev.of_node) { const struct of_device_id *match; match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node); - data = (struct s3c_rtc_drv_data *) match->data; - return data->cpu_type; + return match->data; } #endif return platform_get_device_id(pdev)->driver_data; @@ -670,27 +664,20 @@ static int s3c_rtc_resume(struct platform_device *pdev) #define s3c_rtc_resume NULL #endif -static struct s3c_rtc_drv_data s3c_rtc_drv_data_array[] = { - [TYPE_S3C2410] = { TYPE_S3C2410 }, - [TYPE_S3C2416] = { TYPE_S3C2416 }, - [TYPE_S3C2443] = { TYPE_S3C2443 }, - [TYPE_S3C64XX] = { TYPE_S3C64XX }, -}; - #ifdef CONFIG_OF static const struct of_device_id s3c_rtc_dt_match[] = { { - .compatible = "samsung,s3c2410-rtc", - .data = &s3c_rtc_drv_data_array[TYPE_S3C2410], + .compatible = "samsung,s3c2410-rtc" + .data = TYPE_S3C2410, }, { - .compatible = "samsung,s3c2416-rtc", - .data = &s3c_rtc_drv_data_array[TYPE_S3C2416], + .compatible = "samsung,s3c2416-rtc" + .data = TYPE_S3C2416, }, { - .compatible = "samsung,s3c2443-rtc", - .data = &s3c_rtc_drv_data_array[TYPE_S3C2443], + .compatible = "samsung,s3c2443-rtc" + .data = TYPE_S3C2443, }, { - .compatible = "samsung,s3c6410-rtc", - .data = &s3c_rtc_drv_data_array[TYPE_S3C64XX], + .compatible = "samsung,s3c6410-rtc" + .data = TYPE_S3C64XX, }, {}, }; diff --git a/trunk/drivers/rtc/rtc-twl.c b/trunk/drivers/rtc/rtc-twl.c index 258abeabf624..4c2c6df2a9ef 100644 --- a/trunk/drivers/rtc/rtc-twl.c +++ b/trunk/drivers/rtc/rtc-twl.c @@ -112,7 +112,6 @@ static const u8 twl6030_rtc_reg_map[] = { #define BIT_RTC_CTRL_REG_TEST_MODE_M 0x10 #define BIT_RTC_CTRL_REG_SET_32_COUNTER_M 0x20 #define BIT_RTC_CTRL_REG_GET_TIME_M 0x40 -#define BIT_RTC_CTRL_REG_RTC_V_OPT 0x80 /* RTC_STATUS_REG bitfields */ #define BIT_RTC_STATUS_REG_RUN_M 0x02 @@ -236,57 +235,25 @@ static int twl_rtc_read_time(struct device *dev, struct rtc_time *tm) unsigned char rtc_data[ALL_TIME_REGS + 1]; int ret; u8 save_control; - u8 rtc_control; ret = twl_rtc_read_u8(&save_control, REG_RTC_CTRL_REG); - if (ret < 0) { - dev_err(dev, "%s: reading CTRL_REG, error %d\n", __func__, ret); + if (ret < 0) return ret; - } - /* for twl6030/32 make sure BIT_RTC_CTRL_REG_GET_TIME_M is clear */ - if (twl_class_is_6030()) { - if (save_control & BIT_RTC_CTRL_REG_GET_TIME_M) { - save_control &= ~BIT_RTC_CTRL_REG_GET_TIME_M; - ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG); - if (ret < 0) { - dev_err(dev, "%s clr GET_TIME, error %d\n", - __func__, ret); - return ret; - } - } - } - - /* Copy RTC counting registers to static registers or latches */ - rtc_control = save_control | BIT_RTC_CTRL_REG_GET_TIME_M; - /* for twl6030/32 enable read access to static shadowed registers */ - if (twl_class_is_6030()) - rtc_control |= BIT_RTC_CTRL_REG_RTC_V_OPT; + save_control |= BIT_RTC_CTRL_REG_GET_TIME_M; - ret = twl_rtc_write_u8(rtc_control, REG_RTC_CTRL_REG); - if (ret < 0) { - dev_err(dev, "%s: writing CTRL_REG, error %d\n", __func__, ret); + ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG); + if (ret < 0) return ret; - } ret = twl_i2c_read(TWL_MODULE_RTC, rtc_data, (rtc_reg_map[REG_SECONDS_REG]), ALL_TIME_REGS); if (ret < 0) { - dev_err(dev, "%s: reading data, error %d\n", __func__, ret); + dev_err(dev, "rtc_read_time error %d\n", ret); return ret; } - /* for twl6030 restore original state of rtc control register */ - if (twl_class_is_6030()) { - ret = twl_rtc_write_u8(save_control, REG_RTC_CTRL_REG); - if (ret < 0) { - dev_err(dev, "%s: restore CTRL_REG, error %d\n", - __func__, ret); - return ret; - } - } - tm->tm_sec = bcd2bin(rtc_data[0]); tm->tm_min = bcd2bin(rtc_data[1]); tm->tm_hour = bcd2bin(rtc_data[2]); diff --git a/trunk/drivers/s390/block/dasd_eckd.c b/trunk/drivers/s390/block/dasd_eckd.c index bc2e8a7c265b..c21871a4e73d 100644 --- a/trunk/drivers/s390/block/dasd_eckd.c +++ b/trunk/drivers/s390/block/dasd_eckd.c @@ -2844,7 +2844,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( sector_t recid, trkid; unsigned int offs; unsigned int count, count_to_trk_end; - int ret; basedev = block->base; if (rq_data_dir(req) == READ) { @@ -2885,8 +2884,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0); if (IS_ERR(itcw)) { - ret = -EINVAL; - goto out_error; + dasd_sfree_request(cqr, startdev); + return ERR_PTR(-EINVAL); } cqr->cpaddr = itcw_get_tcw(itcw); if (prepare_itcw(itcw, first_trk, last_trk, @@ -2898,8 +2897,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( /* Clock not in sync and XRC is enabled. * Try again later. */ - ret = -EAGAIN; - goto out_error; + dasd_sfree_request(cqr, startdev); + return ERR_PTR(-EAGAIN); } len_to_track_end = 0; /* @@ -2938,10 +2937,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( tidaw_flags = 0; last_tidaw = itcw_add_tidaw(itcw, tidaw_flags, dst, part_len); - if (IS_ERR(last_tidaw)) { - ret = -EINVAL; - goto out_error; - } + if (IS_ERR(last_tidaw)) + return ERR_PTR(-EINVAL); dst += part_len; } } @@ -2950,10 +2947,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( dst = page_address(bv->bv_page) + bv->bv_offset; last_tidaw = itcw_add_tidaw(itcw, 0x00, dst, bv->bv_len); - if (IS_ERR(last_tidaw)) { - ret = -EINVAL; - goto out_error; - } + if (IS_ERR(last_tidaw)) + return ERR_PTR(-EINVAL); } } last_tidaw->flags |= TIDAW_FLAGS_LAST; @@ -2973,9 +2968,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( cqr->buildclk = get_clock(); cqr->status = DASD_CQR_FILLED; return cqr; -out_error: - dasd_sfree_request(cqr, startdev); - return ERR_PTR(ret); } static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, diff --git a/trunk/drivers/s390/char/vmur.c b/trunk/drivers/s390/char/vmur.c index 73bef0bd394c..85f4a9a5d12e 100644 --- a/trunk/drivers/s390/char/vmur.c +++ b/trunk/drivers/s390/char/vmur.c @@ -903,7 +903,7 @@ static int ur_set_online(struct ccw_device *cdev) goto fail_urdev_put; } - urd->char_device->ops = &ur_fops; + cdev_init(urd->char_device, &ur_fops); urd->char_device->dev = MKDEV(major, minor); urd->char_device->owner = ur_fops.owner; diff --git a/trunk/drivers/s390/net/qeth_core_main.c b/trunk/drivers/s390/net/qeth_core_main.c index 8334dadc681d..120955c66410 100644 --- a/trunk/drivers/s390/net/qeth_core_main.c +++ b/trunk/drivers/s390/net/qeth_core_main.c @@ -1672,8 +1672,7 @@ static void qeth_configure_blkt_default(struct qeth_card *card, char *prcd) { QETH_DBF_TEXT(SETUP, 2, "cfgblkt"); - if (prcd[74] == 0xF0 && prcd[75] == 0xF0 && - (prcd[76] == 0xF5 || prcd[76] == 0xF6)) { + if (prcd[74] == 0xF0 && prcd[75] == 0xF0 && prcd[76] == 0xF5) { card->info.blkt.time_total = 250; card->info.blkt.inter_packet = 5; card->info.blkt.inter_packet_jumbo = 15; @@ -4541,8 +4540,7 @@ static void qeth_determine_capabilities(struct qeth_card *card) goto out_offline; } qeth_configure_unitaddr(card, prcd); - if (ddev_offline) - qeth_configure_blkt_default(card, prcd); + qeth_configure_blkt_default(card, prcd); kfree(prcd); rc = qdio_get_ssqd_desc(ddev, &card->ssqd); diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index 29684c8142b0..a06e608789e3 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -619,7 +619,6 @@ config SCSI_ARCMSR source "drivers/scsi/megaraid/Kconfig.megaraid" source "drivers/scsi/mpt2sas/Kconfig" -source "drivers/scsi/ufs/Kconfig" config SCSI_HPTIOP tristate "HighPoint RocketRAID 3xxx/4xxx Controller support" diff --git a/trunk/drivers/scsi/Makefile b/trunk/drivers/scsi/Makefile index 8deedeaf5608..ad24e065b1e5 100644 --- a/trunk/drivers/scsi/Makefile +++ b/trunk/drivers/scsi/Makefile @@ -108,7 +108,6 @@ obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/ obj-$(CONFIG_MEGARAID_SAS) += megaraid/ obj-$(CONFIG_SCSI_MPT2SAS) += mpt2sas/ -obj-$(CONFIG_SCSI_UFSHCD) += ufs/ obj-$(CONFIG_SCSI_ACARD) += atp870u.o obj-$(CONFIG_SCSI_SUNESP) += esp_scsi.o sun_esp.o obj-$(CONFIG_SCSI_GDTH) += gdth.o diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c index 9328121804bb..7d48700257a7 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -341,10 +341,10 @@ MODULE_PARM_DESC(aic79xx, " (0/256ms,1/128ms,2/64ms,3/32ms)\n" " slowcrc Turn on the SLOWCRC bit (Rev B only)\n" "\n" -" Sample modprobe configuration file:\n" -" # Enable verbose logging\n" -" # Set tag depth on Controller 2/Target 2 to 10 tags\n" -" # Shorten the selection timeout to 128ms\n" +" Sample /etc/modprobe.conf line:\n" +" Enable verbose logging\n" +" Set tag depth on Controller 2/Target 2 to 10 tags\n" +" Shorten the selection timeout to 128ms\n" "\n" " options aic79xx 'aic79xx=verbose.tag_info:{{}.{}.{..10}}.seltime:1'\n" ); diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c index 5a477cdc780d..c6251bb4f438 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -360,10 +360,10 @@ MODULE_PARM_DESC(aic7xxx, " seltime: Selection Timeout\n" " (0/256ms,1/128ms,2/64ms,3/32ms)\n" "\n" -" Sample modprobe configuration file:\n" -" # Toggle EISA/VLB probing\n" -" # Set tag depth on Controller 1/Target 1 to 10 tags\n" -" # Shorten the selection timeout to 128ms\n" +" Sample /etc/modprobe.conf line:\n" +" Toggle EISA/VLB probing\n" +" Set tag depth on Controller 1/Target 1 to 10 tags\n" +" Shorten the selection timeout to 128ms\n" "\n" " options aic7xxx 'aic7xxx=probe_eisa_vl.tag_info:{{}.{.10}}.seltime:1'\n" ); diff --git a/trunk/drivers/scsi/atp870u.c b/trunk/drivers/scsi/atp870u.c index 68ce08552f69..f29d5121d5ed 100644 --- a/trunk/drivers/scsi/atp870u.c +++ b/trunk/drivers/scsi/atp870u.c @@ -2582,7 +2582,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * this than via the PCI device table */ if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) { - atpdev->chip_ver = pdev->revision; + error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver); if (atpdev->chip_ver < 2) goto err_eio; } @@ -2601,7 +2601,7 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) base_io &= 0xfffffff8; if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { - atpdev->chip_ver = pdev->revision; + error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver); pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 host_id = inb(base_io + 0x39); diff --git a/trunk/drivers/scsi/bfa/bfa.h b/trunk/drivers/scsi/bfa/bfa.h index 4ad7e368bbc2..a796de935054 100644 --- a/trunk/drivers/scsi/bfa/bfa.h +++ b/trunk/drivers/scsi/bfa/bfa.h @@ -225,9 +225,9 @@ struct bfa_faa_args_s { }; struct bfa_iocfc_s { - bfa_fsm_t fsm; struct bfa_s *bfa; struct bfa_iocfc_cfg_s cfg; + int action; u32 req_cq_pi[BFI_IOC_MAX_CQS]; u32 rsp_cq_ci[BFI_IOC_MAX_CQS]; u8 hw_qid[BFI_IOC_MAX_CQS]; @@ -236,9 +236,7 @@ struct bfa_iocfc_s { struct bfa_cb_qe_s dis_hcb_qe; struct bfa_cb_qe_s en_hcb_qe; struct bfa_cb_qe_s stats_hcb_qe; - bfa_boolean_t submod_enabled; - bfa_boolean_t cb_reqd; /* Driver call back reqd */ - bfa_status_t op_status; /* Status of bfa iocfc op */ + bfa_boolean_t cfgdone; struct bfa_dma_s cfg_info; struct bfi_iocfc_cfg_s *cfginfo; @@ -343,6 +341,8 @@ void bfa_hwct_msix_getvecs(struct bfa_s *bfa, u32 *vecmap, u32 *nvecs, void bfa_hwct_msix_get_rme_range(struct bfa_s *bfa, u32 *start, u32 *end); void bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t *wwns); +wwn_t bfa_iocfc_get_pwwn(struct bfa_s *bfa); +wwn_t bfa_iocfc_get_nwwn(struct bfa_s *bfa); int bfa_iocfc_get_pbc_vports(struct bfa_s *bfa, struct bfi_pbc_vport_s *pbc_vport); @@ -428,6 +428,7 @@ bfa_status_t bfa_iocfc_israttr_set(struct bfa_s *bfa, void bfa_iocfc_enable(struct bfa_s *bfa); void bfa_iocfc_disable(struct bfa_s *bfa); +void bfa_iocfc_cb_dconf_modinit(struct bfa_s *bfa, bfa_status_t status); #define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout) \ bfa_timer_begin(&(_bfa)->timer_mod, _timer, _timercb, _arg, _timeout) diff --git a/trunk/drivers/scsi/bfa/bfa_core.c b/trunk/drivers/scsi/bfa/bfa_core.c index 456e5762977d..4bd546bcc240 100644 --- a/trunk/drivers/scsi/bfa/bfa_core.c +++ b/trunk/drivers/scsi/bfa/bfa_core.c @@ -199,432 +199,14 @@ enum { #define DEF_CFG_NUM_SBOOT_TGTS 16 #define DEF_CFG_NUM_SBOOT_LUNS 16 -/* - * IOCFC state machine definitions/declarations - */ -bfa_fsm_state_decl(bfa_iocfc, stopped, struct bfa_iocfc_s, enum iocfc_event); -bfa_fsm_state_decl(bfa_iocfc, initing, struct bfa_iocfc_s, enum iocfc_event); -bfa_fsm_state_decl(bfa_iocfc, dconf_read, struct bfa_iocfc_s, enum iocfc_event); -bfa_fsm_state_decl(bfa_iocfc, init_cfg_wait, - struct bfa_iocfc_s, enum iocfc_event); -bfa_fsm_state_decl(bfa_iocfc, init_cfg_done, - struct bfa_iocfc_s, enum iocfc_event); -bfa_fsm_state_decl(bfa_iocfc, operational, - struct bfa_iocfc_s, enum iocfc_event); -bfa_fsm_state_decl(bfa_iocfc, dconf_write, - struct bfa_iocfc_s, enum iocfc_event); -bfa_fsm_state_decl(bfa_iocfc, stopping, struct bfa_iocfc_s, enum iocfc_event); -bfa_fsm_state_decl(bfa_iocfc, enabling, struct bfa_iocfc_s, enum iocfc_event); -bfa_fsm_state_decl(bfa_iocfc, cfg_wait, struct bfa_iocfc_s, enum iocfc_event); -bfa_fsm_state_decl(bfa_iocfc, disabling, struct bfa_iocfc_s, enum iocfc_event); -bfa_fsm_state_decl(bfa_iocfc, disabled, struct bfa_iocfc_s, enum iocfc_event); -bfa_fsm_state_decl(bfa_iocfc, failed, struct bfa_iocfc_s, enum iocfc_event); -bfa_fsm_state_decl(bfa_iocfc, init_failed, - struct bfa_iocfc_s, enum iocfc_event); - /* * forward declaration for IOC FC functions */ -static void bfa_iocfc_start_submod(struct bfa_s *bfa); -static void bfa_iocfc_disable_submod(struct bfa_s *bfa); -static void bfa_iocfc_send_cfg(void *bfa_arg); static void bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status); static void bfa_iocfc_disable_cbfn(void *bfa_arg); static void bfa_iocfc_hbfail_cbfn(void *bfa_arg); static void bfa_iocfc_reset_cbfn(void *bfa_arg); static struct bfa_ioc_cbfn_s bfa_iocfc_cbfn; -static void bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete); -static void bfa_iocfc_stop_cb(void *bfa_arg, bfa_boolean_t compl); -static void bfa_iocfc_enable_cb(void *bfa_arg, bfa_boolean_t compl); -static void bfa_iocfc_disable_cb(void *bfa_arg, bfa_boolean_t compl); - -static void -bfa_iocfc_sm_stopped_entry(struct bfa_iocfc_s *iocfc) -{ -} - -static void -bfa_iocfc_sm_stopped(struct bfa_iocfc_s *iocfc, enum iocfc_event event) -{ - bfa_trc(iocfc->bfa, event); - - switch (event) { - case IOCFC_E_INIT: - case IOCFC_E_ENABLE: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_initing); - break; - default: - bfa_sm_fault(iocfc->bfa, event); - break; - } -} - -static void -bfa_iocfc_sm_initing_entry(struct bfa_iocfc_s *iocfc) -{ - bfa_ioc_enable(&iocfc->bfa->ioc); -} - -static void -bfa_iocfc_sm_initing(struct bfa_iocfc_s *iocfc, enum iocfc_event event) -{ - bfa_trc(iocfc->bfa, event); - - switch (event) { - case IOCFC_E_IOC_ENABLED: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_read); - break; - case IOCFC_E_IOC_FAILED: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed); - break; - default: - bfa_sm_fault(iocfc->bfa, event); - break; - } -} - -static void -bfa_iocfc_sm_dconf_read_entry(struct bfa_iocfc_s *iocfc) -{ - bfa_dconf_modinit(iocfc->bfa); -} - -static void -bfa_iocfc_sm_dconf_read(struct bfa_iocfc_s *iocfc, enum iocfc_event event) -{ - bfa_trc(iocfc->bfa, event); - - switch (event) { - case IOCFC_E_DCONF_DONE: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_cfg_wait); - break; - case IOCFC_E_IOC_FAILED: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed); - break; - default: - bfa_sm_fault(iocfc->bfa, event); - break; - } -} - -static void -bfa_iocfc_sm_init_cfg_wait_entry(struct bfa_iocfc_s *iocfc) -{ - bfa_iocfc_send_cfg(iocfc->bfa); -} - -static void -bfa_iocfc_sm_init_cfg_wait(struct bfa_iocfc_s *iocfc, enum iocfc_event event) -{ - bfa_trc(iocfc->bfa, event); - - switch (event) { - case IOCFC_E_CFG_DONE: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_cfg_done); - break; - case IOCFC_E_IOC_FAILED: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_init_failed); - break; - default: - bfa_sm_fault(iocfc->bfa, event); - break; - } -} - -static void -bfa_iocfc_sm_init_cfg_done_entry(struct bfa_iocfc_s *iocfc) -{ - iocfc->bfa->iocfc.op_status = BFA_STATUS_OK; - bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.init_hcb_qe, - bfa_iocfc_init_cb, iocfc->bfa); -} - -static void -bfa_iocfc_sm_init_cfg_done(struct bfa_iocfc_s *iocfc, enum iocfc_event event) -{ - bfa_trc(iocfc->bfa, event); - - switch (event) { - case IOCFC_E_START: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_operational); - break; - case IOCFC_E_STOP: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping); - break; - case IOCFC_E_DISABLE: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling); - break; - case IOCFC_E_IOC_FAILED: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed); - break; - default: - bfa_sm_fault(iocfc->bfa, event); - break; - } -} - -static void -bfa_iocfc_sm_operational_entry(struct bfa_iocfc_s *iocfc) -{ - bfa_fcport_init(iocfc->bfa); - bfa_iocfc_start_submod(iocfc->bfa); -} - -static void -bfa_iocfc_sm_operational(struct bfa_iocfc_s *iocfc, enum iocfc_event event) -{ - bfa_trc(iocfc->bfa, event); - - switch (event) { - case IOCFC_E_STOP: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_write); - break; - case IOCFC_E_DISABLE: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling); - break; - case IOCFC_E_IOC_FAILED: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed); - break; - default: - bfa_sm_fault(iocfc->bfa, event); - break; - } -} - -static void -bfa_iocfc_sm_dconf_write_entry(struct bfa_iocfc_s *iocfc) -{ - bfa_dconf_modexit(iocfc->bfa); -} - -static void -bfa_iocfc_sm_dconf_write(struct bfa_iocfc_s *iocfc, enum iocfc_event event) -{ - bfa_trc(iocfc->bfa, event); - - switch (event) { - case IOCFC_E_DCONF_DONE: - case IOCFC_E_IOC_FAILED: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping); - break; - default: - bfa_sm_fault(iocfc->bfa, event); - break; - } -} - -static void -bfa_iocfc_sm_stopping_entry(struct bfa_iocfc_s *iocfc) -{ - bfa_ioc_disable(&iocfc->bfa->ioc); -} - -static void -bfa_iocfc_sm_stopping(struct bfa_iocfc_s *iocfc, enum iocfc_event event) -{ - bfa_trc(iocfc->bfa, event); - - switch (event) { - case IOCFC_E_IOC_DISABLED: - bfa_isr_disable(iocfc->bfa); - bfa_iocfc_disable_submod(iocfc->bfa); - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopped); - iocfc->bfa->iocfc.op_status = BFA_STATUS_OK; - bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.stop_hcb_qe, - bfa_iocfc_stop_cb, iocfc->bfa); - break; - default: - bfa_sm_fault(iocfc->bfa, event); - break; - } -} - -static void -bfa_iocfc_sm_enabling_entry(struct bfa_iocfc_s *iocfc) -{ - bfa_ioc_enable(&iocfc->bfa->ioc); -} - -static void -bfa_iocfc_sm_enabling(struct bfa_iocfc_s *iocfc, enum iocfc_event event) -{ - bfa_trc(iocfc->bfa, event); - - switch (event) { - case IOCFC_E_IOC_ENABLED: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_cfg_wait); - break; - case IOCFC_E_IOC_FAILED: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed); - - if (iocfc->bfa->iocfc.cb_reqd == BFA_FALSE) - break; - - iocfc->bfa->iocfc.op_status = BFA_STATUS_FAILED; - bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.en_hcb_qe, - bfa_iocfc_enable_cb, iocfc->bfa); - iocfc->bfa->iocfc.cb_reqd = BFA_FALSE; - break; - default: - bfa_sm_fault(iocfc->bfa, event); - break; - } -} - -static void -bfa_iocfc_sm_cfg_wait_entry(struct bfa_iocfc_s *iocfc) -{ - bfa_iocfc_send_cfg(iocfc->bfa); -} - -static void -bfa_iocfc_sm_cfg_wait(struct bfa_iocfc_s *iocfc, enum iocfc_event event) -{ - bfa_trc(iocfc->bfa, event); - - switch (event) { - case IOCFC_E_CFG_DONE: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_operational); - if (iocfc->bfa->iocfc.cb_reqd == BFA_FALSE) - break; - - iocfc->bfa->iocfc.op_status = BFA_STATUS_OK; - bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.en_hcb_qe, - bfa_iocfc_enable_cb, iocfc->bfa); - iocfc->bfa->iocfc.cb_reqd = BFA_FALSE; - break; - case IOCFC_E_IOC_FAILED: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_failed); - if (iocfc->bfa->iocfc.cb_reqd == BFA_FALSE) - break; - - iocfc->bfa->iocfc.op_status = BFA_STATUS_FAILED; - bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.en_hcb_qe, - bfa_iocfc_enable_cb, iocfc->bfa); - iocfc->bfa->iocfc.cb_reqd = BFA_FALSE; - break; - default: - bfa_sm_fault(iocfc->bfa, event); - break; - } -} - -static void -bfa_iocfc_sm_disabling_entry(struct bfa_iocfc_s *iocfc) -{ - bfa_ioc_disable(&iocfc->bfa->ioc); -} - -static void -bfa_iocfc_sm_disabling(struct bfa_iocfc_s *iocfc, enum iocfc_event event) -{ - bfa_trc(iocfc->bfa, event); - - switch (event) { - case IOCFC_E_IOC_DISABLED: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabled); - break; - default: - bfa_sm_fault(iocfc->bfa, event); - break; - } -} - -static void -bfa_iocfc_sm_disabled_entry(struct bfa_iocfc_s *iocfc) -{ - bfa_isr_disable(iocfc->bfa); - bfa_iocfc_disable_submod(iocfc->bfa); - iocfc->bfa->iocfc.op_status = BFA_STATUS_OK; - bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.dis_hcb_qe, - bfa_iocfc_disable_cb, iocfc->bfa); -} - -static void -bfa_iocfc_sm_disabled(struct bfa_iocfc_s *iocfc, enum iocfc_event event) -{ - bfa_trc(iocfc->bfa, event); - - switch (event) { - case IOCFC_E_STOP: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_write); - break; - case IOCFC_E_ENABLE: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_enabling); - break; - default: - bfa_sm_fault(iocfc->bfa, event); - break; - } -} - -static void -bfa_iocfc_sm_failed_entry(struct bfa_iocfc_s *iocfc) -{ - bfa_isr_disable(iocfc->bfa); - bfa_iocfc_disable_submod(iocfc->bfa); -} - -static void -bfa_iocfc_sm_failed(struct bfa_iocfc_s *iocfc, enum iocfc_event event) -{ - bfa_trc(iocfc->bfa, event); - - switch (event) { - case IOCFC_E_STOP: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_write); - break; - case IOCFC_E_DISABLE: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_disabling); - break; - case IOCFC_E_IOC_ENABLED: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_cfg_wait); - break; - case IOCFC_E_IOC_FAILED: - break; - default: - bfa_sm_fault(iocfc->bfa, event); - break; - } -} - -static void -bfa_iocfc_sm_init_failed_entry(struct bfa_iocfc_s *iocfc) -{ - bfa_isr_disable(iocfc->bfa); - iocfc->bfa->iocfc.op_status = BFA_STATUS_FAILED; - bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.init_hcb_qe, - bfa_iocfc_init_cb, iocfc->bfa); -} - -static void -bfa_iocfc_sm_init_failed(struct bfa_iocfc_s *iocfc, enum iocfc_event event) -{ - bfa_trc(iocfc->bfa, event); - - switch (event) { - case IOCFC_E_STOP: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopping); - break; - case IOCFC_E_DISABLE: - bfa_ioc_disable(&iocfc->bfa->ioc); - break; - case IOCFC_E_IOC_ENABLED: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_dconf_read); - break; - case IOCFC_E_IOC_DISABLED: - bfa_fsm_set_state(iocfc, bfa_iocfc_sm_stopped); - iocfc->bfa->iocfc.op_status = BFA_STATUS_OK; - bfa_cb_queue(iocfc->bfa, &iocfc->bfa->iocfc.dis_hcb_qe, - bfa_iocfc_disable_cb, iocfc->bfa); - break; - case IOCFC_E_IOC_FAILED: - break; - default: - bfa_sm_fault(iocfc->bfa, event); - break; - } -} /* * BFA Interrupt handling functions @@ -649,19 +231,16 @@ bfa_reqq_resume(struct bfa_s *bfa, int qid) } } -bfa_boolean_t +static inline void bfa_isr_rspq(struct bfa_s *bfa, int qid) { struct bfi_msg_s *m; u32 pi, ci; struct list_head *waitq; - bfa_boolean_t ret; ci = bfa_rspq_ci(bfa, qid); pi = bfa_rspq_pi(bfa, qid); - ret = (ci != pi); - while (ci != pi) { m = bfa_rspq_elem(bfa, qid, ci); WARN_ON(m->mhdr.msg_class >= BFI_MC_MAX); @@ -681,8 +260,6 @@ bfa_isr_rspq(struct bfa_s *bfa, int qid) waitq = bfa_reqq(bfa, qid); if (!list_empty(waitq)) bfa_reqq_resume(bfa, qid); - - return ret; } static inline void @@ -743,7 +320,6 @@ bfa_intx(struct bfa_s *bfa) { u32 intr, qintr; int queue; - bfa_boolean_t rspq_comp = BFA_FALSE; intr = readl(bfa->iocfc.bfa_regs.intr_status); @@ -756,12 +332,11 @@ bfa_intx(struct bfa_s *bfa) */ if (bfa->queue_process) { for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++) - if (bfa_isr_rspq(bfa, queue)) - rspq_comp = BFA_TRUE; + bfa_isr_rspq(bfa, queue); } if (!intr) - return (qintr | rspq_comp) ? BFA_TRUE : BFA_FALSE; + return BFA_TRUE; /* * CPE completion queue interrupt @@ -950,9 +525,11 @@ bfa_iocfc_send_cfg(void *bfa_arg) * Enable interrupt coalescing if it is driver init path * and not ioc disable/enable path. */ - if (bfa_fsm_cmp_state(iocfc, bfa_iocfc_sm_init_cfg_wait)) + if (!iocfc->cfgdone) cfg_info->intr_attr.coalesce = BFA_TRUE; + iocfc->cfgdone = BFA_FALSE; + /* * dma map IOC configuration itself */ @@ -972,6 +549,8 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, bfa->bfad = bfad; iocfc->bfa = bfa; + iocfc->action = BFA_IOCFC_ACT_NONE; + iocfc->cfg = *cfg; /* @@ -1104,8 +683,6 @@ bfa_iocfc_start_submod(struct bfa_s *bfa) for (i = 0; hal_mods[i]; i++) hal_mods[i]->start(bfa); - - bfa->iocfc.submod_enabled = BFA_TRUE; } /* @@ -1116,13 +693,8 @@ bfa_iocfc_disable_submod(struct bfa_s *bfa) { int i; - if (bfa->iocfc.submod_enabled == BFA_FALSE) - return; - for (i = 0; hal_mods[i]; i++) hal_mods[i]->iocdisable(bfa); - - bfa->iocfc.submod_enabled = BFA_FALSE; } static void @@ -1130,8 +702,15 @@ bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete) { struct bfa_s *bfa = bfa_arg; - if (complete) - bfa_cb_init(bfa->bfad, bfa->iocfc.op_status); + if (complete) { + if (bfa->iocfc.cfgdone && BFA_DCONF_MOD(bfa)->flashdone) + bfa_cb_init(bfa->bfad, BFA_STATUS_OK); + else + bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED); + } else { + if (bfa->iocfc.cfgdone) + bfa->iocfc.action = BFA_IOCFC_ACT_NONE; + } } static void @@ -1142,6 +721,8 @@ bfa_iocfc_stop_cb(void *bfa_arg, bfa_boolean_t compl) if (compl) complete(&bfad->comp); + else + bfa->iocfc.action = BFA_IOCFC_ACT_NONE; } static void @@ -1213,6 +794,8 @@ bfa_iocfc_cfgrsp(struct bfa_s *bfa) fwcfg->num_uf_bufs = be16_to_cpu(fwcfg->num_uf_bufs); fwcfg->num_rports = be16_to_cpu(fwcfg->num_rports); + iocfc->cfgdone = BFA_TRUE; + /* * configure queue register offsets as learnt from firmware */ @@ -1228,13 +811,22 @@ bfa_iocfc_cfgrsp(struct bfa_s *bfa) */ bfa_msix_queue_install(bfa); - if (bfa->iocfc.cfgrsp->pbc_cfg.pbc_pwwn != 0) { - bfa->ioc.attr->pwwn = bfa->iocfc.cfgrsp->pbc_cfg.pbc_pwwn; - bfa->ioc.attr->nwwn = bfa->iocfc.cfgrsp->pbc_cfg.pbc_nwwn; - bfa_fsm_send_event(iocfc, IOCFC_E_CFG_DONE); + /* + * Configuration is complete - initialize/start submodules + */ + bfa_fcport_init(bfa); + + if (iocfc->action == BFA_IOCFC_ACT_INIT) { + if (BFA_DCONF_MOD(bfa)->flashdone == BFA_TRUE) + bfa_cb_queue(bfa, &iocfc->init_hcb_qe, + bfa_iocfc_init_cb, bfa); + } else { + if (bfa->iocfc.action == BFA_IOCFC_ACT_ENABLE) + bfa_cb_queue(bfa, &bfa->iocfc.en_hcb_qe, + bfa_iocfc_enable_cb, bfa); + bfa_iocfc_start_submod(bfa); } } - void bfa_iocfc_reset_queues(struct bfa_s *bfa) { @@ -1248,23 +840,6 @@ bfa_iocfc_reset_queues(struct bfa_s *bfa) } } -/* - * Process FAA pwwn msg from fw. - */ -static void -bfa_iocfc_process_faa_addr(struct bfa_s *bfa, struct bfi_faa_addr_msg_s *msg) -{ - struct bfa_iocfc_s *iocfc = &bfa->iocfc; - struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp; - - cfgrsp->pbc_cfg.pbc_pwwn = msg->pwwn; - cfgrsp->pbc_cfg.pbc_nwwn = msg->nwwn; - - bfa->ioc.attr->pwwn = msg->pwwn; - bfa->ioc.attr->nwwn = msg->nwwn; - bfa_fsm_send_event(iocfc, IOCFC_E_CFG_DONE); -} - /* Fabric Assigned Address specific functions */ /* @@ -1280,12 +855,83 @@ bfa_faa_validate_request(struct bfa_s *bfa) if ((ioc_type != BFA_IOC_TYPE_FC) || bfa_mfg_is_mezz(card_type)) return BFA_STATUS_FEATURE_NOT_SUPPORTED; } else { - return BFA_STATUS_IOC_NON_OP; + if (!bfa_ioc_is_acq_addr(&bfa->ioc)) + return BFA_STATUS_IOC_NON_OP; } return BFA_STATUS_OK; } +bfa_status_t +bfa_faa_enable(struct bfa_s *bfa, bfa_cb_iocfc_t cbfn, void *cbarg) +{ + struct bfi_faa_en_dis_s faa_enable_req; + struct bfa_iocfc_s *iocfc = &bfa->iocfc; + bfa_status_t status; + + iocfc->faa_args.faa_cb.faa_cbfn = cbfn; + iocfc->faa_args.faa_cb.faa_cbarg = cbarg; + + status = bfa_faa_validate_request(bfa); + if (status != BFA_STATUS_OK) + return status; + + if (iocfc->faa_args.busy == BFA_TRUE) + return BFA_STATUS_DEVBUSY; + + if (iocfc->faa_args.faa_state == BFA_FAA_ENABLED) + return BFA_STATUS_FAA_ENABLED; + + if (bfa_fcport_is_trunk_enabled(bfa)) + return BFA_STATUS_ERROR_TRUNK_ENABLED; + + bfa_fcport_cfg_faa(bfa, BFA_FAA_ENABLED); + iocfc->faa_args.busy = BFA_TRUE; + + memset(&faa_enable_req, 0, sizeof(struct bfi_faa_en_dis_s)); + bfi_h2i_set(faa_enable_req.mh, BFI_MC_IOCFC, + BFI_IOCFC_H2I_FAA_ENABLE_REQ, bfa_fn_lpu(bfa)); + + bfa_ioc_mbox_send(&bfa->ioc, &faa_enable_req, + sizeof(struct bfi_faa_en_dis_s)); + + return BFA_STATUS_OK; +} + +bfa_status_t +bfa_faa_disable(struct bfa_s *bfa, bfa_cb_iocfc_t cbfn, + void *cbarg) +{ + struct bfi_faa_en_dis_s faa_disable_req; + struct bfa_iocfc_s *iocfc = &bfa->iocfc; + bfa_status_t status; + + iocfc->faa_args.faa_cb.faa_cbfn = cbfn; + iocfc->faa_args.faa_cb.faa_cbarg = cbarg; + + status = bfa_faa_validate_request(bfa); + if (status != BFA_STATUS_OK) + return status; + + if (iocfc->faa_args.busy == BFA_TRUE) + return BFA_STATUS_DEVBUSY; + + if (iocfc->faa_args.faa_state == BFA_FAA_DISABLED) + return BFA_STATUS_FAA_DISABLED; + + bfa_fcport_cfg_faa(bfa, BFA_FAA_DISABLED); + iocfc->faa_args.busy = BFA_TRUE; + + memset(&faa_disable_req, 0, sizeof(struct bfi_faa_en_dis_s)); + bfi_h2i_set(faa_disable_req.mh, BFI_MC_IOCFC, + BFI_IOCFC_H2I_FAA_DISABLE_REQ, bfa_fn_lpu(bfa)); + + bfa_ioc_mbox_send(&bfa->ioc, &faa_disable_req, + sizeof(struct bfi_faa_en_dis_s)); + + return BFA_STATUS_OK; +} + bfa_status_t bfa_faa_query(struct bfa_s *bfa, struct bfa_faa_attr_s *attr, bfa_cb_iocfc_t cbfn, void *cbarg) @@ -1316,6 +962,38 @@ bfa_faa_query(struct bfa_s *bfa, struct bfa_faa_attr_s *attr, return BFA_STATUS_OK; } +/* + * FAA enable response + */ +static void +bfa_faa_enable_reply(struct bfa_iocfc_s *iocfc, + struct bfi_faa_en_dis_rsp_s *rsp) +{ + void *cbarg = iocfc->faa_args.faa_cb.faa_cbarg; + bfa_status_t status = rsp->status; + + WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn); + + iocfc->faa_args.faa_cb.faa_cbfn(cbarg, status); + iocfc->faa_args.busy = BFA_FALSE; +} + +/* + * FAA disable response + */ +static void +bfa_faa_disable_reply(struct bfa_iocfc_s *iocfc, + struct bfi_faa_en_dis_rsp_s *rsp) +{ + void *cbarg = iocfc->faa_args.faa_cb.faa_cbarg; + bfa_status_t status = rsp->status; + + WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn); + + iocfc->faa_args.faa_cb.faa_cbfn(cbarg, status); + iocfc->faa_args.busy = BFA_FALSE; +} + /* * FAA query response */ @@ -1345,10 +1023,25 @@ bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status) { struct bfa_s *bfa = bfa_arg; - if (status == BFA_STATUS_OK) - bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_IOC_ENABLED); - else - bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_IOC_FAILED); + if (status == BFA_STATUS_FAA_ACQ_ADDR) { + bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe, + bfa_iocfc_init_cb, bfa); + return; + } + + if (status != BFA_STATUS_OK) { + bfa_isr_disable(bfa); + if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT) + bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe, + bfa_iocfc_init_cb, bfa); + else if (bfa->iocfc.action == BFA_IOCFC_ACT_ENABLE) + bfa_cb_queue(bfa, &bfa->iocfc.en_hcb_qe, + bfa_iocfc_enable_cb, bfa); + return; + } + + bfa_iocfc_send_cfg(bfa); + bfa_dconf_modinit(bfa); } /* @@ -1359,7 +1052,17 @@ bfa_iocfc_disable_cbfn(void *bfa_arg) { struct bfa_s *bfa = bfa_arg; - bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_IOC_DISABLED); + bfa_isr_disable(bfa); + bfa_iocfc_disable_submod(bfa); + + if (bfa->iocfc.action == BFA_IOCFC_ACT_STOP) + bfa_cb_queue(bfa, &bfa->iocfc.stop_hcb_qe, bfa_iocfc_stop_cb, + bfa); + else { + WARN_ON(bfa->iocfc.action != BFA_IOCFC_ACT_DISABLE); + bfa_cb_queue(bfa, &bfa->iocfc.dis_hcb_qe, bfa_iocfc_disable_cb, + bfa); + } } /* @@ -1371,7 +1074,13 @@ bfa_iocfc_hbfail_cbfn(void *bfa_arg) struct bfa_s *bfa = bfa_arg; bfa->queue_process = BFA_FALSE; - bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_IOC_FAILED); + + bfa_isr_disable(bfa); + bfa_iocfc_disable_submod(bfa); + + if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT) + bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe, bfa_iocfc_init_cb, + bfa); } /* @@ -1386,6 +1095,7 @@ bfa_iocfc_reset_cbfn(void *bfa_arg) bfa_isr_enable(bfa); } + /* * Query IOC memory requirement information. */ @@ -1461,12 +1171,6 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, INIT_LIST_HEAD(&bfa->comp_q); for (i = 0; i < BFI_IOC_MAX_CQS; i++) INIT_LIST_HEAD(&bfa->reqq_waitq[i]); - - bfa->iocfc.cb_reqd = BFA_FALSE; - bfa->iocfc.op_status = BFA_STATUS_OK; - bfa->iocfc.submod_enabled = BFA_FALSE; - - bfa_fsm_set_state(&bfa->iocfc, bfa_iocfc_sm_stopped); } /* @@ -1475,7 +1179,8 @@ bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, void bfa_iocfc_init(struct bfa_s *bfa) { - bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_INIT); + bfa->iocfc.action = BFA_IOCFC_ACT_INIT; + bfa_ioc_enable(&bfa->ioc); } /* @@ -1485,7 +1190,8 @@ bfa_iocfc_init(struct bfa_s *bfa) void bfa_iocfc_start(struct bfa_s *bfa) { - bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_START); + if (bfa->iocfc.cfgdone) + bfa_iocfc_start_submod(bfa); } /* @@ -1495,8 +1201,12 @@ bfa_iocfc_start(struct bfa_s *bfa) void bfa_iocfc_stop(struct bfa_s *bfa) { + bfa->iocfc.action = BFA_IOCFC_ACT_STOP; + bfa->queue_process = BFA_FALSE; - bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_STOP); + bfa_dconf_modexit(bfa); + if (BFA_DCONF_MOD(bfa)->flashdone == BFA_TRUE) + bfa_ioc_disable(&bfa->ioc); } void @@ -1516,9 +1226,13 @@ bfa_iocfc_isr(void *bfaarg, struct bfi_mbmsg_s *m) case BFI_IOCFC_I2H_UPDATEQ_RSP: iocfc->updateq_cbfn(iocfc->updateq_cbarg, BFA_STATUS_OK); break; - case BFI_IOCFC_I2H_ADDR_MSG: - bfa_iocfc_process_faa_addr(bfa, - (struct bfi_faa_addr_msg_s *)msg); + case BFI_IOCFC_I2H_FAA_ENABLE_RSP: + bfa_faa_enable_reply(iocfc, + (struct bfi_faa_en_dis_rsp_s *)msg); + break; + case BFI_IOCFC_I2H_FAA_DISABLE_RSP: + bfa_faa_disable_reply(iocfc, + (struct bfi_faa_en_dis_rsp_s *)msg); break; case BFI_IOCFC_I2H_FAA_QUERY_RSP: bfa_faa_query_reply(iocfc, (bfi_faa_query_rsp_t *)msg); @@ -1592,8 +1306,8 @@ bfa_iocfc_enable(struct bfa_s *bfa) { bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0, "IOC Enable"); - bfa->iocfc.cb_reqd = BFA_TRUE; - bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_ENABLE); + bfa->iocfc.action = BFA_IOCFC_ACT_ENABLE; + bfa_ioc_enable(&bfa->ioc); } void @@ -1601,16 +1315,17 @@ bfa_iocfc_disable(struct bfa_s *bfa) { bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0, "IOC Disable"); + bfa->iocfc.action = BFA_IOCFC_ACT_DISABLE; bfa->queue_process = BFA_FALSE; - bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_DISABLE); + bfa_ioc_disable(&bfa->ioc); } + bfa_boolean_t bfa_iocfc_is_operational(struct bfa_s *bfa) { - return bfa_ioc_is_operational(&bfa->ioc) && - bfa_fsm_cmp_state(&bfa->iocfc, bfa_iocfc_sm_operational); + return bfa_ioc_is_operational(&bfa->ioc) && bfa->iocfc.cfgdone; } /* @@ -1852,6 +1567,16 @@ bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q) } } +void +bfa_iocfc_cb_dconf_modinit(struct bfa_s *bfa, bfa_status_t status) +{ + if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT) { + if (bfa->iocfc.cfgdone == BFA_TRUE) + bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe, + bfa_iocfc_init_cb, bfa); + } +} + /* * Return the list of PCI vendor/device id lists supported by this * BFA instance. diff --git a/trunk/drivers/scsi/bfa/bfa_defs_svc.h b/trunk/drivers/scsi/bfa/bfa_defs_svc.h index 36756ce0e58f..cb07c628b2f1 100644 --- a/trunk/drivers/scsi/bfa/bfa_defs_svc.h +++ b/trunk/drivers/scsi/bfa/bfa_defs_svc.h @@ -52,7 +52,7 @@ struct bfa_iocfc_fwcfg_s { u16 num_uf_bufs; /* unsolicited recv buffers */ u8 num_cqs; u8 fw_tick_res; /* FW clock resolution in ms */ - u8 rsvd[6]; + u8 rsvd[2]; }; #pragma pack() diff --git a/trunk/drivers/scsi/bfa/bfa_fcs_lport.c b/trunk/drivers/scsi/bfa/bfa_fcs_lport.c index 5d2a1307e5ce..d4f951fe753e 100644 --- a/trunk/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/trunk/drivers/scsi/bfa/bfa_fcs_lport.c @@ -5717,8 +5717,6 @@ bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport) if (vport_drv->comp_del) complete(vport_drv->comp_del); - else - kfree(vport_drv); bfa_lps_delete(vport->lps); } diff --git a/trunk/drivers/scsi/bfa/bfa_fcs_rport.c b/trunk/drivers/scsi/bfa/bfa_fcs_rport.c index fe0463a1db04..52628d5d3c9b 100644 --- a/trunk/drivers/scsi/bfa/bfa_fcs_rport.c +++ b/trunk/drivers/scsi/bfa/bfa_fcs_rport.c @@ -2169,10 +2169,7 @@ bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi) * - MAX receive frame size */ rport->cisc = plogi->csp.cisc; - if (be16_to_cpu(plogi->class3.rxsz) < be16_to_cpu(plogi->csp.rxsz)) - rport->maxfrsize = be16_to_cpu(plogi->class3.rxsz); - else - rport->maxfrsize = be16_to_cpu(plogi->csp.rxsz); + rport->maxfrsize = be16_to_cpu(plogi->class3.rxsz); bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred)); bfa_trc(port->fcs, port->fabric->bb_credit); diff --git a/trunk/drivers/scsi/bfa/bfa_ioc.c b/trunk/drivers/scsi/bfa/bfa_ioc.c index 14e6284e48e4..eca7ab78085b 100644 --- a/trunk/drivers/scsi/bfa/bfa_ioc.c +++ b/trunk/drivers/scsi/bfa/bfa_ioc.c @@ -88,6 +88,7 @@ static void bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc); static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc); static void bfa_ioc_mbox_flush(struct bfa_ioc_s *ioc); static void bfa_ioc_recover(struct bfa_ioc_s *ioc); +static void bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc); static void bfa_ioc_event_notify(struct bfa_ioc_s *ioc , enum bfa_ioc_event_e event); static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc); @@ -96,6 +97,7 @@ static void bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc); static void bfa_ioc_fail_notify(struct bfa_ioc_s *ioc); static void bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc); + /* * IOC state machine definitions/declarations */ @@ -112,6 +114,7 @@ enum ioc_event { IOC_E_HWERROR = 10, /* hardware error interrupt */ IOC_E_TIMEOUT = 11, /* timeout */ IOC_E_HWFAILED = 12, /* PCI mapping failure notice */ + IOC_E_FWRSP_ACQ_ADDR = 13, /* Acquiring address */ }; bfa_fsm_state_decl(bfa_ioc, uninit, struct bfa_ioc_s, enum ioc_event); @@ -124,6 +127,7 @@ bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc_s, enum ioc_event); bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event); bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event); bfa_fsm_state_decl(bfa_ioc, hwfail, struct bfa_ioc_s, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, acq_addr, struct bfa_ioc_s, enum ioc_event); static struct bfa_sm_table_s ioc_sm_table[] = { {BFA_SM(bfa_ioc_sm_uninit), BFA_IOC_UNINIT}, @@ -136,6 +140,7 @@ static struct bfa_sm_table_s ioc_sm_table[] = { {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING}, {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED}, {BFA_SM(bfa_ioc_sm_hwfail), BFA_IOC_HWFAIL}, + {BFA_SM(bfa_ioc_sm_acq_addr), BFA_IOC_ACQ_ADDR}, }; /* @@ -366,9 +371,17 @@ bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event) switch (event) { case IOC_E_FWRSP_GETATTR: bfa_ioc_timer_stop(ioc); + bfa_ioc_check_attr_wwns(ioc); + bfa_ioc_hb_monitor(ioc); bfa_fsm_set_state(ioc, bfa_ioc_sm_op); break; + case IOC_E_FWRSP_ACQ_ADDR: + bfa_ioc_timer_stop(ioc); + bfa_ioc_hb_monitor(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_acq_addr); + break; + case IOC_E_PFFAILED: case IOC_E_HWERROR: bfa_ioc_timer_stop(ioc); @@ -393,6 +406,51 @@ bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event) } } +/* + * Acquiring address from fabric (entry function) + */ +static void +bfa_ioc_sm_acq_addr_entry(struct bfa_ioc_s *ioc) +{ +} + +/* + * Acquiring address from the fabric + */ +static void +bfa_ioc_sm_acq_addr(struct bfa_ioc_s *ioc, enum ioc_event event) +{ + bfa_trc(ioc, event); + + switch (event) { + case IOC_E_FWRSP_GETATTR: + bfa_ioc_check_attr_wwns(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_op); + break; + + case IOC_E_PFFAILED: + case IOC_E_HWERROR: + bfa_hb_timer_stop(ioc); + case IOC_E_HBFAIL: + ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); + bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); + if (event != IOC_E_PFFAILED) + bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL); + break; + + case IOC_E_DISABLE: + bfa_hb_timer_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); + break; + + case IOC_E_ENABLE: + break; + + default: + bfa_sm_fault(ioc, event); + } +} + static void bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc) { @@ -400,7 +458,6 @@ bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc) ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK); bfa_ioc_event_notify(ioc, BFA_IOC_E_ENABLED); - bfa_ioc_hb_monitor(ioc); BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n"); bfa_ioc_aen_post(ioc, BFA_IOC_AEN_ENABLE); } @@ -681,60 +738,26 @@ static void bfa_iocpf_sm_fwcheck_entry(struct bfa_iocpf_s *iocpf) { struct bfi_ioc_image_hdr_s fwhdr; - u32 r32, fwstate, pgnum, pgoff, loff = 0; - int i; - - /* - * Spin on init semaphore to serialize. - */ - r32 = readl(iocpf->ioc->ioc_regs.ioc_init_sem_reg); - while (r32 & 0x1) { - udelay(20); - r32 = readl(iocpf->ioc->ioc_regs.ioc_init_sem_reg); - } + u32 fwstate = readl(iocpf->ioc->ioc_regs.ioc_fwstate); /* h/w sem init */ - fwstate = readl(iocpf->ioc->ioc_regs.ioc_fwstate); - if (fwstate == BFI_IOC_UNINIT) { - writel(1, iocpf->ioc->ioc_regs.ioc_init_sem_reg); + if (fwstate == BFI_IOC_UNINIT) goto sem_get; - } bfa_ioc_fwver_get(iocpf->ioc, &fwhdr); - if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL) { - writel(1, iocpf->ioc->ioc_regs.ioc_init_sem_reg); + if (swab32(fwhdr.exec) == BFI_FWBOOT_TYPE_NORMAL) goto sem_get; - } - - /* - * Clear fwver hdr - */ - pgnum = PSS_SMEM_PGNUM(iocpf->ioc->ioc_regs.smem_pg0, loff); - pgoff = PSS_SMEM_PGOFF(loff); - writel(pgnum, iocpf->ioc->ioc_regs.host_page_num_fn); - - for (i = 0; i < sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32); i++) { - bfa_mem_write(iocpf->ioc->ioc_regs.smem_page_start, loff, 0); - loff += sizeof(u32); - } bfa_trc(iocpf->ioc, fwstate); - bfa_trc(iocpf->ioc, swab32(fwhdr.exec)); + bfa_trc(iocpf->ioc, fwhdr.exec); writel(BFI_IOC_UNINIT, iocpf->ioc->ioc_regs.ioc_fwstate); - writel(BFI_IOC_UNINIT, iocpf->ioc->ioc_regs.alt_ioc_fwstate); /* - * Unlock the hw semaphore. Should be here only once per boot. + * Try to lock and then unlock the semaphore. */ readl(iocpf->ioc->ioc_regs.ioc_sem_reg); writel(1, iocpf->ioc->ioc_regs.ioc_sem_reg); - - /* - * unlock init semaphore. - */ - writel(1, iocpf->ioc->ioc_regs.ioc_init_sem_reg); - sem_get: bfa_ioc_hw_sem_get(iocpf->ioc); } @@ -1684,6 +1707,11 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type, u32 i; u32 asicmode; + /* + * Initialize LMEM first before code download + */ + bfa_ioc_lmem_init(ioc); + bfa_trc(ioc, bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc))); fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), chunkno); @@ -1971,12 +1999,6 @@ bfa_ioc_pll_init(struct bfa_ioc_s *ioc) bfa_ioc_pll_init_asic(ioc); ioc->pllinit = BFA_TRUE; - - /* - * Initialize LMEM - */ - bfa_ioc_lmem_init(ioc); - /* * release semaphore. */ @@ -2100,6 +2122,10 @@ bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m) bfa_ioc_getattr_reply(ioc); break; + case BFI_IOC_I2H_ACQ_ADDR_REPLY: + bfa_fsm_send_event(ioc, IOC_E_FWRSP_ACQ_ADDR); + break; + default: bfa_trc(ioc, msg->mh.msg_id); WARN_ON(1); @@ -2389,6 +2415,15 @@ bfa_ioc_is_disabled(struct bfa_ioc_s *ioc) bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled); } +/* + * Return TRUE if IOC is in acquiring address state + */ +bfa_boolean_t +bfa_ioc_is_acq_addr(struct bfa_ioc_s *ioc) +{ + return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_acq_addr); +} + /* * return true if IOC firmware is different. */ @@ -2881,6 +2916,17 @@ bfa_ioc_recover(struct bfa_ioc_s *ioc) bfa_fsm_send_event(ioc, IOC_E_HBFAIL); } +static void +bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc) +{ + if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL) + return; + if (ioc->attr->nwwn == 0) + bfa_ioc_aen_post(ioc, BFA_IOC_AEN_INVALID_NWWN); + if (ioc->attr->pwwn == 0) + bfa_ioc_aen_post(ioc, BFA_IOC_AEN_INVALID_PWWN); +} + /* * BFA IOC PF private functions */ @@ -4449,7 +4495,7 @@ bfa_flash_read_part(struct bfa_flash_s *flash, enum bfa_flash_part_type type, */ #define BFA_DIAG_MEMTEST_TOV 50000 /* memtest timeout in msec */ -#define CT2_BFA_DIAG_MEMTEST_TOV (9*30*1000) /* 4.5 min */ +#define BFA_DIAG_FWPING_TOV 1000 /* msec */ /* IOC event handler */ static void @@ -4726,7 +4772,7 @@ diag_ledtest_send(struct bfa_diag_s *diag, struct bfa_diag_ledtest_s *ledtest) } static void -diag_ledtest_comp(struct bfa_diag_s *diag, struct bfi_diag_ledtest_rsp_s *msg) +diag_ledtest_comp(struct bfa_diag_s *diag, struct bfi_diag_ledtest_rsp_s * msg) { bfa_trc(diag, diag->ledtest.lock); diag->ledtest.lock = BFA_FALSE; @@ -4804,8 +4850,6 @@ bfa_diag_memtest(struct bfa_diag_s *diag, struct bfa_diag_memtest_s *memtest, u32 pattern, struct bfa_diag_memtest_result *result, bfa_cb_diag_t cbfn, void *cbarg) { - u32 memtest_tov; - bfa_trc(diag, pattern); if (!bfa_ioc_adapter_is_disabled(diag->ioc)) @@ -4825,10 +4869,8 @@ bfa_diag_memtest(struct bfa_diag_s *diag, struct bfa_diag_memtest_s *memtest, /* download memtest code and take LPU0 out of reset */ bfa_ioc_boot(diag->ioc, BFI_FWBOOT_TYPE_MEMTEST, BFI_FWBOOT_ENV_OS); - memtest_tov = (bfa_ioc_asic_gen(diag->ioc) == BFI_ASIC_GEN_CT2) ? - CT2_BFA_DIAG_MEMTEST_TOV : BFA_DIAG_MEMTEST_TOV; bfa_timer_begin(diag->ioc->timer_mod, &diag->timer, - bfa_diag_memtest_done, diag, memtest_tov); + bfa_diag_memtest_done, diag, BFA_DIAG_MEMTEST_TOV); diag->timer_active = 1; return BFA_STATUS_OK; } @@ -5599,27 +5641,24 @@ bfa_dconf_sm_uninit(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event) case BFA_DCONF_SM_INIT: if (dconf->min_cfg) { bfa_trc(dconf->bfa, dconf->min_cfg); - bfa_fsm_send_event(&dconf->bfa->iocfc, - IOCFC_E_DCONF_DONE); return; } bfa_sm_set_state(dconf, bfa_dconf_sm_flash_read); - bfa_timer_start(dconf->bfa, &dconf->timer, - bfa_dconf_timer, dconf, BFA_DCONF_UPDATE_TOV); + dconf->flashdone = BFA_FALSE; + bfa_trc(dconf->bfa, dconf->flashdone); bfa_status = bfa_flash_read_part(BFA_FLASH(dconf->bfa), BFA_FLASH_PART_DRV, dconf->instance, dconf->dconf, sizeof(struct bfa_dconf_s), 0, bfa_dconf_init_cb, dconf->bfa); if (bfa_status != BFA_STATUS_OK) { - bfa_timer_stop(&dconf->timer); bfa_dconf_init_cb(dconf->bfa, BFA_STATUS_FAILED); bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); return; } break; case BFA_DCONF_SM_EXIT: - bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE); + dconf->flashdone = BFA_TRUE; case BFA_DCONF_SM_IOCDISABLE: case BFA_DCONF_SM_WR: case BFA_DCONF_SM_FLASH_COMP: @@ -5640,20 +5679,15 @@ bfa_dconf_sm_flash_read(struct bfa_dconf_mod_s *dconf, switch (event) { case BFA_DCONF_SM_FLASH_COMP: - bfa_timer_stop(&dconf->timer); bfa_sm_set_state(dconf, bfa_dconf_sm_ready); break; case BFA_DCONF_SM_TIMEOUT: bfa_sm_set_state(dconf, bfa_dconf_sm_ready); - bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_IOC_FAILED); break; case BFA_DCONF_SM_EXIT: - bfa_timer_stop(&dconf->timer); - bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); - bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE); - break; + dconf->flashdone = BFA_TRUE; + bfa_trc(dconf->bfa, dconf->flashdone); case BFA_DCONF_SM_IOCDISABLE: - bfa_timer_stop(&dconf->timer); bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); break; default: @@ -5676,8 +5710,9 @@ bfa_dconf_sm_ready(struct bfa_dconf_mod_s *dconf, enum bfa_dconf_event event) bfa_sm_set_state(dconf, bfa_dconf_sm_dirty); break; case BFA_DCONF_SM_EXIT: + dconf->flashdone = BFA_TRUE; + bfa_trc(dconf->bfa, dconf->flashdone); bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); - bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE); break; case BFA_DCONF_SM_INIT: case BFA_DCONF_SM_IOCDISABLE: @@ -5739,7 +5774,9 @@ bfa_dconf_sm_final_sync(struct bfa_dconf_mod_s *dconf, bfa_timer_stop(&dconf->timer); case BFA_DCONF_SM_TIMEOUT: bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); - bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE); + dconf->flashdone = BFA_TRUE; + bfa_trc(dconf->bfa, dconf->flashdone); + bfa_ioc_disable(&dconf->bfa->ioc); break; default: bfa_sm_fault(dconf->bfa, event); @@ -5786,8 +5823,8 @@ bfa_dconf_sm_iocdown_dirty(struct bfa_dconf_mod_s *dconf, bfa_sm_set_state(dconf, bfa_dconf_sm_dirty); break; case BFA_DCONF_SM_EXIT: + dconf->flashdone = BFA_TRUE; bfa_sm_set_state(dconf, bfa_dconf_sm_uninit); - bfa_fsm_send_event(&dconf->bfa->iocfc, IOCFC_E_DCONF_DONE); break; case BFA_DCONF_SM_IOCDISABLE: break; @@ -5828,6 +5865,11 @@ bfa_dconf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, if (cfg->drvcfg.min_cfg) { bfa_mem_kva_curp(dconf) += sizeof(struct bfa_dconf_hdr_s); dconf->min_cfg = BFA_TRUE; + /* + * Set the flashdone flag to TRUE explicitly as no flash + * write will happen in min_cfg mode. + */ + dconf->flashdone = BFA_TRUE; } else { dconf->min_cfg = BFA_FALSE; bfa_mem_kva_curp(dconf) += sizeof(struct bfa_dconf_s); @@ -5843,7 +5885,9 @@ bfa_dconf_init_cb(void *arg, bfa_status_t status) struct bfa_s *bfa = arg; struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); - bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP); + dconf->flashdone = BFA_TRUE; + bfa_trc(bfa, dconf->flashdone); + bfa_iocfc_cb_dconf_modinit(bfa, status); if (status == BFA_STATUS_OK) { bfa_dconf_read_data_valid(bfa) = BFA_TRUE; if (dconf->dconf->hdr.signature != BFI_DCONF_SIGNATURE) @@ -5851,7 +5895,7 @@ bfa_dconf_init_cb(void *arg, bfa_status_t status) if (dconf->dconf->hdr.version != BFI_DCONF_VERSION) dconf->dconf->hdr.version = BFI_DCONF_VERSION; } - bfa_fsm_send_event(&bfa->iocfc, IOCFC_E_DCONF_DONE); + bfa_sm_send_event(dconf, BFA_DCONF_SM_FLASH_COMP); } void @@ -5933,5 +5977,7 @@ void bfa_dconf_modexit(struct bfa_s *bfa) { struct bfa_dconf_mod_s *dconf = BFA_DCONF_MOD(bfa); + BFA_DCONF_MOD(bfa)->flashdone = BFA_FALSE; + bfa_trc(bfa, BFA_DCONF_MOD(bfa)->flashdone); bfa_sm_send_event(dconf, BFA_DCONF_SM_EXIT); } diff --git a/trunk/drivers/scsi/bfa/bfa_ioc.h b/trunk/drivers/scsi/bfa/bfa_ioc.h index 1a99d4b5b50f..546d46b37101 100644 --- a/trunk/drivers/scsi/bfa/bfa_ioc.h +++ b/trunk/drivers/scsi/bfa/bfa_ioc.h @@ -372,22 +372,6 @@ struct bfa_cb_qe_s { void *cbarg; }; -/* - * IOCFC state machine definitions/declarations - */ -enum iocfc_event { - IOCFC_E_INIT = 1, /* IOCFC init request */ - IOCFC_E_START = 2, /* IOCFC mod start request */ - IOCFC_E_STOP = 3, /* IOCFC stop request */ - IOCFC_E_ENABLE = 4, /* IOCFC enable request */ - IOCFC_E_DISABLE = 5, /* IOCFC disable request */ - IOCFC_E_IOC_ENABLED = 6, /* IOC enabled message */ - IOCFC_E_IOC_DISABLED = 7, /* IOC disabled message */ - IOCFC_E_IOC_FAILED = 8, /* failure notice by IOC sm */ - IOCFC_E_DCONF_DONE = 9, /* dconf read/write done */ - IOCFC_E_CFG_DONE = 10, /* IOCFC config complete */ -}; - /* * ASIC block configurtion related */ @@ -722,6 +706,7 @@ struct bfa_dconf_s { struct bfa_dconf_mod_s { bfa_sm_t sm; u8 instance; + bfa_boolean_t flashdone; bfa_boolean_t read_data_valid; bfa_boolean_t min_cfg; struct bfa_timer_s timer; diff --git a/trunk/drivers/scsi/bfa/bfa_ioc_ct.c b/trunk/drivers/scsi/bfa/bfa_ioc_ct.c index 2eb0c6a2938d..d1b8f0caaa79 100644 --- a/trunk/drivers/scsi/bfa/bfa_ioc_ct.c +++ b/trunk/drivers/scsi/bfa/bfa_ioc_ct.c @@ -786,73 +786,17 @@ bfa_ioc_ct2_mac_reset(void __iomem *rb) } #define CT2_NFC_MAX_DELAY 1000 -#define CT2_NFC_VER_VALID 0x143 -#define BFA_IOC_PLL_POLL 1000000 - -static bfa_boolean_t -bfa_ioc_ct2_nfc_halted(void __iomem *rb) -{ - u32 r32; - - r32 = readl(rb + CT2_NFC_CSR_SET_REG); - if (r32 & __NFC_CONTROLLER_HALTED) - return BFA_TRUE; - - return BFA_FALSE; -} - -static void -bfa_ioc_ct2_nfc_resume(void __iomem *rb) -{ - u32 r32; - int i; - - writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_CLR_REG); - for (i = 0; i < CT2_NFC_MAX_DELAY; i++) { - r32 = readl(rb + CT2_NFC_CSR_SET_REG); - if (!(r32 & __NFC_CONTROLLER_HALTED)) - return; - udelay(1000); - } - WARN_ON(1); -} - bfa_status_t bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode) { - u32 wgn, r32, nfc_ver, i; + u32 wgn, r32; + int i; + /* + * Initialize PLL if not already done by NFC + */ wgn = readl(rb + CT2_WGN_STATUS); - nfc_ver = readl(rb + CT2_RSC_GPR15_REG); - - if ((wgn == (__A2T_AHB_LOAD | __WGN_READY)) && - (nfc_ver >= CT2_NFC_VER_VALID)) { - if (bfa_ioc_ct2_nfc_halted(rb)) - bfa_ioc_ct2_nfc_resume(rb); - - writel(__RESET_AND_START_SCLK_LCLK_PLLS, - rb + CT2_CSI_FW_CTL_SET_REG); - - for (i = 0; i < BFA_IOC_PLL_POLL; i++) { - r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG); - if (r32 & __RESET_AND_START_SCLK_LCLK_PLLS) - break; - } - - WARN_ON(!(r32 & __RESET_AND_START_SCLK_LCLK_PLLS)); - - for (i = 0; i < BFA_IOC_PLL_POLL; i++) { - r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG); - if (!(r32 & __RESET_AND_START_SCLK_LCLK_PLLS)) - break; - } - - WARN_ON(r32 & __RESET_AND_START_SCLK_LCLK_PLLS); - udelay(1000); - - r32 = readl(rb + CT2_CSI_FW_CTL_REG); - WARN_ON(r32 & __RESET_AND_START_SCLK_LCLK_PLLS); - } else { + if (!(wgn & __GLBL_PF_VF_CFG_RDY)) { writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_SET_REG); for (i = 0; i < CT2_NFC_MAX_DELAY; i++) { r32 = readl(rb + CT2_NFC_CSR_SET_REG); @@ -860,34 +804,6 @@ bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode) break; udelay(1000); } - - bfa_ioc_ct2_mac_reset(rb); - bfa_ioc_ct2_sclk_init(rb); - bfa_ioc_ct2_lclk_init(rb); - - /* - * release soft reset on s_clk & l_clk - */ - r32 = readl(rb + CT2_APP_PLL_SCLK_CTL_REG); - writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET, - (rb + CT2_APP_PLL_SCLK_CTL_REG)); - - /* - * release soft reset on s_clk & l_clk - */ - r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG); - writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET, - (rb + CT2_APP_PLL_LCLK_CTL_REG)); - } - - /* - * Announce flash device presence, if flash was corrupted. - */ - if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) { - r32 = readl(rb + PSS_GPIO_OUT_REG); - writel(r32 & ~1, (rb + PSS_GPIO_OUT_REG)); - r32 = readl(rb + PSS_GPIO_OE_REG); - writel(r32 | 1, (rb + PSS_GPIO_OE_REG)); } /* @@ -897,25 +813,48 @@ bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode) writel(1, (rb + CT2_LPU0_HOSTFN_MBOX0_MSK)); writel(1, (rb + CT2_LPU1_HOSTFN_MBOX0_MSK)); - /* For first time initialization, no need to clear interrupts */ - r32 = readl(rb + HOST_SEM5_REG); - if (r32 & 0x1) { - r32 = readl(rb + CT2_LPU0_HOSTFN_CMD_STAT); - if (r32 == 1) { - writel(1, rb + CT2_LPU0_HOSTFN_CMD_STAT); - readl((rb + CT2_LPU0_HOSTFN_CMD_STAT)); - } - r32 = readl(rb + CT2_LPU1_HOSTFN_CMD_STAT); - if (r32 == 1) { - writel(1, rb + CT2_LPU1_HOSTFN_CMD_STAT); - readl(rb + CT2_LPU1_HOSTFN_CMD_STAT); - } + r32 = readl((rb + CT2_LPU0_HOSTFN_CMD_STAT)); + if (r32 == 1) { + writel(1, (rb + CT2_LPU0_HOSTFN_CMD_STAT)); + readl((rb + CT2_LPU0_HOSTFN_CMD_STAT)); + } + r32 = readl((rb + CT2_LPU1_HOSTFN_CMD_STAT)); + if (r32 == 1) { + writel(1, (rb + CT2_LPU1_HOSTFN_CMD_STAT)); + readl((rb + CT2_LPU1_HOSTFN_CMD_STAT)); } - bfa_ioc_ct2_mem_init(rb); + bfa_ioc_ct2_mac_reset(rb); + bfa_ioc_ct2_sclk_init(rb); + bfa_ioc_ct2_lclk_init(rb); - writel(BFI_IOC_UNINIT, rb + CT2_BFA_IOC0_STATE_REG); - writel(BFI_IOC_UNINIT, rb + CT2_BFA_IOC1_STATE_REG); + /* + * release soft reset on s_clk & l_clk + */ + r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); + writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET, + (rb + CT2_APP_PLL_SCLK_CTL_REG)); + + /* + * release soft reset on s_clk & l_clk + */ + r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); + writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET, + (rb + CT2_APP_PLL_LCLK_CTL_REG)); + + /* + * Announce flash device presence, if flash was corrupted. + */ + if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) { + r32 = readl((rb + PSS_GPIO_OUT_REG)); + writel(r32 & ~1, (rb + PSS_GPIO_OUT_REG)); + r32 = readl((rb + PSS_GPIO_OE_REG)); + writel(r32 | 1, (rb + PSS_GPIO_OE_REG)); + } + + bfa_ioc_ct2_mem_init(rb); + writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC0_STATE_REG)); + writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC1_STATE_REG)); return BFA_STATUS_OK; } diff --git a/trunk/drivers/scsi/bfa/bfa_svc.c b/trunk/drivers/scsi/bfa/bfa_svc.c index 2e856e6710f7..aa8a0eaf91f9 100644 --- a/trunk/drivers/scsi/bfa/bfa_svc.c +++ b/trunk/drivers/scsi/bfa/bfa_svc.c @@ -1280,7 +1280,6 @@ bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event) switch (event) { case BFA_LPS_SM_RESUME: bfa_sm_set_state(lps, bfa_lps_sm_login); - bfa_lps_send_login(lps); break; case BFA_LPS_SM_OFFLINE: @@ -1579,7 +1578,7 @@ bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp) break; case BFA_STATUS_VPORT_MAX: - if (rsp->ext_status) + if (!rsp->ext_status) bfa_lps_no_res(lps, rsp->ext_status); break; @@ -3084,6 +3083,33 @@ bfa_fcport_set_wwns(struct bfa_fcport_s *fcport) bfa_trc(fcport->bfa, fcport->nwwn); } +static void +bfa_fcport_send_txcredit(void *port_cbarg) +{ + + struct bfa_fcport_s *fcport = port_cbarg; + struct bfi_fcport_set_svc_params_req_s *m; + + /* + * check for room in queue to send request now + */ + m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT); + if (!m) { + bfa_trc(fcport->bfa, fcport->cfg.tx_bbcredit); + return; + } + + bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ, + bfa_fn_lpu(fcport->bfa)); + m->tx_bbcredit = cpu_to_be16((u16)fcport->cfg.tx_bbcredit); + m->bb_scn = fcport->cfg.bb_scn; + + /* + * queue I/O message to firmware + */ + bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, m->mh); +} + static void bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d, struct bfa_qos_stats_s *s) @@ -3576,24 +3602,26 @@ bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_port_speed speed) return BFA_STATUS_UNSUPP_SPEED; } - /* Port speed entered needs to be checked */ - if (bfa_ioc_get_type(&fcport->bfa->ioc) == BFA_IOC_TYPE_FC) { - /* For CT2, 1G is not supported */ - if ((speed == BFA_PORT_SPEED_1GBPS) && - (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id))) - return BFA_STATUS_UNSUPP_SPEED; + /* For Mezz card, port speed entered needs to be checked */ + if (bfa_mfg_is_mezz(fcport->bfa->ioc.attr->card_type)) { + if (bfa_ioc_get_type(&fcport->bfa->ioc) == BFA_IOC_TYPE_FC) { + /* For CT2, 1G is not supported */ + if ((speed == BFA_PORT_SPEED_1GBPS) && + (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id))) + return BFA_STATUS_UNSUPP_SPEED; - /* Already checked for Auto Speed and Max Speed supp */ - if (!(speed == BFA_PORT_SPEED_1GBPS || - speed == BFA_PORT_SPEED_2GBPS || - speed == BFA_PORT_SPEED_4GBPS || - speed == BFA_PORT_SPEED_8GBPS || - speed == BFA_PORT_SPEED_16GBPS || - speed == BFA_PORT_SPEED_AUTO)) - return BFA_STATUS_UNSUPP_SPEED; - } else { - if (speed != BFA_PORT_SPEED_10GBPS) - return BFA_STATUS_UNSUPP_SPEED; + /* Already checked for Auto Speed and Max Speed supp */ + if (!(speed == BFA_PORT_SPEED_1GBPS || + speed == BFA_PORT_SPEED_2GBPS || + speed == BFA_PORT_SPEED_4GBPS || + speed == BFA_PORT_SPEED_8GBPS || + speed == BFA_PORT_SPEED_16GBPS || + speed == BFA_PORT_SPEED_AUTO)) + return BFA_STATUS_UNSUPP_SPEED; + } else { + if (speed != BFA_PORT_SPEED_10GBPS) + return BFA_STATUS_UNSUPP_SPEED; + } } fcport->cfg.speed = speed; @@ -3737,6 +3765,7 @@ bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn) fcport->cfg.bb_scn = bb_scn; if (bb_scn) fcport->bbsc_op_state = BFA_TRUE; + bfa_fcport_send_txcredit(fcport); } /* @@ -3796,6 +3825,8 @@ bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr) attr->port_state = BFA_PORT_ST_IOCDIS; else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc)) attr->port_state = BFA_PORT_ST_FWMISMATCH; + else if (bfa_ioc_is_acq_addr(&fcport->bfa->ioc)) + attr->port_state = BFA_PORT_ST_ACQ_ADDR; } /* FCoE vlan */ diff --git a/trunk/drivers/scsi/bfa/bfa_svc.h b/trunk/drivers/scsi/bfa/bfa_svc.h index f30067564639..b52cbb6bcd5a 100644 --- a/trunk/drivers/scsi/bfa/bfa_svc.h +++ b/trunk/drivers/scsi/bfa/bfa_svc.h @@ -663,6 +663,10 @@ void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg); void bfa_cb_lps_cvl_event(void *bfad, void *uarg); /* FAA specific APIs */ +bfa_status_t bfa_faa_enable(struct bfa_s *bfa, + bfa_cb_iocfc_t cbfn, void *cbarg); +bfa_status_t bfa_faa_disable(struct bfa_s *bfa, + bfa_cb_iocfc_t cbfn, void *cbarg); bfa_status_t bfa_faa_query(struct bfa_s *bfa, struct bfa_faa_attr_s *attr, bfa_cb_iocfc_t cbfn, void *cbarg); diff --git a/trunk/drivers/scsi/bfa/bfad_attr.c b/trunk/drivers/scsi/bfa/bfad_attr.c index 7b1ecd2b3ffe..1938fe0473e9 100644 --- a/trunk/drivers/scsi/bfa/bfad_attr.c +++ b/trunk/drivers/scsi/bfa/bfad_attr.c @@ -442,43 +442,6 @@ bfad_im_vport_create(struct fc_vport *fc_vport, bool disable) return status; } -int -bfad_im_issue_fc_host_lip(struct Scsi_Host *shost) -{ - struct bfad_im_port_s *im_port = - (struct bfad_im_port_s *) shost->hostdata[0]; - struct bfad_s *bfad = im_port->bfad; - struct bfad_hal_comp fcomp; - unsigned long flags; - uint32_t status; - - init_completion(&fcomp.comp); - spin_lock_irqsave(&bfad->bfad_lock, flags); - status = bfa_port_disable(&bfad->bfa.modules.port, - bfad_hcb_comp, &fcomp); - spin_unlock_irqrestore(&bfad->bfad_lock, flags); - - if (status != BFA_STATUS_OK) - return -EIO; - - wait_for_completion(&fcomp.comp); - if (fcomp.status != BFA_STATUS_OK) - return -EIO; - - spin_lock_irqsave(&bfad->bfad_lock, flags); - status = bfa_port_enable(&bfad->bfa.modules.port, - bfad_hcb_comp, &fcomp); - spin_unlock_irqrestore(&bfad->bfad_lock, flags); - if (status != BFA_STATUS_OK) - return -EIO; - - wait_for_completion(&fcomp.comp); - if (fcomp.status != BFA_STATUS_OK) - return -EIO; - - return 0; -} - static int bfad_im_vport_delete(struct fc_vport *fc_vport) { @@ -494,11 +457,8 @@ bfad_im_vport_delete(struct fc_vport *fc_vport) unsigned long flags; struct completion fcomp; - if (im_port->flags & BFAD_PORT_DELETE) { - bfad_scsi_host_free(bfad, im_port); - list_del(&vport->list_entry); - return 0; - } + if (im_port->flags & BFAD_PORT_DELETE) + goto free_scsi_host; port = im_port->port; @@ -529,6 +489,7 @@ bfad_im_vport_delete(struct fc_vport *fc_vport) wait_for_completion(vport->comp_del); +free_scsi_host: bfad_scsi_host_free(bfad, im_port); list_del(&vport->list_entry); kfree(vport); @@ -618,7 +579,7 @@ struct fc_function_template bfad_im_fc_function_template = { .show_rport_dev_loss_tmo = 1, .get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo, .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo, - .issue_fc_host_lip = bfad_im_issue_fc_host_lip, + .vport_create = bfad_im_vport_create, .vport_delete = bfad_im_vport_delete, .vport_disable = bfad_im_vport_disable, diff --git a/trunk/drivers/scsi/bfa/bfad_bsg.c b/trunk/drivers/scsi/bfa/bfad_bsg.c index e1f4b10df42a..8005c6c5a080 100644 --- a/trunk/drivers/scsi/bfa/bfad_bsg.c +++ b/trunk/drivers/scsi/bfa/bfad_bsg.c @@ -1287,6 +1287,50 @@ bfad_iocmd_ablk_optrom(struct bfad_s *bfad, unsigned int cmd, void *pcmd) return 0; } +int +bfad_iocmd_faa_enable(struct bfad_s *bfad, void *cmd) +{ + struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; + unsigned long flags; + struct bfad_hal_comp fcomp; + + init_completion(&fcomp.comp); + iocmd->status = BFA_STATUS_OK; + spin_lock_irqsave(&bfad->bfad_lock, flags); + iocmd->status = bfa_faa_enable(&bfad->bfa, bfad_hcb_comp, &fcomp); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + + if (iocmd->status != BFA_STATUS_OK) + goto out; + + wait_for_completion(&fcomp.comp); + iocmd->status = fcomp.status; +out: + return 0; +} + +int +bfad_iocmd_faa_disable(struct bfad_s *bfad, void *cmd) +{ + struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; + unsigned long flags; + struct bfad_hal_comp fcomp; + + init_completion(&fcomp.comp); + iocmd->status = BFA_STATUS_OK; + spin_lock_irqsave(&bfad->bfad_lock, flags); + iocmd->status = bfa_faa_disable(&bfad->bfa, bfad_hcb_comp, &fcomp); + spin_unlock_irqrestore(&bfad->bfad_lock, flags); + + if (iocmd->status != BFA_STATUS_OK) + goto out; + + wait_for_completion(&fcomp.comp); + iocmd->status = fcomp.status; +out: + return 0; +} + int bfad_iocmd_faa_query(struct bfad_s *bfad, void *cmd) { @@ -1874,7 +1918,6 @@ bfad_iocmd_debug_fw_core(struct bfad_s *bfad, void *cmd, struct bfa_bsg_debug_s *iocmd = (struct bfa_bsg_debug_s *)cmd; void *iocmd_bufptr; unsigned long flags; - u32 offset; if (bfad_chk_iocmd_sz(payload_len, sizeof(struct bfa_bsg_debug_s), BFA_DEBUG_FW_CORE_CHUNK_SZ) != BFA_STATUS_OK) { @@ -1892,10 +1935,8 @@ bfad_iocmd_debug_fw_core(struct bfad_s *bfad, void *cmd, iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_debug_s); spin_lock_irqsave(&bfad->bfad_lock, flags); - offset = iocmd->offset; iocmd->status = bfa_ioc_debug_fwcore(&bfad->bfa.ioc, iocmd_bufptr, - &offset, &iocmd->bufsz); - iocmd->offset = offset; + (u32 *)&iocmd->offset, &iocmd->bufsz); spin_unlock_irqrestore(&bfad->bfad_lock, flags); out: return 0; @@ -2592,6 +2633,12 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, case IOCMD_FLASH_DISABLE_OPTROM: rc = bfad_iocmd_ablk_optrom(bfad, cmd, iocmd); break; + case IOCMD_FAA_ENABLE: + rc = bfad_iocmd_faa_enable(bfad, iocmd); + break; + case IOCMD_FAA_DISABLE: + rc = bfad_iocmd_faa_disable(bfad, iocmd); + break; case IOCMD_FAA_QUERY: rc = bfad_iocmd_faa_query(bfad, iocmd); break; @@ -2762,16 +2809,9 @@ bfad_im_bsg_vendor_request(struct fc_bsg_job *job) struct bfad_im_port_s *im_port = (struct bfad_im_port_s *) job->shost->hostdata[0]; struct bfad_s *bfad = im_port->bfad; - struct request_queue *request_q = job->req->q; void *payload_kbuf; int rc = -EINVAL; - /* - * Set the BSG device request_queue size to 256 to support - * payloads larger than 512*1024K bytes. - */ - blk_queue_max_segments(request_q, 256); - /* Allocate a temp buffer to hold the passed in user space command */ payload_kbuf = kzalloc(job->request_payload.payload_len, GFP_KERNEL); if (!payload_kbuf) { diff --git a/trunk/drivers/scsi/bfa/bfad_bsg.h b/trunk/drivers/scsi/bfa/bfad_bsg.h index 17ad67283130..e859adb9aa9e 100644 --- a/trunk/drivers/scsi/bfa/bfad_bsg.h +++ b/trunk/drivers/scsi/bfa/bfad_bsg.h @@ -83,6 +83,8 @@ enum { IOCMD_PORT_CFG_MODE, IOCMD_FLASH_ENABLE_OPTROM, IOCMD_FLASH_DISABLE_OPTROM, + IOCMD_FAA_ENABLE, + IOCMD_FAA_DISABLE, IOCMD_FAA_QUERY, IOCMD_CEE_GET_ATTR, IOCMD_CEE_GET_STATS, diff --git a/trunk/drivers/scsi/bfa/bfad_drv.h b/trunk/drivers/scsi/bfa/bfad_drv.h index 7f74f1d19124..dc5b9d99c450 100644 --- a/trunk/drivers/scsi/bfa/bfad_drv.h +++ b/trunk/drivers/scsi/bfa/bfad_drv.h @@ -56,7 +56,7 @@ #ifdef BFA_DRIVER_VERSION #define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION #else -#define BFAD_DRIVER_VERSION "3.0.23.0" +#define BFAD_DRIVER_VERSION "3.0.2.2" #endif #define BFAD_PROTO_NAME FCPI_NAME diff --git a/trunk/drivers/scsi/bfa/bfi_ms.h b/trunk/drivers/scsi/bfa/bfi_ms.h index d4220e13cafa..0d9f1fb50db0 100644 --- a/trunk/drivers/scsi/bfa/bfi_ms.h +++ b/trunk/drivers/scsi/bfa/bfi_ms.h @@ -28,15 +28,17 @@ enum bfi_iocfc_h2i_msgs { BFI_IOCFC_H2I_CFG_REQ = 1, BFI_IOCFC_H2I_SET_INTR_REQ = 2, BFI_IOCFC_H2I_UPDATEQ_REQ = 3, - BFI_IOCFC_H2I_FAA_QUERY_REQ = 4, - BFI_IOCFC_H2I_ADDR_REQ = 5, + BFI_IOCFC_H2I_FAA_ENABLE_REQ = 4, + BFI_IOCFC_H2I_FAA_DISABLE_REQ = 5, + BFI_IOCFC_H2I_FAA_QUERY_REQ = 6, }; enum bfi_iocfc_i2h_msgs { BFI_IOCFC_I2H_CFG_REPLY = BFA_I2HM(1), BFI_IOCFC_I2H_UPDATEQ_RSP = BFA_I2HM(3), - BFI_IOCFC_I2H_FAA_QUERY_RSP = BFA_I2HM(4), - BFI_IOCFC_I2H_ADDR_MSG = BFA_I2HM(5), + BFI_IOCFC_I2H_FAA_ENABLE_RSP = BFA_I2HM(4), + BFI_IOCFC_I2H_FAA_DISABLE_RSP = BFA_I2HM(5), + BFI_IOCFC_I2H_FAA_QUERY_RSP = BFA_I2HM(6), }; struct bfi_iocfc_cfg_s { @@ -182,13 +184,6 @@ struct bfi_faa_en_dis_s { struct bfi_mhdr_s mh; /* common msg header */ }; -struct bfi_faa_addr_msg_s { - struct bfi_mhdr_s mh; /* common msg header */ - u8 rsvd[4]; - wwn_t pwwn; /* Fabric acquired PWWN */ - wwn_t nwwn; /* Fabric acquired PWWN */ -}; - /* * BFI_IOCFC_H2I_FAA_QUERY_REQ message */ diff --git a/trunk/drivers/scsi/bfa/bfi_reg.h b/trunk/drivers/scsi/bfa/bfi_reg.h index ed5f159e1867..d892064b64a8 100644 --- a/trunk/drivers/scsi/bfa/bfi_reg.h +++ b/trunk/drivers/scsi/bfa/bfi_reg.h @@ -335,17 +335,11 @@ enum { #define __PMM_1T_PNDB_P 0x00000002 #define CT2_PMM_1T_CONTROL_REG_P1 0x00023c1c #define CT2_WGN_STATUS 0x00014990 -#define __A2T_AHB_LOAD 0x00000800 #define __WGN_READY 0x00000400 #define __GLBL_PF_VF_CFG_RDY 0x00000200 -#define CT2_NFC_CSR_CLR_REG 0x00027420 #define CT2_NFC_CSR_SET_REG 0x00027424 #define __HALT_NFC_CONTROLLER 0x00000002 #define __NFC_CONTROLLER_HALTED 0x00001000 -#define CT2_RSC_GPR15_REG 0x0002765c -#define CT2_CSI_FW_CTL_REG 0x00027080 -#define CT2_CSI_FW_CTL_SET_REG 0x00027088 -#define __RESET_AND_START_SCLK_LCLK_PLLS 0x00010000 #define CT2_CSI_MAC0_CONTROL_REG 0x000270d0 #define __CSI_MAC_RESET 0x00000010 diff --git a/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index c1c6a92a0b98..abd72a01856d 100644 --- a/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -439,13 +439,13 @@ static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev, fr->fr_dev = lport; bg = &bnx2fc_global; - spin_lock(&bg->fcoe_rx_list.lock); + spin_lock_bh(&bg->fcoe_rx_list.lock); __skb_queue_tail(&bg->fcoe_rx_list, skb); if (bg->fcoe_rx_list.qlen == 1) wake_up_process(bg->thread); - spin_unlock(&bg->fcoe_rx_list.lock); + spin_unlock_bh(&bg->fcoe_rx_list.lock); return 0; err: diff --git a/trunk/drivers/scsi/fcoe/fcoe.c b/trunk/drivers/scsi/fcoe/fcoe.c index 335e85192807..ae7d15c44e2a 100644 --- a/trunk/drivers/scsi/fcoe/fcoe.c +++ b/trunk/drivers/scsi/fcoe/fcoe.c @@ -1436,7 +1436,7 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, goto err; fps = &per_cpu(fcoe_percpu, cpu); - spin_lock(&fps->fcoe_rx_list.lock); + spin_lock_bh(&fps->fcoe_rx_list.lock); if (unlikely(!fps->thread)) { /* * The targeted CPU is not ready, let's target @@ -1447,12 +1447,12 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, "ready for incoming skb- using first online " "CPU.\n"); - spin_unlock(&fps->fcoe_rx_list.lock); + spin_unlock_bh(&fps->fcoe_rx_list.lock); cpu = cpumask_first(cpu_online_mask); fps = &per_cpu(fcoe_percpu, cpu); - spin_lock(&fps->fcoe_rx_list.lock); + spin_lock_bh(&fps->fcoe_rx_list.lock); if (!fps->thread) { - spin_unlock(&fps->fcoe_rx_list.lock); + spin_unlock_bh(&fps->fcoe_rx_list.lock); goto err; } } @@ -1463,17 +1463,24 @@ static int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, * so we're free to queue skbs into it's queue. */ - /* - * Note: We used to have a set of conditions under which we would - * call fcoe_recv_frame directly, rather than queuing to the rx list - * as it could save a few cycles, but doing so is prohibited, as - * fcoe_recv_frame has several paths that may sleep, which is forbidden - * in softirq context. + /* If this is a SCSI-FCP frame, and this is already executing on the + * correct CPU, and the queue for this CPU is empty, then go ahead + * and process the frame directly in the softirq context. + * This lets us process completions without context switching from the + * NET_RX softirq, to our receive processing thread, and then back to + * BLOCK softirq context. */ - __skb_queue_tail(&fps->fcoe_rx_list, skb); - if (fps->thread->state == TASK_INTERRUPTIBLE) - wake_up_process(fps->thread); - spin_unlock(&fps->fcoe_rx_list.lock); + if (fh->fh_type == FC_TYPE_FCP && + cpu == smp_processor_id() && + skb_queue_empty(&fps->fcoe_rx_list)) { + spin_unlock_bh(&fps->fcoe_rx_list.lock); + fcoe_recv_frame(skb); + } else { + __skb_queue_tail(&fps->fcoe_rx_list, skb); + if (fps->fcoe_rx_list.qlen == 1) + wake_up_process(fps->thread); + spin_unlock_bh(&fps->fcoe_rx_list.lock); + } return 0; err: @@ -1790,29 +1797,23 @@ static int fcoe_percpu_receive_thread(void *arg) { struct fcoe_percpu_s *p = arg; struct sk_buff *skb; - struct sk_buff_head tmp; - - skb_queue_head_init(&tmp); set_user_nice(current, -20); while (!kthread_should_stop()) { spin_lock_bh(&p->fcoe_rx_list.lock); - skb_queue_splice_init(&p->fcoe_rx_list, &tmp); - spin_unlock_bh(&p->fcoe_rx_list.lock); - - while ((skb = __skb_dequeue(&tmp)) != NULL) - fcoe_recv_frame(skb); - - spin_lock_bh(&p->fcoe_rx_list.lock); - if (!skb_queue_len(&p->fcoe_rx_list)) { + while ((skb = __skb_dequeue(&p->fcoe_rx_list)) == NULL) { set_current_state(TASK_INTERRUPTIBLE); spin_unlock_bh(&p->fcoe_rx_list.lock); schedule(); set_current_state(TASK_RUNNING); - } else - spin_unlock_bh(&p->fcoe_rx_list.lock); + if (kthread_should_stop()) + return 0; + spin_lock_bh(&p->fcoe_rx_list.lock); + } + spin_unlock_bh(&p->fcoe_rx_list.lock); + fcoe_recv_frame(skb); } return 0; } @@ -2186,12 +2187,8 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) /* start FIP Discovery and FLOGI */ lport->boot_time = jiffies; fc_fabric_login(lport); - if (!fcoe_link_ok(lport)) { - rtnl_unlock(); + if (!fcoe_link_ok(lport)) fcoe_ctlr_link_up(&fcoe->ctlr); - mutex_unlock(&fcoe_config_mutex); - return rc; - } out_nodev: rtnl_unlock(); @@ -2264,14 +2261,31 @@ static int fcoe_link_ok(struct fc_lport *lport) static void fcoe_percpu_clean(struct fc_lport *lport) { struct fcoe_percpu_s *pp; - struct sk_buff *skb; + struct fcoe_rcv_info *fr; + struct sk_buff_head *list; + struct sk_buff *skb, *next; + struct sk_buff *head; unsigned int cpu; for_each_possible_cpu(cpu) { pp = &per_cpu(fcoe_percpu, cpu); + spin_lock_bh(&pp->fcoe_rx_list.lock); + list = &pp->fcoe_rx_list; + head = list->next; + for (skb = head; skb != (struct sk_buff *)list; + skb = next) { + next = skb->next; + fr = fcoe_dev_from_skb(skb); + if (fr->fr_dev == lport) { + __skb_unlink(skb, list); + kfree_skb(skb); + } + } - if (!pp->thread || !cpu_online(cpu)) + if (!pp->thread || !cpu_online(cpu)) { + spin_unlock_bh(&pp->fcoe_rx_list.lock); continue; + } skb = dev_alloc_skb(0); if (!skb) { @@ -2280,7 +2294,6 @@ static void fcoe_percpu_clean(struct fc_lport *lport) } skb->destructor = fcoe_percpu_flush_done; - spin_lock_bh(&pp->fcoe_rx_list.lock); __skb_queue_tail(&pp->fcoe_rx_list, skb); if (pp->fcoe_rx_list.qlen == 1) wake_up_process(pp->thread); diff --git a/trunk/drivers/scsi/fcoe/fcoe_ctlr.c b/trunk/drivers/scsi/fcoe/fcoe_ctlr.c index 249a106888d9..e7522dcc296e 100644 --- a/trunk/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/trunk/drivers/scsi/fcoe/fcoe_ctlr.c @@ -242,7 +242,7 @@ static void fcoe_ctlr_announce(struct fcoe_ctlr *fip) printk(KERN_INFO "libfcoe: host%d: FIP selected " "Fibre-Channel Forwarder MAC %pM\n", fip->lp->host->host_no, sel->fcf_mac); - memcpy(fip->dest_addr, sel->fcoe_mac, ETH_ALEN); + memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN); fip->map_dest = 0; } unlock: @@ -824,7 +824,6 @@ static int fcoe_ctlr_parse_adv(struct fcoe_ctlr *fip, memcpy(fcf->fcf_mac, ((struct fip_mac_desc *)desc)->fd_mac, ETH_ALEN); - memcpy(fcf->fcoe_mac, fcf->fcf_mac, ETH_ALEN); if (!is_valid_ether_addr(fcf->fcf_mac)) { LIBFCOE_FIP_DBG(fip, "Invalid MAC addr %pM in FIP adv\n", @@ -1014,7 +1013,6 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) struct fip_desc *desc; struct fip_encaps *els; struct fcoe_dev_stats *stats; - struct fcoe_fcf *sel; enum fip_desc_type els_dtype = 0; u8 els_op; u8 sub; @@ -1042,8 +1040,7 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) goto drop; /* Drop ELS if there are duplicate critical descriptors */ if (desc->fip_dtype < 32) { - if ((desc->fip_dtype != FIP_DT_MAC) && - (desc_mask & 1U << desc->fip_dtype)) { + if (desc_mask & 1U << desc->fip_dtype) { LIBFCOE_FIP_DBG(fip, "Duplicate Critical " "Descriptors in FIP ELS\n"); goto drop; @@ -1052,32 +1049,17 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) } switch (desc->fip_dtype) { case FIP_DT_MAC: - sel = fip->sel_fcf; if (desc_cnt == 1) { LIBFCOE_FIP_DBG(fip, "FIP descriptors " "received out of order\n"); goto drop; } - /* - * Some switch implementations send two MAC descriptors, - * with first MAC(granted_mac) being the FPMA, and the - * second one(fcoe_mac) is used as destination address - * for sending/receiving FCoE packets. FIP traffic is - * sent using fip_mac. For regular switches, both - * fip_mac and fcoe_mac would be the same. - */ - if (desc_cnt == 2) - memcpy(granted_mac, - ((struct fip_mac_desc *)desc)->fd_mac, - ETH_ALEN); if (dlen != sizeof(struct fip_mac_desc)) goto len_err; - - if ((desc_cnt == 3) && (sel)) - memcpy(sel->fcoe_mac, - ((struct fip_mac_desc *)desc)->fd_mac, - ETH_ALEN); + memcpy(granted_mac, + ((struct fip_mac_desc *)desc)->fd_mac, + ETH_ALEN); break; case FIP_DT_FLOGI: case FIP_DT_FDISC: @@ -1291,6 +1273,11 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, * No Vx_Port description. Clear all NPIV ports, * followed by physical port */ + mutex_lock(&lport->lp_mutex); + list_for_each_entry(vn_port, &lport->vports, list) + fc_lport_reset(vn_port); + mutex_unlock(&lport->lp_mutex); + mutex_lock(&fip->ctlr_mutex); per_cpu_ptr(lport->dev_stats, get_cpu())->VLinkFailureCount++; @@ -1298,11 +1285,6 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, fcoe_ctlr_reset(fip); mutex_unlock(&fip->ctlr_mutex); - mutex_lock(&lport->lp_mutex); - list_for_each_entry(vn_port, &lport->vports, list) - fc_lport_reset(vn_port); - mutex_unlock(&lport->lp_mutex); - fc_lport_reset(fip->lp); fcoe_ctlr_solicit(fip, NULL); } else { diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index 467dc38246f9..cdfe5a16de2a 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -104,9 +104,7 @@ static DEFINE_SPINLOCK(ipr_driver_lock); static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { { /* Gemstone, Citrine, Obsidian, and Obsidian-E */ .mailbox = 0x0042C, - .max_cmds = 100, .cache_line_size = 0x20, - .clear_isr = 1, { .set_interrupt_mask_reg = 0x0022C, .clr_interrupt_mask_reg = 0x00230, @@ -128,9 +126,7 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { }, { /* Snipe and Scamp */ .mailbox = 0x0052C, - .max_cmds = 100, .cache_line_size = 0x20, - .clear_isr = 1, { .set_interrupt_mask_reg = 0x00288, .clr_interrupt_mask_reg = 0x0028C, @@ -152,9 +148,7 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { }, { /* CRoC */ .mailbox = 0x00044, - .max_cmds = 1000, .cache_line_size = 0x20, - .clear_isr = 0, { .set_interrupt_mask_reg = 0x00010, .clr_interrupt_mask_reg = 0x00018, @@ -853,6 +847,8 @@ static void ipr_do_req(struct ipr_cmnd *ipr_cmd, ipr_trc_hook(ipr_cmd, IPR_TRACE_START, 0); + mb(); + ipr_send_command(ipr_cmd); } @@ -986,6 +982,8 @@ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type, ipr_trc_hook(ipr_cmd, IPR_TRACE_START, IPR_IOA_RES_ADDR); + mb(); + ipr_send_command(ipr_cmd); } else { list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q); @@ -4341,7 +4339,8 @@ static struct ipr_resource_entry *ipr_find_starget(struct scsi_target *starget) list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { if ((res->bus == starget->channel) && - (res->target == starget->id)) { + (res->target == starget->id) && + (res->lun == 0)) { return res; } } @@ -4415,14 +4414,12 @@ static void ipr_target_destroy(struct scsi_target *starget) struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata; if (ioa_cfg->sis64) { - if (!ipr_find_starget(starget)) { - if (starget->channel == IPR_ARRAY_VIRTUAL_BUS) - clear_bit(starget->id, ioa_cfg->array_ids); - else if (starget->channel == IPR_VSET_VIRTUAL_BUS) - clear_bit(starget->id, ioa_cfg->vset_ids); - else if (starget->channel == 0) - clear_bit(starget->id, ioa_cfg->target_ids); - } + if (starget->channel == IPR_ARRAY_VIRTUAL_BUS) + clear_bit(starget->id, ioa_cfg->array_ids); + else if (starget->channel == IPR_VSET_VIRTUAL_BUS) + clear_bit(starget->id, ioa_cfg->vset_ids); + else if (starget->channel == 0) + clear_bit(starget->id, ioa_cfg->target_ids); } if (sata_port) { @@ -4549,12 +4546,8 @@ static int ipr_ata_slave_alloc(struct scsi_device *sdev) ENTER; if (sdev->sdev_target) sata_port = sdev->sdev_target->hostdata; - if (sata_port) { + if (sata_port) rc = ata_sas_port_init(sata_port->ap); - if (rc == 0) - rc = ata_sas_sync_probe(sata_port->ap); - } - if (rc) ipr_slave_destroy(sdev); @@ -5055,14 +5048,12 @@ static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg, del_timer(&ioa_cfg->reset_cmd->timer); ipr_reset_ioa_job(ioa_cfg->reset_cmd); } else if ((int_reg & IPR_PCII_HRRQ_UPDATED) == int_reg) { - if (ioa_cfg->clear_isr) { - if (ipr_debug && printk_ratelimit()) - dev_err(&ioa_cfg->pdev->dev, - "Spurious interrupt detected. 0x%08X\n", int_reg); - writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32); - int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32); - return IRQ_NONE; - } + if (ipr_debug && printk_ratelimit()) + dev_err(&ioa_cfg->pdev->dev, + "Spurious interrupt detected. 0x%08X\n", int_reg); + writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32); + int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32); + return IRQ_NONE; } else { if (int_reg & IPR_PCII_IOA_UNIT_CHECKED) ioa_cfg->ioa_unit_checked = 1; @@ -5162,9 +5153,6 @@ static irqreturn_t ipr_isr(int irq, void *devp) } } - if (ipr_cmd && !ioa_cfg->clear_isr) - break; - if (ipr_cmd != NULL) { /* Clear the PCI interrupt */ num_hrrq = 0; @@ -5866,12 +5854,14 @@ static int ipr_queuecommand_lck(struct scsi_cmnd *scsi_cmd, rc = ipr_build_ioadl(ioa_cfg, ipr_cmd); } - if (unlikely(rc != 0)) { - list_move_tail(&ipr_cmd->queue, &ioa_cfg->free_q); - return SCSI_MLQUEUE_HOST_BUSY; + if (likely(rc == 0)) { + mb(); + ipr_send_command(ipr_cmd); + } else { + list_move_tail(&ipr_cmd->queue, &ioa_cfg->free_q); + return SCSI_MLQUEUE_HOST_BUSY; } - ipr_send_command(ipr_cmd); return 0; } @@ -6249,6 +6239,8 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) return AC_ERR_INVALID; } + mb(); + ipr_send_command(ipr_cmd); return 0; @@ -8285,10 +8277,6 @@ static void ipr_free_cmd_blks(struct ipr_ioa_cfg *ioa_cfg) if (ioa_cfg->ipr_cmd_pool) pci_pool_destroy (ioa_cfg->ipr_cmd_pool); - kfree(ioa_cfg->ipr_cmnd_list); - kfree(ioa_cfg->ipr_cmnd_list_dma); - ioa_cfg->ipr_cmnd_list = NULL; - ioa_cfg->ipr_cmnd_list_dma = NULL; ioa_cfg->ipr_cmd_pool = NULL; } @@ -8364,19 +8352,11 @@ static int __devinit ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg) int i; ioa_cfg->ipr_cmd_pool = pci_pool_create (IPR_NAME, ioa_cfg->pdev, - sizeof(struct ipr_cmnd), 512, 0); + sizeof(struct ipr_cmnd), 16, 0); if (!ioa_cfg->ipr_cmd_pool) return -ENOMEM; - ioa_cfg->ipr_cmnd_list = kcalloc(IPR_NUM_CMD_BLKS, sizeof(struct ipr_cmnd *), GFP_KERNEL); - ioa_cfg->ipr_cmnd_list_dma = kcalloc(IPR_NUM_CMD_BLKS, sizeof(dma_addr_t), GFP_KERNEL); - - if (!ioa_cfg->ipr_cmnd_list || !ioa_cfg->ipr_cmnd_list_dma) { - ipr_free_cmd_blks(ioa_cfg); - return -ENOMEM; - } - for (i = 0; i < IPR_NUM_CMD_BLKS; i++) { ipr_cmd = pci_pool_alloc (ioa_cfg->ipr_cmd_pool, GFP_KERNEL, &dma_addr); @@ -8604,7 +8584,6 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, host->max_channel = IPR_MAX_BUS_TO_SCAN; host->unique_id = host->host_no; host->max_cmd_len = IPR_MAX_CDB_LEN; - host->can_queue = ioa_cfg->max_cmds; pci_set_drvdata(pdev, ioa_cfg); p = &ioa_cfg->chip_cfg->regs; @@ -8789,8 +8768,6 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, /* set SIS 32 or SIS 64 */ ioa_cfg->sis64 = ioa_cfg->ipr_chip->sis_type == IPR_SIS64 ? 1 : 0; ioa_cfg->chip_cfg = ioa_cfg->ipr_chip->cfg; - ioa_cfg->clear_isr = ioa_cfg->chip_cfg->clear_isr; - ioa_cfg->max_cmds = ioa_cfg->chip_cfg->max_cmds; if (ipr_transop_timeout) ioa_cfg->transop_timeout = ipr_transop_timeout; diff --git a/trunk/drivers/scsi/ipr.h b/trunk/drivers/scsi/ipr.h index 153b8bd91d1e..f94eaee2ff16 100644 --- a/trunk/drivers/scsi/ipr.h +++ b/trunk/drivers/scsi/ipr.h @@ -38,8 +38,8 @@ /* * Literals */ -#define IPR_DRIVER_VERSION "2.5.3" -#define IPR_DRIVER_DATE "(March 10, 2012)" +#define IPR_DRIVER_VERSION "2.5.2" +#define IPR_DRIVER_DATE "(April 27, 2011)" /* * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding @@ -53,7 +53,7 @@ * IPR_NUM_BASE_CMD_BLKS: This defines the maximum number of * ops the mid-layer can send to the adapter. */ -#define IPR_NUM_BASE_CMD_BLKS (ioa_cfg->max_cmds) +#define IPR_NUM_BASE_CMD_BLKS 100 #define PCI_DEVICE_ID_IBM_OBSIDIAN_E 0x0339 @@ -153,7 +153,7 @@ #define IPR_NUM_INTERNAL_CMD_BLKS (IPR_NUM_HCAMS + \ ((IPR_NUM_RESET_RELOAD_RETRIES + 1) * 2) + 4) -#define IPR_MAX_COMMANDS 100 +#define IPR_MAX_COMMANDS IPR_NUM_BASE_CMD_BLKS #define IPR_NUM_CMD_BLKS (IPR_NUM_BASE_CMD_BLKS + \ IPR_NUM_INTERNAL_CMD_BLKS) @@ -1305,9 +1305,7 @@ struct ipr_interrupts { struct ipr_chip_cfg_t { u32 mailbox; - u16 max_cmds; u8 cache_line_size; - u8 clear_isr; struct ipr_interrupt_offsets regs; }; @@ -1390,7 +1388,6 @@ struct ipr_ioa_cfg { u8 sis64:1; u8 dump_timeout:1; u8 cfg_locked:1; - u8 clear_isr:1; u8 revid; @@ -1504,9 +1501,8 @@ struct ipr_ioa_cfg { struct ata_host ata_host; char ipr_cmd_label[8]; #define IPR_CMD_LABEL "ipr_cmd" - u32 max_cmds; - struct ipr_cmnd **ipr_cmnd_list; - dma_addr_t *ipr_cmnd_list_dma; + struct ipr_cmnd *ipr_cmnd_list[IPR_NUM_CMD_BLKS]; + dma_addr_t ipr_cmnd_list_dma[IPR_NUM_CMD_BLKS]; }; /* struct ipr_ioa_cfg */ struct ipr_cmnd { diff --git a/trunk/drivers/scsi/libfc/fc_exch.c b/trunk/drivers/scsi/libfc/fc_exch.c index aceffadb21c7..630291f01826 100644 --- a/trunk/drivers/scsi/libfc/fc_exch.c +++ b/trunk/drivers/scsi/libfc/fc_exch.c @@ -2263,18 +2263,7 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lport, mp->class = class; /* adjust em exch xid range for offload */ mp->min_xid = min_xid; - - /* reduce range so per cpu pool fits into PCPU_MIN_UNIT_SIZE pool */ - pool_exch_range = (PCPU_MIN_UNIT_SIZE - sizeof(*pool)) / - sizeof(struct fc_exch *); - if ((max_xid - min_xid + 1) / (fc_cpu_mask + 1) > pool_exch_range) { - mp->max_xid = pool_exch_range * (fc_cpu_mask + 1) + - min_xid - 1; - } else { - mp->max_xid = max_xid; - pool_exch_range = (mp->max_xid - mp->min_xid + 1) / - (fc_cpu_mask + 1); - } + mp->max_xid = max_xid; mp->ep_pool = mempool_create_slab_pool(2, fc_em_cachep); if (!mp->ep_pool) @@ -2285,6 +2274,7 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lport, * divided across all cpus. The exch pointers array memory is * allocated for exch range per pool. */ + pool_exch_range = (mp->max_xid - mp->min_xid + 1) / (fc_cpu_mask + 1); mp->pool_max_index = pool_exch_range - 1; /* diff --git a/trunk/drivers/scsi/libfc/fc_lport.c b/trunk/drivers/scsi/libfc/fc_lport.c index cc83b66d45b7..bd5d31d022d9 100644 --- a/trunk/drivers/scsi/libfc/fc_lport.c +++ b/trunk/drivers/scsi/libfc/fc_lport.c @@ -1742,19 +1742,9 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, mfs = ntohs(flp->fl_csp.sp_bb_data) & FC_SP_BB_DATA_MASK; - - if (mfs < FC_SP_MIN_MAX_PAYLOAD || mfs > FC_SP_MAX_MAX_PAYLOAD) { - FC_LPORT_DBG(lport, "FLOGI bad mfs:%hu response, " - "lport->mfs:%hu\n", mfs, lport->mfs); - fc_lport_error(lport, fp); - goto err; - } - - if (mfs <= lport->mfs) { + if (mfs >= FC_SP_MIN_MAX_PAYLOAD && + mfs < lport->mfs) lport->mfs = mfs; - fc_host_maxframe_size(lport->host) = mfs; - } - csp_flags = ntohs(flp->fl_csp.sp_features); r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov); e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov); diff --git a/trunk/drivers/scsi/libsas/sas_ata.c b/trunk/drivers/scsi/libsas/sas_ata.c index 441d88ad99a7..bc0cecc6ad62 100644 --- a/trunk/drivers/scsi/libsas/sas_ata.c +++ b/trunk/drivers/scsi/libsas/sas_ata.c @@ -546,12 +546,11 @@ static struct ata_port_info sata_port_info = { .port_ops = &sas_sata_ops }; -int sas_ata_init(struct domain_device *found_dev) +int sas_ata_init_host_and_port(struct domain_device *found_dev) { struct sas_ha_struct *ha = found_dev->port->ha; struct Scsi_Host *shost = ha->core.shost; struct ata_port *ap; - int rc; ata_host_init(&found_dev->sata_dev.ata_host, ha->dev, @@ -568,11 +567,8 @@ int sas_ata_init(struct domain_device *found_dev) ap->private_data = found_dev; ap->cbl = ATA_CBL_SATA; ap->scsi_host = shost; - rc = ata_sas_port_init(ap); - if (rc) { - ata_sas_port_destroy(ap); - return rc; - } + /* publish initialized ata port */ + smp_wmb(); found_dev->sata_dev.ap = ap; return 0; @@ -652,13 +648,18 @@ static void sas_get_ata_command_set(struct domain_device *dev) void sas_probe_sata(struct asd_sas_port *port) { struct domain_device *dev, *n; + int err; mutex_lock(&port->ha->disco_mutex); - list_for_each_entry(dev, &port->disco_list, disco_list_node) { + list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) { if (!dev_is_sata(dev)) continue; - ata_sas_async_probe(dev->sata_dev.ap); + err = sas_ata_init_host_and_port(dev); + if (err) + sas_fail_probe(dev, __func__, err); + else + ata_sas_async_port_init(dev->sata_dev.ap); } mutex_unlock(&port->ha->disco_mutex); @@ -717,6 +718,18 @@ static void async_sas_ata_eh(void *data, async_cookie_t cookie) sas_put_device(dev); } +static bool sas_ata_dev_eh_valid(struct domain_device *dev) +{ + struct ata_port *ap; + + if (!dev_is_sata(dev)) + return false; + ap = dev->sata_dev.ap; + /* consume fully initialized ata ports */ + smp_rmb(); + return !!ap; +} + void sas_ata_strategy_handler(struct Scsi_Host *shost) { struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost); @@ -740,7 +753,7 @@ void sas_ata_strategy_handler(struct Scsi_Host *shost) spin_lock(&port->dev_list_lock); list_for_each_entry(dev, &port->dev_list, dev_list_node) { - if (!dev_is_sata(dev)) + if (!sas_ata_dev_eh_valid(dev)) continue; async_schedule_domain(async_sas_ata_eh, dev, &async); } diff --git a/trunk/drivers/scsi/libsas/sas_discover.c b/trunk/drivers/scsi/libsas/sas_discover.c index 629a0865b130..364679675602 100644 --- a/trunk/drivers/scsi/libsas/sas_discover.c +++ b/trunk/drivers/scsi/libsas/sas_discover.c @@ -72,7 +72,6 @@ static int sas_get_port_device(struct asd_sas_port *port) struct asd_sas_phy *phy; struct sas_rphy *rphy; struct domain_device *dev; - int rc = -ENODEV; dev = sas_alloc_device(); if (!dev) @@ -111,16 +110,9 @@ static int sas_get_port_device(struct asd_sas_port *port) sas_init_dev(dev); - dev->port = port; switch (dev->dev_type) { - case SATA_DEV: - rc = sas_ata_init(dev); - if (rc) { - rphy = NULL; - break; - } - /* fall through */ case SAS_END_DEV: + case SATA_DEV: rphy = sas_end_device_alloc(port->port); break; case EDGE_DEV: @@ -139,14 +131,19 @@ static int sas_get_port_device(struct asd_sas_port *port) if (!rphy) { sas_put_device(dev); - return rc; + return -ENODEV; } + spin_lock_irq(&port->phy_list_lock); + list_for_each_entry(phy, &port->phy_list, port_phy_el) + sas_phy_set_target(phy, dev); + spin_unlock_irq(&port->phy_list_lock); rphy->identify.phy_identifier = phy->phy->identify.phy_identifier; memcpy(dev->sas_addr, port->attached_sas_addr, SAS_ADDR_SIZE); sas_fill_in_rphy(dev, rphy); sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr); port->port_dev = dev; + dev->port = port; dev->linkrate = port->linkrate; dev->min_linkrate = port->linkrate; dev->max_linkrate = port->linkrate; @@ -158,7 +155,6 @@ static int sas_get_port_device(struct asd_sas_port *port) sas_device_set_phy(dev, port->port); dev->rphy = rphy; - get_device(&dev->rphy->dev); if (dev_is_sata(dev) || dev->dev_type == SAS_END_DEV) list_add_tail(&dev->disco_list_node, &port->disco_list); @@ -168,11 +164,6 @@ static int sas_get_port_device(struct asd_sas_port *port) spin_unlock_irq(&port->dev_list_lock); } - spin_lock_irq(&port->phy_list_lock); - list_for_each_entry(phy, &port->phy_list, port_phy_el) - sas_phy_set_target(phy, dev); - spin_unlock_irq(&port->phy_list_lock); - return 0; } @@ -214,7 +205,8 @@ void sas_notify_lldd_dev_gone(struct domain_device *dev) static void sas_probe_devices(struct work_struct *work) { struct domain_device *dev, *n; - struct sas_discovery_event *ev = to_sas_discovery_event(work); + struct sas_discovery_event *ev = + container_of(work, struct sas_discovery_event, work); struct asd_sas_port *port = ev->port; clear_bit(DISCE_PROBE, &port->disc.pending); @@ -263,9 +255,6 @@ void sas_free_device(struct kref *kref) { struct domain_device *dev = container_of(kref, typeof(*dev), kref); - put_device(&dev->rphy->dev); - dev->rphy = NULL; - if (dev->parent) sas_put_device(dev->parent); @@ -302,7 +291,8 @@ static void sas_unregister_common_dev(struct asd_sas_port *port, struct domain_d static void sas_destruct_devices(struct work_struct *work) { struct domain_device *dev, *n; - struct sas_discovery_event *ev = to_sas_discovery_event(work); + struct sas_discovery_event *ev = + container_of(work, struct sas_discovery_event, work); struct asd_sas_port *port = ev->port; clear_bit(DISCE_DESTRUCT, &port->disc.pending); @@ -312,6 +302,7 @@ static void sas_destruct_devices(struct work_struct *work) sas_remove_children(&dev->rphy->dev); sas_rphy_delete(dev->rphy); + dev->rphy = NULL; sas_unregister_common_dev(port, dev); } } @@ -323,11 +314,11 @@ void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev) /* this rphy never saw sas_rphy_add */ list_del_init(&dev->disco_list_node); sas_rphy_free(dev->rphy); + dev->rphy = NULL; sas_unregister_common_dev(port, dev); - return; } - if (!test_and_set_bit(SAS_DEV_DESTROY, &dev->state)) { + if (dev->rphy && !test_and_set_bit(SAS_DEV_DESTROY, &dev->state)) { sas_rphy_unlink(dev->rphy); list_move_tail(&dev->disco_list_node, &port->destroy_list); sas_discover_event(dev->port, DISCE_DESTRUCT); @@ -386,7 +377,8 @@ static void sas_discover_domain(struct work_struct *work) { struct domain_device *dev; int error = 0; - struct sas_discovery_event *ev = to_sas_discovery_event(work); + struct sas_discovery_event *ev = + container_of(work, struct sas_discovery_event, work); struct asd_sas_port *port = ev->port; clear_bit(DISCE_DISCOVER_DOMAIN, &port->disc.pending); @@ -427,6 +419,8 @@ static void sas_discover_domain(struct work_struct *work) if (error) { sas_rphy_free(dev->rphy); + dev->rphy = NULL; + list_del_init(&dev->disco_list_node); spin_lock_irq(&port->dev_list_lock); list_del_init(&dev->dev_list_node); @@ -443,7 +437,8 @@ static void sas_discover_domain(struct work_struct *work) static void sas_revalidate_domain(struct work_struct *work) { int res = 0; - struct sas_discovery_event *ev = to_sas_discovery_event(work); + struct sas_discovery_event *ev = + container_of(work, struct sas_discovery_event, work); struct asd_sas_port *port = ev->port; struct sas_ha_struct *ha = port->ha; @@ -471,25 +466,21 @@ static void sas_revalidate_domain(struct work_struct *work) /* ---------- Events ---------- */ -static void sas_chain_work(struct sas_ha_struct *ha, struct sas_work *sw) +static void sas_chain_work(struct sas_ha_struct *ha, struct work_struct *work) { - /* chained work is not subject to SA_HA_DRAINING or - * SAS_HA_REGISTERED, because it is either submitted in the - * workqueue, or known to be submitted from a context that is - * not racing against draining - */ - scsi_queue_work(ha->core.shost, &sw->work); + /* chained work is not subject to SA_HA_DRAINING or SAS_HA_REGISTERED */ + scsi_queue_work(ha->core.shost, work); } static void sas_chain_event(int event, unsigned long *pending, - struct sas_work *sw, + struct work_struct *work, struct sas_ha_struct *ha) { if (!test_and_set_bit(event, pending)) { unsigned long flags; spin_lock_irqsave(&ha->state_lock, flags); - sas_chain_work(ha, sw); + sas_chain_work(ha, work); spin_unlock_irqrestore(&ha->state_lock, flags); } } @@ -528,7 +519,7 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port) disc->pending = 0; for (i = 0; i < DISC_NUM_EVENTS; i++) { - INIT_SAS_WORK(&disc->disc_work[i].work, sas_event_fns[i]); + INIT_WORK(&disc->disc_work[i].work, sas_event_fns[i]); disc->disc_work[i].port = port; } } diff --git a/trunk/drivers/scsi/libsas/sas_event.c b/trunk/drivers/scsi/libsas/sas_event.c index 4e4292d210c1..16639bbae629 100644 --- a/trunk/drivers/scsi/libsas/sas_event.c +++ b/trunk/drivers/scsi/libsas/sas_event.c @@ -27,21 +27,19 @@ #include "sas_internal.h" #include "sas_dump.h" -void sas_queue_work(struct sas_ha_struct *ha, struct sas_work *sw) +void sas_queue_work(struct sas_ha_struct *ha, struct work_struct *work) { if (!test_bit(SAS_HA_REGISTERED, &ha->state)) return; - if (test_bit(SAS_HA_DRAINING, &ha->state)) { - /* add it to the defer list, if not already pending */ - if (list_empty(&sw->drain_node)) - list_add(&sw->drain_node, &ha->defer_q); - } else - scsi_queue_work(ha->core.shost, &sw->work); + if (test_bit(SAS_HA_DRAINING, &ha->state)) + list_add(&work->entry, &ha->defer_q); + else + scsi_queue_work(ha->core.shost, work); } static void sas_queue_event(int event, unsigned long *pending, - struct sas_work *work, + struct work_struct *work, struct sas_ha_struct *ha) { if (!test_and_set_bit(event, pending)) { @@ -57,7 +55,7 @@ static void sas_queue_event(int event, unsigned long *pending, void __sas_drain_work(struct sas_ha_struct *ha) { struct workqueue_struct *wq = ha->core.shost->work_q; - struct sas_work *sw, *_sw; + struct work_struct *w, *_w; set_bit(SAS_HA_DRAINING, &ha->state); /* flush submitters */ @@ -68,9 +66,9 @@ void __sas_drain_work(struct sas_ha_struct *ha) spin_lock_irq(&ha->state_lock); clear_bit(SAS_HA_DRAINING, &ha->state); - list_for_each_entry_safe(sw, _sw, &ha->defer_q, drain_node) { - list_del_init(&sw->drain_node); - sas_queue_work(ha, sw); + list_for_each_entry_safe(w, _w, &ha->defer_q, entry) { + list_del_init(&w->entry); + sas_queue_work(ha, w); } spin_unlock_irq(&ha->state_lock); } @@ -153,7 +151,7 @@ int sas_init_events(struct sas_ha_struct *sas_ha) int i; for (i = 0; i < HA_NUM_EVENTS; i++) { - INIT_SAS_WORK(&sas_ha->ha_events[i].work, sas_ha_event_fns[i]); + INIT_WORK(&sas_ha->ha_events[i].work, sas_ha_event_fns[i]); sas_ha->ha_events[i].ha = sas_ha; } diff --git a/trunk/drivers/scsi/libsas/sas_expander.c b/trunk/drivers/scsi/libsas/sas_expander.c index caa0525d2523..05acd9e35fc4 100644 --- a/trunk/drivers/scsi/libsas/sas_expander.c +++ b/trunk/drivers/scsi/libsas/sas_expander.c @@ -202,7 +202,6 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) u8 sas_addr[SAS_ADDR_SIZE]; struct smp_resp *resp = rsp; struct discover_resp *dr = &resp->disc; - struct sas_ha_struct *ha = dev->port->ha; struct expander_device *ex = &dev->ex_dev; struct ex_phy *phy = &ex->ex_phy[phy_id]; struct sas_rphy *rphy = dev->rphy; @@ -210,8 +209,6 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) char *type; if (new_phy) { - if (WARN_ON_ONCE(test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state))) - return; phy->phy = sas_phy_alloc(&rphy->dev, phy_id); /* FIXME: error_handling */ @@ -236,8 +233,6 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) memcpy(sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE); phy->attached_dev_type = to_dev_type(dr); - if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) - goto out; phy->phy_id = phy_id; phy->linkrate = dr->linkrate; phy->attached_sata_host = dr->attached_sata_host; @@ -245,14 +240,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) phy->attached_sata_ps = dr->attached_sata_ps; phy->attached_iproto = dr->iproto << 1; phy->attached_tproto = dr->tproto << 1; - /* help some expanders that fail to zero sas_address in the 'no - * device' case - */ - if (phy->attached_dev_type == NO_DEVICE || - phy->linkrate < SAS_LINK_RATE_1_5_GBPS) - memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE); - else - memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE); + memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE); phy->attached_phy_id = dr->attached_phy_id; phy->phy_change_count = dr->change_count; phy->routing_attr = dr->routing_attr; @@ -278,7 +266,6 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) return; } - out: switch (phy->attached_dev_type) { case SATA_PENDING: type = "stp pending"; @@ -317,15 +304,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) else return; - /* if the attached device type changed and ata_eh is active, - * make sure we run revalidation when eh completes (see: - * sas_enable_revalidation) - */ - if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) - set_bit(DISCE_REVALIDATE_DOMAIN, &dev->port->disc.pending); - - SAS_DPRINTK("%sex %016llx phy%02d:%c:%X attached: %016llx (%s)\n", - test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state) ? "ata: " : "", + SAS_DPRINTK("ex %016llx phy%02d:%c:%X attached: %016llx (%s)\n", SAS_ADDR(dev->sas_addr), phy->phy_id, sas_route_char(dev, phy), phy->linkrate, SAS_ADDR(phy->attached_sas_addr), type); @@ -797,16 +776,13 @@ static struct domain_device *sas_ex_discover_end_dev( if (res) goto out_free; - sas_init_dev(child); - res = sas_ata_init(child); - if (res) - goto out_free; rphy = sas_end_device_alloc(phy->port); - if (!rphy) + if (unlikely(!rphy)) goto out_free; + sas_init_dev(child); + child->rphy = rphy; - get_device(&rphy->dev); list_add_tail(&child->disco_list_node, &parent->port->disco_list); @@ -830,7 +806,6 @@ static struct domain_device *sas_ex_discover_end_dev( sas_init_dev(child); child->rphy = rphy; - get_device(&rphy->dev); sas_fill_in_rphy(child, rphy); list_add_tail(&child->disco_list_node, &parent->port->disco_list); @@ -855,6 +830,8 @@ static struct domain_device *sas_ex_discover_end_dev( out_list_del: sas_rphy_free(child->rphy); + child->rphy = NULL; + list_del(&child->disco_list_node); spin_lock_irq(&parent->port->dev_list_lock); list_del(&child->dev_list_node); @@ -934,7 +911,6 @@ static struct domain_device *sas_ex_discover_expander( } port = parent->port; child->rphy = rphy; - get_device(&rphy->dev); edev = rphy_to_expander_device(rphy); child->dev_type = phy->attached_dev_type; kref_get(&parent->kref); @@ -958,7 +934,6 @@ static struct domain_device *sas_ex_discover_expander( res = sas_discover_expander(child); if (res) { - sas_rphy_delete(rphy); spin_lock_irq(&parent->port->dev_list_lock); list_del(&child->dev_list_node); spin_unlock_irq(&parent->port->dev_list_lock); @@ -1743,17 +1718,9 @@ static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id, int phy_change_count = 0; res = sas_get_phy_change_count(dev, i, &phy_change_count); - switch (res) { - case SMP_RESP_PHY_VACANT: - case SMP_RESP_NO_PHY: - continue; - case SMP_RESP_FUNC_ACC: - break; - default: - return res; - } - - if (phy_change_count != ex->ex_phy[i].phy_change_count) { + if (res) + goto out; + else if (phy_change_count != ex->ex_phy[i].phy_change_count) { if (update) ex->ex_phy[i].phy_change_count = phy_change_count; @@ -1761,7 +1728,8 @@ static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id, return 0; } } - return 0; +out: + return res; } static int sas_get_ex_change_count(struct domain_device *dev, int *ecc) diff --git a/trunk/drivers/scsi/libsas/sas_init.c b/trunk/drivers/scsi/libsas/sas_init.c index 10cb5ae30977..120bff64be30 100644 --- a/trunk/drivers/scsi/libsas/sas_init.c +++ b/trunk/drivers/scsi/libsas/sas_init.c @@ -94,7 +94,8 @@ void sas_hash_addr(u8 *hashed, const u8 *sas_addr) void sas_hae_reset(struct work_struct *work) { - struct sas_ha_event *ev = to_sas_ha_event(work); + struct sas_ha_event *ev = + container_of(work, struct sas_ha_event, work); struct sas_ha_struct *ha = ev->ha; clear_bit(HAE_RESET, &ha->pending); @@ -368,14 +369,14 @@ static void sas_phy_release(struct sas_phy *phy) static void phy_reset_work(struct work_struct *work) { - struct sas_phy_data *d = container_of(work, typeof(*d), reset_work.work); + struct sas_phy_data *d = container_of(work, typeof(*d), reset_work); d->reset_result = transport_sas_phy_reset(d->phy, d->hard_reset); } static void phy_enable_work(struct work_struct *work) { - struct sas_phy_data *d = container_of(work, typeof(*d), enable_work.work); + struct sas_phy_data *d = container_of(work, typeof(*d), enable_work); d->enable_result = sas_phy_enable(d->phy, d->enable); } @@ -388,8 +389,8 @@ static int sas_phy_setup(struct sas_phy *phy) return -ENOMEM; mutex_init(&d->event_lock); - INIT_SAS_WORK(&d->reset_work, phy_reset_work); - INIT_SAS_WORK(&d->enable_work, phy_enable_work); + INIT_WORK(&d->reset_work, phy_reset_work); + INIT_WORK(&d->enable_work, phy_enable_work); d->phy = phy; phy->hostdata = d; diff --git a/trunk/drivers/scsi/libsas/sas_internal.h b/trunk/drivers/scsi/libsas/sas_internal.h index 507e4cf12e56..f05c63879949 100644 --- a/trunk/drivers/scsi/libsas/sas_internal.h +++ b/trunk/drivers/scsi/libsas/sas_internal.h @@ -45,10 +45,10 @@ struct sas_phy_data { struct mutex event_lock; int hard_reset; int reset_result; - struct sas_work reset_work; + struct work_struct reset_work; int enable; int enable_result; - struct sas_work enable_work; + struct work_struct enable_work; }; void sas_scsi_recover_host(struct Scsi_Host *shost); @@ -80,7 +80,7 @@ void sas_porte_broadcast_rcvd(struct work_struct *work); void sas_porte_link_reset_err(struct work_struct *work); void sas_porte_timer_event(struct work_struct *work); void sas_porte_hard_reset(struct work_struct *work); -void sas_queue_work(struct sas_ha_struct *ha, struct sas_work *sw); +void sas_queue_work(struct sas_ha_struct *ha, struct work_struct *work); int sas_notify_lldd_dev_found(struct domain_device *); void sas_notify_lldd_dev_gone(struct domain_device *); diff --git a/trunk/drivers/scsi/libsas/sas_phy.c b/trunk/drivers/scsi/libsas/sas_phy.c index 521422e857ab..dcfd4a9105c5 100644 --- a/trunk/drivers/scsi/libsas/sas_phy.c +++ b/trunk/drivers/scsi/libsas/sas_phy.c @@ -32,7 +32,8 @@ static void sas_phye_loss_of_signal(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; clear_bit(PHYE_LOSS_OF_SIGNAL, &phy->phy_events_pending); @@ -42,7 +43,8 @@ static void sas_phye_loss_of_signal(struct work_struct *work) static void sas_phye_oob_done(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; clear_bit(PHYE_OOB_DONE, &phy->phy_events_pending); @@ -51,7 +53,8 @@ static void sas_phye_oob_done(struct work_struct *work) static void sas_phye_oob_error(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; struct sas_ha_struct *sas_ha = phy->ha; struct asd_sas_port *port = phy->port; @@ -82,7 +85,8 @@ static void sas_phye_oob_error(struct work_struct *work) static void sas_phye_spinup_hold(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; struct sas_ha_struct *sas_ha = phy->ha; struct sas_internal *i = @@ -123,12 +127,14 @@ int sas_register_phys(struct sas_ha_struct *sas_ha) phy->error = 0; INIT_LIST_HEAD(&phy->port_phy_el); for (k = 0; k < PORT_NUM_EVENTS; k++) { - INIT_SAS_WORK(&phy->port_events[k].work, sas_port_event_fns[k]); + INIT_WORK(&phy->port_events[k].work, + sas_port_event_fns[k]); phy->port_events[k].phy = phy; } for (k = 0; k < PHY_NUM_EVENTS; k++) { - INIT_SAS_WORK(&phy->phy_events[k].work, sas_phy_event_fns[k]); + INIT_WORK(&phy->phy_events[k].work, + sas_phy_event_fns[k]); phy->phy_events[k].phy = phy; } @@ -138,7 +144,8 @@ int sas_register_phys(struct sas_ha_struct *sas_ha) spin_lock_init(&phy->sas_prim_lock); phy->frame_rcvd_size = 0; - phy->phy = sas_phy_alloc(&sas_ha->core.shost->shost_gendev, i); + phy->phy = sas_phy_alloc(&sas_ha->core.shost->shost_gendev, + i); if (!phy->phy) return -ENOMEM; diff --git a/trunk/drivers/scsi/libsas/sas_port.c b/trunk/drivers/scsi/libsas/sas_port.c index e884a8c58a0c..eb19c016d500 100644 --- a/trunk/drivers/scsi/libsas/sas_port.c +++ b/trunk/drivers/scsi/libsas/sas_port.c @@ -123,7 +123,7 @@ static void sas_form_port(struct asd_sas_phy *phy) spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags); if (!port->port) { - port->port = sas_port_alloc(phy->phy->dev.parent, port->id); + port->port = sas_port_alloc(phy->phy->dev.parent, phy->id); BUG_ON(!port->port); sas_port_add(port->port); } @@ -208,7 +208,8 @@ void sas_deform_port(struct asd_sas_phy *phy, int gone) void sas_porte_bytes_dmaed(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; clear_bit(PORTE_BYTES_DMAED, &phy->port_events_pending); @@ -218,7 +219,8 @@ void sas_porte_bytes_dmaed(struct work_struct *work) void sas_porte_broadcast_rcvd(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; unsigned long flags; u32 prim; @@ -235,7 +237,8 @@ void sas_porte_broadcast_rcvd(struct work_struct *work) void sas_porte_link_reset_err(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; clear_bit(PORTE_LINK_RESET_ERR, &phy->port_events_pending); @@ -245,7 +248,8 @@ void sas_porte_link_reset_err(struct work_struct *work) void sas_porte_timer_event(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; clear_bit(PORTE_TIMER_EVENT, &phy->port_events_pending); @@ -255,7 +259,8 @@ void sas_porte_timer_event(struct work_struct *work) void sas_porte_hard_reset(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; clear_bit(PORTE_HARD_RESET, &phy->port_events_pending); diff --git a/trunk/drivers/scsi/lpfc/Makefile b/trunk/drivers/scsi/lpfc/Makefile index fe5d396aca73..88928f00aa2d 100644 --- a/trunk/drivers/scsi/lpfc/Makefile +++ b/trunk/drivers/scsi/lpfc/Makefile @@ -1,7 +1,7 @@ #/******************************************************************* # * This file is part of the Emulex Linux Device Driver for * # * Fibre Channel Host Bus Adapters. * -# * Copyright (C) 2004-2012 Emulex. All rights reserved. * +# * Copyright (C) 2004-2011 Emulex. All rights reserved. * # * EMULEX and SLI are trademarks of Emulex. * # * www.emulex.com * # * * @@ -22,8 +22,6 @@ ccflags-$(GCOV) := -fprofile-arcs -ftest-coverage ccflags-$(GCOV) += -O0 -ccflags-y += -Werror - obj-$(CONFIG_SCSI_LPFC) := lpfc.o lpfc-objs := lpfc_mem.o lpfc_sli.o lpfc_ct.o lpfc_els.o lpfc_hbadisc.o \ diff --git a/trunk/drivers/scsi/lpfc/lpfc.h b/trunk/drivers/scsi/lpfc/lpfc.h index 3a1ffdd6d831..5fc044ff656e 100644 --- a/trunk/drivers/scsi/lpfc/lpfc.h +++ b/trunk/drivers/scsi/lpfc/lpfc.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2011 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -840,8 +840,6 @@ struct lpfc_hba { struct dentry *debug_dumpData; /* BlockGuard BPL */ struct dentry *debug_dumpDif; /* BlockGuard BPL */ struct dentry *debug_InjErrLBA; /* LBA to inject errors at */ - struct dentry *debug_InjErrNPortID; /* NPortID to inject errors at */ - struct dentry *debug_InjErrWWPN; /* WWPN to inject errors at */ struct dentry *debug_writeGuard; /* inject write guard_tag errors */ struct dentry *debug_writeApp; /* inject write app_tag errors */ struct dentry *debug_writeRef; /* inject write ref_tag errors */ @@ -856,8 +854,6 @@ struct lpfc_hba { uint32_t lpfc_injerr_rgrd_cnt; uint32_t lpfc_injerr_rapp_cnt; uint32_t lpfc_injerr_rref_cnt; - uint32_t lpfc_injerr_nportid; - struct lpfc_name lpfc_injerr_wwpn; sector_t lpfc_injerr_lba; #define LPFC_INJERR_LBA_OFF (sector_t)(-1) @@ -912,8 +908,6 @@ struct lpfc_hba { atomic_t fast_event_count; uint32_t fcoe_eventtag; uint32_t fcoe_eventtag_at_fcf_scan; - uint32_t fcoe_cvl_eventtag; - uint32_t fcoe_cvl_eventtag_attn; struct lpfc_fcf fcf; uint8_t fc_map[3]; uint8_t valid_vlan; diff --git a/trunk/drivers/scsi/lpfc/lpfc_attr.c b/trunk/drivers/scsi/lpfc/lpfc_attr.c index 5eb2bc116183..296ad5bc4240 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_attr.c +++ b/trunk/drivers/scsi/lpfc/lpfc_attr.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2011 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -2575,7 +2575,7 @@ LPFC_VPORT_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffffffff, # lpfc_enable_da_id: This turns on the DA_ID CT command that deregisters # objects that have been registered with the nameserver after login. */ -LPFC_VPORT_ATTR_R(enable_da_id, 1, 0, 1, +LPFC_VPORT_ATTR_R(enable_da_id, 0, 0, 1, "Deregister nameserver objects before LOGO"); /* diff --git a/trunk/drivers/scsi/lpfc/lpfc_debugfs.c b/trunk/drivers/scsi/lpfc/lpfc_debugfs.c index af04b0d6688d..22e17be04d8a 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/trunk/drivers/scsi/lpfc/lpfc_debugfs.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2007-2012 Emulex. All rights reserved. * + * Copyright (C) 2007-2011 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -997,41 +997,38 @@ lpfc_debugfs_dumpDataDif_write(struct file *file, const char __user *buf, return nbytes; } +static int +lpfc_debugfs_dif_err_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static ssize_t lpfc_debugfs_dif_err_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) { struct dentry *dent = file->f_dentry; struct lpfc_hba *phba = file->private_data; - char cbuf[32]; - uint64_t tmp = 0; + char cbuf[16]; int cnt = 0; if (dent == phba->debug_writeGuard) - cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wgrd_cnt); + cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wgrd_cnt); else if (dent == phba->debug_writeApp) - cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wapp_cnt); + cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wapp_cnt); else if (dent == phba->debug_writeRef) - cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_wref_cnt); + cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wref_cnt); else if (dent == phba->debug_readGuard) - cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rgrd_cnt); + cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rgrd_cnt); else if (dent == phba->debug_readApp) - cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rapp_cnt); + cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rapp_cnt); else if (dent == phba->debug_readRef) - cnt = snprintf(cbuf, 32, "%u\n", phba->lpfc_injerr_rref_cnt); - else if (dent == phba->debug_InjErrNPortID) - cnt = snprintf(cbuf, 32, "0x%06x\n", phba->lpfc_injerr_nportid); - else if (dent == phba->debug_InjErrWWPN) { - memcpy(&tmp, &phba->lpfc_injerr_wwpn, sizeof(struct lpfc_name)); - tmp = cpu_to_be64(tmp); - cnt = snprintf(cbuf, 32, "0x%016llx\n", tmp); - } else if (dent == phba->debug_InjErrLBA) { - if (phba->lpfc_injerr_lba == (sector_t)(-1)) - cnt = snprintf(cbuf, 32, "off\n"); - else - cnt = snprintf(cbuf, 32, "0x%llx\n", - (uint64_t) phba->lpfc_injerr_lba); - } else + cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rref_cnt); + else if (dent == phba->debug_InjErrLBA) + cnt = snprintf(cbuf, 16, "0x%lx\n", + (unsigned long) phba->lpfc_injerr_lba); + else lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0547 Unknown debugfs error injection entry\n"); @@ -1045,7 +1042,7 @@ lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf, struct dentry *dent = file->f_dentry; struct lpfc_hba *phba = file->private_data; char dstbuf[32]; - uint64_t tmp = 0; + unsigned long tmp; int size; memset(dstbuf, 0, 32); @@ -1053,12 +1050,7 @@ lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf, if (copy_from_user(dstbuf, buf, size)) return 0; - if (dent == phba->debug_InjErrLBA) { - if ((buf[0] == 'o') && (buf[1] == 'f') && (buf[2] == 'f')) - tmp = (uint64_t)(-1); - } - - if ((tmp == 0) && (kstrtoull(dstbuf, 0, &tmp))) + if (strict_strtoul(dstbuf, 0, &tmp)) return 0; if (dent == phba->debug_writeGuard) @@ -1075,12 +1067,7 @@ lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf, phba->lpfc_injerr_rref_cnt = (uint32_t)tmp; else if (dent == phba->debug_InjErrLBA) phba->lpfc_injerr_lba = (sector_t)tmp; - else if (dent == phba->debug_InjErrNPortID) - phba->lpfc_injerr_nportid = (uint32_t)(tmp & Mask_DID); - else if (dent == phba->debug_InjErrWWPN) { - tmp = cpu_to_be64(tmp); - memcpy(&phba->lpfc_injerr_wwpn, &tmp, sizeof(struct lpfc_name)); - } else + else lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0548 Unknown debugfs error injection entry\n"); @@ -3534,7 +3521,7 @@ static const struct file_operations lpfc_debugfs_op_dumpDif = { #undef lpfc_debugfs_op_dif_err static const struct file_operations lpfc_debugfs_op_dif_err = { .owner = THIS_MODULE, - .open = simple_open, + .open = lpfc_debugfs_dif_err_open, .llseek = lpfc_debugfs_lseek, .read = lpfc_debugfs_dif_err_read, .write = lpfc_debugfs_dif_err_write, @@ -3962,28 +3949,6 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) } phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; - snprintf(name, sizeof(name), "InjErrNPortID"); - phba->debug_InjErrNPortID = - debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, - phba->hba_debugfs_root, - phba, &lpfc_debugfs_op_dif_err); - if (!phba->debug_InjErrNPortID) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0809 Cannot create debugfs InjErrNPortID\n"); - goto debug_failed; - } - - snprintf(name, sizeof(name), "InjErrWWPN"); - phba->debug_InjErrWWPN = - debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, - phba->hba_debugfs_root, - phba, &lpfc_debugfs_op_dif_err); - if (!phba->debug_InjErrWWPN) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, - "0810 Cannot create debugfs InjErrWWPN\n"); - goto debug_failed; - } - snprintf(name, sizeof(name), "writeGuardInjErr"); phba->debug_writeGuard = debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, @@ -4356,14 +4321,6 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport) debugfs_remove(phba->debug_InjErrLBA); /* InjErrLBA */ phba->debug_InjErrLBA = NULL; } - if (phba->debug_InjErrNPortID) { /* InjErrNPortID */ - debugfs_remove(phba->debug_InjErrNPortID); - phba->debug_InjErrNPortID = NULL; - } - if (phba->debug_InjErrWWPN) { - debugfs_remove(phba->debug_InjErrWWPN); /* InjErrWWPN */ - phba->debug_InjErrWWPN = NULL; - } if (phba->debug_writeGuard) { debugfs_remove(phba->debug_writeGuard); /* writeGuard */ phba->debug_writeGuard = NULL; diff --git a/trunk/drivers/scsi/lpfc/lpfc_els.c b/trunk/drivers/scsi/lpfc/lpfc_els.c index 3407b39e0a3f..8db2fb3b45ec 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_els.c +++ b/trunk/drivers/scsi/lpfc/lpfc_els.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2011 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -925,17 +925,9 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * due to new FCF discovery */ if ((phba->hba_flag & HBA_FIP_SUPPORT) && - (phba->fcf.fcf_flag & FCF_DISCOVERY)) { - if (phba->link_state < LPFC_LINK_UP) - goto stop_rr_fcf_flogi; - if ((phba->fcoe_cvl_eventtag_attn == - phba->fcoe_cvl_eventtag) && - (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && - (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED)) - goto stop_rr_fcf_flogi; - else - phba->fcoe_cvl_eventtag_attn = - phba->fcoe_cvl_eventtag; + (phba->fcf.fcf_flag & FCF_DISCOVERY) && + !((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && + (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED))) { lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS, "2611 FLOGI failed on FCF (x%x), " "status:x%x/x%x, tmo:x%x, perform " @@ -951,7 +943,6 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, goto out; } -stop_rr_fcf_flogi: /* FLOGI failure */ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, "2858 FLOGI failure Status:x%x/x%x TMO:x%x\n", diff --git a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c index b507536dc5b5..343d87ba4df8 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2011 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -2843,14 +2843,7 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) struct lpfc_vport *vport = mboxq->vport; struct Scsi_Host *shost = lpfc_shost_from_vport(vport); - /* - * VFI not supported for interface type 0, so ignore any mailbox - * error (except VFI in use) and continue with the discovery. - */ - if (mboxq->u.mb.mbxStatus && - (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != - LPFC_SLI_INTF_IF_TYPE_0) && - mboxq->u.mb.mbxStatus != MBX_VFI_IN_USE) { + if (mboxq->u.mb.mbxStatus) { lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, "2018 REG_VFI mbxStatus error x%x " "HBA state x%x\n", @@ -5680,13 +5673,14 @@ lpfc_fcf_inuse(struct lpfc_hba *phba) ret = 1; spin_unlock_irq(shost->host_lock); goto out; - } else if (ndlp->nlp_flag & NLP_RPI_REGISTERED) { - ret = 1; + } else { lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "2624 RPI %x DID %x flag %x " - "still logged in\n", - ndlp->nlp_rpi, ndlp->nlp_DID, - ndlp->nlp_flag); + "2624 RPI %x DID %x flg %x still " + "logged in\n", + ndlp->nlp_rpi, ndlp->nlp_DID, + ndlp->nlp_flag); + if (ndlp->nlp_flag & NLP_RPI_REGISTERED) + ret = 1; } } spin_unlock_irq(shost->host_lock); diff --git a/trunk/drivers/scsi/lpfc/lpfc_hw4.h b/trunk/drivers/scsi/lpfc/lpfc_hw4.h index 91f09761bd32..9e2b9b227e1a 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hw4.h +++ b/trunk/drivers/scsi/lpfc/lpfc_hw4.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2009-2012 Emulex. All rights reserved. * + * Copyright (C) 2009 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -338,12 +338,6 @@ struct lpfc_cqe { #define CQE_CODE_XRI_ABORTED 0x5 #define CQE_CODE_RECEIVE_V1 0x9 -/* - * Define mask value for xri_aborted and wcqe completed CQE extended status. - * Currently, extended status is limited to 9 bits (0x0 -> 0x103) . - */ -#define WCQE_PARAM_MASK 0x1FF; - /* completion queue entry for wqe completions */ struct lpfc_wcqe_complete { uint32_t word0; diff --git a/trunk/drivers/scsi/lpfc/lpfc_init.c b/trunk/drivers/scsi/lpfc/lpfc_init.c index 9598fdcb08ab..b38f99f3be32 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_init.c +++ b/trunk/drivers/scsi/lpfc/lpfc_init.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2011 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -2704,14 +2704,16 @@ lpfc_offline_prep(struct lpfc_hba * phba) } spin_lock_irq(shost->host_lock); ndlp->nlp_flag &= ~NLP_NPR_ADISC; - spin_unlock_irq(shost->host_lock); + /* * Whenever an SLI4 port goes offline, free the - * RPI. Get a new RPI when the adapter port - * comes back online. + * RPI. A new RPI when the adapter port comes + * back online. */ if (phba->sli_rev == LPFC_SLI_REV4) lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi); + + spin_unlock_irq(shost->host_lock); lpfc_unreg_rpi(vports[i], ndlp); } } @@ -2784,13 +2786,9 @@ lpfc_scsi_buf_update(struct lpfc_hba *phba) spin_lock_irq(&phba->hbalock); spin_lock(&phba->scsi_buf_list_lock); - list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list) { + list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list) sb->cur_iocbq.sli4_xritag = phba->sli4_hba.xri_ids[sb->cur_iocbq.sli4_lxritag]; - set_bit(sb->cur_iocbq.sli4_lxritag, phba->sli4_hba.xri_bmask); - phba->sli4_hba.max_cfg_param.xri_used++; - phba->sli4_hba.xri_count++; - } spin_unlock(&phba->scsi_buf_list_lock); spin_unlock_irq(&phba->hbalock); return 0; @@ -3725,7 +3723,6 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba, break; case LPFC_FIP_EVENT_TYPE_FCF_DEAD: - phba->fcoe_cvl_eventtag = acqe_fip->event_tag; lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, "2549 FCF (x%x) disconnected from network, " "tag:x%x\n", acqe_fip->index, acqe_fip->event_tag); @@ -3787,7 +3784,6 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba, } break; case LPFC_FIP_EVENT_TYPE_CVL: - phba->fcoe_cvl_eventtag = acqe_fip->event_tag; lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY, "2718 Clear Virtual Link Received for VPI 0x%x" " tag 0x%x\n", acqe_fip->index, acqe_fip->event_tag); @@ -5230,7 +5226,8 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba) * rpi is normalized to a zero base because the physical rpi is * port based. */ - curr_rpi_range = phba->sli4_hba.next_rpi; + curr_rpi_range = phba->sli4_hba.next_rpi - + phba->sli4_hba.max_cfg_param.rpi_base; spin_unlock_irq(&phba->hbalock); /* @@ -5821,9 +5818,10 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba) readl(phba->sli4_hba.u.if_type2. ERR2regaddr); lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "2888 Unrecoverable port error " - "following POST: port status reg " - "0x%x, port_smphr reg 0x%x, " + "2888 Port Error Detected " + "during POST: " + "port status reg 0x%x, " + "port_smphr reg 0x%x, " "error 1=0x%x, error 2=0x%x\n", reg_data.word0, portsmphr_reg.word0, @@ -6144,6 +6142,7 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) phba->sli4_hba.next_xri = phba->sli4_hba.max_cfg_param.xri_base; phba->vpi_base = phba->sli4_hba.max_cfg_param.vpi_base; phba->vfi_base = phba->sli4_hba.max_cfg_param.vfi_base; + phba->sli4_hba.next_rpi = phba->sli4_hba.max_cfg_param.rpi_base; phba->max_vpi = (phba->sli4_hba.max_cfg_param.max_vpi > 0) ? (phba->sli4_hba.max_cfg_param.max_vpi - 1) : 0; phba->max_vports = phba->max_vpi; @@ -7232,7 +7231,6 @@ lpfc_pci_function_reset(struct lpfc_hba *phba) uint32_t rdy_chk, num_resets = 0, reset_again = 0; union lpfc_sli4_cfg_shdr *shdr; struct lpfc_register reg_data; - uint16_t devid; if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); switch (if_type) { @@ -7279,9 +7277,7 @@ lpfc_pci_function_reset(struct lpfc_hba *phba) LPFC_SLIPORT_INIT_PORT); writel(reg_data.word0, phba->sli4_hba.u.if_type2. CTRLregaddr); - /* flush */ - pci_read_config_word(phba->pcidev, - PCI_DEVICE_ID, &devid); + /* * Poll the Port Status Register and wait for RDY for * up to 10 seconds. If the port doesn't respond, treat @@ -7319,10 +7315,11 @@ lpfc_pci_function_reset(struct lpfc_hba *phba) phba->work_status[1] = readl( phba->sli4_hba.u.if_type2.ERR2regaddr); lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "2890 Port error detected during port " - "reset(%d): port status reg 0x%x, " + "2890 Port Error Detected " + "during Port Reset: " + "port status reg 0x%x, " "error 1=0x%x, error 2=0x%x\n", - num_resets, reg_data.word0, + reg_data.word0, phba->work_status[0], phba->work_status[1]); rc = -ENODEV; diff --git a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c index 15ca2a9a0cdd..7b6b2aa5795a 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2009 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -440,15 +440,11 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, spin_unlock_irq(shost->host_lock); stat.un.b.lsRjtRsnCode = LSRJT_INVALID_CMD; stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; - rc = lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, + lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, mbox); - if (rc) - mempool_free(mbox, phba->mbox_mem_pool); return 1; } - rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox); - if (rc) - mempool_free(mbox, phba->mbox_mem_pool); + lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox); return 1; out: stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; diff --git a/trunk/drivers/scsi/lpfc/lpfc_scsi.c b/trunk/drivers/scsi/lpfc/lpfc_scsi.c index 88f3a83dbd2e..efc055b6bac4 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_scsi.c +++ b/trunk/drivers/scsi/lpfc/lpfc_scsi.c @@ -39,8 +39,8 @@ #include "lpfc_sli4.h" #include "lpfc_nl.h" #include "lpfc_disc.h" -#include "lpfc.h" #include "lpfc_scsi.h" +#include "lpfc.h" #include "lpfc_logmsg.h" #include "lpfc_crtn.h" #include "lpfc_vport.h" @@ -51,19 +51,13 @@ int _dump_buf_done; static char *dif_op_str[] = { - "PROT_NORMAL", - "PROT_READ_INSERT", - "PROT_WRITE_STRIP", - "PROT_READ_STRIP", - "PROT_WRITE_INSERT", - "PROT_READ_PASS", - "PROT_WRITE_PASS", -}; - -static char *dif_grd_str[] = { - "NO_GUARD", - "DIF_CRC", - "DIX_IP", + "SCSI_PROT_NORMAL", + "SCSI_PROT_READ_INSERT", + "SCSI_PROT_WRITE_STRIP", + "SCSI_PROT_READ_STRIP", + "SCSI_PROT_WRITE_INSERT", + "SCSI_PROT_READ_PASS", + "SCSI_PROT_WRITE_PASS", }; struct scsi_dif_tuple { @@ -1287,14 +1281,10 @@ lpfc_cmd_blksize(struct scsi_cmnd *sc) #ifdef CONFIG_SCSI_LPFC_DEBUG_FS -/* Return if if error injection is detected by Initiator */ -#define BG_ERR_INIT 0x1 -/* Return if if error injection is detected by Target */ -#define BG_ERR_TGT 0x2 -/* Return if if swapping CSUM<-->CRC is required for error injection */ -#define BG_ERR_SWAP 0x10 -/* Return if disabling Guard/Ref/App checking is required for error injection */ -#define BG_ERR_CHECK 0x20 +#define BG_ERR_INIT 1 +#define BG_ERR_TGT 2 +#define BG_ERR_SWAP 3 +#define BG_ERR_CHECK 4 /** * lpfc_bg_err_inject - Determine if we should inject an error @@ -1304,7 +1294,10 @@ lpfc_cmd_blksize(struct scsi_cmnd *sc) * @apptag: (out) BlockGuard application tag for transmitted data * @new_guard (in) Value to replace CRC with if needed * - * Returns BG_ERR_* bit mask or 0 if request ignored + * Returns (1) if error injection is detected by Initiator + * Returns (2) if error injection is detected by Target + * Returns (3) if swapping CSUM->CRC is required for error injection + * Returns (4) disabling Guard/Ref/App checking is required for error injection **/ static int lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, @@ -1312,10 +1305,7 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, { struct scatterlist *sgpe; /* s/g prot entry */ struct scatterlist *sgde; /* s/g data entry */ - struct lpfc_scsi_buf *lpfc_cmd = NULL; struct scsi_dif_tuple *src = NULL; - struct lpfc_nodelist *ndlp; - struct lpfc_rport_data *rdata; uint32_t op = scsi_get_prot_op(sc); uint32_t blksize; uint32_t numblks; @@ -1328,9 +1318,8 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, sgpe = scsi_prot_sglist(sc); sgde = scsi_sglist(sc); - lba = scsi_get_lba(sc); - /* First check if we need to match the LBA */ + lba = scsi_get_lba(sc); if (phba->lpfc_injerr_lba != LPFC_INJERR_LBA_OFF) { blksize = lpfc_cmd_blksize(sc); numblks = (scsi_bufflen(sc) + blksize - 1) / blksize; @@ -1345,123 +1334,66 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, sizeof(struct scsi_dif_tuple); if (numblks < blockoff) blockoff = numblks; + src = (struct scsi_dif_tuple *)sg_virt(sgpe); + src += blockoff; } } - /* Next check if we need to match the remote NPortID or WWPN */ - rdata = sc->device->hostdata; - if (rdata && rdata->pnode) { - ndlp = rdata->pnode; - - /* Make sure we have the right NPortID if one is specified */ - if (phba->lpfc_injerr_nportid && - (phba->lpfc_injerr_nportid != ndlp->nlp_DID)) - return 0; - - /* - * Make sure we have the right WWPN if one is specified. - * wwn[0] should be a non-zero NAA in a good WWPN. - */ - if (phba->lpfc_injerr_wwpn.u.wwn[0] && - (memcmp(&ndlp->nlp_portname, &phba->lpfc_injerr_wwpn, - sizeof(struct lpfc_name)) != 0)) - return 0; - } - - /* Setup a ptr to the protection data if the SCSI host provides it */ - if (sgpe) { - src = (struct scsi_dif_tuple *)sg_virt(sgpe); - src += blockoff; - lpfc_cmd = (struct lpfc_scsi_buf *)sc->host_scribble; - } - /* Should we change the Reference Tag */ if (reftag) { if (phba->lpfc_injerr_wref_cnt) { switch (op) { case SCSI_PROT_WRITE_PASS: - if (src) { - /* - * For WRITE_PASS, force the error - * to be sent on the wire. It should - * be detected by the Target. - * If blockoff != 0 error will be - * inserted in middle of the IO. - */ + if (blockoff && src) { + /* Insert error in middle of the IO */ lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9076 BLKGRD: Injecting reftag error: " "write lba x%lx + x%x oldrefTag x%x\n", (unsigned long)lba, blockoff, - be32_to_cpu(src->ref_tag)); + src->ref_tag); /* - * Save the old ref_tag so we can - * restore it on completion. + * NOTE, this will change ref tag in + * the memory location forever! */ - if (lpfc_cmd) { - lpfc_cmd->prot_data_type = - LPFC_INJERR_REFTAG; - lpfc_cmd->prot_data_segment = - src; - lpfc_cmd->prot_data = - src->ref_tag; - } - src->ref_tag = cpu_to_be32(0xDEADBEEF); + src->ref_tag = 0xDEADBEEF; phba->lpfc_injerr_wref_cnt--; - if (phba->lpfc_injerr_wref_cnt == 0) { - phba->lpfc_injerr_nportid = 0; - phba->lpfc_injerr_lba = - LPFC_INJERR_LBA_OFF; - memset(&phba->lpfc_injerr_wwpn, - 0, sizeof(struct lpfc_name)); - } - rc = BG_ERR_TGT | BG_ERR_CHECK; - + phba->lpfc_injerr_lba = + LPFC_INJERR_LBA_OFF; + rc = BG_ERR_CHECK; break; } /* Drop thru */ - case SCSI_PROT_WRITE_INSERT: + case SCSI_PROT_WRITE_STRIP: /* - * For WRITE_INSERT, force the error - * to be sent on the wire. It should be - * detected by the Target. + * For WRITE_STRIP and WRITE_PASS, + * force the error on data + * being copied from SLI-Host to SLI-Port. */ - /* DEADBEEF will be the reftag on the wire */ *reftag = 0xDEADBEEF; phba->lpfc_injerr_wref_cnt--; - if (phba->lpfc_injerr_wref_cnt == 0) { - phba->lpfc_injerr_nportid = 0; - phba->lpfc_injerr_lba = - LPFC_INJERR_LBA_OFF; - memset(&phba->lpfc_injerr_wwpn, - 0, sizeof(struct lpfc_name)); - } - rc = BG_ERR_TGT | BG_ERR_CHECK; + phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; + rc = BG_ERR_INIT; lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "9078 BLKGRD: Injecting reftag error: " + "9077 BLKGRD: Injecting reftag error: " "write lba x%lx\n", (unsigned long)lba); break; - case SCSI_PROT_WRITE_STRIP: + case SCSI_PROT_WRITE_INSERT: /* - * For WRITE_STRIP and WRITE_PASS, - * force the error on data - * being copied from SLI-Host to SLI-Port. + * For WRITE_INSERT, force the + * error to be sent on the wire. It should be + * detected by the Target. */ + /* DEADBEEF will be the reftag on the wire */ *reftag = 0xDEADBEEF; phba->lpfc_injerr_wref_cnt--; - if (phba->lpfc_injerr_wref_cnt == 0) { - phba->lpfc_injerr_nportid = 0; - phba->lpfc_injerr_lba = - LPFC_INJERR_LBA_OFF; - memset(&phba->lpfc_injerr_wwpn, - 0, sizeof(struct lpfc_name)); - } - rc = BG_ERR_INIT; + phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; + rc = BG_ERR_TGT; lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "9077 BLKGRD: Injecting reftag error: " + "9078 BLKGRD: Injecting reftag error: " "write lba x%lx\n", (unsigned long)lba); break; } @@ -1469,6 +1401,11 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, if (phba->lpfc_injerr_rref_cnt) { switch (op) { case SCSI_PROT_READ_INSERT: + /* + * For READ_INSERT, it doesn't make sense + * to change the reftag. + */ + break; case SCSI_PROT_READ_STRIP: case SCSI_PROT_READ_PASS: /* @@ -1478,13 +1415,7 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, */ *reftag = 0xDEADBEEF; phba->lpfc_injerr_rref_cnt--; - if (phba->lpfc_injerr_rref_cnt == 0) { - phba->lpfc_injerr_nportid = 0; - phba->lpfc_injerr_lba = - LPFC_INJERR_LBA_OFF; - memset(&phba->lpfc_injerr_wwpn, - 0, sizeof(struct lpfc_name)); - } + phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; rc = BG_ERR_INIT; lpfc_printf_log(phba, KERN_ERR, LOG_BG, @@ -1500,87 +1431,56 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, if (phba->lpfc_injerr_wapp_cnt) { switch (op) { case SCSI_PROT_WRITE_PASS: - if (src) { - /* - * For WRITE_PASS, force the error - * to be sent on the wire. It should - * be detected by the Target. - * If blockoff != 0 error will be - * inserted in middle of the IO. - */ + if (blockoff && src) { + /* Insert error in middle of the IO */ lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9080 BLKGRD: Injecting apptag error: " "write lba x%lx + x%x oldappTag x%x\n", (unsigned long)lba, blockoff, - be16_to_cpu(src->app_tag)); + src->app_tag); /* - * Save the old app_tag so we can - * restore it on completion. + * NOTE, this will change app tag in + * the memory location forever! */ - if (lpfc_cmd) { - lpfc_cmd->prot_data_type = - LPFC_INJERR_APPTAG; - lpfc_cmd->prot_data_segment = - src; - lpfc_cmd->prot_data = - src->app_tag; - } - src->app_tag = cpu_to_be16(0xDEAD); + src->app_tag = 0xDEAD; phba->lpfc_injerr_wapp_cnt--; - if (phba->lpfc_injerr_wapp_cnt == 0) { - phba->lpfc_injerr_nportid = 0; - phba->lpfc_injerr_lba = - LPFC_INJERR_LBA_OFF; - memset(&phba->lpfc_injerr_wwpn, - 0, sizeof(struct lpfc_name)); - } - rc = BG_ERR_TGT | BG_ERR_CHECK; + phba->lpfc_injerr_lba = + LPFC_INJERR_LBA_OFF; + rc = BG_ERR_CHECK; break; } /* Drop thru */ - case SCSI_PROT_WRITE_INSERT: + case SCSI_PROT_WRITE_STRIP: /* - * For WRITE_INSERT, force the - * error to be sent on the wire. It should be - * detected by the Target. + * For WRITE_STRIP and WRITE_PASS, + * force the error on data + * being copied from SLI-Host to SLI-Port. */ - /* DEAD will be the apptag on the wire */ *apptag = 0xDEAD; phba->lpfc_injerr_wapp_cnt--; - if (phba->lpfc_injerr_wapp_cnt == 0) { - phba->lpfc_injerr_nportid = 0; - phba->lpfc_injerr_lba = - LPFC_INJERR_LBA_OFF; - memset(&phba->lpfc_injerr_wwpn, - 0, sizeof(struct lpfc_name)); - } - rc = BG_ERR_TGT | BG_ERR_CHECK; + phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; + rc = BG_ERR_INIT; lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "0813 BLKGRD: Injecting apptag error: " + "0812 BLKGRD: Injecting apptag error: " "write lba x%lx\n", (unsigned long)lba); break; - case SCSI_PROT_WRITE_STRIP: + case SCSI_PROT_WRITE_INSERT: /* - * For WRITE_STRIP and WRITE_PASS, - * force the error on data - * being copied from SLI-Host to SLI-Port. + * For WRITE_INSERT, force the + * error to be sent on the wire. It should be + * detected by the Target. */ + /* DEAD will be the apptag on the wire */ *apptag = 0xDEAD; phba->lpfc_injerr_wapp_cnt--; - if (phba->lpfc_injerr_wapp_cnt == 0) { - phba->lpfc_injerr_nportid = 0; - phba->lpfc_injerr_lba = - LPFC_INJERR_LBA_OFF; - memset(&phba->lpfc_injerr_wwpn, - 0, sizeof(struct lpfc_name)); - } - rc = BG_ERR_INIT; + phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; + rc = BG_ERR_TGT; lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "0812 BLKGRD: Injecting apptag error: " + "0813 BLKGRD: Injecting apptag error: " "write lba x%lx\n", (unsigned long)lba); break; } @@ -1588,6 +1488,11 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, if (phba->lpfc_injerr_rapp_cnt) { switch (op) { case SCSI_PROT_READ_INSERT: + /* + * For READ_INSERT, it doesn't make sense + * to change the apptag. + */ + break; case SCSI_PROT_READ_STRIP: case SCSI_PROT_READ_PASS: /* @@ -1597,13 +1502,7 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, */ *apptag = 0xDEAD; phba->lpfc_injerr_rapp_cnt--; - if (phba->lpfc_injerr_rapp_cnt == 0) { - phba->lpfc_injerr_nportid = 0; - phba->lpfc_injerr_lba = - LPFC_INJERR_LBA_OFF; - memset(&phba->lpfc_injerr_wwpn, - 0, sizeof(struct lpfc_name)); - } + phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; rc = BG_ERR_INIT; lpfc_printf_log(phba, KERN_ERR, LOG_BG, @@ -1620,51 +1519,57 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, if (phba->lpfc_injerr_wgrd_cnt) { switch (op) { case SCSI_PROT_WRITE_PASS: - rc = BG_ERR_CHECK; - /* Drop thru */ + if (blockoff && src) { + /* Insert error in middle of the IO */ - case SCSI_PROT_WRITE_INSERT: - /* - * For WRITE_INSERT, force the - * error to be sent on the wire. It should be - * detected by the Target. - */ - phba->lpfc_injerr_wgrd_cnt--; - if (phba->lpfc_injerr_wgrd_cnt == 0) { - phba->lpfc_injerr_nportid = 0; + lpfc_printf_log(phba, KERN_ERR, LOG_BG, + "0815 BLKGRD: Injecting guard error: " + "write lba x%lx + x%x oldgrdTag x%x\n", + (unsigned long)lba, blockoff, + src->guard_tag); + + /* + * NOTE, this will change guard tag in + * the memory location forever! + */ + src->guard_tag = 0xDEAD; + phba->lpfc_injerr_wgrd_cnt--; phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; - memset(&phba->lpfc_injerr_wwpn, - 0, sizeof(struct lpfc_name)); + rc = BG_ERR_CHECK; + break; } + /* Drop thru */ + case SCSI_PROT_WRITE_STRIP: + /* + * For WRITE_STRIP and WRITE_PASS, + * force the error on data + * being copied from SLI-Host to SLI-Port. + */ + phba->lpfc_injerr_wgrd_cnt--; + phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; - rc |= BG_ERR_TGT | BG_ERR_SWAP; + rc = BG_ERR_SWAP; /* Signals the caller to swap CRC->CSUM */ lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "0817 BLKGRD: Injecting guard error: " + "0816 BLKGRD: Injecting guard error: " "write lba x%lx\n", (unsigned long)lba); break; - case SCSI_PROT_WRITE_STRIP: + case SCSI_PROT_WRITE_INSERT: /* - * For WRITE_STRIP and WRITE_PASS, - * force the error on data - * being copied from SLI-Host to SLI-Port. + * For WRITE_INSERT, force the + * error to be sent on the wire. It should be + * detected by the Target. */ phba->lpfc_injerr_wgrd_cnt--; - if (phba->lpfc_injerr_wgrd_cnt == 0) { - phba->lpfc_injerr_nportid = 0; - phba->lpfc_injerr_lba = - LPFC_INJERR_LBA_OFF; - memset(&phba->lpfc_injerr_wwpn, - 0, sizeof(struct lpfc_name)); - } + phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; - rc = BG_ERR_INIT | BG_ERR_SWAP; + rc = BG_ERR_SWAP; /* Signals the caller to swap CRC->CSUM */ lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "0816 BLKGRD: Injecting guard error: " + "0817 BLKGRD: Injecting guard error: " "write lba x%lx\n", (unsigned long)lba); break; } @@ -1672,6 +1577,11 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, if (phba->lpfc_injerr_rgrd_cnt) { switch (op) { case SCSI_PROT_READ_INSERT: + /* + * For READ_INSERT, it doesn't make sense + * to change the guard tag. + */ + break; case SCSI_PROT_READ_STRIP: case SCSI_PROT_READ_PASS: /* @@ -1679,16 +1589,11 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, * error on data being read off the wire. It * should force an IO error to the driver. */ + *apptag = 0xDEAD; phba->lpfc_injerr_rgrd_cnt--; - if (phba->lpfc_injerr_rgrd_cnt == 0) { - phba->lpfc_injerr_nportid = 0; - phba->lpfc_injerr_lba = - LPFC_INJERR_LBA_OFF; - memset(&phba->lpfc_injerr_wwpn, - 0, sizeof(struct lpfc_name)); - } + phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; - rc = BG_ERR_INIT | BG_ERR_SWAP; + rc = BG_ERR_SWAP; /* Signals the caller to swap CRC->CSUM */ lpfc_printf_log(phba, KERN_ERR, LOG_BG, @@ -1724,20 +1629,20 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc, switch (scsi_get_prot_op(sc)) { case SCSI_PROT_READ_INSERT: case SCSI_PROT_WRITE_STRIP: - *rxop = BG_OP_IN_NODIF_OUT_CSUM; *txop = BG_OP_IN_CSUM_OUT_NODIF; + *rxop = BG_OP_IN_NODIF_OUT_CSUM; break; case SCSI_PROT_READ_STRIP: case SCSI_PROT_WRITE_INSERT: - *rxop = BG_OP_IN_CRC_OUT_NODIF; *txop = BG_OP_IN_NODIF_OUT_CRC; + *rxop = BG_OP_IN_CRC_OUT_NODIF; break; case SCSI_PROT_READ_PASS: case SCSI_PROT_WRITE_PASS: - *rxop = BG_OP_IN_CRC_OUT_CSUM; *txop = BG_OP_IN_CSUM_OUT_CRC; + *rxop = BG_OP_IN_CRC_OUT_CSUM; break; case SCSI_PROT_NORMAL: @@ -1753,20 +1658,20 @@ lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc, switch (scsi_get_prot_op(sc)) { case SCSI_PROT_READ_STRIP: case SCSI_PROT_WRITE_INSERT: - *rxop = BG_OP_IN_CRC_OUT_NODIF; *txop = BG_OP_IN_NODIF_OUT_CRC; + *rxop = BG_OP_IN_CRC_OUT_NODIF; break; case SCSI_PROT_READ_PASS: case SCSI_PROT_WRITE_PASS: - *rxop = BG_OP_IN_CRC_OUT_CRC; *txop = BG_OP_IN_CRC_OUT_CRC; + *rxop = BG_OP_IN_CRC_OUT_CRC; break; case SCSI_PROT_READ_INSERT: case SCSI_PROT_WRITE_STRIP: - *rxop = BG_OP_IN_NODIF_OUT_CRC; *txop = BG_OP_IN_CRC_OUT_NODIF; + *rxop = BG_OP_IN_NODIF_OUT_CRC; break; case SCSI_PROT_NORMAL: @@ -1805,20 +1710,20 @@ lpfc_bg_err_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc, switch (scsi_get_prot_op(sc)) { case SCSI_PROT_READ_INSERT: case SCSI_PROT_WRITE_STRIP: - *rxop = BG_OP_IN_NODIF_OUT_CRC; *txop = BG_OP_IN_CRC_OUT_NODIF; + *rxop = BG_OP_IN_NODIF_OUT_CRC; break; case SCSI_PROT_READ_STRIP: case SCSI_PROT_WRITE_INSERT: - *rxop = BG_OP_IN_CSUM_OUT_NODIF; *txop = BG_OP_IN_NODIF_OUT_CSUM; + *rxop = BG_OP_IN_CSUM_OUT_NODIF; break; case SCSI_PROT_READ_PASS: case SCSI_PROT_WRITE_PASS: - *rxop = BG_OP_IN_CSUM_OUT_CRC; - *txop = BG_OP_IN_CRC_OUT_CSUM; + *txop = BG_OP_IN_CRC_OUT_CRC; + *rxop = BG_OP_IN_CRC_OUT_CRC; break; case SCSI_PROT_NORMAL: @@ -1830,20 +1735,20 @@ lpfc_bg_err_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc, switch (scsi_get_prot_op(sc)) { case SCSI_PROT_READ_STRIP: case SCSI_PROT_WRITE_INSERT: - *rxop = BG_OP_IN_CSUM_OUT_NODIF; *txop = BG_OP_IN_NODIF_OUT_CSUM; + *rxop = BG_OP_IN_CSUM_OUT_NODIF; break; case SCSI_PROT_READ_PASS: case SCSI_PROT_WRITE_PASS: - *rxop = BG_OP_IN_CSUM_OUT_CSUM; - *txop = BG_OP_IN_CSUM_OUT_CSUM; + *txop = BG_OP_IN_CSUM_OUT_CRC; + *rxop = BG_OP_IN_CRC_OUT_CSUM; break; case SCSI_PROT_READ_INSERT: case SCSI_PROT_WRITE_STRIP: - *rxop = BG_OP_IN_NODIF_OUT_CSUM; *txop = BG_OP_IN_CSUM_OUT_NODIF; + *rxop = BG_OP_IN_NODIF_OUT_CSUM; break; case SCSI_PROT_NORMAL: @@ -1912,11 +1817,11 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */ #ifdef CONFIG_SCSI_LPFC_DEBUG_FS - rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); + rc = lpfc_bg_err_inject(phba, sc, &reftag, 0, 1); if (rc) { - if (rc & BG_ERR_SWAP) + if (rc == BG_ERR_SWAP) lpfc_bg_err_opcodes(phba, sc, &txop, &rxop); - if (rc & BG_ERR_CHECK) + if (rc == BG_ERR_CHECK) checking = 0; } #endif @@ -2059,11 +1964,11 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */ #ifdef CONFIG_SCSI_LPFC_DEBUG_FS - rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); + rc = lpfc_bg_err_inject(phba, sc, &reftag, 0, 1); if (rc) { - if (rc & BG_ERR_SWAP) + if (rc == BG_ERR_SWAP) lpfc_bg_err_opcodes(phba, sc, &txop, &rxop); - if (rc & BG_ERR_CHECK) + if (rc == BG_ERR_CHECK) checking = 0; } #endif @@ -2267,11 +2172,11 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */ #ifdef CONFIG_SCSI_LPFC_DEBUG_FS - rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); + rc = lpfc_bg_err_inject(phba, sc, &reftag, 0, 1); if (rc) { - if (rc & BG_ERR_SWAP) + if (rc == BG_ERR_SWAP) lpfc_bg_err_opcodes(phba, sc, &txop, &rxop); - if (rc & BG_ERR_CHECK) + if (rc == BG_ERR_CHECK) checking = 0; } #endif @@ -2407,11 +2312,11 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */ #ifdef CONFIG_SCSI_LPFC_DEBUG_FS - rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); + rc = lpfc_bg_err_inject(phba, sc, &reftag, 0, 1); if (rc) { - if (rc & BG_ERR_SWAP) + if (rc == BG_ERR_SWAP) lpfc_bg_err_opcodes(phba, sc, &txop, &rxop); - if (rc & BG_ERR_CHECK) + if (rc == BG_ERR_CHECK) checking = 0; } #endif @@ -2883,7 +2788,7 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd, /* No error was reported - problem in FW? */ cmd->result = ScsiResult(DID_ERROR, 0); lpfc_printf_log(phba, KERN_ERR, LOG_BG, - "9057 BLKGRD: Unknown error reported!\n"); + "9057 BLKGRD: no errors reported!\n"); } out: @@ -3555,37 +3460,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, /* pick up SLI4 exhange busy status from HBA */ lpfc_cmd->exch_busy = pIocbOut->iocb_flag & LPFC_EXCHANGE_BUSY; -#ifdef CONFIG_SCSI_LPFC_DEBUG_FS - if (lpfc_cmd->prot_data_type) { - struct scsi_dif_tuple *src = NULL; - - src = (struct scsi_dif_tuple *)lpfc_cmd->prot_data_segment; - /* - * Used to restore any changes to protection - * data for error injection. - */ - switch (lpfc_cmd->prot_data_type) { - case LPFC_INJERR_REFTAG: - src->ref_tag = - lpfc_cmd->prot_data; - break; - case LPFC_INJERR_APPTAG: - src->app_tag = - (uint16_t)lpfc_cmd->prot_data; - break; - case LPFC_INJERR_GUARD: - src->guard_tag = - (uint16_t)lpfc_cmd->prot_data; - break; - default: - break; - } - - lpfc_cmd->prot_data = 0; - lpfc_cmd->prot_data_type = 0; - lpfc_cmd->prot_data_segment = NULL; - } -#endif if (pnode && NLP_CHK_NODE_ACT(pnode)) atomic_dec(&pnode->cmd_pending); @@ -4187,6 +4061,15 @@ lpfc_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) cmnd->result = err; goto out_fail_command; } + /* + * Do not let the mid-layer retry I/O too fast. If an I/O is retried + * without waiting a bit then indicate that the device is busy. + */ + if (cmnd->retries && + time_before(jiffies, (cmnd->jiffies_at_alloc + + msecs_to_jiffies(LPFC_RETRY_PAUSE * + cmnd->retries)))) + return SCSI_MLQUEUE_DEVICE_BUSY; ndlp = rdata->pnode; if ((scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) && @@ -4236,48 +4119,63 @@ lpfc_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) if (scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) { if (vport->phba->cfg_enable_bg) { lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, - "9033 BLKGRD: rcvd protected cmd:%02x op=%s " - "guard=%s\n", cmnd->cmnd[0], - dif_op_str[scsi_get_prot_op(cmnd)], - dif_grd_str[scsi_host_get_guard(shost)]); + "9033 BLKGRD: rcvd protected cmd:%02x op:%02x " + "str=%s\n", + cmnd->cmnd[0], scsi_get_prot_op(cmnd), + dif_op_str[scsi_get_prot_op(cmnd)]); + lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, + "9034 BLKGRD: CDB: %02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x\n", + cmnd->cmnd[0], cmnd->cmnd[1], cmnd->cmnd[2], + cmnd->cmnd[3], cmnd->cmnd[4], cmnd->cmnd[5], + cmnd->cmnd[6], cmnd->cmnd[7], cmnd->cmnd[8], + cmnd->cmnd[9]); if (cmnd->cmnd[0] == READ_10) lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, "9035 BLKGRD: READ @ sector %llu, " - "cnt %u, rpt %d\n", + "count %u\n", (unsigned long long)scsi_get_lba(cmnd), - blk_rq_sectors(cmnd->request), - (cmnd->cmnd[1]>>5)); + blk_rq_sectors(cmnd->request)); else if (cmnd->cmnd[0] == WRITE_10) lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, "9036 BLKGRD: WRITE @ sector %llu, " - "cnt %u, wpt %d\n", + "count %u cmd=%p\n", (unsigned long long)scsi_get_lba(cmnd), blk_rq_sectors(cmnd->request), - (cmnd->cmnd[1]>>5)); + cmnd); } err = lpfc_bg_scsi_prep_dma_buf(phba, lpfc_cmd); } else { if (vport->phba->cfg_enable_bg) { lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, - "9038 BLKGRD: rcvd unprotected cmd:" - "%02x op=%s guard=%s\n", cmnd->cmnd[0], - dif_op_str[scsi_get_prot_op(cmnd)], - dif_grd_str[scsi_host_get_guard(shost)]); + "9038 BLKGRD: rcvd unprotected cmd:" + "%02x op:%02x str=%s\n", + cmnd->cmnd[0], scsi_get_prot_op(cmnd), + dif_op_str[scsi_get_prot_op(cmnd)]); + lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, + "9039 BLKGRD: CDB: %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x\n", + cmnd->cmnd[0], cmnd->cmnd[1], + cmnd->cmnd[2], cmnd->cmnd[3], + cmnd->cmnd[4], cmnd->cmnd[5], + cmnd->cmnd[6], cmnd->cmnd[7], + cmnd->cmnd[8], cmnd->cmnd[9]); if (cmnd->cmnd[0] == READ_10) lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, "9040 dbg: READ @ sector %llu, " - "cnt %u, rpt %d\n", + "count %u\n", (unsigned long long)scsi_get_lba(cmnd), - blk_rq_sectors(cmnd->request), - (cmnd->cmnd[1]>>5)); + blk_rq_sectors(cmnd->request)); else if (cmnd->cmnd[0] == WRITE_10) lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, - "9041 dbg: WRITE @ sector %llu, " - "cnt %u, wpt %d\n", - (unsigned long long)scsi_get_lba(cmnd), - blk_rq_sectors(cmnd->request), - (cmnd->cmnd[1]>>5)); + "9041 dbg: WRITE @ sector %llu, " + "count %u cmd=%p\n", + (unsigned long long)scsi_get_lba(cmnd), + blk_rq_sectors(cmnd->request), cmnd); + else + lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, + "9042 dbg: parser not implemented\n"); } err = lpfc_scsi_prep_dma_buf(phba, lpfc_cmd); } diff --git a/trunk/drivers/scsi/lpfc/lpfc_scsi.h b/trunk/drivers/scsi/lpfc/lpfc_scsi.h index 21a2ffe67eac..9075a08cf781 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_scsi.h +++ b/trunk/drivers/scsi/lpfc/lpfc_scsi.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2006 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -150,18 +150,9 @@ struct lpfc_scsi_buf { struct lpfc_iocbq cur_iocbq; wait_queue_head_t *waitq; unsigned long start_time; - -#ifdef CONFIG_SCSI_LPFC_DEBUG_FS - /* Used to restore any changes to protection data for error injection */ - void *prot_data_segment; - uint32_t prot_data; - uint32_t prot_data_type; -#define LPFC_INJERR_REFTAG 1 -#define LPFC_INJERR_APPTAG 2 -#define LPFC_INJERR_GUARD 3 -#endif }; #define LPFC_SCSI_DMA_EXT_SIZE 264 #define LPFC_BPL_SIZE 1024 +#define LPFC_RETRY_PAUSE 300 #define MDAC_DIRECT_CMD 0x22 diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.c b/trunk/drivers/scsi/lpfc/lpfc_sli.c index dbaf5b963bff..e0e4d8d18244 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.c +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2011 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -5578,6 +5578,8 @@ lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *phba) for (i = 0; i < count; i++) phba->sli4_hba.rpi_ids[i] = base + i; + lpfc_sli4_node_prep(phba); + /* VPIs. */ count = phba->sli4_hba.max_cfg_param.max_vpi; base = phba->sli4_hba.max_cfg_param.vpi_base; @@ -5611,8 +5613,6 @@ lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *phba) rc = -ENOMEM; goto free_vpi_ids; } - phba->sli4_hba.max_cfg_param.xri_used = 0; - phba->sli4_hba.xri_count = 0; phba->sli4_hba.xri_ids = kzalloc(count * sizeof(uint16_t), GFP_KERNEL); @@ -6147,7 +6147,6 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) rc = -ENODEV; goto out_free_mbox; } - lpfc_sli4_node_prep(phba); /* Create all the SLI4 queues */ rc = lpfc_sli4_queue_create(phba); @@ -7252,13 +7251,11 @@ lpfc_sli4_post_async_mbox(struct lpfc_hba *phba) out_not_finished: spin_lock_irqsave(&phba->hbalock, iflags); - if (phba->sli.mbox_active) { - mboxq->u.mb.mbxStatus = MBX_NOT_FINISHED; - __lpfc_mbox_cmpl_put(phba, mboxq); - /* Release the token */ - psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; - phba->sli.mbox_active = NULL; - } + mboxq->u.mb.mbxStatus = MBX_NOT_FINISHED; + __lpfc_mbox_cmpl_put(phba, mboxq); + /* Release the token */ + psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; + phba->sli.mbox_active = NULL; spin_unlock_irqrestore(&phba->hbalock, iflags); return MBX_NOT_FINISHED; @@ -7746,7 +7743,6 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, if (pcmd && (*pcmd == ELS_CMD_FLOGI || *pcmd == ELS_CMD_SCR || *pcmd == ELS_CMD_FDISC || - *pcmd == ELS_CMD_LOGO || *pcmd == ELS_CMD_PLOGI)) { bf_set(els_req64_sp, &wqe->els_req, 1); bf_set(els_req64_sid, &wqe->els_req, @@ -8389,7 +8385,6 @@ lpfc_sli4_abts_err_handler(struct lpfc_hba *phba, struct sli4_wcqe_xri_aborted *axri) { struct lpfc_vport *vport; - uint32_t ext_status = 0; if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { lpfc_printf_log(phba, KERN_INFO, LOG_SLI, @@ -8401,20 +8396,12 @@ lpfc_sli4_abts_err_handler(struct lpfc_hba *phba, vport = ndlp->vport; lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, "3116 Port generated FCP XRI ABORT event on " - "vpi %d rpi %d xri x%x status 0x%x parameter x%x\n", + "vpi %d rpi %d xri x%x status 0x%x\n", ndlp->vport->vpi, ndlp->nlp_rpi, bf_get(lpfc_wcqe_xa_xri, axri), - bf_get(lpfc_wcqe_xa_status, axri), - axri->parameter); + bf_get(lpfc_wcqe_xa_status, axri)); - /* - * Catch the ABTS protocol failure case. Older OCe FW releases returned - * LOCAL_REJECT and 0 for a failed ABTS exchange and later OCe and - * LPe FW releases returned LOCAL_REJECT and SEQUENCE_TIMEOUT. - */ - ext_status = axri->parameter & WCQE_PARAM_MASK; - if ((bf_get(lpfc_wcqe_xa_status, axri) == IOSTAT_LOCAL_REJECT) && - ((ext_status == IOERR_SEQUENCE_TIMEOUT) || (ext_status == 0))) + if (bf_get(lpfc_wcqe_xa_status, axri) == IOSTAT_LOCAL_REJECT) lpfc_sli_abts_recover_port(vport, ndlp); } @@ -9820,11 +9807,12 @@ lpfc_sli_mbox_sys_shutdown(struct lpfc_hba *phba) unsigned long timeout; timeout = msecs_to_jiffies(LPFC_MBOX_TMO * 1000) + jiffies; - spin_lock_irq(&phba->hbalock); psli->sli_flag |= LPFC_SLI_ASYNC_MBX_BLK; + spin_unlock_irq(&phba->hbalock); if (psli->sli_flag & LPFC_SLI_ACTIVE) { + spin_lock_irq(&phba->hbalock); /* Determine how long we might wait for the active mailbox * command to be gracefully completed by firmware. */ @@ -9843,9 +9831,7 @@ lpfc_sli_mbox_sys_shutdown(struct lpfc_hba *phba) */ break; } - } else - spin_unlock_irq(&phba->hbalock); - + } lpfc_sli_mbox_sys_flush(phba); } @@ -13286,7 +13272,7 @@ lpfc_sli4_post_els_sgl_list_ext(struct lpfc_hba *phba) LPFC_MBOXQ_t *mbox; uint32_t reqlen, alloclen, index; uint32_t mbox_tmo; - uint16_t rsrc_start, rsrc_size, els_xri_cnt, post_els_xri_cnt; + uint16_t rsrc_start, rsrc_size, els_xri_cnt; uint16_t xritag_start = 0, lxri = 0; struct lpfc_rsrc_blks *rsrc_blk; int cnt, ttl_cnt, rc = 0; @@ -13308,7 +13294,6 @@ lpfc_sli4_post_els_sgl_list_ext(struct lpfc_hba *phba) cnt = 0; ttl_cnt = 0; - post_els_xri_cnt = els_xri_cnt; list_for_each_entry(rsrc_blk, &phba->sli4_hba.lpfc_xri_blk_list, list) { rsrc_start = rsrc_blk->rsrc_start; @@ -13318,12 +13303,11 @@ lpfc_sli4_post_els_sgl_list_ext(struct lpfc_hba *phba) "3014 Working ELS Extent start %d, cnt %d\n", rsrc_start, rsrc_size); - loop_cnt = min(post_els_xri_cnt, rsrc_size); - if (loop_cnt < post_els_xri_cnt) { - post_els_xri_cnt -= loop_cnt; - ttl_cnt += loop_cnt; - } else - ttl_cnt += post_els_xri_cnt; + loop_cnt = min(els_xri_cnt, rsrc_size); + if (ttl_cnt + loop_cnt >= els_xri_cnt) { + loop_cnt = els_xri_cnt - ttl_cnt; + ttl_cnt = els_xri_cnt; + } mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!mbox) @@ -14219,14 +14203,15 @@ lpfc_sli4_seq_abort_rsp(struct lpfc_hba *phba, * field and RX_ID from ABTS for RX_ID field. */ bf_set(lpfc_abts_orig, &icmd->un.bls_rsp, LPFC_ABTS_UNSOL_RSP); + bf_set(lpfc_abts_rxid, &icmd->un.bls_rsp, rxid); } else { /* ABTS sent by initiator to CT exchange, construction * of BA_ACC will need to allocate a new XRI as for the - * XRI_TAG field. + * XRI_TAG and RX_ID fields. */ bf_set(lpfc_abts_orig, &icmd->un.bls_rsp, LPFC_ABTS_UNSOL_INT); + bf_set(lpfc_abts_rxid, &icmd->un.bls_rsp, NO_XRI); } - bf_set(lpfc_abts_rxid, &icmd->un.bls_rsp, rxid); bf_set(lpfc_abts_oxid, &icmd->un.bls_rsp, oxid); /* Xmit CT abts response on exchange */ @@ -15057,7 +15042,6 @@ lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, uint16_t fcf_index) LPFC_MBOXQ_t *mboxq; phba->fcoe_eventtag_at_fcf_scan = phba->fcoe_eventtag; - phba->fcoe_cvl_eventtag_attn = phba->fcoe_cvl_eventtag; mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!mboxq) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, diff --git a/trunk/drivers/scsi/lpfc/lpfc_version.h b/trunk/drivers/scsi/lpfc/lpfc_version.h index 25cefc254b76..f2a2602e5c35 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_version.h +++ b/trunk/drivers/scsi/lpfc/lpfc_version.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2012 Emulex. All rights reserved. * + * Copyright (C) 2004-2011 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.3.30" +#define LPFC_DRIVER_VERSION "8.3.29" #define LPFC_DRIVER_NAME "lpfc" #define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp" #define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp" diff --git a/trunk/drivers/scsi/mpt2sas/mpt2sas_base.c b/trunk/drivers/scsi/mpt2sas/mpt2sas_base.c index 8a59a772fdf2..5e69f468535f 100644 --- a/trunk/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/trunk/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -657,7 +657,7 @@ _base_sas_log_info(struct MPT2SAS_ADAPTER *ioc , u32 log_info) return; /* eat the loginfos associated with task aborts */ - if (ioc->ignore_loginfos && (log_info == 0x30050000 || log_info == + if (ioc->ignore_loginfos && (log_info == 30050000 || log_info == 0x31140000 || log_info == 0x31130000)) return; @@ -2060,10 +2060,12 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) { int i = 0; char desc[16]; + u8 revision; u32 iounit_pg1_flags; u32 bios_version; bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion); + pci_read_config_byte(ioc->pdev, PCI_CLASS_REVISION, &revision); strncpy(desc, ioc->manu_pg0.ChipName, 16); printk(MPT2SAS_INFO_FMT "%s: FWVersion(%02d.%02d.%02d.%02d), " "ChipRevision(0x%02x), BiosVersion(%02d.%02d.%02d.%02d)\n", @@ -2072,7 +2074,7 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc) (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16, (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8, ioc->facts.FWVersion.Word & 0x000000FF, - ioc->pdev->revision, + revision, (bios_version & 0xFF000000) >> 24, (bios_version & 0x00FF0000) >> 16, (bios_version & 0x0000FF00) >> 8, diff --git a/trunk/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/trunk/drivers/scsi/mpt2sas/mpt2sas_ctl.c index 3b9a28efea82..7fceb899029e 100644 --- a/trunk/drivers/scsi/mpt2sas/mpt2sas_ctl.c +++ b/trunk/drivers/scsi/mpt2sas/mpt2sas_ctl.c @@ -1026,6 +1026,7 @@ _ctl_getiocinfo(void __user *arg) { struct mpt2_ioctl_iocinfo karg; struct MPT2SAS_ADAPTER *ioc; + u8 revision; if (copy_from_user(&karg, arg, sizeof(karg))) { printk(KERN_ERR "failure at %s:%d/%s()!\n", @@ -1045,7 +1046,8 @@ _ctl_getiocinfo(void __user *arg) karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2; if (ioc->pfacts) karg.port_number = ioc->pfacts[0].PortNumber; - karg.hw_rev = ioc->pdev->revision; + pci_read_config_byte(ioc->pdev, PCI_CLASS_REVISION, &revision); + karg.hw_rev = revision; karg.pci_id = ioc->pdev->device; karg.subsystem_device = ioc->pdev->subsystem_device; karg.subsystem_vendor = ioc->pdev->subsystem_vendor; diff --git a/trunk/drivers/scsi/pm8001/pm8001_hwi.c b/trunk/drivers/scsi/pm8001/pm8001_hwi.c index 9d82ee5c10de..3619f6eeeeda 100644 --- a/trunk/drivers/scsi/pm8001/pm8001_hwi.c +++ b/trunk/drivers/scsi/pm8001/pm8001_hwi.c @@ -2093,7 +2093,6 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) struct ata_task_resp *resp ; u32 *sata_resp; struct pm8001_device *pm8001_dev; - unsigned long flags; psataPayload = (struct sata_completion_resp *)(piomb + 4); status = le32_to_cpu(psataPayload->status); @@ -2383,26 +2382,26 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->stat = SAS_DEV_NO_RESPONSE; break; } - spin_lock_irqsave(&t->task_state_lock, flags); + spin_lock_irq(&t->task_state_lock); t->task_state_flags &= ~SAS_TASK_STATE_PENDING; t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; t->task_state_flags |= SAS_TASK_STATE_DONE; if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { - spin_unlock_irqrestore(&t->task_state_lock, flags); + spin_unlock_irq(&t->task_state_lock); PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("task 0x%p done with io_status 0x%x" " resp 0x%x stat 0x%x but aborted by upper layer!\n", t, status, ts->resp, ts->stat)); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); } else if (t->uldd_task) { - spin_unlock_irqrestore(&t->task_state_lock, flags); + spin_unlock_irq(&t->task_state_lock); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/* ditto */ spin_unlock_irq(&pm8001_ha->lock); t->task_done(t); spin_lock_irq(&pm8001_ha->lock); } else if (!t->uldd_task) { - spin_unlock_irqrestore(&t->task_state_lock, flags); + spin_unlock_irq(&t->task_state_lock); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/*ditto*/ spin_unlock_irq(&pm8001_ha->lock); @@ -2424,7 +2423,6 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) u32 tag = le32_to_cpu(psataPayload->tag); u32 port_id = le32_to_cpu(psataPayload->port_id); u32 dev_id = le32_to_cpu(psataPayload->device_id); - unsigned long flags; ccb = &pm8001_ha->ccb_info[tag]; t = ccb->task; @@ -2595,26 +2593,26 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->stat = SAS_OPEN_TO; break; } - spin_lock_irqsave(&t->task_state_lock, flags); + spin_lock_irq(&t->task_state_lock); t->task_state_flags &= ~SAS_TASK_STATE_PENDING; t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; t->task_state_flags |= SAS_TASK_STATE_DONE; if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { - spin_unlock_irqrestore(&t->task_state_lock, flags); + spin_unlock_irq(&t->task_state_lock); PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("task 0x%p done with io_status 0x%x" " resp 0x%x stat 0x%x but aborted by upper layer!\n", t, event, ts->resp, ts->stat)); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); } else if (t->uldd_task) { - spin_unlock_irqrestore(&t->task_state_lock, flags); + spin_unlock_irq(&t->task_state_lock); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/* ditto */ spin_unlock_irq(&pm8001_ha->lock); t->task_done(t); spin_lock_irq(&pm8001_ha->lock); } else if (!t->uldd_task) { - spin_unlock_irqrestore(&t->task_state_lock, flags); + spin_unlock_irq(&t->task_state_lock); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb();/*ditto*/ spin_unlock_irq(&pm8001_ha->lock); diff --git a/trunk/drivers/scsi/qla4xxx/ql4_isr.c b/trunk/drivers/scsi/qla4xxx/ql4_isr.c index fc542a9bb106..7c9f28b7da72 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_isr.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_isr.c @@ -431,9 +431,9 @@ static void qla4xxx_mbox_status_entry(struct scsi_qla_host *ha, mbox_sts_entry->out_mbox[6])); if (mbox_sts_entry->out_mbox[0] == MBOX_STS_COMMAND_COMPLETE) - status = ISCSI_PING_SUCCESS; + status = QLA_SUCCESS; else - status = mbox_sts_entry->out_mbox[6]; + status = QLA_ERROR; data_size = sizeof(mbox_sts_entry->out_mbox); diff --git a/trunk/drivers/scsi/qla4xxx/ql4_os.c b/trunk/drivers/scsi/qla4xxx/ql4_os.c index ee47820c30a6..3d9419460e0c 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_os.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_os.c @@ -834,7 +834,7 @@ static enum blk_eh_timer_return qla4xxx_eh_cmd_timed_out(struct scsi_cmnd *sc) static void qla4xxx_set_port_speed(struct Scsi_Host *shost) { struct scsi_qla_host *ha = to_qla_host(shost); - struct iscsi_cls_host *ihost = shost->shost_data; + struct iscsi_cls_host *ihost = shost_priv(shost); uint32_t speed = ISCSI_PORT_SPEED_UNKNOWN; qla4xxx_get_firmware_state(ha); @@ -859,7 +859,7 @@ static void qla4xxx_set_port_speed(struct Scsi_Host *shost) static void qla4xxx_set_port_state(struct Scsi_Host *shost) { struct scsi_qla_host *ha = to_qla_host(shost); - struct iscsi_cls_host *ihost = shost->shost_data; + struct iscsi_cls_host *ihost = shost_priv(shost); uint32_t state = ISCSI_PORT_STATE_DOWN; if (test_bit(AF_LINK_UP, &ha->flags)) @@ -3445,6 +3445,7 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha) int qla4_8xxx_iospace_config(struct scsi_qla_host *ha) { int status = 0; + uint8_t revision_id; unsigned long mem_base, mem_len, db_base, db_len; struct pci_dev *pdev = ha->pdev; @@ -3456,9 +3457,10 @@ int qla4_8xxx_iospace_config(struct scsi_qla_host *ha) goto iospace_error_exit; } + pci_read_config_byte(pdev, PCI_REVISION_ID, &revision_id); DEBUG2(printk(KERN_INFO "%s: revision-id=%d\n", - __func__, pdev->revision)); - ha->revision_id = pdev->revision; + __func__, revision_id)); + ha->revision_id = revision_id; /* remap phys address */ mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ diff --git a/trunk/drivers/scsi/qla4xxx/ql4_version.h b/trunk/drivers/scsi/qla4xxx/ql4_version.h index 97b30c108e36..ede9af944141 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_version.h +++ b/trunk/drivers/scsi/qla4xxx/ql4_version.h @@ -5,4 +5,4 @@ * See LICENSE.qla4xxx for copyright and licensing details. */ -#define QLA4XXX_DRIVER_VERSION "5.02.00-k16" +#define QLA4XXX_DRIVER_VERSION "5.02.00-k15" diff --git a/trunk/drivers/scsi/scsi_debug.c b/trunk/drivers/scsi/scsi_debug.c index 182d5a57ab74..591856131c4e 100644 --- a/trunk/drivers/scsi/scsi_debug.c +++ b/trunk/drivers/scsi/scsi_debug.c @@ -101,7 +101,6 @@ static const char * scsi_debug_version_date = "20100324"; #define DEF_LBPU 0 #define DEF_LBPWS 0 #define DEF_LBPWS10 0 -#define DEF_LBPRZ 1 #define DEF_LOWEST_ALIGNED 0 #define DEF_NO_LUN_0 0 #define DEF_NUM_PARTS 0 @@ -187,7 +186,6 @@ static int scsi_debug_vpd_use_hostno = DEF_VPD_USE_HOSTNO; static unsigned int scsi_debug_lbpu = DEF_LBPU; static unsigned int scsi_debug_lbpws = DEF_LBPWS; static unsigned int scsi_debug_lbpws10 = DEF_LBPWS10; -static unsigned int scsi_debug_lbprz = DEF_LBPRZ; static unsigned int scsi_debug_unmap_alignment = DEF_UNMAP_ALIGNMENT; static unsigned int scsi_debug_unmap_granularity = DEF_UNMAP_GRANULARITY; static unsigned int scsi_debug_unmap_max_blocks = DEF_UNMAP_MAX_BLOCKS; @@ -777,10 +775,10 @@ static int inquiry_evpd_b1(unsigned char *arr) return 0x3c; } -/* Logical block provisioning VPD page (SBC-3) */ +/* Thin provisioning VPD page (SBC-3) */ static int inquiry_evpd_b2(unsigned char *arr) { - memset(arr, 0, 0x4); + memset(arr, 0, 0x8); arr[0] = 0; /* threshold exponent */ if (scsi_debug_lbpu) @@ -792,10 +790,7 @@ static int inquiry_evpd_b2(unsigned char *arr) if (scsi_debug_lbpws10) arr[1] |= 1 << 5; - if (scsi_debug_lbprz) - arr[1] |= 1 << 2; - - return 0x4; + return 0x8; } #define SDEBUG_LONG_INQ_SZ 96 @@ -1076,11 +1071,8 @@ static int resp_readcap16(struct scsi_cmnd * scp, arr[13] = scsi_debug_physblk_exp & 0xf; arr[14] = (scsi_debug_lowest_aligned >> 8) & 0x3f; - if (scsi_debug_lbp()) { + if (scsi_debug_lbp()) arr[14] |= 0x80; /* LBPME */ - if (scsi_debug_lbprz) - arr[14] |= 0x40; /* LBPRZ */ - } arr[15] = scsi_debug_lowest_aligned & 0xff; @@ -2054,13 +2046,10 @@ static void unmap_region(sector_t lba, unsigned int len) block = lba + alignment; rem = do_div(block, granularity); - if (rem == 0 && lba + granularity <= end && block < map_size) { + if (rem == 0 && lba + granularity <= end && + block < map_size) clear_bit(block, map_storep); - if (scsi_debug_lbprz) - memset(fake_storep + - block * scsi_debug_sector_size, 0, - scsi_debug_sector_size); - } + lba += granularity - rem; } } @@ -2742,7 +2731,6 @@ module_param_named(guard, scsi_debug_guard, int, S_IRUGO); module_param_named(lbpu, scsi_debug_lbpu, int, S_IRUGO); module_param_named(lbpws, scsi_debug_lbpws, int, S_IRUGO); module_param_named(lbpws10, scsi_debug_lbpws10, int, S_IRUGO); -module_param_named(lbprz, scsi_debug_lbprz, int, S_IRUGO); module_param_named(lowest_aligned, scsi_debug_lowest_aligned, int, S_IRUGO); module_param_named(max_luns, scsi_debug_max_luns, int, S_IRUGO | S_IWUSR); module_param_named(max_queue, scsi_debug_max_queue, int, S_IRUGO | S_IWUSR); @@ -2784,7 +2772,6 @@ MODULE_PARM_DESC(guard, "protection checksum: 0=crc, 1=ip (def=0)"); MODULE_PARM_DESC(lbpu, "enable LBP, support UNMAP command (def=0)"); MODULE_PARM_DESC(lbpws, "enable LBP, support WRITE SAME(16) with UNMAP bit (def=0)"); MODULE_PARM_DESC(lbpws10, "enable LBP, support WRITE SAME(10) with UNMAP bit (def=0)"); -MODULE_PARM_DESC(lbprz, "unmapped blocks return 0 on read (def=1)"); MODULE_PARM_DESC(lowest_aligned, "lowest aligned lba (def=0)"); MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)"); MODULE_PARM_DESC(max_queue, "max number of queued commands (1 to 255(def))"); diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c index 386f0c53bea7..2cfcbffa41fd 100644 --- a/trunk/drivers/scsi/scsi_error.c +++ b/trunk/drivers/scsi/scsi_error.c @@ -835,7 +835,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, scsi_eh_restore_cmnd(scmd, &ses); - if (sdrv && sdrv->eh_action) + if (sdrv->eh_action) rtn = sdrv->eh_action(scmd, cmnd, cmnd_size, rtn); return rtn; diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index 5dfd7495d1a1..ead6405f3e51 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -1638,7 +1638,7 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, request_fn_proc *request_fn) { struct request_queue *q; - struct device *dev = shost->dma_dev; + struct device *dev = shost->shost_gendev.parent; q = blk_init_queue(request_fn, NULL); if (!q) diff --git a/trunk/drivers/scsi/scsi_transport_iscsi.c b/trunk/drivers/scsi/scsi_transport_iscsi.c index 1cf640e575da..fac31730addf 100644 --- a/trunk/drivers/scsi/scsi_transport_iscsi.c +++ b/trunk/drivers/scsi/scsi_transport_iscsi.c @@ -1486,7 +1486,7 @@ void iscsi_post_host_event(uint32_t host_no, struct iscsi_transport *transport, struct iscsi_uevent *ev; int len = NLMSG_SPACE(sizeof(*ev) + data_size); - skb = alloc_skb(len, GFP_NOIO); + skb = alloc_skb(len, GFP_KERNEL); if (!skb) { printk(KERN_ERR "gracefully ignored host event (%d):%d OOM\n", host_no, code); @@ -1504,7 +1504,7 @@ void iscsi_post_host_event(uint32_t host_no, struct iscsi_transport *transport, if (data_size) memcpy((char *)ev + sizeof(*ev), data, data_size); - iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_NOIO); + iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_KERNEL); } EXPORT_SYMBOL_GPL(iscsi_post_host_event); @@ -1517,7 +1517,7 @@ void iscsi_ping_comp_event(uint32_t host_no, struct iscsi_transport *transport, struct iscsi_uevent *ev; int len = NLMSG_SPACE(sizeof(*ev) + data_size); - skb = alloc_skb(len, GFP_NOIO); + skb = alloc_skb(len, GFP_KERNEL); if (!skb) { printk(KERN_ERR "gracefully ignored ping comp: OOM\n"); return; @@ -1533,7 +1533,7 @@ void iscsi_ping_comp_event(uint32_t host_no, struct iscsi_transport *transport, ev->r.ping_comp.data_size = data_size; memcpy((char *)ev + sizeof(*ev), data, data_size); - iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_NOIO); + iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_KERNEL); } EXPORT_SYMBOL_GPL(iscsi_ping_comp_event); diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index 5ba5c2a9e8e9..09e3df42a402 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/drivers/scsi/sd.c @@ -664,7 +664,7 @@ static void sd_unprep_fn(struct request_queue *q, struct request *rq) } /** - * sd_prep_fn - build a scsi (read or write) command from + * sd_init_command - build a scsi (read or write) command from * information in the request structure. * @SCpnt: pointer to mid-level's per scsi command structure that * contains request and into which the scsi command is written @@ -711,7 +711,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) ret = BLKPREP_KILL; SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt, - "sd_prep_fn: block=%llu, " + "sd_init_command: block=%llu, " "count=%d\n", (unsigned long long)block, this_count)); @@ -1212,14 +1212,9 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing) retval = -ENODEV; if (scsi_block_when_processing_errors(sdp)) { - retval = scsi_autopm_get_device(sdp); - if (retval) - goto out; - sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL); retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES, sshdr); - scsi_autopm_put_device(sdp); } /* failed to execute TUR, assume media not present */ @@ -2649,8 +2644,8 @@ static void sd_probe_async(void *data, async_cookie_t cookie) * (e.g. /dev/sda). More precisely it is the block device major * and minor number that is chosen here. * - * Assume sd_probe is not re-entrant (for time being) - * Also think about sd_probe() and sd_remove() running coincidentally. + * Assume sd_attach is not re-entrant (for time being) + * Also think about sd_attach() and sd_remove() running coincidentally. **/ static int sd_probe(struct device *dev) { @@ -2665,7 +2660,7 @@ static int sd_probe(struct device *dev) goto out; SCSI_LOG_HLQUEUE(3, sdev_printk(KERN_INFO, sdp, - "sd_probe\n")); + "sd_attach\n")); error = -ENOMEM; sdkp = kzalloc(sizeof(*sdkp), GFP_KERNEL); diff --git a/trunk/drivers/scsi/st.c b/trunk/drivers/scsi/st.c index e41998cb098e..a15f691f9d34 100644 --- a/trunk/drivers/scsi/st.c +++ b/trunk/drivers/scsi/st.c @@ -1105,12 +1105,6 @@ static int check_tape(struct scsi_tape *STp, struct file *filp) STp->drv_buffer)); } STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0; - if (!STp->drv_buffer && STp->immediate_filemark) { - printk(KERN_WARNING - "%s: non-buffered tape: disabling writing immediate filemarks\n", - name); - STp->immediate_filemark = 0; - } } st_release_request(SRpnt); SRpnt = NULL; @@ -1319,8 +1313,6 @@ static int st_flush(struct file *filp, fl_owner_t id) memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = WRITE_FILEMARKS; - if (STp->immediate_filemark) - cmd[1] = 1; cmd[4] = 1 + STp->two_fm; SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE, @@ -2188,9 +2180,8 @@ static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions, STp->scsi2_logical); printk(KERN_INFO - "%s: sysv: %d nowait: %d sili: %d nowait_filemark: %d\n", - name, STm->sysv, STp->immediate, STp->sili, - STp->immediate_filemark); + "%s: sysv: %d nowait: %d sili: %d\n", name, STm->sysv, STp->immediate, + STp->sili); printk(KERN_INFO "%s: debugging: %d\n", name, debugging); } @@ -2232,7 +2223,6 @@ static int st_set_options(struct scsi_tape *STp, long options) STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0; STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0; STp->immediate = (options & MT_ST_NOWAIT) != 0; - STp->immediate_filemark = (options & MT_ST_NOWAIT_EOF) != 0; STm->sysv = (options & MT_ST_SYSV) != 0; STp->sili = (options & MT_ST_SILI) != 0; DEB( debugging = (options & MT_ST_DEBUGGING) != 0; @@ -2264,8 +2254,6 @@ static int st_set_options(struct scsi_tape *STp, long options) STp->scsi2_logical = value; if ((options & MT_ST_NOWAIT) != 0) STp->immediate = value; - if ((options & MT_ST_NOWAIT_EOF) != 0) - STp->immediate_filemark = value; if ((options & MT_ST_SYSV) != 0) STm->sysv = value; if ((options & MT_ST_SILI) != 0) @@ -2725,8 +2713,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon cmd[0] = WRITE_FILEMARKS; if (cmd_in == MTWSM) cmd[1] = 2; - if (cmd_in == MTWEOFI || - (cmd_in == MTWEOF && STp->immediate_filemark)) + if (cmd_in == MTWEOFI) cmd[1] |= 1; cmd[2] = (arg >> 16); cmd[3] = (arg >> 8); @@ -4105,7 +4092,6 @@ static int st_probe(struct device *dev) tpnt->scsi2_logical = ST_SCSI2LOGICAL; tpnt->sili = ST_SILI; tpnt->immediate = ST_NOWAIT; - tpnt->immediate_filemark = 0; tpnt->default_drvbuffer = 0xff; /* No forced buffering */ tpnt->partition = 0; tpnt->new_partition = 0; @@ -4491,7 +4477,6 @@ st_options_show(struct device *dev, struct device_attribute *attr, char *buf) options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0; options |= STm->sysv ? MT_ST_SYSV : 0; options |= STp->immediate ? MT_ST_NOWAIT : 0; - options |= STp->immediate_filemark ? MT_ST_NOWAIT_EOF : 0; options |= STp->sili ? MT_ST_SILI : 0; l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options); diff --git a/trunk/drivers/scsi/st.h b/trunk/drivers/scsi/st.h index ea35632b986c..f91a67c6d968 100644 --- a/trunk/drivers/scsi/st.h +++ b/trunk/drivers/scsi/st.h @@ -120,7 +120,6 @@ struct scsi_tape { unsigned char c_algo; /* compression algorithm */ unsigned char pos_unknown; /* after reset position unknown */ unsigned char sili; /* use SILI when reading in variable b mode */ - unsigned char immediate_filemark; /* write filemark immediately */ int tape_type; int long_timeout; /* timeout for commands known to take long time */ diff --git a/trunk/drivers/scsi/ufs/Kconfig b/trunk/drivers/scsi/ufs/Kconfig deleted file mode 100644 index 8f27f9d6f91d..000000000000 --- a/trunk/drivers/scsi/ufs/Kconfig +++ /dev/null @@ -1,49 +0,0 @@ -# -# Kernel configuration file for the UFS Host Controller -# -# This code is based on drivers/scsi/ufs/Kconfig -# Copyright (C) 2011 Samsung Samsung India Software Operations -# -# Santosh Yaraganavi -# Vinayak Holikatti - -# 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. - -# NO WARRANTY -# THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR -# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT -# LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, -# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is -# solely responsible for determining the appropriateness of using and -# distributing the Program and assumes all risks associated with its -# exercise of rights under this Agreement, including but not limited to -# the risks and costs of program errors, damage to or loss of data, -# programs or equipment, and unavailability or interruption of operations. - -# DISCLAIMER OF LIABILITY -# NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -# USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED -# HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES - -# 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-1301, -# USA. - -config SCSI_UFSHCD - tristate "Universal Flash Storage host controller driver" - depends on PCI && SCSI - ---help--- - This is a generic driver which supports PCIe UFS Host controllers. diff --git a/trunk/drivers/scsi/ufs/Makefile b/trunk/drivers/scsi/ufs/Makefile deleted file mode 100644 index adf7895a6a91..000000000000 --- a/trunk/drivers/scsi/ufs/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -# UFSHCD makefile -obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o diff --git a/trunk/drivers/scsi/ufs/ufs.h b/trunk/drivers/scsi/ufs/ufs.h deleted file mode 100644 index b207529f8d54..000000000000 --- a/trunk/drivers/scsi/ufs/ufs.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Universal Flash Storage Host controller driver - * - * This code is based on drivers/scsi/ufs/ufs.h - * Copyright (C) 2011-2012 Samsung India Software Operations - * - * Santosh Yaraganavi - * Vinayak Holikatti - * - * 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. - * - * NO WARRANTY - * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT - * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is - * solely responsible for determining the appropriateness of using and - * distributing the Program and assumes all risks associated with its - * exercise of rights under this Agreement, including but not limited to - * the risks and costs of program errors, damage to or loss of data, - * programs or equipment, and unavailability or interruption of operations. - - * DISCLAIMER OF LIABILITY - * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED - * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES - - * 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-1301, - * USA. - */ - -#ifndef _UFS_H -#define _UFS_H - -#define MAX_CDB_SIZE 16 - -#define UPIU_HEADER_DWORD(byte3, byte2, byte1, byte0)\ - ((byte3 << 24) | (byte2 << 16) |\ - (byte1 << 8) | (byte0)) - -/* - * UFS Protocol Information Unit related definitions - */ - -/* Task management functions */ -enum { - UFS_ABORT_TASK = 0x01, - UFS_ABORT_TASK_SET = 0x02, - UFS_CLEAR_TASK_SET = 0x04, - UFS_LOGICAL_RESET = 0x08, - UFS_QUERY_TASK = 0x80, - UFS_QUERY_TASK_SET = 0x81, -}; - -/* UTP UPIU Transaction Codes Initiator to Target */ -enum { - UPIU_TRANSACTION_NOP_OUT = 0x00, - UPIU_TRANSACTION_COMMAND = 0x01, - UPIU_TRANSACTION_DATA_OUT = 0x02, - UPIU_TRANSACTION_TASK_REQ = 0x04, - UPIU_TRANSACTION_QUERY_REQ = 0x26, -}; - -/* UTP UPIU Transaction Codes Target to Initiator */ -enum { - UPIU_TRANSACTION_NOP_IN = 0x20, - UPIU_TRANSACTION_RESPONSE = 0x21, - UPIU_TRANSACTION_DATA_IN = 0x22, - UPIU_TRANSACTION_TASK_RSP = 0x24, - UPIU_TRANSACTION_READY_XFER = 0x31, - UPIU_TRANSACTION_QUERY_RSP = 0x36, -}; - -/* UPIU Read/Write flags */ -enum { - UPIU_CMD_FLAGS_NONE = 0x00, - UPIU_CMD_FLAGS_WRITE = 0x20, - UPIU_CMD_FLAGS_READ = 0x40, -}; - -/* UPIU Task Attributes */ -enum { - UPIU_TASK_ATTR_SIMPLE = 0x00, - UPIU_TASK_ATTR_ORDERED = 0x01, - UPIU_TASK_ATTR_HEADQ = 0x02, - UPIU_TASK_ATTR_ACA = 0x03, -}; - -/* UTP QUERY Transaction Specific Fields OpCode */ -enum { - UPIU_QUERY_OPCODE_NOP = 0x0, - UPIU_QUERY_OPCODE_READ_DESC = 0x1, - UPIU_QUERY_OPCODE_WRITE_DESC = 0x2, - UPIU_QUERY_OPCODE_READ_ATTR = 0x3, - UPIU_QUERY_OPCODE_WRITE_ATTR = 0x4, - UPIU_QUERY_OPCODE_READ_FLAG = 0x5, - UPIU_QUERY_OPCODE_SET_FLAG = 0x6, - UPIU_QUERY_OPCODE_CLEAR_FLAG = 0x7, - UPIU_QUERY_OPCODE_TOGGLE_FLAG = 0x8, -}; - -/* UTP Transfer Request Command Type (CT) */ -enum { - UPIU_COMMAND_SET_TYPE_SCSI = 0x0, - UPIU_COMMAND_SET_TYPE_UFS = 0x1, - UPIU_COMMAND_SET_TYPE_QUERY = 0x2, -}; - -enum { - MASK_SCSI_STATUS = 0xFF, - MASK_TASK_RESPONSE = 0xFF00, - MASK_RSP_UPIU_RESULT = 0xFFFF, -}; - -/* Task management service response */ -enum { - UPIU_TASK_MANAGEMENT_FUNC_COMPL = 0x00, - UPIU_TASK_MANAGEMENT_FUNC_NOT_SUPPORTED = 0x04, - UPIU_TASK_MANAGEMENT_FUNC_SUCCEEDED = 0x08, - UPIU_TASK_MANAGEMENT_FUNC_FAILED = 0x05, - UPIU_INCORRECT_LOGICAL_UNIT_NO = 0x09, -}; -/** - * struct utp_upiu_header - UPIU header structure - * @dword_0: UPIU header DW-0 - * @dword_1: UPIU header DW-1 - * @dword_2: UPIU header DW-2 - */ -struct utp_upiu_header { - u32 dword_0; - u32 dword_1; - u32 dword_2; -}; - -/** - * struct utp_upiu_cmd - Command UPIU structure - * @header: UPIU header structure DW-0 to DW-2 - * @data_transfer_len: Data Transfer Length DW-3 - * @cdb: Command Descriptor Block CDB DW-4 to DW-7 - */ -struct utp_upiu_cmd { - struct utp_upiu_header header; - u32 exp_data_transfer_len; - u8 cdb[MAX_CDB_SIZE]; -}; - -/** - * struct utp_upiu_rsp - Response UPIU structure - * @header: UPIU header DW-0 to DW-2 - * @residual_transfer_count: Residual transfer count DW-3 - * @reserved: Reserved double words DW-4 to DW-7 - * @sense_data_len: Sense data length DW-8 U16 - * @sense_data: Sense data field DW-8 to DW-12 - */ -struct utp_upiu_rsp { - struct utp_upiu_header header; - u32 residual_transfer_count; - u32 reserved[4]; - u16 sense_data_len; - u8 sense_data[18]; -}; - -/** - * struct utp_upiu_task_req - Task request UPIU structure - * @header - UPIU header structure DW0 to DW-2 - * @input_param1: Input parameter 1 DW-3 - * @input_param2: Input parameter 2 DW-4 - * @input_param3: Input parameter 3 DW-5 - * @reserved: Reserved double words DW-6 to DW-7 - */ -struct utp_upiu_task_req { - struct utp_upiu_header header; - u32 input_param1; - u32 input_param2; - u32 input_param3; - u32 reserved[2]; -}; - -/** - * struct utp_upiu_task_rsp - Task Management Response UPIU structure - * @header: UPIU header structure DW0-DW-2 - * @output_param1: Ouput parameter 1 DW3 - * @output_param2: Output parameter 2 DW4 - * @reserved: Reserved double words DW-5 to DW-7 - */ -struct utp_upiu_task_rsp { - struct utp_upiu_header header; - u32 output_param1; - u32 output_param2; - u32 reserved[3]; -}; - -#endif /* End of Header */ diff --git a/trunk/drivers/scsi/ufs/ufshcd.c b/trunk/drivers/scsi/ufs/ufshcd.c deleted file mode 100644 index 52b96e8bf92e..000000000000 --- a/trunk/drivers/scsi/ufs/ufshcd.c +++ /dev/null @@ -1,1978 +0,0 @@ -/* - * Universal Flash Storage Host controller driver - * - * This code is based on drivers/scsi/ufs/ufshcd.c - * Copyright (C) 2011-2012 Samsung India Software Operations - * - * Santosh Yaraganavi - * Vinayak Holikatti - * - * 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. - * - * NO WARRANTY - * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT - * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is - * solely responsible for determining the appropriateness of using and - * distributing the Program and assumes all risks associated with its - * exercise of rights under this Agreement, including but not limited to - * the risks and costs of program errors, damage to or loss of data, - * programs or equipment, and unavailability or interruption of operations. - - * DISCLAIMER OF LIABILITY - * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED - * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES - - * 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-1301, - * USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ufs.h" -#include "ufshci.h" - -#define UFSHCD "ufshcd" -#define UFSHCD_DRIVER_VERSION "0.1" - -enum { - UFSHCD_MAX_CHANNEL = 0, - UFSHCD_MAX_ID = 1, - UFSHCD_MAX_LUNS = 8, - UFSHCD_CMD_PER_LUN = 32, - UFSHCD_CAN_QUEUE = 32, -}; - -/* UFSHCD states */ -enum { - UFSHCD_STATE_OPERATIONAL, - UFSHCD_STATE_RESET, - UFSHCD_STATE_ERROR, -}; - -/* Interrupt configuration options */ -enum { - UFSHCD_INT_DISABLE, - UFSHCD_INT_ENABLE, - UFSHCD_INT_CLEAR, -}; - -/* Interrupt aggregation options */ -enum { - INT_AGGR_RESET, - INT_AGGR_CONFIG, -}; - -/** - * struct uic_command - UIC command structure - * @command: UIC command - * @argument1: UIC command argument 1 - * @argument2: UIC command argument 2 - * @argument3: UIC command argument 3 - * @cmd_active: Indicate if UIC command is outstanding - * @result: UIC command result - */ -struct uic_command { - u32 command; - u32 argument1; - u32 argument2; - u32 argument3; - int cmd_active; - int result; -}; - -/** - * struct ufs_hba - per adapter private structure - * @mmio_base: UFSHCI base register address - * @ucdl_base_addr: UFS Command Descriptor base address - * @utrdl_base_addr: UTP Transfer Request Descriptor base address - * @utmrdl_base_addr: UTP Task Management Descriptor base address - * @ucdl_dma_addr: UFS Command Descriptor DMA address - * @utrdl_dma_addr: UTRDL DMA address - * @utmrdl_dma_addr: UTMRDL DMA address - * @host: Scsi_Host instance of the driver - * @pdev: PCI device handle - * @lrb: local reference block - * @outstanding_tasks: Bits representing outstanding task requests - * @outstanding_reqs: Bits representing outstanding transfer requests - * @capabilities: UFS Controller Capabilities - * @nutrs: Transfer Request Queue depth supported by controller - * @nutmrs: Task Management Queue depth supported by controller - * @active_uic_cmd: handle of active UIC command - * @ufshcd_tm_wait_queue: wait queue for task management - * @tm_condition: condition variable for task management - * @ufshcd_state: UFSHCD states - * @int_enable_mask: Interrupt Mask Bits - * @uic_workq: Work queue for UIC completion handling - * @feh_workq: Work queue for fatal controller error handling - * @errors: HBA errors - */ -struct ufs_hba { - void __iomem *mmio_base; - - /* Virtual memory reference */ - struct utp_transfer_cmd_desc *ucdl_base_addr; - struct utp_transfer_req_desc *utrdl_base_addr; - struct utp_task_req_desc *utmrdl_base_addr; - - /* DMA memory reference */ - dma_addr_t ucdl_dma_addr; - dma_addr_t utrdl_dma_addr; - dma_addr_t utmrdl_dma_addr; - - struct Scsi_Host *host; - struct pci_dev *pdev; - - struct ufshcd_lrb *lrb; - - unsigned long outstanding_tasks; - unsigned long outstanding_reqs; - - u32 capabilities; - int nutrs; - int nutmrs; - u32 ufs_version; - - struct uic_command active_uic_cmd; - wait_queue_head_t ufshcd_tm_wait_queue; - unsigned long tm_condition; - - u32 ufshcd_state; - u32 int_enable_mask; - - /* Work Queues */ - struct work_struct uic_workq; - struct work_struct feh_workq; - - /* HBA Errors */ - u32 errors; -}; - -/** - * struct ufshcd_lrb - local reference block - * @utr_descriptor_ptr: UTRD address of the command - * @ucd_cmd_ptr: UCD address of the command - * @ucd_rsp_ptr: Response UPIU address for this command - * @ucd_prdt_ptr: PRDT address of the command - * @cmd: pointer to SCSI command - * @sense_buffer: pointer to sense buffer address of the SCSI command - * @sense_bufflen: Length of the sense buffer - * @scsi_status: SCSI status of the command - * @command_type: SCSI, UFS, Query. - * @task_tag: Task tag of the command - * @lun: LUN of the command - */ -struct ufshcd_lrb { - struct utp_transfer_req_desc *utr_descriptor_ptr; - struct utp_upiu_cmd *ucd_cmd_ptr; - struct utp_upiu_rsp *ucd_rsp_ptr; - struct ufshcd_sg_entry *ucd_prdt_ptr; - - struct scsi_cmnd *cmd; - u8 *sense_buffer; - unsigned int sense_bufflen; - int scsi_status; - - int command_type; - int task_tag; - unsigned int lun; -}; - -/** - * ufshcd_get_ufs_version - Get the UFS version supported by the HBA - * @hba - Pointer to adapter instance - * - * Returns UFSHCI version supported by the controller - */ -static inline u32 ufshcd_get_ufs_version(struct ufs_hba *hba) -{ - return readl(hba->mmio_base + REG_UFS_VERSION); -} - -/** - * ufshcd_is_device_present - Check if any device connected to - * the host controller - * @reg_hcs - host controller status register value - * - * Returns 0 if device present, non-zero if no device detected - */ -static inline int ufshcd_is_device_present(u32 reg_hcs) -{ - return (DEVICE_PRESENT & reg_hcs) ? 0 : -1; -} - -/** - * ufshcd_get_tr_ocs - Get the UTRD Overall Command Status - * @lrb: pointer to local command reference block - * - * This function is used to get the OCS field from UTRD - * Returns the OCS field in the UTRD - */ -static inline int ufshcd_get_tr_ocs(struct ufshcd_lrb *lrbp) -{ - return lrbp->utr_descriptor_ptr->header.dword_2 & MASK_OCS; -} - -/** - * ufshcd_get_tmr_ocs - Get the UTMRD Overall Command Status - * @task_req_descp: pointer to utp_task_req_desc structure - * - * This function is used to get the OCS field from UTMRD - * Returns the OCS field in the UTMRD - */ -static inline int -ufshcd_get_tmr_ocs(struct utp_task_req_desc *task_req_descp) -{ - return task_req_descp->header.dword_2 & MASK_OCS; -} - -/** - * ufshcd_get_tm_free_slot - get a free slot for task management request - * @hba: per adapter instance - * - * Returns maximum number of task management request slots in case of - * task management queue full or returns the free slot number - */ -static inline int ufshcd_get_tm_free_slot(struct ufs_hba *hba) -{ - return find_first_zero_bit(&hba->outstanding_tasks, hba->nutmrs); -} - -/** - * ufshcd_utrl_clear - Clear a bit in UTRLCLR register - * @hba: per adapter instance - * @pos: position of the bit to be cleared - */ -static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 pos) -{ - writel(~(1 << pos), - (hba->mmio_base + REG_UTP_TRANSFER_REQ_LIST_CLEAR)); -} - -/** - * ufshcd_get_lists_status - Check UCRDY, UTRLRDY and UTMRLRDY - * @reg: Register value of host controller status - * - * Returns integer, 0 on Success and positive value if failed - */ -static inline int ufshcd_get_lists_status(u32 reg) -{ - /* - * The mask 0xFF is for the following HCS register bits - * Bit Description - * 0 Device Present - * 1 UTRLRDY - * 2 UTMRLRDY - * 3 UCRDY - * 4 HEI - * 5 DEI - * 6-7 reserved - */ - return (((reg) & (0xFF)) >> 1) ^ (0x07); -} - -/** - * ufshcd_get_uic_cmd_result - Get the UIC command result - * @hba: Pointer to adapter instance - * - * This function gets the result of UIC command completion - * Returns 0 on success, non zero value on error - */ -static inline int ufshcd_get_uic_cmd_result(struct ufs_hba *hba) -{ - return readl(hba->mmio_base + REG_UIC_COMMAND_ARG_2) & - MASK_UIC_COMMAND_RESULT; -} - -/** - * ufshcd_free_hba_memory - Free allocated memory for LRB, request - * and task lists - * @hba: Pointer to adapter instance - */ -static inline void ufshcd_free_hba_memory(struct ufs_hba *hba) -{ - size_t utmrdl_size, utrdl_size, ucdl_size; - - kfree(hba->lrb); - - if (hba->utmrdl_base_addr) { - utmrdl_size = sizeof(struct utp_task_req_desc) * hba->nutmrs; - dma_free_coherent(&hba->pdev->dev, utmrdl_size, - hba->utmrdl_base_addr, hba->utmrdl_dma_addr); - } - - if (hba->utrdl_base_addr) { - utrdl_size = - (sizeof(struct utp_transfer_req_desc) * hba->nutrs); - dma_free_coherent(&hba->pdev->dev, utrdl_size, - hba->utrdl_base_addr, hba->utrdl_dma_addr); - } - - if (hba->ucdl_base_addr) { - ucdl_size = - (sizeof(struct utp_transfer_cmd_desc) * hba->nutrs); - dma_free_coherent(&hba->pdev->dev, ucdl_size, - hba->ucdl_base_addr, hba->ucdl_dma_addr); - } -} - -/** - * ufshcd_is_valid_req_rsp - checks if controller TR response is valid - * @ucd_rsp_ptr: pointer to response UPIU - * - * This function checks the response UPIU for valid transaction type in - * response field - * Returns 0 on success, non-zero on failure - */ -static inline int -ufshcd_is_valid_req_rsp(struct utp_upiu_rsp *ucd_rsp_ptr) -{ - return ((be32_to_cpu(ucd_rsp_ptr->header.dword_0) >> 24) == - UPIU_TRANSACTION_RESPONSE) ? 0 : DID_ERROR << 16; -} - -/** - * ufshcd_get_rsp_upiu_result - Get the result from response UPIU - * @ucd_rsp_ptr: pointer to response UPIU - * - * This function gets the response status and scsi_status from response UPIU - * Returns the response result code. - */ -static inline int -ufshcd_get_rsp_upiu_result(struct utp_upiu_rsp *ucd_rsp_ptr) -{ - return be32_to_cpu(ucd_rsp_ptr->header.dword_1) & MASK_RSP_UPIU_RESULT; -} - -/** - * ufshcd_config_int_aggr - Configure interrupt aggregation values. - * Currently there is no use case where we want to configure - * interrupt aggregation dynamically. So to configure interrupt - * aggregation, #define INT_AGGR_COUNTER_THRESHOLD_VALUE and - * INT_AGGR_TIMEOUT_VALUE are used. - * @hba: per adapter instance - * @option: Interrupt aggregation option - */ -static inline void -ufshcd_config_int_aggr(struct ufs_hba *hba, int option) -{ - switch (option) { - case INT_AGGR_RESET: - writel((INT_AGGR_ENABLE | - INT_AGGR_COUNTER_AND_TIMER_RESET), - (hba->mmio_base + - REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL)); - break; - case INT_AGGR_CONFIG: - writel((INT_AGGR_ENABLE | - INT_AGGR_PARAM_WRITE | - INT_AGGR_COUNTER_THRESHOLD_VALUE | - INT_AGGR_TIMEOUT_VALUE), - (hba->mmio_base + - REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL)); - break; - } -} - -/** - * ufshcd_enable_run_stop_reg - Enable run-stop registers, - * When run-stop registers are set to 1, it indicates the - * host controller that it can process the requests - * @hba: per adapter instance - */ -static void ufshcd_enable_run_stop_reg(struct ufs_hba *hba) -{ - writel(UTP_TASK_REQ_LIST_RUN_STOP_BIT, - (hba->mmio_base + - REG_UTP_TASK_REQ_LIST_RUN_STOP)); - writel(UTP_TRANSFER_REQ_LIST_RUN_STOP_BIT, - (hba->mmio_base + - REG_UTP_TRANSFER_REQ_LIST_RUN_STOP)); -} - -/** - * ufshcd_hba_stop - Send controller to reset state - * @hba: per adapter instance - */ -static inline void ufshcd_hba_stop(struct ufs_hba *hba) -{ - writel(CONTROLLER_DISABLE, (hba->mmio_base + REG_CONTROLLER_ENABLE)); -} - -/** - * ufshcd_hba_start - Start controller initialization sequence - * @hba: per adapter instance - */ -static inline void ufshcd_hba_start(struct ufs_hba *hba) -{ - writel(CONTROLLER_ENABLE , (hba->mmio_base + REG_CONTROLLER_ENABLE)); -} - -/** - * ufshcd_is_hba_active - Get controller state - * @hba: per adapter instance - * - * Returns zero if controller is active, 1 otherwise - */ -static inline int ufshcd_is_hba_active(struct ufs_hba *hba) -{ - return (readl(hba->mmio_base + REG_CONTROLLER_ENABLE) & 0x1) ? 0 : 1; -} - -/** - * ufshcd_send_command - Send SCSI or device management commands - * @hba: per adapter instance - * @task_tag: Task tag of the command - */ -static inline -void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) -{ - __set_bit(task_tag, &hba->outstanding_reqs); - writel((1 << task_tag), - (hba->mmio_base + REG_UTP_TRANSFER_REQ_DOOR_BELL)); -} - -/** - * ufshcd_copy_sense_data - Copy sense data in case of check condition - * @lrb - pointer to local reference block - */ -static inline void ufshcd_copy_sense_data(struct ufshcd_lrb *lrbp) -{ - int len; - if (lrbp->sense_buffer) { - len = be16_to_cpu(lrbp->ucd_rsp_ptr->sense_data_len); - memcpy(lrbp->sense_buffer, - lrbp->ucd_rsp_ptr->sense_data, - min_t(int, len, SCSI_SENSE_BUFFERSIZE)); - } -} - -/** - * ufshcd_hba_capabilities - Read controller capabilities - * @hba: per adapter instance - */ -static inline void ufshcd_hba_capabilities(struct ufs_hba *hba) -{ - hba->capabilities = - readl(hba->mmio_base + REG_CONTROLLER_CAPABILITIES); - - /* nutrs and nutmrs are 0 based values */ - hba->nutrs = (hba->capabilities & MASK_TRANSFER_REQUESTS_SLOTS) + 1; - hba->nutmrs = - ((hba->capabilities & MASK_TASK_MANAGEMENT_REQUEST_SLOTS) >> 16) + 1; -} - -/** - * ufshcd_send_uic_command - Send UIC commands to unipro layers - * @hba: per adapter instance - * @uic_command: UIC command - */ -static inline void -ufshcd_send_uic_command(struct ufs_hba *hba, struct uic_command *uic_cmnd) -{ - /* Write Args */ - writel(uic_cmnd->argument1, - (hba->mmio_base + REG_UIC_COMMAND_ARG_1)); - writel(uic_cmnd->argument2, - (hba->mmio_base + REG_UIC_COMMAND_ARG_2)); - writel(uic_cmnd->argument3, - (hba->mmio_base + REG_UIC_COMMAND_ARG_3)); - - /* Write UIC Cmd */ - writel((uic_cmnd->command & COMMAND_OPCODE_MASK), - (hba->mmio_base + REG_UIC_COMMAND)); -} - -/** - * ufshcd_map_sg - Map scatter-gather list to prdt - * @lrbp - pointer to local reference block - * - * Returns 0 in case of success, non-zero value in case of failure - */ -static int ufshcd_map_sg(struct ufshcd_lrb *lrbp) -{ - struct ufshcd_sg_entry *prd_table; - struct scatterlist *sg; - struct scsi_cmnd *cmd; - int sg_segments; - int i; - - cmd = lrbp->cmd; - sg_segments = scsi_dma_map(cmd); - if (sg_segments < 0) - return sg_segments; - - if (sg_segments) { - lrbp->utr_descriptor_ptr->prd_table_length = - cpu_to_le16((u16) (sg_segments)); - - prd_table = (struct ufshcd_sg_entry *)lrbp->ucd_prdt_ptr; - - scsi_for_each_sg(cmd, sg, sg_segments, i) { - prd_table[i].size = - cpu_to_le32(((u32) sg_dma_len(sg))-1); - prd_table[i].base_addr = - cpu_to_le32(lower_32_bits(sg->dma_address)); - prd_table[i].upper_addr = - cpu_to_le32(upper_32_bits(sg->dma_address)); - } - } else { - lrbp->utr_descriptor_ptr->prd_table_length = 0; - } - - return 0; -} - -/** - * ufshcd_int_config - enable/disable interrupts - * @hba: per adapter instance - * @option: interrupt option - */ -static void ufshcd_int_config(struct ufs_hba *hba, u32 option) -{ - switch (option) { - case UFSHCD_INT_ENABLE: - writel(hba->int_enable_mask, - (hba->mmio_base + REG_INTERRUPT_ENABLE)); - break; - case UFSHCD_INT_DISABLE: - if (hba->ufs_version == UFSHCI_VERSION_10) - writel(INTERRUPT_DISABLE_MASK_10, - (hba->mmio_base + REG_INTERRUPT_ENABLE)); - else - writel(INTERRUPT_DISABLE_MASK_11, - (hba->mmio_base + REG_INTERRUPT_ENABLE)); - break; - } -} - -/** - * ufshcd_compose_upiu - form UFS Protocol Information Unit(UPIU) - * @lrb - pointer to local reference block - */ -static void ufshcd_compose_upiu(struct ufshcd_lrb *lrbp) -{ - struct utp_transfer_req_desc *req_desc; - struct utp_upiu_cmd *ucd_cmd_ptr; - u32 data_direction; - u32 upiu_flags; - - ucd_cmd_ptr = lrbp->ucd_cmd_ptr; - req_desc = lrbp->utr_descriptor_ptr; - - switch (lrbp->command_type) { - case UTP_CMD_TYPE_SCSI: - if (lrbp->cmd->sc_data_direction == DMA_FROM_DEVICE) { - data_direction = UTP_DEVICE_TO_HOST; - upiu_flags = UPIU_CMD_FLAGS_READ; - } else if (lrbp->cmd->sc_data_direction == DMA_TO_DEVICE) { - data_direction = UTP_HOST_TO_DEVICE; - upiu_flags = UPIU_CMD_FLAGS_WRITE; - } else { - data_direction = UTP_NO_DATA_TRANSFER; - upiu_flags = UPIU_CMD_FLAGS_NONE; - } - - /* Transfer request descriptor header fields */ - req_desc->header.dword_0 = - cpu_to_le32(data_direction | UTP_SCSI_COMMAND); - - /* - * assigning invalid value for command status. Controller - * updates OCS on command completion, with the command - * status - */ - req_desc->header.dword_2 = - cpu_to_le32(OCS_INVALID_COMMAND_STATUS); - - /* command descriptor fields */ - ucd_cmd_ptr->header.dword_0 = - cpu_to_be32(UPIU_HEADER_DWORD(UPIU_TRANSACTION_COMMAND, - upiu_flags, - lrbp->lun, - lrbp->task_tag)); - ucd_cmd_ptr->header.dword_1 = - cpu_to_be32( - UPIU_HEADER_DWORD(UPIU_COMMAND_SET_TYPE_SCSI, - 0, - 0, - 0)); - - /* Total EHS length and Data segment length will be zero */ - ucd_cmd_ptr->header.dword_2 = 0; - - ucd_cmd_ptr->exp_data_transfer_len = - cpu_to_be32(lrbp->cmd->transfersize); - - memcpy(ucd_cmd_ptr->cdb, - lrbp->cmd->cmnd, - (min_t(unsigned short, - lrbp->cmd->cmd_len, - MAX_CDB_SIZE))); - break; - case UTP_CMD_TYPE_DEV_MANAGE: - /* For query function implementation */ - break; - case UTP_CMD_TYPE_UFS: - /* For UFS native command implementation */ - break; - } /* end of switch */ -} - -/** - * ufshcd_queuecommand - main entry point for SCSI requests - * @cmd: command from SCSI Midlayer - * @done: call back function - * - * Returns 0 for success, non-zero in case of failure - */ -static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) -{ - struct ufshcd_lrb *lrbp; - struct ufs_hba *hba; - unsigned long flags; - int tag; - int err = 0; - - hba = shost_priv(host); - - tag = cmd->request->tag; - - if (hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL) { - err = SCSI_MLQUEUE_HOST_BUSY; - goto out; - } - - lrbp = &hba->lrb[tag]; - - lrbp->cmd = cmd; - lrbp->sense_bufflen = SCSI_SENSE_BUFFERSIZE; - lrbp->sense_buffer = cmd->sense_buffer; - lrbp->task_tag = tag; - lrbp->lun = cmd->device->lun; - - lrbp->command_type = UTP_CMD_TYPE_SCSI; - - /* form UPIU before issuing the command */ - ufshcd_compose_upiu(lrbp); - err = ufshcd_map_sg(lrbp); - if (err) - goto out; - - /* issue command to the controller */ - spin_lock_irqsave(hba->host->host_lock, flags); - ufshcd_send_command(hba, tag); - spin_unlock_irqrestore(hba->host->host_lock, flags); -out: - return err; -} - -/** - * ufshcd_memory_alloc - allocate memory for host memory space data structures - * @hba: per adapter instance - * - * 1. Allocate DMA memory for Command Descriptor array - * Each command descriptor consist of Command UPIU, Response UPIU and PRDT - * 2. Allocate DMA memory for UTP Transfer Request Descriptor List (UTRDL). - * 3. Allocate DMA memory for UTP Task Management Request Descriptor List - * (UTMRDL) - * 4. Allocate memory for local reference block(lrb). - * - * Returns 0 for success, non-zero in case of failure - */ -static int ufshcd_memory_alloc(struct ufs_hba *hba) -{ - size_t utmrdl_size, utrdl_size, ucdl_size; - - /* Allocate memory for UTP command descriptors */ - ucdl_size = (sizeof(struct utp_transfer_cmd_desc) * hba->nutrs); - hba->ucdl_base_addr = dma_alloc_coherent(&hba->pdev->dev, - ucdl_size, - &hba->ucdl_dma_addr, - GFP_KERNEL); - - /* - * UFSHCI requires UTP command descriptor to be 128 byte aligned. - * make sure hba->ucdl_dma_addr is aligned to PAGE_SIZE - * if hba->ucdl_dma_addr is aligned to PAGE_SIZE, then it will - * be aligned to 128 bytes as well - */ - if (!hba->ucdl_base_addr || - WARN_ON(hba->ucdl_dma_addr & (PAGE_SIZE - 1))) { - dev_err(&hba->pdev->dev, - "Command Descriptor Memory allocation failed\n"); - goto out; - } - - /* - * Allocate memory for UTP Transfer descriptors - * UFSHCI requires 1024 byte alignment of UTRD - */ - utrdl_size = (sizeof(struct utp_transfer_req_desc) * hba->nutrs); - hba->utrdl_base_addr = dma_alloc_coherent(&hba->pdev->dev, - utrdl_size, - &hba->utrdl_dma_addr, - GFP_KERNEL); - if (!hba->utrdl_base_addr || - WARN_ON(hba->utrdl_dma_addr & (PAGE_SIZE - 1))) { - dev_err(&hba->pdev->dev, - "Transfer Descriptor Memory allocation failed\n"); - goto out; - } - - /* - * Allocate memory for UTP Task Management descriptors - * UFSHCI requires 1024 byte alignment of UTMRD - */ - utmrdl_size = sizeof(struct utp_task_req_desc) * hba->nutmrs; - hba->utmrdl_base_addr = dma_alloc_coherent(&hba->pdev->dev, - utmrdl_size, - &hba->utmrdl_dma_addr, - GFP_KERNEL); - if (!hba->utmrdl_base_addr || - WARN_ON(hba->utmrdl_dma_addr & (PAGE_SIZE - 1))) { - dev_err(&hba->pdev->dev, - "Task Management Descriptor Memory allocation failed\n"); - goto out; - } - - /* Allocate memory for local reference block */ - hba->lrb = kcalloc(hba->nutrs, sizeof(struct ufshcd_lrb), GFP_KERNEL); - if (!hba->lrb) { - dev_err(&hba->pdev->dev, "LRB Memory allocation failed\n"); - goto out; - } - return 0; -out: - ufshcd_free_hba_memory(hba); - return -ENOMEM; -} - -/** - * ufshcd_host_memory_configure - configure local reference block with - * memory offsets - * @hba: per adapter instance - * - * Configure Host memory space - * 1. Update Corresponding UTRD.UCDBA and UTRD.UCDBAU with UCD DMA - * address. - * 2. Update each UTRD with Response UPIU offset, Response UPIU length - * and PRDT offset. - * 3. Save the corresponding addresses of UTRD, UCD.CMD, UCD.RSP and UCD.PRDT - * into local reference block. - */ -static void ufshcd_host_memory_configure(struct ufs_hba *hba) -{ - struct utp_transfer_cmd_desc *cmd_descp; - struct utp_transfer_req_desc *utrdlp; - dma_addr_t cmd_desc_dma_addr; - dma_addr_t cmd_desc_element_addr; - u16 response_offset; - u16 prdt_offset; - int cmd_desc_size; - int i; - - utrdlp = hba->utrdl_base_addr; - cmd_descp = hba->ucdl_base_addr; - - response_offset = - offsetof(struct utp_transfer_cmd_desc, response_upiu); - prdt_offset = - offsetof(struct utp_transfer_cmd_desc, prd_table); - - cmd_desc_size = sizeof(struct utp_transfer_cmd_desc); - cmd_desc_dma_addr = hba->ucdl_dma_addr; - - for (i = 0; i < hba->nutrs; i++) { - /* Configure UTRD with command descriptor base address */ - cmd_desc_element_addr = - (cmd_desc_dma_addr + (cmd_desc_size * i)); - utrdlp[i].command_desc_base_addr_lo = - cpu_to_le32(lower_32_bits(cmd_desc_element_addr)); - utrdlp[i].command_desc_base_addr_hi = - cpu_to_le32(upper_32_bits(cmd_desc_element_addr)); - - /* Response upiu and prdt offset should be in double words */ - utrdlp[i].response_upiu_offset = - cpu_to_le16((response_offset >> 2)); - utrdlp[i].prd_table_offset = - cpu_to_le16((prdt_offset >> 2)); - utrdlp[i].response_upiu_length = - cpu_to_le16(ALIGNED_UPIU_SIZE); - - hba->lrb[i].utr_descriptor_ptr = (utrdlp + i); - hba->lrb[i].ucd_cmd_ptr = - (struct utp_upiu_cmd *)(cmd_descp + i); - hba->lrb[i].ucd_rsp_ptr = - (struct utp_upiu_rsp *)cmd_descp[i].response_upiu; - hba->lrb[i].ucd_prdt_ptr = - (struct ufshcd_sg_entry *)cmd_descp[i].prd_table; - } -} - -/** - * ufshcd_dme_link_startup - Notify Unipro to perform link startup - * @hba: per adapter instance - * - * UIC_CMD_DME_LINK_STARTUP command must be issued to Unipro layer, - * in order to initialize the Unipro link startup procedure. - * Once the Unipro links are up, the device connected to the controller - * is detected. - * - * Returns 0 on success, non-zero value on failure - */ -static int ufshcd_dme_link_startup(struct ufs_hba *hba) -{ - struct uic_command *uic_cmd; - unsigned long flags; - - /* check if controller is ready to accept UIC commands */ - if (((readl(hba->mmio_base + REG_CONTROLLER_STATUS)) & - UIC_COMMAND_READY) == 0x0) { - dev_err(&hba->pdev->dev, - "Controller not ready" - " to accept UIC commands\n"); - return -EIO; - } - - spin_lock_irqsave(hba->host->host_lock, flags); - - /* form UIC command */ - uic_cmd = &hba->active_uic_cmd; - uic_cmd->command = UIC_CMD_DME_LINK_STARTUP; - uic_cmd->argument1 = 0; - uic_cmd->argument2 = 0; - uic_cmd->argument3 = 0; - - /* enable UIC related interrupts */ - hba->int_enable_mask |= UIC_COMMAND_COMPL; - ufshcd_int_config(hba, UFSHCD_INT_ENABLE); - - /* sending UIC commands to controller */ - ufshcd_send_uic_command(hba, uic_cmd); - spin_unlock_irqrestore(hba->host->host_lock, flags); - return 0; -} - -/** - * ufshcd_make_hba_operational - Make UFS controller operational - * @hba: per adapter instance - * - * To bring UFS host controller to operational state, - * 1. Check if device is present - * 2. Configure run-stop-registers - * 3. Enable required interrupts - * 4. Configure interrupt aggregation - * - * Returns 0 on success, non-zero value on failure - */ -static int ufshcd_make_hba_operational(struct ufs_hba *hba) -{ - int err = 0; - u32 reg; - - /* check if device present */ - reg = readl((hba->mmio_base + REG_CONTROLLER_STATUS)); - if (ufshcd_is_device_present(reg)) { - dev_err(&hba->pdev->dev, "cc: Device not present\n"); - err = -ENXIO; - goto out; - } - - /* - * UCRDY, UTMRLDY and UTRLRDY bits must be 1 - * DEI, HEI bits must be 0 - */ - if (!(ufshcd_get_lists_status(reg))) { - ufshcd_enable_run_stop_reg(hba); - } else { - dev_err(&hba->pdev->dev, - "Host controller not ready to process requests"); - err = -EIO; - goto out; - } - - /* Enable required interrupts */ - hba->int_enable_mask |= (UTP_TRANSFER_REQ_COMPL | - UIC_ERROR | - UTP_TASK_REQ_COMPL | - DEVICE_FATAL_ERROR | - CONTROLLER_FATAL_ERROR | - SYSTEM_BUS_FATAL_ERROR); - ufshcd_int_config(hba, UFSHCD_INT_ENABLE); - - /* Configure interrupt aggregation */ - ufshcd_config_int_aggr(hba, INT_AGGR_CONFIG); - - if (hba->ufshcd_state == UFSHCD_STATE_RESET) - scsi_unblock_requests(hba->host); - - hba->ufshcd_state = UFSHCD_STATE_OPERATIONAL; - scsi_scan_host(hba->host); -out: - return err; -} - -/** - * ufshcd_hba_enable - initialize the controller - * @hba: per adapter instance - * - * The controller resets itself and controller firmware initialization - * sequence kicks off. When controller is ready it will set - * the Host Controller Enable bit to 1. - * - * Returns 0 on success, non-zero value on failure - */ -static int ufshcd_hba_enable(struct ufs_hba *hba) -{ - int retry; - - /* - * msleep of 1 and 5 used in this function might result in msleep(20), - * but it was necessary to send the UFS FPGA to reset mode during - * development and testing of this driver. msleep can be changed to - * mdelay and retry count can be reduced based on the controller. - */ - if (!ufshcd_is_hba_active(hba)) { - - /* change controller state to "reset state" */ - ufshcd_hba_stop(hba); - - /* - * This delay is based on the testing done with UFS host - * controller FPGA. The delay can be changed based on the - * host controller used. - */ - msleep(5); - } - - /* start controller initialization sequence */ - ufshcd_hba_start(hba); - - /* - * To initialize a UFS host controller HCE bit must be set to 1. - * During initialization the HCE bit value changes from 1->0->1. - * When the host controller completes initialization sequence - * it sets the value of HCE bit to 1. The same HCE bit is read back - * to check if the controller has completed initialization sequence. - * So without this delay the value HCE = 1, set in the previous - * instruction might be read back. - * This delay can be changed based on the controller. - */ - msleep(1); - - /* wait for the host controller to complete initialization */ - retry = 10; - while (ufshcd_is_hba_active(hba)) { - if (retry) { - retry--; - } else { - dev_err(&hba->pdev->dev, - "Controller enable failed\n"); - return -EIO; - } - msleep(5); - } - return 0; -} - -/** - * ufshcd_initialize_hba - start the initialization process - * @hba: per adapter instance - * - * 1. Enable the controller via ufshcd_hba_enable. - * 2. Program the Transfer Request List Address with the starting address of - * UTRDL. - * 3. Program the Task Management Request List Address with starting address - * of UTMRDL. - * - * Returns 0 on success, non-zero value on failure. - */ -static int ufshcd_initialize_hba(struct ufs_hba *hba) -{ - if (ufshcd_hba_enable(hba)) - return -EIO; - - /* Configure UTRL and UTMRL base address registers */ - writel(hba->utrdl_dma_addr, - (hba->mmio_base + REG_UTP_TRANSFER_REQ_LIST_BASE_L)); - writel(lower_32_bits(hba->utrdl_dma_addr), - (hba->mmio_base + REG_UTP_TRANSFER_REQ_LIST_BASE_H)); - writel(hba->utmrdl_dma_addr, - (hba->mmio_base + REG_UTP_TASK_REQ_LIST_BASE_L)); - writel(upper_32_bits(hba->utmrdl_dma_addr), - (hba->mmio_base + REG_UTP_TASK_REQ_LIST_BASE_H)); - - /* Initialize unipro link startup procedure */ - return ufshcd_dme_link_startup(hba); -} - -/** - * ufshcd_do_reset - reset the host controller - * @hba: per adapter instance - * - * Returns SUCCESS/FAILED - */ -static int ufshcd_do_reset(struct ufs_hba *hba) -{ - struct ufshcd_lrb *lrbp; - unsigned long flags; - int tag; - - /* block commands from midlayer */ - scsi_block_requests(hba->host); - - spin_lock_irqsave(hba->host->host_lock, flags); - hba->ufshcd_state = UFSHCD_STATE_RESET; - - /* send controller to reset state */ - ufshcd_hba_stop(hba); - spin_unlock_irqrestore(hba->host->host_lock, flags); - - /* abort outstanding commands */ - for (tag = 0; tag < hba->nutrs; tag++) { - if (test_bit(tag, &hba->outstanding_reqs)) { - lrbp = &hba->lrb[tag]; - scsi_dma_unmap(lrbp->cmd); - lrbp->cmd->result = DID_RESET << 16; - lrbp->cmd->scsi_done(lrbp->cmd); - lrbp->cmd = NULL; - } - } - - /* clear outstanding request/task bit maps */ - hba->outstanding_reqs = 0; - hba->outstanding_tasks = 0; - - /* start the initialization process */ - if (ufshcd_initialize_hba(hba)) { - dev_err(&hba->pdev->dev, - "Reset: Controller initialization failed\n"); - return FAILED; - } - return SUCCESS; -} - -/** - * ufshcd_slave_alloc - handle initial SCSI device configurations - * @sdev: pointer to SCSI device - * - * Returns success - */ -static int ufshcd_slave_alloc(struct scsi_device *sdev) -{ - struct ufs_hba *hba; - - hba = shost_priv(sdev->host); - sdev->tagged_supported = 1; - - /* Mode sense(6) is not supported by UFS, so use Mode sense(10) */ - sdev->use_10_for_ms = 1; - scsi_set_tag_type(sdev, MSG_SIMPLE_TAG); - - /* - * Inform SCSI Midlayer that the LUN queue depth is same as the - * controller queue depth. If a LUN queue depth is less than the - * controller queue depth and if the LUN reports - * SAM_STAT_TASK_SET_FULL, the LUN queue depth will be adjusted - * with scsi_adjust_queue_depth. - */ - scsi_activate_tcq(sdev, hba->nutrs); - return 0; -} - -/** - * ufshcd_slave_destroy - remove SCSI device configurations - * @sdev: pointer to SCSI device - */ -static void ufshcd_slave_destroy(struct scsi_device *sdev) -{ - struct ufs_hba *hba; - - hba = shost_priv(sdev->host); - scsi_deactivate_tcq(sdev, hba->nutrs); -} - -/** - * ufshcd_task_req_compl - handle task management request completion - * @hba: per adapter instance - * @index: index of the completed request - * - * Returns SUCCESS/FAILED - */ -static int ufshcd_task_req_compl(struct ufs_hba *hba, u32 index) -{ - struct utp_task_req_desc *task_req_descp; - struct utp_upiu_task_rsp *task_rsp_upiup; - unsigned long flags; - int ocs_value; - int task_result; - - spin_lock_irqsave(hba->host->host_lock, flags); - - /* Clear completed tasks from outstanding_tasks */ - __clear_bit(index, &hba->outstanding_tasks); - - task_req_descp = hba->utmrdl_base_addr; - ocs_value = ufshcd_get_tmr_ocs(&task_req_descp[index]); - - if (ocs_value == OCS_SUCCESS) { - task_rsp_upiup = (struct utp_upiu_task_rsp *) - task_req_descp[index].task_rsp_upiu; - task_result = be32_to_cpu(task_rsp_upiup->header.dword_1); - task_result = ((task_result & MASK_TASK_RESPONSE) >> 8); - - if (task_result != UPIU_TASK_MANAGEMENT_FUNC_COMPL || - task_result != UPIU_TASK_MANAGEMENT_FUNC_SUCCEEDED) - task_result = FAILED; - } else { - task_result = FAILED; - dev_err(&hba->pdev->dev, - "trc: Invalid ocs = %x\n", ocs_value); - } - spin_unlock_irqrestore(hba->host->host_lock, flags); - return task_result; -} - -/** - * ufshcd_adjust_lun_qdepth - Update LUN queue depth if device responds with - * SAM_STAT_TASK_SET_FULL SCSI command status. - * @cmd: pointer to SCSI command - */ -static void ufshcd_adjust_lun_qdepth(struct scsi_cmnd *cmd) -{ - struct ufs_hba *hba; - int i; - int lun_qdepth = 0; - - hba = shost_priv(cmd->device->host); - - /* - * LUN queue depth can be obtained by counting outstanding commands - * on the LUN. - */ - for (i = 0; i < hba->nutrs; i++) { - if (test_bit(i, &hba->outstanding_reqs)) { - - /* - * Check if the outstanding command belongs - * to the LUN which reported SAM_STAT_TASK_SET_FULL. - */ - if (cmd->device->lun == hba->lrb[i].lun) - lun_qdepth++; - } - } - - /* - * LUN queue depth will be total outstanding commands, except the - * command for which the LUN reported SAM_STAT_TASK_SET_FULL. - */ - scsi_adjust_queue_depth(cmd->device, MSG_SIMPLE_TAG, lun_qdepth - 1); -} - -/** - * ufshcd_scsi_cmd_status - Update SCSI command result based on SCSI status - * @lrb: pointer to local reference block of completed command - * @scsi_status: SCSI command status - * - * Returns value base on SCSI command status - */ -static inline int -ufshcd_scsi_cmd_status(struct ufshcd_lrb *lrbp, int scsi_status) -{ - int result = 0; - - switch (scsi_status) { - case SAM_STAT_GOOD: - result |= DID_OK << 16 | - COMMAND_COMPLETE << 8 | - SAM_STAT_GOOD; - break; - case SAM_STAT_CHECK_CONDITION: - result |= DID_OK << 16 | - COMMAND_COMPLETE << 8 | - SAM_STAT_CHECK_CONDITION; - ufshcd_copy_sense_data(lrbp); - break; - case SAM_STAT_BUSY: - result |= SAM_STAT_BUSY; - break; - case SAM_STAT_TASK_SET_FULL: - - /* - * If a LUN reports SAM_STAT_TASK_SET_FULL, then the LUN queue - * depth needs to be adjusted to the exact number of - * outstanding commands the LUN can handle at any given time. - */ - ufshcd_adjust_lun_qdepth(lrbp->cmd); - result |= SAM_STAT_TASK_SET_FULL; - break; - case SAM_STAT_TASK_ABORTED: - result |= SAM_STAT_TASK_ABORTED; - break; - default: - result |= DID_ERROR << 16; - break; - } /* end of switch */ - - return result; -} - -/** - * ufshcd_transfer_rsp_status - Get overall status of the response - * @hba: per adapter instance - * @lrb: pointer to local reference block of completed command - * - * Returns result of the command to notify SCSI midlayer - */ -static inline int -ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) -{ - int result = 0; - int scsi_status; - int ocs; - - /* overall command status of utrd */ - ocs = ufshcd_get_tr_ocs(lrbp); - - switch (ocs) { - case OCS_SUCCESS: - - /* check if the returned transfer response is valid */ - result = ufshcd_is_valid_req_rsp(lrbp->ucd_rsp_ptr); - if (result) { - dev_err(&hba->pdev->dev, - "Invalid response = %x\n", result); - break; - } - - /* - * get the response UPIU result to extract - * the SCSI command status - */ - result = ufshcd_get_rsp_upiu_result(lrbp->ucd_rsp_ptr); - - /* - * get the result based on SCSI status response - * to notify the SCSI midlayer of the command status - */ - scsi_status = result & MASK_SCSI_STATUS; - result = ufshcd_scsi_cmd_status(lrbp, scsi_status); - break; - case OCS_ABORTED: - result |= DID_ABORT << 16; - break; - case OCS_INVALID_CMD_TABLE_ATTR: - case OCS_INVALID_PRDT_ATTR: - case OCS_MISMATCH_DATA_BUF_SIZE: - case OCS_MISMATCH_RESP_UPIU_SIZE: - case OCS_PEER_COMM_FAILURE: - case OCS_FATAL_ERROR: - default: - result |= DID_ERROR << 16; - dev_err(&hba->pdev->dev, - "OCS error from controller = %x\n", ocs); - break; - } /* end of switch */ - - return result; -} - -/** - * ufshcd_transfer_req_compl - handle SCSI and query command completion - * @hba: per adapter instance - */ -static void ufshcd_transfer_req_compl(struct ufs_hba *hba) -{ - struct ufshcd_lrb *lrb; - unsigned long completed_reqs; - u32 tr_doorbell; - int result; - int index; - - lrb = hba->lrb; - tr_doorbell = - readl(hba->mmio_base + REG_UTP_TRANSFER_REQ_DOOR_BELL); - completed_reqs = tr_doorbell ^ hba->outstanding_reqs; - - for (index = 0; index < hba->nutrs; index++) { - if (test_bit(index, &completed_reqs)) { - - result = ufshcd_transfer_rsp_status(hba, &lrb[index]); - - if (lrb[index].cmd) { - scsi_dma_unmap(lrb[index].cmd); - lrb[index].cmd->result = result; - lrb[index].cmd->scsi_done(lrb[index].cmd); - - /* Mark completed command as NULL in LRB */ - lrb[index].cmd = NULL; - } - } /* end of if */ - } /* end of for */ - - /* clear corresponding bits of completed commands */ - hba->outstanding_reqs ^= completed_reqs; - - /* Reset interrupt aggregation counters */ - ufshcd_config_int_aggr(hba, INT_AGGR_RESET); -} - -/** - * ufshcd_uic_cc_handler - handle UIC command completion - * @work: pointer to a work queue structure - * - * Returns 0 on success, non-zero value on failure - */ -static void ufshcd_uic_cc_handler (struct work_struct *work) -{ - struct ufs_hba *hba; - - hba = container_of(work, struct ufs_hba, uic_workq); - - if ((hba->active_uic_cmd.command == UIC_CMD_DME_LINK_STARTUP) && - !(ufshcd_get_uic_cmd_result(hba))) { - - if (ufshcd_make_hba_operational(hba)) - dev_err(&hba->pdev->dev, - "cc: hba not operational state\n"); - return; - } -} - -/** - * ufshcd_fatal_err_handler - handle fatal errors - * @hba: per adapter instance - */ -static void ufshcd_fatal_err_handler(struct work_struct *work) -{ - struct ufs_hba *hba; - hba = container_of(work, struct ufs_hba, feh_workq); - - /* check if reset is already in progress */ - if (hba->ufshcd_state != UFSHCD_STATE_RESET) - ufshcd_do_reset(hba); -} - -/** - * ufshcd_err_handler - Check for fatal errors - * @work: pointer to a work queue structure - */ -static void ufshcd_err_handler(struct ufs_hba *hba) -{ - u32 reg; - - if (hba->errors & INT_FATAL_ERRORS) - goto fatal_eh; - - if (hba->errors & UIC_ERROR) { - - reg = readl(hba->mmio_base + - REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER); - if (reg & UIC_DATA_LINK_LAYER_ERROR_PA_INIT) - goto fatal_eh; - } - return; -fatal_eh: - hba->ufshcd_state = UFSHCD_STATE_ERROR; - schedule_work(&hba->feh_workq); -} - -/** - * ufshcd_tmc_handler - handle task management function completion - * @hba: per adapter instance - */ -static void ufshcd_tmc_handler(struct ufs_hba *hba) -{ - u32 tm_doorbell; - - tm_doorbell = readl(hba->mmio_base + REG_UTP_TASK_REQ_DOOR_BELL); - hba->tm_condition = tm_doorbell ^ hba->outstanding_tasks; - wake_up_interruptible(&hba->ufshcd_tm_wait_queue); -} - -/** - * ufshcd_sl_intr - Interrupt service routine - * @hba: per adapter instance - * @intr_status: contains interrupts generated by the controller - */ -static void ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status) -{ - hba->errors = UFSHCD_ERROR_MASK & intr_status; - if (hba->errors) - ufshcd_err_handler(hba); - - if (intr_status & UIC_COMMAND_COMPL) - schedule_work(&hba->uic_workq); - - if (intr_status & UTP_TASK_REQ_COMPL) - ufshcd_tmc_handler(hba); - - if (intr_status & UTP_TRANSFER_REQ_COMPL) - ufshcd_transfer_req_compl(hba); -} - -/** - * ufshcd_intr - Main interrupt service routine - * @irq: irq number - * @__hba: pointer to adapter instance - * - * Returns IRQ_HANDLED - If interrupt is valid - * IRQ_NONE - If invalid interrupt - */ -static irqreturn_t ufshcd_intr(int irq, void *__hba) -{ - u32 intr_status; - irqreturn_t retval = IRQ_NONE; - struct ufs_hba *hba = __hba; - - spin_lock(hba->host->host_lock); - intr_status = readl(hba->mmio_base + REG_INTERRUPT_STATUS); - - if (intr_status) { - ufshcd_sl_intr(hba, intr_status); - - /* If UFSHCI 1.0 then clear interrupt status register */ - if (hba->ufs_version == UFSHCI_VERSION_10) - writel(intr_status, - (hba->mmio_base + REG_INTERRUPT_STATUS)); - retval = IRQ_HANDLED; - } - spin_unlock(hba->host->host_lock); - return retval; -} - -/** - * ufshcd_issue_tm_cmd - issues task management commands to controller - * @hba: per adapter instance - * @lrbp: pointer to local reference block - * - * Returns SUCCESS/FAILED - */ -static int -ufshcd_issue_tm_cmd(struct ufs_hba *hba, - struct ufshcd_lrb *lrbp, - u8 tm_function) -{ - struct utp_task_req_desc *task_req_descp; - struct utp_upiu_task_req *task_req_upiup; - struct Scsi_Host *host; - unsigned long flags; - int free_slot = 0; - int err; - - host = hba->host; - - spin_lock_irqsave(host->host_lock, flags); - - /* If task management queue is full */ - free_slot = ufshcd_get_tm_free_slot(hba); - if (free_slot >= hba->nutmrs) { - spin_unlock_irqrestore(host->host_lock, flags); - dev_err(&hba->pdev->dev, "Task management queue full\n"); - err = FAILED; - goto out; - } - - task_req_descp = hba->utmrdl_base_addr; - task_req_descp += free_slot; - - /* Configure task request descriptor */ - task_req_descp->header.dword_0 = cpu_to_le32(UTP_REQ_DESC_INT_CMD); - task_req_descp->header.dword_2 = - cpu_to_le32(OCS_INVALID_COMMAND_STATUS); - - /* Configure task request UPIU */ - task_req_upiup = - (struct utp_upiu_task_req *) task_req_descp->task_req_upiu; - task_req_upiup->header.dword_0 = - cpu_to_be32(UPIU_HEADER_DWORD(UPIU_TRANSACTION_TASK_REQ, 0, - lrbp->lun, lrbp->task_tag)); - task_req_upiup->header.dword_1 = - cpu_to_be32(UPIU_HEADER_DWORD(0, tm_function, 0, 0)); - - task_req_upiup->input_param1 = lrbp->lun; - task_req_upiup->input_param1 = - cpu_to_be32(task_req_upiup->input_param1); - task_req_upiup->input_param2 = lrbp->task_tag; - task_req_upiup->input_param2 = - cpu_to_be32(task_req_upiup->input_param2); - - /* send command to the controller */ - __set_bit(free_slot, &hba->outstanding_tasks); - writel((1 << free_slot), - (hba->mmio_base + REG_UTP_TASK_REQ_DOOR_BELL)); - - spin_unlock_irqrestore(host->host_lock, flags); - - /* wait until the task management command is completed */ - err = - wait_event_interruptible_timeout(hba->ufshcd_tm_wait_queue, - (test_bit(free_slot, - &hba->tm_condition) != 0), - 60 * HZ); - if (!err) { - dev_err(&hba->pdev->dev, - "Task management command timed-out\n"); - err = FAILED; - goto out; - } - clear_bit(free_slot, &hba->tm_condition); - return ufshcd_task_req_compl(hba, free_slot); -out: - return err; -} - -/** - * ufshcd_device_reset - reset device and abort all the pending commands - * @cmd: SCSI command pointer - * - * Returns SUCCESS/FAILED - */ -static int ufshcd_device_reset(struct scsi_cmnd *cmd) -{ - struct Scsi_Host *host; - struct ufs_hba *hba; - unsigned int tag; - u32 pos; - int err; - - host = cmd->device->host; - hba = shost_priv(host); - tag = cmd->request->tag; - - err = ufshcd_issue_tm_cmd(hba, &hba->lrb[tag], UFS_LOGICAL_RESET); - if (err) - goto out; - - for (pos = 0; pos < hba->nutrs; pos++) { - if (test_bit(pos, &hba->outstanding_reqs) && - (hba->lrb[tag].lun == hba->lrb[pos].lun)) { - - /* clear the respective UTRLCLR register bit */ - ufshcd_utrl_clear(hba, pos); - - clear_bit(pos, &hba->outstanding_reqs); - - if (hba->lrb[pos].cmd) { - scsi_dma_unmap(hba->lrb[pos].cmd); - hba->lrb[pos].cmd->result = - DID_ABORT << 16; - hba->lrb[pos].cmd->scsi_done(cmd); - hba->lrb[pos].cmd = NULL; - } - } - } /* end of for */ -out: - return err; -} - -/** - * ufshcd_host_reset - Main reset function registered with scsi layer - * @cmd: SCSI command pointer - * - * Returns SUCCESS/FAILED - */ -static int ufshcd_host_reset(struct scsi_cmnd *cmd) -{ - struct ufs_hba *hba; - - hba = shost_priv(cmd->device->host); - - if (hba->ufshcd_state == UFSHCD_STATE_RESET) - return SUCCESS; - - return (ufshcd_do_reset(hba) == SUCCESS) ? SUCCESS : FAILED; -} - -/** - * ufshcd_abort - abort a specific command - * @cmd: SCSI command pointer - * - * Returns SUCCESS/FAILED - */ -static int ufshcd_abort(struct scsi_cmnd *cmd) -{ - struct Scsi_Host *host; - struct ufs_hba *hba; - unsigned long flags; - unsigned int tag; - int err; - - host = cmd->device->host; - hba = shost_priv(host); - tag = cmd->request->tag; - - spin_lock_irqsave(host->host_lock, flags); - - /* check if command is still pending */ - if (!(test_bit(tag, &hba->outstanding_reqs))) { - err = FAILED; - spin_unlock_irqrestore(host->host_lock, flags); - goto out; - } - spin_unlock_irqrestore(host->host_lock, flags); - - err = ufshcd_issue_tm_cmd(hba, &hba->lrb[tag], UFS_ABORT_TASK); - if (err) - goto out; - - scsi_dma_unmap(cmd); - - spin_lock_irqsave(host->host_lock, flags); - - /* clear the respective UTRLCLR register bit */ - ufshcd_utrl_clear(hba, tag); - - __clear_bit(tag, &hba->outstanding_reqs); - hba->lrb[tag].cmd = NULL; - spin_unlock_irqrestore(host->host_lock, flags); -out: - return err; -} - -static struct scsi_host_template ufshcd_driver_template = { - .module = THIS_MODULE, - .name = UFSHCD, - .proc_name = UFSHCD, - .queuecommand = ufshcd_queuecommand, - .slave_alloc = ufshcd_slave_alloc, - .slave_destroy = ufshcd_slave_destroy, - .eh_abort_handler = ufshcd_abort, - .eh_device_reset_handler = ufshcd_device_reset, - .eh_host_reset_handler = ufshcd_host_reset, - .this_id = -1, - .sg_tablesize = SG_ALL, - .cmd_per_lun = UFSHCD_CMD_PER_LUN, - .can_queue = UFSHCD_CAN_QUEUE, -}; - -/** - * ufshcd_shutdown - main function to put the controller in reset state - * @pdev: pointer to PCI device handle - */ -static void ufshcd_shutdown(struct pci_dev *pdev) -{ - ufshcd_hba_stop((struct ufs_hba *)pci_get_drvdata(pdev)); -} - -#ifdef CONFIG_PM -/** - * ufshcd_suspend - suspend power management function - * @pdev: pointer to PCI device handle - * @state: power state - * - * Returns -ENOSYS - */ -static int ufshcd_suspend(struct pci_dev *pdev, pm_message_t state) -{ - /* - * TODO: - * 1. Block SCSI requests from SCSI midlayer - * 2. Change the internal driver state to non operational - * 3. Set UTRLRSR and UTMRLRSR bits to zero - * 4. Wait until outstanding commands are completed - * 5. Set HCE to zero to send the UFS host controller to reset state - */ - - return -ENOSYS; -} - -/** - * ufshcd_resume - resume power management function - * @pdev: pointer to PCI device handle - * - * Returns -ENOSYS - */ -static int ufshcd_resume(struct pci_dev *pdev) -{ - /* - * TODO: - * 1. Set HCE to 1, to start the UFS host controller - * initialization process - * 2. Set UTRLRSR and UTMRLRSR bits to 1 - * 3. Change the internal driver state to operational - * 4. Unblock SCSI requests from SCSI midlayer - */ - - return -ENOSYS; -} -#endif /* CONFIG_PM */ - -/** - * ufshcd_hba_free - free allocated memory for - * host memory space data structures - * @hba: per adapter instance - */ -static void ufshcd_hba_free(struct ufs_hba *hba) -{ - iounmap(hba->mmio_base); - ufshcd_free_hba_memory(hba); - pci_release_regions(hba->pdev); -} - -/** - * ufshcd_remove - de-allocate PCI/SCSI host and host memory space - * data structure memory - * @pdev - pointer to PCI handle - */ -static void ufshcd_remove(struct pci_dev *pdev) -{ - struct ufs_hba *hba = pci_get_drvdata(pdev); - - /* disable interrupts */ - ufshcd_int_config(hba, UFSHCD_INT_DISABLE); - free_irq(pdev->irq, hba); - - ufshcd_hba_stop(hba); - ufshcd_hba_free(hba); - - scsi_remove_host(hba->host); - scsi_host_put(hba->host); - pci_set_drvdata(pdev, NULL); - pci_clear_master(pdev); - pci_disable_device(pdev); -} - -/** - * ufshcd_set_dma_mask - Set dma mask based on the controller - * addressing capability - * @pdev: PCI device structure - * - * Returns 0 for success, non-zero for failure - */ -static int ufshcd_set_dma_mask(struct ufs_hba *hba) -{ - int err; - u64 dma_mask; - - /* - * If controller supports 64 bit addressing mode, then set the DMA - * mask to 64-bit, else set the DMA mask to 32-bit - */ - if (hba->capabilities & MASK_64_ADDRESSING_SUPPORT) - dma_mask = DMA_BIT_MASK(64); - else - dma_mask = DMA_BIT_MASK(32); - - err = pci_set_dma_mask(hba->pdev, dma_mask); - if (err) - return err; - - err = pci_set_consistent_dma_mask(hba->pdev, dma_mask); - - return err; -} - -/** - * ufshcd_probe - probe routine of the driver - * @pdev: pointer to PCI device handle - * @id: PCI device id - * - * Returns 0 on success, non-zero value on failure - */ -static int __devinit -ufshcd_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ - struct Scsi_Host *host; - struct ufs_hba *hba; - int err; - - err = pci_enable_device(pdev); - if (err) { - dev_err(&pdev->dev, "pci_enable_device failed\n"); - goto out_error; - } - - pci_set_master(pdev); - - host = scsi_host_alloc(&ufshcd_driver_template, - sizeof(struct ufs_hba)); - if (!host) { - dev_err(&pdev->dev, "scsi_host_alloc failed\n"); - err = -ENOMEM; - goto out_disable; - } - hba = shost_priv(host); - - err = pci_request_regions(pdev, UFSHCD); - if (err < 0) { - dev_err(&pdev->dev, "request regions failed\n"); - goto out_disable; - } - - hba->mmio_base = pci_ioremap_bar(pdev, 0); - if (!hba->mmio_base) { - dev_err(&pdev->dev, "memory map failed\n"); - err = -ENOMEM; - goto out_release_regions; - } - - hba->host = host; - hba->pdev = pdev; - - /* Read capabilities registers */ - ufshcd_hba_capabilities(hba); - - /* Get UFS version supported by the controller */ - hba->ufs_version = ufshcd_get_ufs_version(hba); - - err = ufshcd_set_dma_mask(hba); - if (err) { - dev_err(&pdev->dev, "set dma mask failed\n"); - goto out_iounmap; - } - - /* Allocate memory for host memory space */ - err = ufshcd_memory_alloc(hba); - if (err) { - dev_err(&pdev->dev, "Memory allocation failed\n"); - goto out_iounmap; - } - - /* Configure LRB */ - ufshcd_host_memory_configure(hba); - - host->can_queue = hba->nutrs; - host->cmd_per_lun = hba->nutrs; - host->max_id = UFSHCD_MAX_ID; - host->max_lun = UFSHCD_MAX_LUNS; - host->max_channel = UFSHCD_MAX_CHANNEL; - host->unique_id = host->host_no; - host->max_cmd_len = MAX_CDB_SIZE; - - /* Initailize wait queue for task management */ - init_waitqueue_head(&hba->ufshcd_tm_wait_queue); - - /* Initialize work queues */ - INIT_WORK(&hba->uic_workq, ufshcd_uic_cc_handler); - INIT_WORK(&hba->feh_workq, ufshcd_fatal_err_handler); - - /* IRQ registration */ - err = request_irq(pdev->irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba); - if (err) { - dev_err(&pdev->dev, "request irq failed\n"); - goto out_lrb_free; - } - - /* Enable SCSI tag mapping */ - err = scsi_init_shared_tag_map(host, host->can_queue); - if (err) { - dev_err(&pdev->dev, "init shared queue failed\n"); - goto out_free_irq; - } - - pci_set_drvdata(pdev, hba); - - err = scsi_add_host(host, &pdev->dev); - if (err) { - dev_err(&pdev->dev, "scsi_add_host failed\n"); - goto out_free_irq; - } - - /* Initialization routine */ - err = ufshcd_initialize_hba(hba); - if (err) { - dev_err(&pdev->dev, "Initialization failed\n"); - goto out_free_irq; - } - - return 0; - -out_free_irq: - free_irq(pdev->irq, hba); -out_lrb_free: - ufshcd_free_hba_memory(hba); -out_iounmap: - iounmap(hba->mmio_base); -out_release_regions: - pci_release_regions(pdev); -out_disable: - scsi_host_put(host); - pci_clear_master(pdev); - pci_disable_device(pdev); -out_error: - return err; -} - -static DEFINE_PCI_DEVICE_TABLE(ufshcd_pci_tbl) = { - { PCI_VENDOR_ID_SAMSUNG, 0xC00C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { } /* terminate list */ -}; - -MODULE_DEVICE_TABLE(pci, ufshcd_pci_tbl); - -static struct pci_driver ufshcd_pci_driver = { - .name = UFSHCD, - .id_table = ufshcd_pci_tbl, - .probe = ufshcd_probe, - .remove = __devexit_p(ufshcd_remove), - .shutdown = ufshcd_shutdown, -#ifdef CONFIG_PM - .suspend = ufshcd_suspend, - .resume = ufshcd_resume, -#endif -}; - -/** - * ufshcd_init - Driver registration routine - */ -static int __init ufshcd_init(void) -{ - return pci_register_driver(&ufshcd_pci_driver); -} -module_init(ufshcd_init); - -/** - * ufshcd_exit - Driver exit clean-up routine - */ -static void __exit ufshcd_exit(void) -{ - pci_unregister_driver(&ufshcd_pci_driver); -} -module_exit(ufshcd_exit); - - -MODULE_AUTHOR("Santosh Yaragnavi , " - "Vinayak Holikatti "); -MODULE_DESCRIPTION("Generic UFS host controller driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(UFSHCD_DRIVER_VERSION); diff --git a/trunk/drivers/scsi/ufs/ufshci.h b/trunk/drivers/scsi/ufs/ufshci.h deleted file mode 100644 index 6e3510f71167..000000000000 --- a/trunk/drivers/scsi/ufs/ufshci.h +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Universal Flash Storage Host controller driver - * - * This code is based on drivers/scsi/ufs/ufshci.h - * Copyright (C) 2011-2012 Samsung India Software Operations - * - * Santosh Yaraganavi - * Vinayak Holikatti - * - * 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. - * - * NO WARRANTY - * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT - * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is - * solely responsible for determining the appropriateness of using and - * distributing the Program and assumes all risks associated with its - * exercise of rights under this Agreement, including but not limited to - * the risks and costs of program errors, damage to or loss of data, - * programs or equipment, and unavailability or interruption of operations. - - * DISCLAIMER OF LIABILITY - * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED - * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES - - * 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-1301, - * USA. - */ - -#ifndef _UFSHCI_H -#define _UFSHCI_H - -enum { - TASK_REQ_UPIU_SIZE_DWORDS = 8, - TASK_RSP_UPIU_SIZE_DWORDS = 8, - ALIGNED_UPIU_SIZE = 128, -}; - -/* UFSHCI Registers */ -enum { - REG_CONTROLLER_CAPABILITIES = 0x00, - REG_UFS_VERSION = 0x08, - REG_CONTROLLER_DEV_ID = 0x10, - REG_CONTROLLER_PROD_ID = 0x14, - REG_INTERRUPT_STATUS = 0x20, - REG_INTERRUPT_ENABLE = 0x24, - REG_CONTROLLER_STATUS = 0x30, - REG_CONTROLLER_ENABLE = 0x34, - REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER = 0x38, - REG_UIC_ERROR_CODE_DATA_LINK_LAYER = 0x3C, - REG_UIC_ERROR_CODE_NETWORK_LAYER = 0x40, - REG_UIC_ERROR_CODE_TRANSPORT_LAYER = 0x44, - REG_UIC_ERROR_CODE_DME = 0x48, - REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL = 0x4C, - REG_UTP_TRANSFER_REQ_LIST_BASE_L = 0x50, - REG_UTP_TRANSFER_REQ_LIST_BASE_H = 0x54, - REG_UTP_TRANSFER_REQ_DOOR_BELL = 0x58, - REG_UTP_TRANSFER_REQ_LIST_CLEAR = 0x5C, - REG_UTP_TRANSFER_REQ_LIST_RUN_STOP = 0x60, - REG_UTP_TASK_REQ_LIST_BASE_L = 0x70, - REG_UTP_TASK_REQ_LIST_BASE_H = 0x74, - REG_UTP_TASK_REQ_DOOR_BELL = 0x78, - REG_UTP_TASK_REQ_LIST_CLEAR = 0x7C, - REG_UTP_TASK_REQ_LIST_RUN_STOP = 0x80, - REG_UIC_COMMAND = 0x90, - REG_UIC_COMMAND_ARG_1 = 0x94, - REG_UIC_COMMAND_ARG_2 = 0x98, - REG_UIC_COMMAND_ARG_3 = 0x9C, -}; - -/* Controller capability masks */ -enum { - MASK_TRANSFER_REQUESTS_SLOTS = 0x0000001F, - MASK_TASK_MANAGEMENT_REQUEST_SLOTS = 0x00070000, - MASK_64_ADDRESSING_SUPPORT = 0x01000000, - MASK_OUT_OF_ORDER_DATA_DELIVERY_SUPPORT = 0x02000000, - MASK_UIC_DME_TEST_MODE_SUPPORT = 0x04000000, -}; - -/* UFS Version 08h */ -#define MINOR_VERSION_NUM_MASK UFS_MASK(0xFFFF, 0) -#define MAJOR_VERSION_NUM_MASK UFS_MASK(0xFFFF, 16) - -/* Controller UFSHCI version */ -enum { - UFSHCI_VERSION_10 = 0x00010000, - UFSHCI_VERSION_11 = 0x00010100, -}; - -/* - * HCDDID - Host Controller Identification Descriptor - * - Device ID and Device Class 10h - */ -#define DEVICE_CLASS UFS_MASK(0xFFFF, 0) -#define DEVICE_ID UFS_MASK(0xFF, 24) - -/* - * HCPMID - Host Controller Identification Descriptor - * - Product/Manufacturer ID 14h - */ -#define MANUFACTURE_ID_MASK UFS_MASK(0xFFFF, 0) -#define PRODUCT_ID_MASK UFS_MASK(0xFFFF, 16) - -#define UFS_BIT(x) (1L << (x)) - -#define UTP_TRANSFER_REQ_COMPL UFS_BIT(0) -#define UIC_DME_END_PT_RESET UFS_BIT(1) -#define UIC_ERROR UFS_BIT(2) -#define UIC_TEST_MODE UFS_BIT(3) -#define UIC_POWER_MODE UFS_BIT(4) -#define UIC_HIBERNATE_EXIT UFS_BIT(5) -#define UIC_HIBERNATE_ENTER UFS_BIT(6) -#define UIC_LINK_LOST UFS_BIT(7) -#define UIC_LINK_STARTUP UFS_BIT(8) -#define UTP_TASK_REQ_COMPL UFS_BIT(9) -#define UIC_COMMAND_COMPL UFS_BIT(10) -#define DEVICE_FATAL_ERROR UFS_BIT(11) -#define CONTROLLER_FATAL_ERROR UFS_BIT(16) -#define SYSTEM_BUS_FATAL_ERROR UFS_BIT(17) - -#define UFSHCD_ERROR_MASK (UIC_ERROR |\ - DEVICE_FATAL_ERROR |\ - CONTROLLER_FATAL_ERROR |\ - SYSTEM_BUS_FATAL_ERROR) - -#define INT_FATAL_ERRORS (DEVICE_FATAL_ERROR |\ - CONTROLLER_FATAL_ERROR |\ - SYSTEM_BUS_FATAL_ERROR) - -/* HCS - Host Controller Status 30h */ -#define DEVICE_PRESENT UFS_BIT(0) -#define UTP_TRANSFER_REQ_LIST_READY UFS_BIT(1) -#define UTP_TASK_REQ_LIST_READY UFS_BIT(2) -#define UIC_COMMAND_READY UFS_BIT(3) -#define HOST_ERROR_INDICATOR UFS_BIT(4) -#define DEVICE_ERROR_INDICATOR UFS_BIT(5) -#define UIC_POWER_MODE_CHANGE_REQ_STATUS_MASK UFS_MASK(0x7, 8) - -/* HCE - Host Controller Enable 34h */ -#define CONTROLLER_ENABLE UFS_BIT(0) -#define CONTROLLER_DISABLE 0x0 - -/* UECPA - Host UIC Error Code PHY Adapter Layer 38h */ -#define UIC_PHY_ADAPTER_LAYER_ERROR UFS_BIT(31) -#define UIC_PHY_ADAPTER_LAYER_ERROR_CODE_MASK 0x1F - -/* UECDL - Host UIC Error Code Data Link Layer 3Ch */ -#define UIC_DATA_LINK_LAYER_ERROR UFS_BIT(31) -#define UIC_DATA_LINK_LAYER_ERROR_CODE_MASK 0x7FFF -#define UIC_DATA_LINK_LAYER_ERROR_PA_INIT 0x2000 - -/* UECN - Host UIC Error Code Network Layer 40h */ -#define UIC_NETWORK_LAYER_ERROR UFS_BIT(31) -#define UIC_NETWORK_LAYER_ERROR_CODE_MASK 0x7 - -/* UECT - Host UIC Error Code Transport Layer 44h */ -#define UIC_TRANSPORT_LAYER_ERROR UFS_BIT(31) -#define UIC_TRANSPORT_LAYER_ERROR_CODE_MASK 0x7F - -/* UECDME - Host UIC Error Code DME 48h */ -#define UIC_DME_ERROR UFS_BIT(31) -#define UIC_DME_ERROR_CODE_MASK 0x1 - -#define INT_AGGR_TIMEOUT_VAL_MASK 0xFF -#define INT_AGGR_COUNTER_THRESHOLD_MASK UFS_MASK(0x1F, 8) -#define INT_AGGR_COUNTER_AND_TIMER_RESET UFS_BIT(16) -#define INT_AGGR_STATUS_BIT UFS_BIT(20) -#define INT_AGGR_PARAM_WRITE UFS_BIT(24) -#define INT_AGGR_ENABLE UFS_BIT(31) - -/* UTRLRSR - UTP Transfer Request Run-Stop Register 60h */ -#define UTP_TRANSFER_REQ_LIST_RUN_STOP_BIT UFS_BIT(0) - -/* UTMRLRSR - UTP Task Management Request Run-Stop Register 80h */ -#define UTP_TASK_REQ_LIST_RUN_STOP_BIT UFS_BIT(0) - -/* UICCMD - UIC Command */ -#define COMMAND_OPCODE_MASK 0xFF -#define GEN_SELECTOR_INDEX_MASK 0xFFFF - -#define MIB_ATTRIBUTE_MASK UFS_MASK(0xFFFF, 16) -#define RESET_LEVEL 0xFF - -#define ATTR_SET_TYPE_MASK UFS_MASK(0xFF, 16) -#define CONFIG_RESULT_CODE_MASK 0xFF -#define GENERIC_ERROR_CODE_MASK 0xFF - -/* UIC Commands */ -enum { - UIC_CMD_DME_GET = 0x01, - UIC_CMD_DME_SET = 0x02, - UIC_CMD_DME_PEER_GET = 0x03, - UIC_CMD_DME_PEER_SET = 0x04, - UIC_CMD_DME_POWERON = 0x10, - UIC_CMD_DME_POWEROFF = 0x11, - UIC_CMD_DME_ENABLE = 0x12, - UIC_CMD_DME_RESET = 0x14, - UIC_CMD_DME_END_PT_RST = 0x15, - UIC_CMD_DME_LINK_STARTUP = 0x16, - UIC_CMD_DME_HIBER_ENTER = 0x17, - UIC_CMD_DME_HIBER_EXIT = 0x18, - UIC_CMD_DME_TEST_MODE = 0x1A, -}; - -/* UIC Config result code / Generic error code */ -enum { - UIC_CMD_RESULT_SUCCESS = 0x00, - UIC_CMD_RESULT_INVALID_ATTR = 0x01, - UIC_CMD_RESULT_FAILURE = 0x01, - UIC_CMD_RESULT_INVALID_ATTR_VALUE = 0x02, - UIC_CMD_RESULT_READ_ONLY_ATTR = 0x03, - UIC_CMD_RESULT_WRITE_ONLY_ATTR = 0x04, - UIC_CMD_RESULT_BAD_INDEX = 0x05, - UIC_CMD_RESULT_LOCKED_ATTR = 0x06, - UIC_CMD_RESULT_BAD_TEST_FEATURE_INDEX = 0x07, - UIC_CMD_RESULT_PEER_COMM_FAILURE = 0x08, - UIC_CMD_RESULT_BUSY = 0x09, - UIC_CMD_RESULT_DME_FAILURE = 0x0A, -}; - -#define MASK_UIC_COMMAND_RESULT 0xFF - -#define INT_AGGR_COUNTER_THRESHOLD_VALUE (0x1F << 8) -#define INT_AGGR_TIMEOUT_VALUE (0x02) - -/* Interrupt disable masks */ -enum { - /* Interrupt disable mask for UFSHCI v1.0 */ - INTERRUPT_DISABLE_MASK_10 = 0xFFFF, - - /* Interrupt disable mask for UFSHCI v1.1 */ - INTERRUPT_DISABLE_MASK_11 = 0x0, -}; - -/* - * Request Descriptor Definitions - */ - -/* Transfer request command type */ -enum { - UTP_CMD_TYPE_SCSI = 0x0, - UTP_CMD_TYPE_UFS = 0x1, - UTP_CMD_TYPE_DEV_MANAGE = 0x2, -}; - -enum { - UTP_SCSI_COMMAND = 0x00000000, - UTP_NATIVE_UFS_COMMAND = 0x10000000, - UTP_DEVICE_MANAGEMENT_FUNCTION = 0x20000000, - UTP_REQ_DESC_INT_CMD = 0x01000000, -}; - -/* UTP Transfer Request Data Direction (DD) */ -enum { - UTP_NO_DATA_TRANSFER = 0x00000000, - UTP_HOST_TO_DEVICE = 0x02000000, - UTP_DEVICE_TO_HOST = 0x04000000, -}; - -/* Overall command status values */ -enum { - OCS_SUCCESS = 0x0, - OCS_INVALID_CMD_TABLE_ATTR = 0x1, - OCS_INVALID_PRDT_ATTR = 0x2, - OCS_MISMATCH_DATA_BUF_SIZE = 0x3, - OCS_MISMATCH_RESP_UPIU_SIZE = 0x4, - OCS_PEER_COMM_FAILURE = 0x5, - OCS_ABORTED = 0x6, - OCS_FATAL_ERROR = 0x7, - OCS_INVALID_COMMAND_STATUS = 0x0F, - MASK_OCS = 0x0F, -}; - -/** - * struct ufshcd_sg_entry - UFSHCI PRD Entry - * @base_addr: Lower 32bit physical address DW-0 - * @upper_addr: Upper 32bit physical address DW-1 - * @reserved: Reserved for future use DW-2 - * @size: size of physical segment DW-3 - */ -struct ufshcd_sg_entry { - u32 base_addr; - u32 upper_addr; - u32 reserved; - u32 size; -}; - -/** - * struct utp_transfer_cmd_desc - UFS Command Descriptor structure - * @command_upiu: Command UPIU Frame address - * @response_upiu: Response UPIU Frame address - * @prd_table: Physical Region Descriptor - */ -struct utp_transfer_cmd_desc { - u8 command_upiu[ALIGNED_UPIU_SIZE]; - u8 response_upiu[ALIGNED_UPIU_SIZE]; - struct ufshcd_sg_entry prd_table[SG_ALL]; -}; - -/** - * struct request_desc_header - Descriptor Header common to both UTRD and UTMRD - * @dword0: Descriptor Header DW0 - * @dword1: Descriptor Header DW1 - * @dword2: Descriptor Header DW2 - * @dword3: Descriptor Header DW3 - */ -struct request_desc_header { - u32 dword_0; - u32 dword_1; - u32 dword_2; - u32 dword_3; -}; - -/** - * struct utp_transfer_req_desc - UTRD structure - * @header: UTRD header DW-0 to DW-3 - * @command_desc_base_addr_lo: UCD base address low DW-4 - * @command_desc_base_addr_hi: UCD base address high DW-5 - * @response_upiu_length: response UPIU length DW-6 - * @response_upiu_offset: response UPIU offset DW-6 - * @prd_table_length: Physical region descriptor length DW-7 - * @prd_table_offset: Physical region descriptor offset DW-7 - */ -struct utp_transfer_req_desc { - - /* DW 0-3 */ - struct request_desc_header header; - - /* DW 4-5*/ - u32 command_desc_base_addr_lo; - u32 command_desc_base_addr_hi; - - /* DW 6 */ - u16 response_upiu_length; - u16 response_upiu_offset; - - /* DW 7 */ - u16 prd_table_length; - u16 prd_table_offset; -}; - -/** - * struct utp_task_req_desc - UTMRD structure - * @header: UTMRD header DW-0 to DW-3 - * @task_req_upiu: Pointer to task request UPIU DW-4 to DW-11 - * @task_rsp_upiu: Pointer to task response UPIU DW12 to DW-19 - */ -struct utp_task_req_desc { - - /* DW 0-3 */ - struct request_desc_header header; - - /* DW 4-11 */ - u32 task_req_upiu[TASK_REQ_UPIU_SIZE_DWORDS]; - - /* DW 12-19 */ - u32 task_rsp_upiu[TASK_RSP_UPIU_SIZE_DWORDS]; -}; - -#endif /* End of Header */ diff --git a/trunk/drivers/scsi/vmw_pvscsi.c b/trunk/drivers/scsi/vmw_pvscsi.c index 4411d4224401..7264116185d5 100644 --- a/trunk/drivers/scsi/vmw_pvscsi.c +++ b/trunk/drivers/scsi/vmw_pvscsi.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * - * Maintained by: Arvind Kumar + * Maintained by: Alok N Kataria * */ @@ -1178,67 +1178,11 @@ static int __devinit pvscsi_allocate_sg(struct pvscsi_adapter *adapter) return 0; } -/* - * Query the device, fetch the config info and return the - * maximum number of targets on the adapter. In case of - * failure due to any reason return default i.e. 16. - */ -static u32 pvscsi_get_max_targets(struct pvscsi_adapter *adapter) -{ - struct PVSCSICmdDescConfigCmd cmd; - struct PVSCSIConfigPageHeader *header; - struct device *dev; - dma_addr_t configPagePA; - void *config_page; - u32 numPhys = 16; - - dev = pvscsi_dev(adapter); - config_page = pci_alloc_consistent(adapter->dev, PAGE_SIZE, - &configPagePA); - if (!config_page) { - dev_warn(dev, "vmw_pvscsi: failed to allocate memory for config page\n"); - goto exit; - } - BUG_ON(configPagePA & ~PAGE_MASK); - - /* Fetch config info from the device. */ - cmd.configPageAddress = ((u64)PVSCSI_CONFIG_CONTROLLER_ADDRESS) << 32; - cmd.configPageNum = PVSCSI_CONFIG_PAGE_CONTROLLER; - cmd.cmpAddr = configPagePA; - cmd._pad = 0; - - /* - * Mark the completion page header with error values. If the device - * completes the command successfully, it sets the status values to - * indicate success. - */ - header = config_page; - memset(header, 0, sizeof *header); - header->hostStatus = BTSTAT_INVPARAM; - header->scsiStatus = SDSTAT_CHECK; - - pvscsi_write_cmd_desc(adapter, PVSCSI_CMD_CONFIG, &cmd, sizeof cmd); - - if (header->hostStatus == BTSTAT_SUCCESS && - header->scsiStatus == SDSTAT_GOOD) { - struct PVSCSIConfigPageController *config; - - config = config_page; - numPhys = config->numPhys; - } else - dev_warn(dev, "vmw_pvscsi: PVSCSI_CMD_CONFIG failed. hostStatus = 0x%x, scsiStatus = 0x%x\n", - header->hostStatus, header->scsiStatus); - pci_free_consistent(adapter->dev, PAGE_SIZE, config_page, configPagePA); -exit: - return numPhys; -} - static int __devinit pvscsi_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct pvscsi_adapter *adapter; struct Scsi_Host *host; - struct device *dev; unsigned int i; unsigned long flags = 0; int error; @@ -1327,13 +1271,6 @@ static int __devinit pvscsi_probe(struct pci_dev *pdev, goto out_release_resources; } - /* - * Ask the device for max number of targets. - */ - host->max_id = pvscsi_get_max_targets(adapter); - dev = pvscsi_dev(adapter); - dev_info(dev, "vmw_pvscsi: host->max_id: %u\n", host->max_id); - /* * From this point on we should reset the adapter if anything goes * wrong. diff --git a/trunk/drivers/scsi/vmw_pvscsi.h b/trunk/drivers/scsi/vmw_pvscsi.h index 3546e8662e30..62e36e75715e 100644 --- a/trunk/drivers/scsi/vmw_pvscsi.h +++ b/trunk/drivers/scsi/vmw_pvscsi.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * - * Maintained by: Arvind Kumar + * Maintained by: Alok N Kataria * */ @@ -26,7 +26,7 @@ #include -#define PVSCSI_DRIVER_VERSION_STRING "1.0.2.0-k" +#define PVSCSI_DRIVER_VERSION_STRING "1.0.1.0-k" #define PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT 128 @@ -39,45 +39,28 @@ * host adapter status/error codes */ enum HostBusAdapterStatus { - BTSTAT_SUCCESS = 0x00, /* CCB complete normally with no errors */ - BTSTAT_LINKED_COMMAND_COMPLETED = 0x0a, - BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG = 0x0b, - BTSTAT_DATA_UNDERRUN = 0x0c, - BTSTAT_SELTIMEO = 0x11, /* SCSI selection timeout */ - BTSTAT_DATARUN = 0x12, /* data overrun/underrun */ - BTSTAT_BUSFREE = 0x13, /* unexpected bus free */ - BTSTAT_INVPHASE = 0x14, /* invalid bus phase or sequence - * requested by target */ - BTSTAT_LUNMISMATCH = 0x17, /* linked CCB has different LUN from - * first CCB */ - BTSTAT_INVPARAM = 0x1a, /* invalid parameter in CCB or segment - * list */ - BTSTAT_SENSFAILED = 0x1b, /* auto request sense failed */ - BTSTAT_TAGREJECT = 0x1c, /* SCSI II tagged queueing message - * rejected by target */ - BTSTAT_BADMSG = 0x1d, /* unsupported message received by the - * host adapter */ - BTSTAT_HAHARDWARE = 0x20, /* host adapter hardware failed */ - BTSTAT_NORESPONSE = 0x21, /* target did not respond to SCSI ATN, - * sent a SCSI RST */ - BTSTAT_SENTRST = 0x22, /* host adapter asserted a SCSI RST */ - BTSTAT_RECVRST = 0x23, /* other SCSI devices asserted a SCSI - * RST */ - BTSTAT_DISCONNECT = 0x24, /* target device reconnected improperly - * (w/o tag) */ - BTSTAT_BUSRESET = 0x25, /* host adapter issued BUS device reset */ - BTSTAT_ABORTQUEUE = 0x26, /* abort queue generated */ - BTSTAT_HASOFTWARE = 0x27, /* host adapter software error */ - BTSTAT_HATIMEOUT = 0x30, /* host adapter hardware timeout error */ - BTSTAT_SCSIPARITY = 0x34, /* SCSI parity error detected */ -}; - -/* - * SCSI device status values. - */ -enum ScsiDeviceStatus { - SDSTAT_GOOD = 0x00, /* No errors. */ - SDSTAT_CHECK = 0x02, /* Check condition. */ + BTSTAT_SUCCESS = 0x00, /* CCB complete normally with no errors */ + BTSTAT_LINKED_COMMAND_COMPLETED = 0x0a, + BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG = 0x0b, + BTSTAT_DATA_UNDERRUN = 0x0c, + BTSTAT_SELTIMEO = 0x11, /* SCSI selection timeout */ + BTSTAT_DATARUN = 0x12, /* data overrun/underrun */ + BTSTAT_BUSFREE = 0x13, /* unexpected bus free */ + BTSTAT_INVPHASE = 0x14, /* invalid bus phase or sequence requested by target */ + BTSTAT_LUNMISMATCH = 0x17, /* linked CCB has different LUN from first CCB */ + BTSTAT_SENSFAILED = 0x1b, /* auto request sense failed */ + BTSTAT_TAGREJECT = 0x1c, /* SCSI II tagged queueing message rejected by target */ + BTSTAT_BADMSG = 0x1d, /* unsupported message received by the host adapter */ + BTSTAT_HAHARDWARE = 0x20, /* host adapter hardware failed */ + BTSTAT_NORESPONSE = 0x21, /* target did not respond to SCSI ATN, sent a SCSI RST */ + BTSTAT_SENTRST = 0x22, /* host adapter asserted a SCSI RST */ + BTSTAT_RECVRST = 0x23, /* other SCSI devices asserted a SCSI RST */ + BTSTAT_DISCONNECT = 0x24, /* target device reconnected improperly (w/o tag) */ + BTSTAT_BUSRESET = 0x25, /* host adapter issued BUS device reset */ + BTSTAT_ABORTQUEUE = 0x26, /* abort queue generated */ + BTSTAT_HASOFTWARE = 0x27, /* host adapter software error */ + BTSTAT_HATIMEOUT = 0x30, /* host adapter hardware timeout error */ + BTSTAT_SCSIPARITY = 0x34, /* SCSI parity error detected */ }; /* @@ -130,29 +113,6 @@ struct PVSCSICmdDescResetDevice { u8 lun[8]; } __packed; -/* - * Command descriptor for PVSCSI_CMD_CONFIG -- - */ - -struct PVSCSICmdDescConfigCmd { - u64 cmpAddr; - u64 configPageAddress; - u32 configPageNum; - u32 _pad; -} __packed; - -enum PVSCSIConfigPageType { - PVSCSI_CONFIG_PAGE_CONTROLLER = 0x1958, - PVSCSI_CONFIG_PAGE_PHY = 0x1959, - PVSCSI_CONFIG_PAGE_DEVICE = 0x195a, -}; - -enum PVSCSIConfigPageAddressType { - PVSCSI_CONFIG_CONTROLLER_ADDRESS = 0x2120, - PVSCSI_CONFIG_BUSTARGET_ADDRESS = 0x2121, - PVSCSI_CONFIG_PHY_ADDRESS = 0x2122, -}; - /* * Command descriptor for PVSCSI_CMD_ABORT_CMD -- * @@ -372,27 +332,6 @@ struct PVSCSIRingCmpDesc { u32 _pad[2]; } __packed; -struct PVSCSIConfigPageHeader { - u32 pageNum; - u16 numDwords; - u16 hostStatus; - u16 scsiStatus; - u16 reserved[3]; -} __packed; - -struct PVSCSIConfigPageController { - struct PVSCSIConfigPageHeader header; - u64 nodeWWN; /* Device name as defined in the SAS spec. */ - u16 manufacturer[64]; - u16 serialNumber[64]; - u16 opromVersion[32]; - u16 hwVersion[32]; - u16 firmwareVersion[32]; - u32 numPhys; - u8 useConsecutivePhyWWNs; - u8 reserved[3]; -} __packed; - /* * Interrupt status / IRQ bits. */ diff --git a/trunk/drivers/spi/Kconfig b/trunk/drivers/spi/Kconfig index 00c024039c97..3ed748355b98 100644 --- a/trunk/drivers/spi/Kconfig +++ b/trunk/drivers/spi/Kconfig @@ -74,7 +74,7 @@ config SPI_ATMEL This selects a driver for the Atmel SPI Controller, present on many AT32 (AVR32) and AT91 (ARM) chips. -config SPI_BFIN5XX +config SPI_BFIN tristate "SPI controller driver for ADI Blackfin5xx" depends on BLACKFIN help diff --git a/trunk/drivers/spi/Makefile b/trunk/drivers/spi/Makefile index 9d75d2198ff5..a1d48e0ba3dc 100644 --- a/trunk/drivers/spi/Makefile +++ b/trunk/drivers/spi/Makefile @@ -15,7 +15,7 @@ obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o obj-$(CONFIG_SPI_ATH79) += spi-ath79.o obj-$(CONFIG_SPI_AU1550) += spi-au1550.o obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o -obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o +obj-$(CONFIG_SPI_BFIN) += spi-bfin5xx.o obj-$(CONFIG_SPI_BFIN_SPORT) += spi-bfin-sport.o obj-$(CONFIG_SPI_BITBANG) += spi-bitbang.o obj-$(CONFIG_SPI_BUTTERFLY) += spi-butterfly.o diff --git a/trunk/drivers/spi/spi-bcm63xx.c b/trunk/drivers/spi/spi-bcm63xx.c index 7491971139a6..f01b2648452e 100644 --- a/trunk/drivers/spi/spi-bcm63xx.c +++ b/trunk/drivers/spi/spi-bcm63xx.c @@ -1,7 +1,7 @@ /* * Broadcom BCM63xx SPI controller support * - * Copyright (C) 2009-2012 Florian Fainelli + * Copyright (C) 2009-2011 Florian Fainelli * Copyright (C) 2010 Tanguy Bouzeloc * * This program is free software; you can redistribute it and/or @@ -30,8 +30,6 @@ #include #include #include -#include -#include #include @@ -39,6 +37,8 @@ #define DRV_VER "0.1.2" struct bcm63xx_spi { + spinlock_t lock; + int stopping; struct completion done; void __iomem *regs; @@ -96,12 +96,17 @@ static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = { { 391000, SPI_CLK_0_391MHZ } }; -static int bcm63xx_spi_check_transfer(struct spi_device *spi, - struct spi_transfer *t) +static int bcm63xx_spi_setup_transfer(struct spi_device *spi, + struct spi_transfer *t) { + struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); u8 bits_per_word; + u8 clk_cfg, reg; + u32 hz; + int i; bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word; + hz = (t) ? t->speed_hz : spi->max_speed_hz; if (bits_per_word != 8) { dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n", __func__, bits_per_word); @@ -114,19 +119,6 @@ static int bcm63xx_spi_check_transfer(struct spi_device *spi, return -EINVAL; } - return 0; -} - -static void bcm63xx_spi_setup_transfer(struct spi_device *spi, - struct spi_transfer *t) -{ - struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); - u32 hz; - u8 clk_cfg, reg; - int i; - - hz = (t) ? t->speed_hz : spi->max_speed_hz; - /* Find the closest clock configuration */ for (i = 0; i < SPI_CLK_MASK; i++) { if (hz <= bcm63xx_spi_freq_table[i][0]) { @@ -147,6 +139,8 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi, bcm_spi_writeb(bs, reg, SPI_CLK_CFG); dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n", clk_cfg, hz); + + return 0; } /* the spi->mode bits understood by this driver: */ @@ -159,6 +153,9 @@ static int bcm63xx_spi_setup(struct spi_device *spi) bs = spi_master_get_devdata(spi->master); + if (bs->stopping) + return -ESHUTDOWN; + if (!spi->bits_per_word) spi->bits_per_word = 8; @@ -168,7 +165,7 @@ static int bcm63xx_spi_setup(struct spi_device *spi) return -EINVAL; } - ret = bcm63xx_spi_check_transfer(spi, NULL); + ret = bcm63xx_spi_setup_transfer(spi, NULL); if (ret < 0) { dev_err(&spi->dev, "setup: unsupported mode bits %x\n", spi->mode & ~MODEBITS); @@ -193,29 +190,28 @@ static void bcm63xx_spi_fill_tx_fifo(struct bcm63xx_spi *bs) bs->remaining_bytes -= size; } -static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi, - struct spi_transfer *t) +static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) { struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); u16 msg_ctl; u16 cmd; - /* Disable the CMD_DONE interrupt */ - bcm_spi_writeb(bs, 0, SPI_INT_MASK); - dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n", t->tx_buf, t->rx_buf, t->len); /* Transmitter is inhibited */ bs->tx_ptr = t->tx_buf; bs->rx_ptr = t->rx_buf; + init_completion(&bs->done); if (t->tx_buf) { bs->remaining_bytes = t->len; bcm63xx_spi_fill_tx_fifo(bs); } - init_completion(&bs->done); + /* Enable the command done interrupt which + * we use to determine completion of a command */ + bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK); /* Fill in the Message control register */ msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT); @@ -234,76 +230,33 @@ static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi, cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT); cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT); bcm_spi_writew(bs, cmd, SPI_CMD); + wait_for_completion(&bs->done); - /* Enable the CMD_DONE interrupt */ - bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK); + /* Disable the CMD_DONE interrupt */ + bcm_spi_writeb(bs, 0, SPI_INT_MASK); return t->len - bs->remaining_bytes; } -static int bcm63xx_spi_prepare_transfer(struct spi_master *master) -{ - struct bcm63xx_spi *bs = spi_master_get_devdata(master); - - pm_runtime_get_sync(&bs->pdev->dev); - - return 0; -} - -static int bcm63xx_spi_unprepare_transfer(struct spi_master *master) +static int bcm63xx_transfer(struct spi_device *spi, struct spi_message *m) { - struct bcm63xx_spi *bs = spi_master_get_devdata(master); - - pm_runtime_put(&bs->pdev->dev); - - return 0; -} - -static int bcm63xx_spi_transfer_one(struct spi_master *master, - struct spi_message *m) -{ - struct bcm63xx_spi *bs = spi_master_get_devdata(master); + struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); struct spi_transfer *t; - struct spi_device *spi = m->spi; - int status = 0; - unsigned int timeout = 0; - - list_for_each_entry(t, &m->transfers, transfer_list) { - unsigned int len = t->len; - u8 rx_tail; - - status = bcm63xx_spi_check_transfer(spi, t); - if (status < 0) - goto exit; - - /* configure adapter for a new transfer */ - bcm63xx_spi_setup_transfer(spi, t); + int ret = 0; - while (len) { - /* send the data */ - len -= bcm63xx_txrx_bufs(spi, t); - - timeout = wait_for_completion_timeout(&bs->done, HZ); - if (!timeout) { - status = -ETIMEDOUT; - goto exit; - } + if (unlikely(list_empty(&m->transfers))) + return -EINVAL; - /* read out all data */ - rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL); + if (bs->stopping) + return -ESHUTDOWN; - /* Read out all the data */ - if (rx_tail) - memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail); - } - - m->actual_length += t->len; + list_for_each_entry(t, &m->transfers, transfer_list) { + ret += bcm63xx_txrx_bufs(spi, t); } -exit: - m->status = status; - spi_finalize_current_message(master); - return 0; + m->complete(m->context); + + return ret; } /* This driver supports single master mode only. Hence @@ -314,15 +267,39 @@ static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id) struct spi_master *master = (struct spi_master *)dev_id; struct bcm63xx_spi *bs = spi_master_get_devdata(master); u8 intr; + u16 cmd; /* Read interupts and clear them immediately */ intr = bcm_spi_readb(bs, SPI_INT_STATUS); bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); bcm_spi_writeb(bs, 0, SPI_INT_MASK); - /* A transfer completed */ - if (intr & SPI_INTR_CMD_DONE) - complete(&bs->done); + /* A tansfer completed */ + if (intr & SPI_INTR_CMD_DONE) { + u8 rx_tail; + + rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL); + + /* Read out all the data */ + if (rx_tail) + memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail); + + /* See if there is more data to send */ + if (bs->remaining_bytes > 0) { + bcm63xx_spi_fill_tx_fifo(bs); + + /* Start the transfer */ + bcm_spi_writew(bs, SPI_HD_W << SPI_MSG_TYPE_SHIFT, + SPI_MSG_CTL); + cmd = bcm_spi_readw(bs, SPI_CMD); + cmd |= SPI_CMD_START_IMMEDIATE; + cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT); + bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK); + bcm_spi_writew(bs, cmd, SPI_CMD); + } else { + complete(&bs->done); + } + } return IRQ_HANDLED; } @@ -368,6 +345,7 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev) } bs = spi_master_get_devdata(master); + init_completion(&bs->done); platform_set_drvdata(pdev, master); bs->pdev = pdev; @@ -401,13 +379,12 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev) master->bus_num = pdata->bus_num; master->num_chipselect = pdata->num_chipselect; master->setup = bcm63xx_spi_setup; - master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer; - master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer; - master->transfer_one_message = bcm63xx_spi_transfer_one; - master->mode_bits = MODEBITS; + master->transfer = bcm63xx_transfer; bs->speed_hz = pdata->speed_hz; + bs->stopping = 0; bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); + spin_lock_init(&bs->lock); /* Initialize hardware */ clk_enable(bs->clk); @@ -441,16 +418,18 @@ static int __devexit bcm63xx_spi_remove(struct platform_device *pdev) struct spi_master *master = platform_get_drvdata(pdev); struct bcm63xx_spi *bs = spi_master_get_devdata(master); - spi_unregister_master(master); - /* reset spi block */ bcm_spi_writeb(bs, 0, SPI_INT_MASK); + spin_lock(&bs->lock); + bs->stopping = 1; /* HW shutdown */ clk_disable(bs->clk); clk_put(bs->clk); + spin_unlock(&bs->lock); platform_set_drvdata(pdev, 0); + spi_unregister_master(master); return 0; } diff --git a/trunk/drivers/spi/spi-bfin-sport.c b/trunk/drivers/spi/spi-bfin-sport.c index 1fe51198a622..248a2cc671a9 100644 --- a/trunk/drivers/spi/spi-bfin-sport.c +++ b/trunk/drivers/spi/spi-bfin-sport.c @@ -252,15 +252,19 @@ static void bfin_sport_spi_restore_state(struct bfin_sport_spi_master_data *drv_data) { struct bfin_sport_spi_slave_data *chip = drv_data->cur_chip; + unsigned int bits = (drv_data->ops == &bfin_sport_transfer_ops_u8 ? 7 : 15); bfin_sport_spi_disable(drv_data); dev_dbg(drv_data->dev, "restoring spi ctl state\n"); bfin_write(&drv_data->regs->tcr1, chip->ctl_reg); + bfin_write(&drv_data->regs->tcr2, bits); bfin_write(&drv_data->regs->tclkdiv, chip->baud); + bfin_write(&drv_data->regs->tfsdiv, bits); SSYNC(); bfin_write(&drv_data->regs->rcr1, chip->ctl_reg & ~(ITCLK | ITFS)); + bfin_write(&drv_data->regs->rcr2, bits); SSYNC(); bfin_sport_spi_cs_active(chip); @@ -416,15 +420,11 @@ bfin_sport_spi_pump_transfers(unsigned long data) drv_data->cs_change = transfer->cs_change; /* Bits per word setup */ - bits_per_word = transfer->bits_per_word ? : - message->spi->bits_per_word ? : 8; - if (bits_per_word % 16 == 0) - drv_data->ops = &bfin_sport_transfer_ops_u16; - else + bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word; + if (bits_per_word == 8) drv_data->ops = &bfin_sport_transfer_ops_u8; - bfin_write(&drv_data->regs->tcr2, bits_per_word - 1); - bfin_write(&drv_data->regs->tfsdiv, bits_per_word - 1); - bfin_write(&drv_data->regs->rcr2, bits_per_word - 1); + else + drv_data->ops = &bfin_sport_transfer_ops_u16; drv_data->state = RUNNING_STATE; @@ -598,12 +598,11 @@ bfin_sport_spi_setup(struct spi_device *spi) } chip->cs_chg_udelay = chip_info->cs_chg_udelay; chip->idle_tx_val = chip_info->idle_tx_val; + spi->bits_per_word = chip_info->bits_per_word; } } - if (spi->bits_per_word % 8) { - dev_err(&spi->dev, "%d bits_per_word is not supported\n", - spi->bits_per_word); + if (spi->bits_per_word != 8 && spi->bits_per_word != 16) { ret = -EINVAL; goto error; } diff --git a/trunk/drivers/spi/spi-bfin5xx.c b/trunk/drivers/spi/spi-bfin5xx.c index 9bb4d4af8547..3b83ff8b1e2b 100644 --- a/trunk/drivers/spi/spi-bfin5xx.c +++ b/trunk/drivers/spi/spi-bfin5xx.c @@ -396,7 +396,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id) /* last read */ if (drv_data->rx) { dev_dbg(&drv_data->pdev->dev, "last read\n"); - if (!(n_bytes % 2)) { + if (n_bytes % 2) { u16 *buf = (u16 *)drv_data->rx; for (loop = 0; loop < n_bytes / 2; loop++) *buf++ = bfin_read(&drv_data->regs->rdbr); @@ -424,7 +424,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id) if (drv_data->rx && drv_data->tx) { /* duplex */ dev_dbg(&drv_data->pdev->dev, "duplex: write_TDBR\n"); - if (!(n_bytes % 2)) { + if (n_bytes % 2) { u16 *buf = (u16 *)drv_data->rx; u16 *buf2 = (u16 *)drv_data->tx; for (loop = 0; loop < n_bytes / 2; loop++) { @@ -442,7 +442,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id) } else if (drv_data->rx) { /* read */ dev_dbg(&drv_data->pdev->dev, "read: write_TDBR\n"); - if (!(n_bytes % 2)) { + if (n_bytes % 2) { u16 *buf = (u16 *)drv_data->rx; for (loop = 0; loop < n_bytes / 2; loop++) { *buf++ = bfin_read(&drv_data->regs->rdbr); @@ -458,7 +458,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id) } else if (drv_data->tx) { /* write */ dev_dbg(&drv_data->pdev->dev, "write: write_TDBR\n"); - if (!(n_bytes % 2)) { + if (n_bytes % 2) { u16 *buf = (u16 *)drv_data->tx; for (loop = 0; loop < n_bytes / 2; loop++) { bfin_read(&drv_data->regs->rdbr); @@ -587,7 +587,6 @@ static void bfin_spi_pump_transfers(unsigned long data) if (message->state == DONE_STATE) { dev_dbg(&drv_data->pdev->dev, "transfer: all done!\n"); message->status = 0; - bfin_spi_flush(drv_data); bfin_spi_giveback(drv_data); return; } @@ -871,10 +870,8 @@ static void bfin_spi_pump_transfers(unsigned long data) message->actual_length += drv_data->len_in_bytes; /* Move to next transfer of this msg */ message->state = bfin_spi_next_transfer(drv_data); - if (drv_data->cs_change && message->state != DONE_STATE) { - bfin_spi_flush(drv_data); + if (drv_data->cs_change) bfin_spi_cs_deactive(drv_data, chip); - } } /* Schedule next transfer tasklet */ @@ -1029,6 +1026,7 @@ static int bfin_spi_setup(struct spi_device *spi) chip->cs_chg_udelay = chip_info->cs_chg_udelay; chip->idle_tx_val = chip_info->idle_tx_val; chip->pio_interrupt = chip_info->pio_interrupt; + spi->bits_per_word = chip_info->bits_per_word; } else { /* force a default base state */ chip->ctl_reg &= bfin_ctl_reg; diff --git a/trunk/drivers/spi/spi-davinci.c b/trunk/drivers/spi/spi-davinci.c index 9b2901feaf78..31bfba805cf4 100644 --- a/trunk/drivers/spi/spi-davinci.c +++ b/trunk/drivers/spi/spi-davinci.c @@ -653,7 +653,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) dev_dbg(sdev, "Couldn't DMA map a %d bytes RX buffer\n", rx_buf_count); if (t->tx_buf) - dma_unmap_single(&spi->dev, t->tx_dma, t->len, + dma_unmap_single(NULL, t->tx_dma, t->len, DMA_TO_DEVICE); return -ENOMEM; } @@ -692,10 +692,10 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) if (spicfg->io_type == SPI_IO_TYPE_DMA) { if (t->tx_buf) - dma_unmap_single(&spi->dev, t->tx_dma, t->len, + dma_unmap_single(NULL, t->tx_dma, t->len, DMA_TO_DEVICE); - dma_unmap_single(&spi->dev, t->rx_dma, rx_buf_count, + dma_unmap_single(NULL, t->rx_dma, rx_buf_count, DMA_FROM_DEVICE); clear_io_bits(dspi->base + SPIINT, SPIINT_DMA_REQ_EN); diff --git a/trunk/drivers/spi/spi-dw.c b/trunk/drivers/spi/spi-dw.c index d1a495f64e2d..082458d73ce9 100644 --- a/trunk/drivers/spi/spi-dw.c +++ b/trunk/drivers/spi/spi-dw.c @@ -63,6 +63,12 @@ struct chip_data { }; #ifdef CONFIG_DEBUG_FS +static int spi_show_regs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + #define SPI_REGS_BUFSIZE 1024 static ssize_t spi_show_regs(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -122,7 +128,7 @@ static ssize_t spi_show_regs(struct file *file, char __user *user_buf, static const struct file_operations mrst_spi_regs_ops = { .owner = THIS_MODULE, - .open = simple_open, + .open = spi_show_regs_open, .read = spi_show_regs, .llseek = default_llseek, }; diff --git a/trunk/drivers/spi/spi-ep93xx.c b/trunk/drivers/spi/spi-ep93xx.c index e8055073e84d..6db2887852d6 100644 --- a/trunk/drivers/spi/spi-ep93xx.c +++ b/trunk/drivers/spi/spi-ep93xx.c @@ -545,12 +545,13 @@ static void ep93xx_spi_pio_transfer(struct ep93xx_spi *espi) * in case of failure. */ static struct dma_async_tx_descriptor * -ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir) +ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_data_direction dir) { struct spi_transfer *t = espi->current_msg->state; struct dma_async_tx_descriptor *txd; enum dma_slave_buswidth buswidth; struct dma_slave_config conf; + enum dma_transfer_direction slave_dirn; struct scatterlist *sg; struct sg_table *sgt; struct dma_chan *chan; @@ -566,13 +567,14 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir) memset(&conf, 0, sizeof(conf)); conf.direction = dir; - if (dir == DMA_DEV_TO_MEM) { + if (dir == DMA_FROM_DEVICE) { chan = espi->dma_rx; buf = t->rx_buf; sgt = &espi->rx_sgt; conf.src_addr = espi->sspdr_phys; conf.src_addr_width = buswidth; + slave_dirn = DMA_DEV_TO_MEM; } else { chan = espi->dma_tx; buf = t->tx_buf; @@ -580,6 +582,7 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir) conf.dst_addr = espi->sspdr_phys; conf.dst_addr_width = buswidth; + slave_dirn = DMA_MEM_TO_DEV; } ret = dmaengine_slave_config(chan, &conf); @@ -630,7 +633,8 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir) if (!nents) return ERR_PTR(-ENOMEM); - txd = dmaengine_prep_slave_sg(chan, sgt->sgl, nents, dir, DMA_CTRL_ACK); + txd = dmaengine_prep_slave_sg(chan, sgt->sgl, nents, + slave_dirn, DMA_CTRL_ACK); if (!txd) { dma_unmap_sg(chan->device->dev, sgt->sgl, sgt->nents, dir); return ERR_PTR(-ENOMEM); @@ -647,12 +651,12 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir) * unmapped. */ static void ep93xx_spi_dma_finish(struct ep93xx_spi *espi, - enum dma_transfer_direction dir) + enum dma_data_direction dir) { struct dma_chan *chan; struct sg_table *sgt; - if (dir == DMA_DEV_TO_MEM) { + if (dir == DMA_FROM_DEVICE) { chan = espi->dma_rx; sgt = &espi->rx_sgt; } else { @@ -673,16 +677,16 @@ static void ep93xx_spi_dma_transfer(struct ep93xx_spi *espi) struct spi_message *msg = espi->current_msg; struct dma_async_tx_descriptor *rxd, *txd; - rxd = ep93xx_spi_dma_prepare(espi, DMA_DEV_TO_MEM); + rxd = ep93xx_spi_dma_prepare(espi, DMA_FROM_DEVICE); if (IS_ERR(rxd)) { dev_err(&espi->pdev->dev, "DMA RX failed: %ld\n", PTR_ERR(rxd)); msg->status = PTR_ERR(rxd); return; } - txd = ep93xx_spi_dma_prepare(espi, DMA_MEM_TO_DEV); + txd = ep93xx_spi_dma_prepare(espi, DMA_TO_DEVICE); if (IS_ERR(txd)) { - ep93xx_spi_dma_finish(espi, DMA_DEV_TO_MEM); + ep93xx_spi_dma_finish(espi, DMA_FROM_DEVICE); dev_err(&espi->pdev->dev, "DMA TX failed: %ld\n", PTR_ERR(rxd)); msg->status = PTR_ERR(txd); return; @@ -701,8 +705,8 @@ static void ep93xx_spi_dma_transfer(struct ep93xx_spi *espi) wait_for_completion(&espi->wait); - ep93xx_spi_dma_finish(espi, DMA_MEM_TO_DEV); - ep93xx_spi_dma_finish(espi, DMA_DEV_TO_MEM); + ep93xx_spi_dma_finish(espi, DMA_TO_DEVICE); + ep93xx_spi_dma_finish(espi, DMA_FROM_DEVICE); } /** diff --git a/trunk/drivers/spi/spi-fsl-spi.c b/trunk/drivers/spi/spi-fsl-spi.c index 5f748c0d96bd..24cacff57786 100644 --- a/trunk/drivers/spi/spi-fsl-spi.c +++ b/trunk/drivers/spi/spi-fsl-spi.c @@ -139,12 +139,10 @@ static void fsl_spi_change_mode(struct spi_device *spi) static void fsl_spi_chipselect(struct spi_device *spi, int value) { struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); - struct fsl_spi_platform_data *pdata; + struct fsl_spi_platform_data *pdata = spi->dev.parent->platform_data; bool pol = spi->mode & SPI_CS_HIGH; struct spi_mpc8xxx_cs *cs = spi->controller_state; - pdata = spi->dev.parent->parent->platform_data; - if (value == BITBANG_CS_INACTIVE) { if (pdata->cs_control) pdata->cs_control(spi, !pol); diff --git a/trunk/drivers/spi/spi-imx.c b/trunk/drivers/spi/spi-imx.c index 570f22053be8..31054e3de4c1 100644 --- a/trunk/drivers/spi/spi-imx.c +++ b/trunk/drivers/spi/spi-imx.c @@ -83,7 +83,7 @@ struct spi_imx_data { struct spi_bitbang bitbang; struct completion xfer_done; - void __iomem *base; + void *base; int irq; struct clk *clk; unsigned long spi_clk; @@ -766,12 +766,8 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) } ret = of_property_read_u32(np, "fsl,spi-num-chipselects", &num_cs); - if (ret < 0) { - if (mxc_platform_info) - num_cs = mxc_platform_info->num_chipselect; - else - return ret; - } + if (ret < 0) + num_cs = mxc_platform_info->num_chipselect; master = spi_alloc_master(&pdev->dev, sizeof(struct spi_imx_data) + sizeof(int) * num_cs); @@ -788,7 +784,7 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) for (i = 0; i < master->num_chipselect; i++) { int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); - if (cs_gpio < 0 && mxc_platform_info) + if (cs_gpio < 0) cs_gpio = mxc_platform_info->chipselect[i]; spi_imx->chipselect[i] = cs_gpio; diff --git a/trunk/drivers/spi/spi-pl022.c b/trunk/drivers/spi/spi-pl022.c index 400ae2121a2a..96f0da66b185 100644 --- a/trunk/drivers/spi/spi-pl022.c +++ b/trunk/drivers/spi/spi-pl022.c @@ -1667,15 +1667,9 @@ static int calculate_effective_freq(struct pl022 *pl022, int freq, struct /* cpsdvsr = 254 & scr = 255 */ min_tclk = spi_rate(rate, CPSDVR_MAX, SCR_MAX); - if (freq > max_tclk) - dev_warn(&pl022->adev->dev, - "Max speed that can be programmed is %d Hz, you requested %d\n", - max_tclk, freq); - - if (freq < min_tclk) { + if (!((freq <= max_tclk) && (freq >= min_tclk))) { dev_err(&pl022->adev->dev, - "Requested frequency: %d Hz is less than minimum possible %d Hz\n", - freq, min_tclk); + "controller data is incorrect: out of range frequency"); return -EINVAL; } @@ -1687,37 +1681,26 @@ static int calculate_effective_freq(struct pl022 *pl022, int freq, struct while (scr <= SCR_MAX) { tmp = spi_rate(rate, cpsdvsr, scr); - if (tmp > freq) { - /* we need lower freq */ + if (tmp > freq) scr++; - continue; - } - /* - * If found exact value, mark found and break. - * If found more closer value, update and break. + * If found exact value, update and break. + * If found more closer value, update and continue. */ - if (tmp > best_freq) { + else if ((tmp == freq) || (tmp > best_freq)) { best_freq = tmp; best_cpsdvsr = cpsdvsr; best_scr = scr; if (tmp == freq) - found = 1; + break; } - /* - * increased scr will give lower rates, which are not - * required - */ - break; + scr++; } cpsdvsr += 2; scr = SCR_MIN; } - WARN(!best_freq, "pl022: Matching cpsdvsr and scr not found for %d Hz rate \n", - freq); - clk_freq->cpsdvsr = (u8) (best_cpsdvsr & 0xFF); clk_freq->scr = (u8) (best_scr & 0xFF); dev_dbg(&pl022->adev->dev, @@ -1840,12 +1823,9 @@ static int pl022_setup(struct spi_device *spi) } else chip->cs_control = chip_info->cs_control; - /* Check bits per word with vendor specific range */ - if ((bits <= 3) || (bits > pl022->vendor->max_bpw)) { + if (bits <= 3) { + /* PL022 doesn't support less than 4-bits */ status = -ENOTSUPP; - dev_err(&spi->dev, "illegal data size for this controller!\n"); - dev_err(&spi->dev, "This controller can only handle 4 <= n <= %d bit words\n", - pl022->vendor->max_bpw); goto err_config_params; } else if (bits <= 8) { dev_dbg(&spi->dev, "4 <= n <=8 bits per word\n"); @@ -1858,10 +1838,20 @@ static int pl022_setup(struct spi_device *spi) chip->read = READING_U16; chip->write = WRITING_U16; } else { - dev_dbg(&spi->dev, "17 <= n <= 32 bits per word\n"); - chip->n_bytes = 4; - chip->read = READING_U32; - chip->write = WRITING_U32; + if (pl022->vendor->max_bpw >= 32) { + dev_dbg(&spi->dev, "17 <= n <= 32 bits per word\n"); + chip->n_bytes = 4; + chip->read = READING_U32; + chip->write = WRITING_U32; + } else { + dev_err(&spi->dev, + "illegal data size for this controller!\n"); + dev_err(&spi->dev, + "a standard pl022 can only handle " + "1 <= n <= 16 bit words\n"); + status = -ENOTSUPP; + goto err_config_params; + } } /* Now Initialize all register settings required for this chip */ @@ -2205,6 +2195,7 @@ static int pl022_runtime_suspend(struct device *dev) struct pl022 *pl022 = dev_get_drvdata(dev); clk_disable(pl022->clk); + amba_vcore_disable(pl022->adev); return 0; } @@ -2213,6 +2204,7 @@ static int pl022_runtime_resume(struct device *dev) { struct pl022 *pl022 = dev_get_drvdata(dev); + amba_vcore_enable(pl022->adev); clk_enable(pl022->clk); return 0; diff --git a/trunk/drivers/staging/android/Kconfig b/trunk/drivers/staging/android/Kconfig index eb1dee26bda3..08a3b1133d29 100644 --- a/trunk/drivers/staging/android/Kconfig +++ b/trunk/drivers/staging/android/Kconfig @@ -27,14 +27,13 @@ config ANDROID_LOGGER config ANDROID_PERSISTENT_RAM bool - depends on HAVE_MEMBLOCK select REED_SOLOMON select REED_SOLOMON_ENC8 select REED_SOLOMON_DEC8 config ANDROID_RAM_CONSOLE bool "Android RAM buffer console" - depends on !S390 && !UML && HAVE_MEMBLOCK + depends on !S390 && !UML select ANDROID_PERSISTENT_RAM default n diff --git a/trunk/drivers/staging/android/lowmemorykiller.c b/trunk/drivers/staging/android/lowmemorykiller.c index b91e4bc332a7..052b43e4e505 100644 --- a/trunk/drivers/staging/android/lowmemorykiller.c +++ b/trunk/drivers/staging/android/lowmemorykiller.c @@ -55,6 +55,7 @@ static int lowmem_minfree[6] = { }; static int lowmem_minfree_size = 4; +static struct task_struct *lowmem_deathpending; static unsigned long lowmem_deathpending_timeout; #define lowmem_print(level, x...) \ @@ -63,6 +64,24 @@ static unsigned long lowmem_deathpending_timeout; printk(x); \ } while (0) +static int +task_notify_func(struct notifier_block *self, unsigned long val, void *data); + +static struct notifier_block task_nb = { + .notifier_call = task_notify_func, +}; + +static int +task_notify_func(struct notifier_block *self, unsigned long val, void *data) +{ + struct task_struct *task = data; + + if (task == lowmem_deathpending) + lowmem_deathpending = NULL; + + return NOTIFY_OK; +} + static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) { struct task_struct *tsk; @@ -78,6 +97,19 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) int other_file = global_page_state(NR_FILE_PAGES) - global_page_state(NR_SHMEM); + /* + * If we already have a death outstanding, then + * bail out right away; indicating to vmscan + * that we have nothing further to offer on + * this pass. + * + * Note: Currently you need CONFIG_PROFILING + * for this to work correctly. + */ + if (lowmem_deathpending && + time_before_eq(jiffies, lowmem_deathpending_timeout)) + return 0; + if (lowmem_adj_size < array_size) array_size = lowmem_adj_size; if (lowmem_minfree_size < array_size) @@ -116,12 +148,6 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) if (!p) continue; - if (test_tsk_thread_flag(p, TIF_MEMDIE) && - time_before_eq(jiffies, lowmem_deathpending_timeout)) { - task_unlock(p); - rcu_read_unlock(); - return 0; - } oom_score_adj = p->signal->oom_score_adj; if (oom_score_adj < min_score_adj) { task_unlock(p); @@ -148,9 +174,15 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n", selected->pid, selected->comm, selected_oom_score_adj, selected_tasksize); + /* + * If CONFIG_PROFILING is off, then we don't want to stall + * the killer by setting lowmem_deathpending. + */ +#ifdef CONFIG_PROFILING + lowmem_deathpending = selected; lowmem_deathpending_timeout = jiffies + HZ; +#endif send_sig(SIGKILL, selected, 0); - set_tsk_thread_flag(selected, TIF_MEMDIE); rem -= selected_tasksize; } lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n", @@ -166,6 +198,7 @@ static struct shrinker lowmem_shrinker = { static int __init lowmem_init(void) { + task_handoff_register(&task_nb); register_shrinker(&lowmem_shrinker); return 0; } @@ -173,6 +206,7 @@ static int __init lowmem_init(void) static void __exit lowmem_exit(void) { unregister_shrinker(&lowmem_shrinker); + task_handoff_unregister(&task_nb); } module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR); diff --git a/trunk/drivers/staging/android/persistent_ram.c b/trunk/drivers/staging/android/persistent_ram.c index 8d8c1e33e0ff..e08f2574e30a 100644 --- a/trunk/drivers/staging/android/persistent_ram.c +++ b/trunk/drivers/staging/android/persistent_ram.c @@ -399,12 +399,12 @@ static __init struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) { struct persistent_ram_zone *prz; - int ret = -ENOMEM; + int ret; prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL); if (!prz) { pr_err("persistent_ram: failed to allocate persistent ram zone\n"); - goto err; + return ERR_PTR(-ENOMEM); } INIT_LIST_HEAD(&prz->node); @@ -412,13 +412,13 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) ret = persistent_ram_buffer_init(dev_name(dev), prz); if (ret) { pr_err("persistent_ram: failed to initialize buffer\n"); - goto err; + return ERR_PTR(ret); } prz->ecc = ecc; ret = persistent_ram_init_ecc(prz, prz->buffer_size); if (ret) - goto err; + return ERR_PTR(ret); if (prz->buffer->sig == PERSISTENT_RAM_SIG) { if (buffer_size(prz) > prz->buffer_size || @@ -442,9 +442,6 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) atomic_set(&prz->buffer->size, 0); return prz; -err: - kfree(prz); - return ERR_PTR(ret); } struct persistent_ram_zone * __init diff --git a/trunk/drivers/staging/android/timed_gpio.c b/trunk/drivers/staging/android/timed_gpio.c index 45c522cbe784..bc723eff11af 100644 --- a/trunk/drivers/staging/android/timed_gpio.c +++ b/trunk/drivers/staging/android/timed_gpio.c @@ -85,7 +85,7 @@ static int timed_gpio_probe(struct platform_device *pdev) struct timed_gpio_platform_data *pdata = pdev->dev.platform_data; struct timed_gpio *cur_gpio; struct timed_gpio_data *gpio_data, *gpio_dat; - int i, ret; + int i, j, ret = 0; if (!pdata) return -EBUSY; @@ -108,12 +108,18 @@ static int timed_gpio_probe(struct platform_device *pdev) gpio_dat->dev.get_time = gpio_get_time; gpio_dat->dev.enable = gpio_enable; ret = gpio_request(cur_gpio->gpio, cur_gpio->name); - if (ret < 0) - goto err_out; - ret = timed_output_dev_register(&gpio_dat->dev); + if (ret >= 0) { + ret = timed_output_dev_register(&gpio_dat->dev); + if (ret < 0) + gpio_free(cur_gpio->gpio); + } if (ret < 0) { - gpio_free(cur_gpio->gpio); - goto err_out; + for (j = 0; j < i; j++) { + timed_output_dev_unregister(&gpio_data[i].dev); + gpio_free(gpio_data[i].gpio); + } + kfree(gpio_data); + return ret; } gpio_dat->gpio = cur_gpio->gpio; @@ -125,15 +131,6 @@ static int timed_gpio_probe(struct platform_device *pdev) platform_set_drvdata(pdev, gpio_data); return 0; - -err_out: - while (--i >= 0) { - timed_output_dev_unregister(&gpio_data[i].dev); - gpio_free(gpio_data[i].gpio); - } - kfree(gpio_data); - - return ret; } static int timed_gpio_remove(struct platform_device *pdev) diff --git a/trunk/drivers/staging/asus_oled/README b/trunk/drivers/staging/asus_oled/README index 2d721232467a..0d82a6d5fa58 100644 --- a/trunk/drivers/staging/asus_oled/README +++ b/trunk/drivers/staging/asus_oled/README @@ -52,7 +52,7 @@ Configuration There is only one option: start_off. You can use it by: 'modprobe asus_oled start_off=1', or by adding this - line to /etc/modprobe.d/asus_oled.conf: + line to /etc/modprobe.conf: options asus_oled start_off=1 With this option provided, asus_oled driver will switch off the display diff --git a/trunk/drivers/staging/iio/inkern.c b/trunk/drivers/staging/iio/inkern.c index ef07a02bf542..de2c8ea64965 100644 --- a/trunk/drivers/staging/iio/inkern.c +++ b/trunk/drivers/staging/iio/inkern.c @@ -82,7 +82,6 @@ int iio_map_array_unregister(struct iio_dev *indio_dev, ret = -ENODEV; goto error_ret; } - i++; } error_ret: mutex_unlock(&iio_map_list_lock); diff --git a/trunk/drivers/staging/iio/magnetometer/ak8975.c b/trunk/drivers/staging/iio/magnetometer/ak8975.c index ebc2d0840caf..d5ddac3d8831 100644 --- a/trunk/drivers/staging/iio/magnetometer/ak8975.c +++ b/trunk/drivers/staging/iio/magnetometer/ak8975.c @@ -108,8 +108,7 @@ static const int ak8975_index_to_reg[] = { static int ak8975_write_data(struct i2c_client *client, u8 reg, u8 val, u8 mask, u8 shift) { - struct iio_dev *indio_dev = i2c_get_clientdata(client); - struct ak8975_data *data = iio_priv(indio_dev); + struct ak8975_data *data = i2c_get_clientdata(client); u8 regval; int ret; @@ -160,8 +159,7 @@ static int ak8975_read_data(struct i2c_client *client, */ static int ak8975_setup(struct i2c_client *client) { - struct iio_dev *indio_dev = i2c_get_clientdata(client); - struct ak8975_data *data = iio_priv(indio_dev); + struct ak8975_data *data = i2c_get_clientdata(client); u8 device_id; int ret; @@ -511,7 +509,6 @@ static int ak8975_probe(struct i2c_client *client, goto exit_gpio; } data = iio_priv(indio_dev); - i2c_set_clientdata(client, indio_dev); /* Perform some basic start-of-day setup of the device. */ err = ak8975_setup(client); if (err < 0) { @@ -519,6 +516,7 @@ static int ak8975_probe(struct i2c_client *client, goto exit_free_iio; } + i2c_set_clientdata(client, indio_dev); data->client = client; mutex_init(&data->lock); data->eoc_irq = client->irq; diff --git a/trunk/drivers/staging/iio/magnetometer/hmc5843.c b/trunk/drivers/staging/iio/magnetometer/hmc5843.c index e00b416c4d33..91dd3da70cb4 100644 --- a/trunk/drivers/staging/iio/magnetometer/hmc5843.c +++ b/trunk/drivers/staging/iio/magnetometer/hmc5843.c @@ -521,9 +521,7 @@ static int hmc5843_detect(struct i2c_client *client, /* Called when we have found a new HMC5843. */ static void hmc5843_init_client(struct i2c_client *client) { - struct iio_dev *indio_dev = i2c_get_clientdata(client); - struct hmc5843_data *data = iio_priv(indio_dev); - + struct hmc5843_data *data = i2c_get_clientdata(client); hmc5843_set_meas_conf(client, data->meas_conf); hmc5843_set_rate(client, data->rate); hmc5843_configure(client, data->operating_mode); diff --git a/trunk/drivers/staging/media/as102/as102_fw.c b/trunk/drivers/staging/media/as102/as102_fw.c index 1075fb1df0d9..43ebc43e6b9a 100644 --- a/trunk/drivers/staging/media/as102/as102_fw.c +++ b/trunk/drivers/staging/media/as102/as102_fw.c @@ -165,7 +165,7 @@ static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap, int as102_fw_upload(struct as10x_bus_adapter_t *bus_adap) { int errno = -EFAULT; - const struct firmware *firmware = NULL; + const struct firmware *firmware; unsigned char *cmd_buf = NULL; char *fw1, *fw2; struct usb_device *dev = bus_adap->usb_dev; diff --git a/trunk/drivers/staging/octeon/ethernet-rx.c b/trunk/drivers/staging/octeon/ethernet-rx.c index d91751f9ffe8..400df8cbee53 100644 --- a/trunk/drivers/staging/octeon/ethernet-rx.c +++ b/trunk/drivers/staging/octeon/ethernet-rx.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #ifdef CONFIG_XFRM #include diff --git a/trunk/drivers/staging/octeon/ethernet-tx.c b/trunk/drivers/staging/octeon/ethernet-tx.c index 91a97b3e45c6..56d74dc2fbd5 100644 --- a/trunk/drivers/staging/octeon/ethernet-tx.c +++ b/trunk/drivers/staging/octeon/ethernet-tx.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #ifdef CONFIG_XFRM #include diff --git a/trunk/drivers/staging/octeon/ethernet.c b/trunk/drivers/staging/octeon/ethernet.c index 60cba8194de3..9112cd882154 100644 --- a/trunk/drivers/staging/octeon/ethernet.c +++ b/trunk/drivers/staging/octeon/ethernet.c @@ -31,7 +31,6 @@ #include #include #include -#include #include diff --git a/trunk/drivers/staging/omapdrm/omap_drv.c b/trunk/drivers/staging/omapdrm/omap_drv.c index 620b8d54223d..3df5b4c58ecd 100644 --- a/trunk/drivers/staging/omapdrm/omap_drv.c +++ b/trunk/drivers/staging/omapdrm/omap_drv.c @@ -803,6 +803,9 @@ static void pdev_shutdown(struct platform_device *device) static int pdev_probe(struct platform_device *device) { DBG("%s", device->name); + if (platform_driver_register(&omap_dmm_driver)) + dev_err(&device->dev, "DMM registration failed\n"); + return drm_platform_init(&omap_drm_driver, device); } @@ -830,10 +833,6 @@ struct platform_driver pdev = { static int __init omap_drm_init(void) { DBG("init"); - if (platform_driver_register(&omap_dmm_driver)) { - /* we can continue on without DMM.. so not fatal */ - dev_err(NULL, "DMM registration failed\n"); - } return platform_driver_register(&pdev); } diff --git a/trunk/drivers/staging/ozwpan/TODO b/trunk/drivers/staging/ozwpan/TODO index c2d30a7112f3..f7a9c122f596 100644 --- a/trunk/drivers/staging/ozwpan/TODO +++ b/trunk/drivers/staging/ozwpan/TODO @@ -8,7 +8,5 @@ TODO: - code review by USB developer community. - testing with as many devices as possible. -Please send any patches for this driver to -Rupesh Gujare -Chris Kelly +Please send any patches for this driver to Chris Kelly and Greg Kroah-Hartman . diff --git a/trunk/drivers/staging/ozwpan/ozpd.c b/trunk/drivers/staging/ozwpan/ozpd.c index 04cd57f2a6da..2b45d3d1800c 100644 --- a/trunk/drivers/staging/ozwpan/ozpd.c +++ b/trunk/drivers/staging/ozwpan/ozpd.c @@ -383,6 +383,8 @@ static void oz_tx_frame_free(struct oz_pd *pd, struct oz_tx_frame *f) pd->tx_pool = &f->link; pd->tx_pool_count++; f = 0; + } else { + kfree(f); } spin_unlock_bh(&pd->tx_frame_lock); if (f) diff --git a/trunk/drivers/staging/ramster/Kconfig b/trunk/drivers/staging/ramster/Kconfig index 4af1f8d4b953..8b57b87edda4 100644 --- a/trunk/drivers/staging/ramster/Kconfig +++ b/trunk/drivers/staging/ramster/Kconfig @@ -1,6 +1,10 @@ +# Dependency on CONFIG_BROKEN is because there is a commit dependency +# on a cleancache naming change to be submitted by Konrad Wilk +# a39c00ded70339603ffe1b0ffdf3ade85bcf009a "Merge branch 'stable/cleancache.v13' +# into linux-next. Once this commit is present, BROKEN can be removed config RAMSTER bool "Cross-machine RAM capacity sharing, aka peer-to-peer tmem" - depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS=y && !ZCACHE && !XVMALLOC && !HIGHMEM + depends on (CLEANCACHE || FRONTSWAP) && CONFIGFS_FS=y && !ZCACHE && !XVMALLOC && !HIGHMEM && BROKEN select LZO_COMPRESS select LZO_DECOMPRESS default n diff --git a/trunk/drivers/staging/rts_pstor/ms.c b/trunk/drivers/staging/rts_pstor/ms.c index f9a4498984cc..66341dff8c99 100644 --- a/trunk/drivers/staging/rts_pstor/ms.c +++ b/trunk/drivers/staging/rts_pstor/ms.c @@ -3498,8 +3498,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 log_blk++; - for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; - seg_no++) { + for (seg_no = 0; seg_no < sizeof(ms_start_idx)/2; seg_no++) { if (log_blk < ms_start_idx[seg_no+1]) break; } diff --git a/trunk/drivers/staging/rts_pstor/rtsx.c b/trunk/drivers/staging/rts_pstor/rtsx.c index 1dccd933a7e4..a7feb3e328a0 100644 --- a/trunk/drivers/staging/rts_pstor/rtsx.c +++ b/trunk/drivers/staging/rts_pstor/rtsx.c @@ -1000,11 +1000,6 @@ static int __devinit rtsx_probe(struct pci_dev *pci, rtsx_init_chip(dev->chip); - /* set the supported max_lun and max_id for the scsi host - * NOTE: the minimal value of max_id is 1 */ - host->max_id = 1; - host->max_lun = dev->chip->max_lun; - /* Start up our control thread */ th = kthread_run(rtsx_control_thread, dev, CR_DRIVER_NAME); if (IS_ERR(th)) { diff --git a/trunk/drivers/staging/rts_pstor/rtsx_transport.c b/trunk/drivers/staging/rts_pstor/rtsx_transport.c index 9b2e5c99870f..4e3d2c106af0 100644 --- a/trunk/drivers/staging/rts_pstor/rtsx_transport.c +++ b/trunk/drivers/staging/rts_pstor/rtsx_transport.c @@ -335,7 +335,6 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, int sg_cnt, i, resid; int err = 0; long timeleft; - struct scatterlist *sg_ptr; u32 val = TRIG_DMA; if ((sg == NULL) || (num_sg <= 0) || !offset || !index) @@ -372,7 +371,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, sg_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); resid = size; - sg_ptr = sg; + chip->sgi = 0; /* Usually the next entry will be @sg@ + 1, but if this sg element * is part of a chained scatterlist, it could jump to the start of @@ -380,14 +379,14 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, * the proper sg */ for (i = 0; i < *index; i++) - sg_ptr = sg_next(sg_ptr); + sg = sg_next(sg); for (i = *index; i < sg_cnt; i++) { dma_addr_t addr; unsigned int len; u8 option; - addr = sg_dma_address(sg_ptr); - len = sg_dma_len(sg_ptr); + addr = sg_dma_address(sg); + len = sg_dma_len(sg); RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n", (unsigned int)addr, len); @@ -416,7 +415,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, if (!resid) break; - sg_ptr = sg_next(sg_ptr); + sg = sg_next(sg); } RTSX_DEBUGP("SG table count = %d\n", chip->sgi); diff --git a/trunk/drivers/staging/sep/sep_main.c b/trunk/drivers/staging/sep/sep_main.c index f1701bc6e312..ad54c2e5c932 100644 --- a/trunk/drivers/staging/sep/sep_main.c +++ b/trunk/drivers/staging/sep/sep_main.c @@ -3114,7 +3114,7 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) current->pid); if (1 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, &call_status->status)) { - dev_dbg(&sep->pdev->dev, + dev_warn(&sep->pdev->dev, "[PID%d] dcb prep needed before send msg\n", current->pid); error = -EPROTO; @@ -3122,9 +3122,9 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } if (!arg) { - dev_dbg(&sep->pdev->dev, + dev_warn(&sep->pdev->dev, "[PID%d] dcb null arg\n", current->pid); - error = -EINVAL; + error = EINVAL; goto end_function; } diff --git a/trunk/drivers/staging/tidspbridge/core/tiomap3430.c b/trunk/drivers/staging/tidspbridge/core/tiomap3430.c index 9cf29fcea11e..7862513cc295 100644 --- a/trunk/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/trunk/drivers/staging/tidspbridge/core/tiomap3430.c @@ -79,6 +79,10 @@ #define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) #define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) +#define OMAP343X_CTRL_REGADDR(reg) \ + OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg)) + + /* Forward Declarations: */ static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt); static int bridge_brd_read(struct bridge_dev_context *dev_ctxt, @@ -414,27 +418,19 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, /* Assert RST1 i.e only the RST only for DSP megacell */ if (!status) { - /* - * XXX: ioremapping MUST be removed once ctrl - * function is made available. - */ - void __iomem *ctrl = ioremap(OMAP343X_CTRL_BASE, SZ_4K); - if (!ctrl) - return -ENOMEM; - (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, OMAP3430_RST1_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); /* Mask address with 1K for compatibility */ __raw_writel(dsp_addr & OMAP3_IVA2_BOOTADDR_MASK, - ctrl + OMAP343X_CONTROL_IVA2_BOOTADDR); + OMAP343X_CTRL_REGADDR( + OMAP343X_CONTROL_IVA2_BOOTADDR)); /* * Set bootmode to self loop if dsp_debug flag is true */ __raw_writel((dsp_debug) ? OMAP3_IVA2_BOOTMOD_IDLE : 0, - ctrl + OMAP343X_CONTROL_IVA2_BOOTMOD); - - iounmap(ctrl); + OMAP343X_CTRL_REGADDR( + OMAP343X_CONTROL_IVA2_BOOTMOD)); } } if (!status) { diff --git a/trunk/drivers/staging/tidspbridge/core/wdt.c b/trunk/drivers/staging/tidspbridge/core/wdt.c index 870f934f4f3b..70055c8111ed 100644 --- a/trunk/drivers/staging/tidspbridge/core/wdt.c +++ b/trunk/drivers/staging/tidspbridge/core/wdt.c @@ -53,10 +53,7 @@ int dsp_wdt_init(void) int ret = 0; dsp_wdt.sm_wdt = NULL; - dsp_wdt.reg_base = ioremap(OMAP34XX_WDT3_BASE, SZ_4K); - if (!dsp_wdt.reg_base) - return -ENOMEM; - + dsp_wdt.reg_base = OMAP2_L4_IO_ADDRESS(OMAP34XX_WDT3_BASE); tasklet_init(&dsp_wdt.wdt3_tasklet, dsp_wdt_dpc, 0); dsp_wdt.fclk = clk_get(NULL, "wdt3_fck"); @@ -102,9 +99,6 @@ void dsp_wdt_exit(void) dsp_wdt.fclk = NULL; dsp_wdt.iclk = NULL; dsp_wdt.sm_wdt = NULL; - - if (dsp_wdt.reg_base) - iounmap(dsp_wdt.reg_base); dsp_wdt.reg_base = NULL; } diff --git a/trunk/drivers/staging/vme/devices/vme_pio2_core.c b/trunk/drivers/staging/vme/devices/vme_pio2_core.c index 573c80003f0c..9fedc442a779 100644 --- a/trunk/drivers/staging/vme/devices/vme_pio2_core.c +++ b/trunk/drivers/staging/vme/devices/vme_pio2_core.c @@ -35,10 +35,10 @@ static int vector[PIO2_CARDS_MAX]; static int vector_num; static int level[PIO2_CARDS_MAX]; static int level_num; -static char *variant[PIO2_CARDS_MAX]; +static const char *variant[PIO2_CARDS_MAX]; static int variant_num; -static bool loopback; +static int loopback; static int pio2_match(struct vme_dev *); static int __devinit pio2_probe(struct vme_dev *); diff --git a/trunk/drivers/staging/vt6655/key.c b/trunk/drivers/staging/vt6655/key.c index 774b0d4a7e06..0ff8d7bbf2a7 100644 --- a/trunk/drivers/staging/vt6655/key.c +++ b/trunk/drivers/staging/vt6655/key.c @@ -655,9 +655,6 @@ bool KeybSetDefaultKey ( return (false); } - if (uKeyLength > MAX_KEY_LEN) - return false; - pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = true; for(ii=0;iiKeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF; diff --git a/trunk/drivers/staging/vt6656/ioctl.c b/trunk/drivers/staging/vt6656/ioctl.c index d59456c29df1..1463d76895f0 100644 --- a/trunk/drivers/staging/vt6656/ioctl.c +++ b/trunk/drivers/staging/vt6656/ioctl.c @@ -565,7 +565,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) result = -ENOMEM; break; } - pNodeList = kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC); + pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC); if (pNodeList == NULL) { result = -ENOMEM; break; @@ -601,7 +601,6 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) } } if (copy_to_user(pReq->data, pNodeList, sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)))) { - kfree(pNodeList); result = -EFAULT; break; } diff --git a/trunk/drivers/staging/vt6656/key.c b/trunk/drivers/staging/vt6656/key.c index ee62a06a75f4..27bb523c8a97 100644 --- a/trunk/drivers/staging/vt6656/key.c +++ b/trunk/drivers/staging/vt6656/key.c @@ -684,9 +684,6 @@ BOOL KeybSetDefaultKey( return (FALSE); } - if (uKeyLength > MAX_KEY_LEN) - return false; - pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = TRUE; for (ii = 0; ii < ETH_ALEN; ii++) pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF; diff --git a/trunk/drivers/staging/xgifb/vb_init.c b/trunk/drivers/staging/xgifb/vb_init.c index 3650bbff7686..94d5c35e22fb 100644 --- a/trunk/drivers/staging/xgifb/vb_init.c +++ b/trunk/drivers/staging/xgifb/vb_init.c @@ -61,7 +61,7 @@ XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension, } temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B); /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */ - if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08)) + if ((temp & 0x88) == 0x80) data = 0; /* DDR */ else data = 1; /* DDRII */ diff --git a/trunk/drivers/staging/xgifb/vb_setmode.c b/trunk/drivers/staging/xgifb/vb_setmode.c index 60d4adf99923..2919924213c4 100644 --- a/trunk/drivers/staging/xgifb/vb_setmode.c +++ b/trunk/drivers/staging/xgifb/vb_setmode.c @@ -152,7 +152,6 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->pXGINew_CR97 = &XG20_CR97; if (ChipType == XG27) { - unsigned char temp; pVBInfo->MCLKData = (struct SiS_MCLKData *) XGI27New_MCLKData; pVBInfo->CR40 = XGI27_cr41; @@ -163,13 +162,7 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->pCRDE = XG27_CRDE; pVBInfo->pSR40 = &XG27_SR40; pVBInfo->pSR41 = &XG27_SR41; - pVBInfo->SR15 = XG27_SR13; - /*Z11m DDR*/ - temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B); - /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */ - if (((temp & 0x88) == 0x80) || ((temp & 0x88) == 0x08)) - pVBInfo->pXGINew_CR97 = &Z11m_CR97; } if (ChipType >= XG20) { diff --git a/trunk/drivers/staging/xgifb/vb_table.h b/trunk/drivers/staging/xgifb/vb_table.h index e8d6f674b274..dddf261ed53d 100644 --- a/trunk/drivers/staging/xgifb/vb_table.h +++ b/trunk/drivers/staging/xgifb/vb_table.h @@ -33,13 +33,6 @@ static struct XGI_ECLKDataStruct XGI340_ECLKData[] = { {0x5c, 0x23, 0x01, 166} }; -static unsigned char XG27_SR13[4][8] = { - {0x35, 0x45, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR13 */ - {0x41, 0x51, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR14 */ - {0x32, 0x32, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR18 */ - {0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00} /* SR1B */ -}; - static unsigned char XGI340_SR13[4][8] = { {0x35, 0x45, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR13 */ {0x41, 0x51, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR14 */ @@ -78,7 +71,7 @@ static unsigned char XGI27_cr41[24][8] = { {0x20, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0 CR41 */ {0xC4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 1 CR8A */ {0xC4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 2 CR8B */ - {0xB3, 0x13, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 3 CR40[7], + {0xB5, 0x13, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 3 CR40[7], CR99[2:0], CR45[3:0]*/ {0xf0, 0xf5, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 4 CR59 */ @@ -2810,8 +2803,6 @@ static unsigned char XG27_CRDE[2]; static unsigned char XG27_SR40 = 0x04 ; static unsigned char XG27_SR41 = 0x00 ; -static unsigned char Z11m_CR97 = 0x80 ; - static struct XGI330_VCLKDataStruct XGI_VCLKData[] = { /* SR2B,SR2C,SR2D */ {0x1B, 0xE1, 25}, /* 00 (25.175MHz) */ diff --git a/trunk/drivers/staging/zcache/Kconfig b/trunk/drivers/staging/zcache/Kconfig index 7048e01f0817..3ed2c8f656a5 100644 --- a/trunk/drivers/staging/zcache/Kconfig +++ b/trunk/drivers/staging/zcache/Kconfig @@ -2,7 +2,7 @@ config ZCACHE bool "Dynamic compression of swap pages and clean pagecache pages" # X86 dependency is because zsmalloc uses non-portable pte/tlb # functions - depends on (CLEANCACHE || FRONTSWAP) && CRYPTO=y && X86 + depends on (CLEANCACHE || FRONTSWAP) && CRYPTO && X86 select ZSMALLOC select CRYPTO_LZO default n diff --git a/trunk/drivers/staging/zsmalloc/zsmalloc-main.c b/trunk/drivers/staging/zsmalloc/zsmalloc-main.c index 917461c66014..09caa4f2687e 100644 --- a/trunk/drivers/staging/zsmalloc/zsmalloc-main.c +++ b/trunk/drivers/staging/zsmalloc/zsmalloc-main.c @@ -267,39 +267,33 @@ static unsigned long obj_idx_to_offset(struct page *page, return off + obj_idx * class_size; } -static void reset_page(struct page *page) -{ - clear_bit(PG_private, &page->flags); - clear_bit(PG_private_2, &page->flags); - set_page_private(page, 0); - page->mapping = NULL; - page->freelist = NULL; - reset_page_mapcount(page); -} - static void free_zspage(struct page *first_page) { - struct page *nextp, *tmp, *head_extra; + struct page *nextp, *tmp; BUG_ON(!is_first_page(first_page)); BUG_ON(first_page->inuse); - head_extra = (struct page *)page_private(first_page); + nextp = (struct page *)page_private(first_page); - reset_page(first_page); + clear_bit(PG_private, &first_page->flags); + clear_bit(PG_private_2, &first_page->flags); + set_page_private(first_page, 0); + first_page->mapping = NULL; + first_page->freelist = NULL; + reset_page_mapcount(first_page); __free_page(first_page); /* zspage with only 1 system page */ - if (!head_extra) + if (!nextp) return; - list_for_each_entry_safe(nextp, tmp, &head_extra->lru, lru) { + list_for_each_entry_safe(nextp, tmp, &nextp->lru, lru) { list_del(&nextp->lru); - reset_page(nextp); + clear_bit(PG_private_2, &nextp->flags); + nextp->index = 0; __free_page(nextp); } - reset_page(head_extra); - __free_page(head_extra); } /* Initialize a newly allocated zspage */ diff --git a/trunk/drivers/target/tcm_fc/tcm_fc.h b/trunk/drivers/target/tcm_fc/tcm_fc.h index c5eb3c33c3db..830657908db8 100644 --- a/trunk/drivers/target/tcm_fc/tcm_fc.h +++ b/trunk/drivers/target/tcm_fc/tcm_fc.h @@ -122,7 +122,6 @@ struct ft_cmd { /* Local sense buffer */ unsigned char ft_sense_buffer[TRANSPORT_SENSE_BUFFER]; u32 was_ddp_setup:1; /* Set only if ddp is setup */ - u32 aborted:1; /* Set if aborted by reset or timeout */ struct scatterlist *sg; /* Set only if DDP is setup */ u32 sg_cnt; /* No. of item in scatterlist */ }; diff --git a/trunk/drivers/target/tcm_fc/tfc_cmd.c b/trunk/drivers/target/tcm_fc/tfc_cmd.c index a375f257aabc..62dec9715ce5 100644 --- a/trunk/drivers/target/tcm_fc/tfc_cmd.c +++ b/trunk/drivers/target/tcm_fc/tfc_cmd.c @@ -121,8 +121,6 @@ int ft_queue_status(struct se_cmd *se_cmd) struct fc_exch *ep; size_t len; - if (cmd->aborted) - return 0; ft_dump_cmd(cmd, __func__); ep = fc_seq_exch(cmd->seq); lport = ep->lp; @@ -189,8 +187,6 @@ int ft_write_pending(struct se_cmd *se_cmd) ft_dump_cmd(cmd, __func__); - if (cmd->aborted) - return 0; ep = fc_seq_exch(cmd->seq); lport = ep->lp; fp = fc_frame_alloc(lport, sizeof(*txrdy)); @@ -256,10 +252,10 @@ static void ft_recv_seq(struct fc_seq *sp, struct fc_frame *fp, void *arg) struct ft_cmd *cmd = arg; struct fc_frame_header *fh; - if (unlikely(IS_ERR(fp))) { + if (IS_ERR(fp)) { /* XXX need to find cmd if queued */ cmd->seq = NULL; - cmd->aborted = true; + transport_generic_free_cmd(&cmd->se_cmd, 0); return; } @@ -403,8 +399,6 @@ int ft_queue_tm_resp(struct se_cmd *se_cmd) struct se_tmr_req *tmr = se_cmd->se_tmr_req; enum fcp_resp_rsp_codes code; - if (cmd->aborted) - return 0; switch (tmr->response) { case TMR_FUNCTION_COMPLETE: code = FCP_TMF_CMPL; diff --git a/trunk/drivers/target/tcm_fc/tfc_conf.c b/trunk/drivers/target/tcm_fc/tfc_conf.c index 2948dc944619..f357039349ba 100644 --- a/trunk/drivers/target/tcm_fc/tfc_conf.c +++ b/trunk/drivers/target/tcm_fc/tfc_conf.c @@ -300,7 +300,6 @@ static struct se_portal_group *ft_add_tpg( { struct ft_lport_acl *lacl; struct ft_tpg *tpg; - struct workqueue_struct *wq; unsigned long index; int ret; @@ -322,20 +321,18 @@ static struct se_portal_group *ft_add_tpg( tpg->lport_acl = lacl; INIT_LIST_HEAD(&tpg->lun_list); - wq = alloc_workqueue("tcm_fc", 0, 1); - if (!wq) { + ret = core_tpg_register(&ft_configfs->tf_ops, wwn, &tpg->se_tpg, + tpg, TRANSPORT_TPG_TYPE_NORMAL); + if (ret < 0) { kfree(tpg); return NULL; } - ret = core_tpg_register(&ft_configfs->tf_ops, wwn, &tpg->se_tpg, - tpg, TRANSPORT_TPG_TYPE_NORMAL); - if (ret < 0) { - destroy_workqueue(wq); + tpg->workqueue = alloc_workqueue("tcm_fc", 0, 1); + if (!tpg->workqueue) { kfree(tpg); return NULL; } - tpg->workqueue = wq; mutex_lock(&ft_lport_lock); list_add_tail(&tpg->list, &lacl->tpg_list); diff --git a/trunk/drivers/target/tcm_fc/tfc_io.c b/trunk/drivers/target/tcm_fc/tfc_io.c index dc7c0db26e20..2b693eefac55 100644 --- a/trunk/drivers/target/tcm_fc/tfc_io.c +++ b/trunk/drivers/target/tcm_fc/tfc_io.c @@ -81,8 +81,6 @@ int ft_queue_data_in(struct se_cmd *se_cmd) void *from; void *to = NULL; - if (cmd->aborted) - return 0; ep = fc_seq_exch(cmd->seq); lport = ep->lp; cmd->seq = lport->tt.seq_start_next(cmd->seq); diff --git a/trunk/drivers/thermal/Kconfig b/trunk/drivers/thermal/Kconfig index 514a691abea0..f7f71b2d3101 100644 --- a/trunk/drivers/thermal/Kconfig +++ b/trunk/drivers/thermal/Kconfig @@ -18,11 +18,3 @@ config THERMAL_HWMON depends on THERMAL depends on HWMON=y || HWMON=THERMAL default y - -config SPEAR_THERMAL - bool "SPEAr thermal sensor driver" - depends on THERMAL - depends on PLAT_SPEAR - help - Enable this to plug the SPEAr thermal sensor driver into the Linux - thermal framework diff --git a/trunk/drivers/thermal/Makefile b/trunk/drivers/thermal/Makefile index a9fff0bf4b14..31108a01c22e 100644 --- a/trunk/drivers/thermal/Makefile +++ b/trunk/drivers/thermal/Makefile @@ -3,4 +3,3 @@ # obj-$(CONFIG_THERMAL) += thermal_sys.o -obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o \ No newline at end of file diff --git a/trunk/drivers/thermal/spear_thermal.c b/trunk/drivers/thermal/spear_thermal.c deleted file mode 100644 index c2e32df3b164..000000000000 --- a/trunk/drivers/thermal/spear_thermal.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * SPEAr thermal driver. - * - * Copyright (C) 2011-2012 ST Microelectronics - * Author: Vincenzo Frascino - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MD_FACTOR 1000 - -/* SPEAr Thermal Sensor Dev Structure */ -struct spear_thermal_dev { - /* pointer to base address of the thermal sensor */ - void __iomem *thermal_base; - /* clk structure */ - struct clk *clk; - /* pointer to thermal flags */ - unsigned int flags; -}; - -static inline int thermal_get_temp(struct thermal_zone_device *thermal, - unsigned long *temp) -{ - struct spear_thermal_dev *stdev = thermal->devdata; - - /* - * Data are ready to be read after 628 usec from POWERDOWN signal - * (PDN) = 1 - */ - *temp = (readl_relaxed(stdev->thermal_base) & 0x7F) * MD_FACTOR; - return 0; -} - -static struct thermal_zone_device_ops ops = { - .get_temp = thermal_get_temp, -}; - -#ifdef CONFIG_PM -static int spear_thermal_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct thermal_zone_device *spear_thermal = platform_get_drvdata(pdev); - struct spear_thermal_dev *stdev = spear_thermal->devdata; - unsigned int actual_mask = 0; - - /* Disable SPEAr Thermal Sensor */ - actual_mask = readl_relaxed(stdev->thermal_base); - writel_relaxed(actual_mask & ~stdev->flags, stdev->thermal_base); - - clk_disable(stdev->clk); - dev_info(dev, "Suspended.\n"); - - return 0; -} - -static int spear_thermal_resume(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct thermal_zone_device *spear_thermal = platform_get_drvdata(pdev); - struct spear_thermal_dev *stdev = spear_thermal->devdata; - unsigned int actual_mask = 0; - int ret = 0; - - ret = clk_enable(stdev->clk); - if (ret) { - dev_err(&pdev->dev, "Can't enable clock\n"); - return ret; - } - - /* Enable SPEAr Thermal Sensor */ - actual_mask = readl_relaxed(stdev->thermal_base); - writel_relaxed(actual_mask | stdev->flags, stdev->thermal_base); - - dev_info(dev, "Resumed.\n"); - - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(spear_thermal_pm_ops, spear_thermal_suspend, - spear_thermal_resume); - -static int spear_thermal_probe(struct platform_device *pdev) -{ - struct thermal_zone_device *spear_thermal = NULL; - struct spear_thermal_dev *stdev; - struct spear_thermal_pdata *pdata; - int ret = 0; - struct resource *stres = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - if (!stres) { - dev_err(&pdev->dev, "memory resource missing\n"); - return -ENODEV; - } - - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) { - dev_err(&pdev->dev, "platform data is NULL\n"); - return -EINVAL; - } - - stdev = devm_kzalloc(&pdev->dev, sizeof(*stdev), GFP_KERNEL); - if (!stdev) { - dev_err(&pdev->dev, "kzalloc fail\n"); - return -ENOMEM; - } - - /* Enable thermal sensor */ - stdev->thermal_base = devm_ioremap(&pdev->dev, stres->start, - resource_size(stres)); - if (!stdev->thermal_base) { - dev_err(&pdev->dev, "ioremap failed\n"); - return -ENOMEM; - } - - stdev->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(stdev->clk)) { - dev_err(&pdev->dev, "Can't get clock\n"); - return PTR_ERR(stdev->clk); - } - - ret = clk_enable(stdev->clk); - if (ret) { - dev_err(&pdev->dev, "Can't enable clock\n"); - goto put_clk; - } - - stdev->flags = pdata->thermal_flags; - writel_relaxed(stdev->flags, stdev->thermal_base); - - spear_thermal = thermal_zone_device_register("spear_thermal", 0, - stdev, &ops, 0, 0, 0, 0); - if (IS_ERR(spear_thermal)) { - dev_err(&pdev->dev, "thermal zone device is NULL\n"); - ret = PTR_ERR(spear_thermal); - goto disable_clk; - } - - platform_set_drvdata(pdev, spear_thermal); - - dev_info(&spear_thermal->device, "Thermal Sensor Loaded at: 0x%p.\n", - stdev->thermal_base); - - return 0; - -disable_clk: - clk_disable(stdev->clk); -put_clk: - clk_put(stdev->clk); - - return ret; -} - -static int spear_thermal_exit(struct platform_device *pdev) -{ - unsigned int actual_mask = 0; - struct thermal_zone_device *spear_thermal = platform_get_drvdata(pdev); - struct spear_thermal_dev *stdev = spear_thermal->devdata; - - thermal_zone_device_unregister(spear_thermal); - platform_set_drvdata(pdev, NULL); - - /* Disable SPEAr Thermal Sensor */ - actual_mask = readl_relaxed(stdev->thermal_base); - writel_relaxed(actual_mask & ~stdev->flags, stdev->thermal_base); - - clk_disable(stdev->clk); - clk_put(stdev->clk); - - return 0; -} - -static struct platform_driver spear_thermal_driver = { - .probe = spear_thermal_probe, - .remove = spear_thermal_exit, - .driver = { - .name = "spear_thermal", - .owner = THIS_MODULE, - .pm = &spear_thermal_pm_ops, - }, -}; - -module_platform_driver(spear_thermal_driver); - -MODULE_AUTHOR("Vincenzo Frascino "); -MODULE_DESCRIPTION("SPEAr thermal driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/thermal/thermal_sys.c b/trunk/drivers/thermal/thermal_sys.c index 022bacb71a7e..220ce7e31cf5 100644 --- a/trunk/drivers/thermal/thermal_sys.c +++ b/trunk/drivers/thermal/thermal_sys.c @@ -23,8 +23,6 @@ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -41,6 +39,8 @@ MODULE_AUTHOR("Zhang Rui"); MODULE_DESCRIPTION("Generic thermal management sysfs support"); MODULE_LICENSE("GPL"); +#define PREFIX "Thermal: " + struct thermal_cooling_device_instance { int id; char name[THERMAL_NAME_LENGTH]; @@ -60,11 +60,13 @@ static LIST_HEAD(thermal_tz_list); static LIST_HEAD(thermal_cdev_list); static DEFINE_MUTEX(thermal_list_lock); +static unsigned int thermal_event_seqnum; + static int get_idr(struct idr *idr, struct mutex *lock, int *id) { int err; -again: + again: if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0)) return -ENOMEM; @@ -150,9 +152,9 @@ mode_store(struct device *dev, struct device_attribute *attr, if (!tz->ops->set_mode) return -EPERM; - if (!strncmp(buf, "enabled", sizeof("enabled") - 1)) + if (!strncmp(buf, "enabled", sizeof("enabled"))) result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED); - else if (!strncmp(buf, "disabled", sizeof("disabled") - 1)) + else if (!strncmp(buf, "disabled", sizeof("disabled"))) result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED); else result = -EINVAL; @@ -281,7 +283,8 @@ passive_show(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(type, 0444, type_show, NULL); static DEVICE_ATTR(temp, 0444, temp_show, NULL); static DEVICE_ATTR(mode, 0644, mode_show, mode_store); -static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store); +static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, \ + passive_store); static struct device_attribute trip_point_attrs[] = { __ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL), @@ -310,6 +313,22 @@ static struct device_attribute trip_point_attrs[] = { __ATTR(trip_point_11_temp, 0444, trip_point_temp_show, NULL), }; +#define TRIP_POINT_ATTR_ADD(_dev, _index, result) \ +do { \ + result = device_create_file(_dev, \ + &trip_point_attrs[_index * 2]); \ + if (result) \ + break; \ + result = device_create_file(_dev, \ + &trip_point_attrs[_index * 2 + 1]); \ +} while (0) + +#define TRIP_POINT_ATTR_REMOVE(_dev, _index) \ +do { \ + device_remove_file(_dev, &trip_point_attrs[_index * 2]); \ + device_remove_file(_dev, &trip_point_attrs[_index * 2 + 1]); \ +} while (0) + /* sys I/F for cooling device */ #define to_cooling_device(_dev) \ container_of(_dev, struct thermal_cooling_device, device) @@ -816,14 +835,15 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, return 0; device_remove_file(&tz->device, &dev->attr); -remove_symbol_link: + remove_symbol_link: sysfs_remove_link(&tz->device.kobj, dev->name); -release_idr: + release_idr: release_idr(&tz->idr, &tz->lock, dev->id); -free_mem: + free_mem: kfree(dev); return result; } + EXPORT_SYMBOL(thermal_zone_bind_cooling_device); /** @@ -853,13 +873,14 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz, return -ENODEV; -unbind: + unbind: device_remove_file(&tz->device, &pos->attr); sysfs_remove_link(&tz->device.kobj, pos->name); release_idr(&tz->idr, &tz->lock, pos->id); kfree(pos); return 0; } + EXPORT_SYMBOL(thermal_zone_unbind_cooling_device); static void thermal_release(struct device *dev) @@ -867,8 +888,7 @@ static void thermal_release(struct device *dev) struct thermal_zone_device *tz; struct thermal_cooling_device *cdev; - if (!strncmp(dev_name(dev), "thermal_zone", - sizeof("thermal_zone") - 1)) { + if (!strncmp(dev_name(dev), "thermal_zone", sizeof "thermal_zone" - 1)) { tz = to_thermal_zone(dev); kfree(tz); } else { @@ -888,9 +908,8 @@ static struct class thermal_class = { * @devdata: device private data. * @ops: standard thermal cooling devices callbacks. */ -struct thermal_cooling_device * -thermal_cooling_device_register(char *type, void *devdata, - const struct thermal_cooling_device_ops *ops) +struct thermal_cooling_device *thermal_cooling_device_register( + char *type, void *devdata, const struct thermal_cooling_device_ops *ops) { struct thermal_cooling_device *cdev; struct thermal_zone_device *pos; @@ -955,11 +974,12 @@ thermal_cooling_device_register(char *type, void *devdata, if (!result) return cdev; -unregister: + unregister: release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id); device_unregister(&cdev->device); return ERR_PTR(result); } + EXPORT_SYMBOL(thermal_cooling_device_register); /** @@ -1004,6 +1024,7 @@ void thermal_cooling_device_unregister(struct device_unregister(&cdev->device); return; } + EXPORT_SYMBOL(thermal_cooling_device_unregister); /** @@ -1023,7 +1044,8 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) if (tz->ops->get_temp(tz, &temp)) { /* get_temp failed - retry it later */ - pr_warn("failed to read out thermal zone %d\n", tz->id); + printk(KERN_WARNING PREFIX "failed to read out thermal zone " + "%d\n", tz->id); goto leave; } @@ -1038,8 +1060,9 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) ret = tz->ops->notify(tz, count, trip_type); if (!ret) { - pr_emerg("Critical temperature reached (%ld C), shutting down\n", - temp/1000); + printk(KERN_EMERG + "Critical temperature reached (%ld C), shutting down.\n", + temp/1000); orderly_poweroff(true); } } @@ -1077,7 +1100,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) tz->last_temperature = temp; -leave: + leave: if (tz->passive) thermal_zone_device_set_polling(tz, tz->passive_delay); else if (tz->polling_delay) @@ -1176,12 +1199,7 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, } for (count = 0; count < trips; count++) { - result = device_create_file(&tz->device, - &trip_point_attrs[count * 2]); - if (result) - break; - result = device_create_file(&tz->device, - &trip_point_attrs[count * 2 + 1]); + TRIP_POINT_ATTR_ADD(&tz->device, count, result); if (result) goto unregister; tz->ops->get_trip_type(tz, count, &trip_type); @@ -1217,11 +1235,12 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, if (!result) return tz; -unregister: + unregister: release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); device_unregister(&tz->device); return ERR_PTR(result); } + EXPORT_SYMBOL(thermal_zone_device_register); /** @@ -1260,12 +1279,9 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) if (tz->ops->get_mode) device_remove_file(&tz->device, &dev_attr_mode); - for (count = 0; count < tz->trips; count++) { - device_remove_file(&tz->device, - &trip_point_attrs[count * 2]); - device_remove_file(&tz->device, - &trip_point_attrs[count * 2 + 1]); - } + for (count = 0; count < tz->trips; count++) + TRIP_POINT_ATTR_REMOVE(&tz->device, count); + thermal_remove_hwmon_sysfs(tz); release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); idr_destroy(&tz->idr); @@ -1273,6 +1289,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) device_unregister(&tz->device); return; } + EXPORT_SYMBOL(thermal_zone_device_unregister); #ifdef CONFIG_NET @@ -1295,11 +1312,10 @@ int thermal_generate_netlink_event(u32 orig, enum events event) void *msg_header; int size; int result; - static unsigned int thermal_event_seqnum; /* allocate memory */ - size = nla_total_size(sizeof(struct thermal_genl_event)) + - nla_total_size(0); + size = nla_total_size(sizeof(struct thermal_genl_event)) + \ + nla_total_size(0); skb = genlmsg_new(size, GFP_ATOMIC); if (!skb) @@ -1315,8 +1331,8 @@ int thermal_generate_netlink_event(u32 orig, enum events event) } /* fill the data */ - attr = nla_reserve(skb, THERMAL_GENL_ATTR_EVENT, - sizeof(struct thermal_genl_event)); + attr = nla_reserve(skb, THERMAL_GENL_ATTR_EVENT, \ + sizeof(struct thermal_genl_event)); if (!attr) { nlmsg_free(skb); @@ -1343,7 +1359,7 @@ int thermal_generate_netlink_event(u32 orig, enum events event) result = genlmsg_multicast(skb, 0, thermal_event_mcgrp.id, GFP_ATOMIC); if (result) - pr_info("failed to send netlink event:%d\n", result); + printk(KERN_INFO "failed to send netlink event:%d", result); return result; } diff --git a/trunk/drivers/tty/amiserial.c b/trunk/drivers/tty/amiserial.c index 6cc4358f68c1..24145c30c9b0 100644 --- a/trunk/drivers/tty/amiserial.c +++ b/trunk/drivers/tty/amiserial.c @@ -1073,10 +1073,8 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, (new_serial.close_delay != port->close_delay) || (new_serial.xmit_fifo_size != state->xmit_fifo_size) || ((new_serial.flags & ~ASYNC_USR_MASK) != - (port->flags & ~ASYNC_USR_MASK))) { - tty_unlock(); + (port->flags & ~ASYNC_USR_MASK))) return -EPERM; - } port->flags = ((port->flags & ~ASYNC_USR_MASK) | (new_serial.flags & ASYNC_USR_MASK)); state->custom_divisor = new_serial.custom_divisor; diff --git a/trunk/drivers/tty/isicom.c b/trunk/drivers/tty/isicom.c index e1235accab74..794ecb40017c 100644 --- a/trunk/drivers/tty/isicom.c +++ b/trunk/drivers/tty/isicom.c @@ -102,7 +102,7 @@ * You can find the original tools for this direct from Multitech * ftp://ftp.multitech.com/ISI-Cards/ * - * Having installed the cards the module options (/etc/modprobe.d/) + * Having installed the cards the module options (/etc/modprobe.conf) * * options isicom io=card1,card2,card3,card4 irq=card1,card2,card3,card4 * diff --git a/trunk/drivers/tty/serial/8250/8250.c b/trunk/drivers/tty/serial/8250/8250.c index 5c27f7e6c9f1..5b149b466ec8 100644 --- a/trunk/drivers/tty/serial/8250/8250.c +++ b/trunk/drivers/tty/serial/8250/8250.c @@ -1572,11 +1572,13 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) do { struct uart_8250_port *up; struct uart_port *port; + bool skip; up = list_entry(l, struct uart_8250_port, list); port = &up->port; + skip = pass_counter && up->port.flags & UPF_IIR_ONCE; - if (port->handle_irq(port)) { + if (!skip && port->handle_irq(port)) { handled = 1; end = NULL; } else if (end == NULL) @@ -2035,12 +2037,10 @@ static int serial8250_startup(struct uart_port *port) spin_unlock_irqrestore(&port->lock, flags); /* - * If the interrupt is not reasserted, or we otherwise - * don't trust the iir, setup a timer to kick the UART - * on a regular basis. + * If the interrupt is not reasserted, setup a timer to + * kick the UART on a regular basis. */ - if ((!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) || - up->port.flags & UPF_BUG_THRE) { + if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) { up->bugs |= UART_BUG_THRE; pr_debug("ttyS%d - using backup timer\n", serial_index(port)); diff --git a/trunk/drivers/tty/serial/8250/8250_pci.c b/trunk/drivers/tty/serial/8250/8250_pci.c index 858dca865d6a..da2b0b0a183f 100644 --- a/trunk/drivers/tty/serial/8250/8250_pci.c +++ b/trunk/drivers/tty/serial/8250/8250_pci.c @@ -1096,7 +1096,7 @@ static int kt_serial_setup(struct serial_private *priv, const struct pciserial_board *board, struct uart_port *port, int idx) { - port->flags |= UPF_BUG_THRE; + port->flags |= UPF_IIR_ONCE; return skip_tx_en_setup(priv, board, port, idx); } @@ -1118,6 +1118,18 @@ pci_xr17c154_setup(struct serial_private *priv, return pci_default_setup(priv, board, port, idx); } +static int try_enable_msi(struct pci_dev *dev) +{ + /* use msi if available, but fallback to legacy otherwise */ + pci_enable_msi(dev); + return 0; +} + +static void disable_msi(struct pci_dev *dev) +{ + pci_disable_msi(dev); +} + #define PCI_VENDOR_ID_SBSMODULARIO 0x124B #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B #define PCI_DEVICE_ID_OCTPRO 0x0001 @@ -1237,7 +1249,9 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .device = PCI_DEVICE_ID_INTEL_PATSBURG_KT, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, + .init = try_enable_msi, .setup = kt_serial_setup, + .exit = disable_msi, }, /* * ITE diff --git a/trunk/drivers/tty/serial/Kconfig b/trunk/drivers/tty/serial/Kconfig index 070b442c1f81..665beb68f670 100644 --- a/trunk/drivers/tty/serial/Kconfig +++ b/trunk/drivers/tty/serial/Kconfig @@ -1041,7 +1041,7 @@ config SERIAL_OMAP config SERIAL_OMAP_CONSOLE bool "Console on OMAP serial port" - depends on SERIAL_OMAP=y + depends on SERIAL_OMAP select SERIAL_CORE_CONSOLE help Select this option if you would like to use omap serial port as diff --git a/trunk/drivers/tty/serial/altera_uart.c b/trunk/drivers/tty/serial/altera_uart.c index 1f0330915d5a..e7903751e058 100644 --- a/trunk/drivers/tty/serial/altera_uart.c +++ b/trunk/drivers/tty/serial/altera_uart.c @@ -556,7 +556,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res_mem) port->mapbase = res_mem->start; - else if (platp) + else if (platp->mapbase) port->mapbase = platp->mapbase; else return -EINVAL; @@ -564,7 +564,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res_irq) port->irq = res_irq->start; - else if (platp) + else if (platp->irq) port->irq = platp->irq; /* Check platform data first so we can override device node data */ diff --git a/trunk/drivers/tty/serial/amba-pl011.c b/trunk/drivers/tty/serial/amba-pl011.c index 3d569cd68f58..0c65c9e66986 100644 --- a/trunk/drivers/tty/serial/amba-pl011.c +++ b/trunk/drivers/tty/serial/amba-pl011.c @@ -1946,6 +1946,10 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) goto unmap; } + /* Ensure interrupts from this UART are masked and cleared */ + writew(0, uap->port.membase + UART011_IMSC); + writew(0xffff, uap->port.membase + UART011_ICR); + uap->vendor = vendor; uap->lcrh_rx = vendor->lcrh_rx; uap->lcrh_tx = vendor->lcrh_tx; @@ -1963,10 +1967,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) uap->port.line = i; pl011_dma_probe(uap); - /* Ensure interrupts from this UART are masked and cleared */ - writew(0, uap->port.membase + UART011_IMSC); - writew(0xffff, uap->port.membase + UART011_ICR); - snprintf(uap->type, sizeof(uap->type), "PL011 rev%u", amba_rev(dev)); amba_ports[i] = uap; diff --git a/trunk/drivers/tty/serial/atmel_serial.c b/trunk/drivers/tty/serial/atmel_serial.c index 3d7e1ee2fa57..f9a6be7a9bed 100644 --- a/trunk/drivers/tty/serial/atmel_serial.c +++ b/trunk/drivers/tty/serial/atmel_serial.c @@ -389,8 +389,6 @@ static void atmel_start_rx(struct uart_port *port) { UART_PUT_CR(port, ATMEL_US_RSTSTA); /* reset status and receiver */ - UART_PUT_CR(port, ATMEL_US_RXEN); - if (atmel_use_dma_rx(port)) { /* enable PDC controller */ UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT | @@ -406,8 +404,6 @@ static void atmel_start_rx(struct uart_port *port) */ static void atmel_stop_rx(struct uart_port *port) { - UART_PUT_CR(port, ATMEL_US_RXDIS); - if (atmel_use_dma_rx(port)) { /* disable PDC receive */ UART_PUT_PTCR(port, ATMEL_PDC_RXTDIS); diff --git a/trunk/drivers/tty/serial/clps711x.c b/trunk/drivers/tty/serial/clps711x.c index 836fe2731234..e6c3dbd781d6 100644 --- a/trunk/drivers/tty/serial/clps711x.c +++ b/trunk/drivers/tty/serial/clps711x.c @@ -154,9 +154,10 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) port->x_char = 0; return IRQ_HANDLED; } - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) - goto disable_tx_irq; + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { + clps711xuart_stop_tx(port); + return IRQ_HANDLED; + } count = port->fifosize >> 1; do { @@ -170,11 +171,8 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); - if (uart_circ_empty(xmit)) { - disable_tx_irq: - disable_irq_nosync(TX_IRQ(port)); - tx_enabled(port) = 0; - } + if (uart_circ_empty(xmit)) + clps711xuart_stop_tx(port); return IRQ_HANDLED; } diff --git a/trunk/drivers/tty/serial/mfd.c b/trunk/drivers/tty/serial/mfd.c index c4b50af46c44..a9234ba8f8d5 100644 --- a/trunk/drivers/tty/serial/mfd.c +++ b/trunk/drivers/tty/serial/mfd.c @@ -127,6 +127,11 @@ static inline void serial_out(struct uart_hsu_port *up, int offset, int value) #define HSU_REGS_BUFSIZE 1024 +static int hsu_show_regs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} static ssize_t port_show_regs(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -226,14 +231,14 @@ static ssize_t dma_show_regs(struct file *file, char __user *user_buf, static const struct file_operations port_regs_ops = { .owner = THIS_MODULE, - .open = simple_open, + .open = hsu_show_regs_open, .read = port_show_regs, .llseek = default_llseek, }; static const struct file_operations dma_regs_ops = { .owner = THIS_MODULE, - .open = simple_open, + .open = hsu_show_regs_open, .read = dma_show_regs, .llseek = default_llseek, }; diff --git a/trunk/drivers/tty/serial/omap-serial.c b/trunk/drivers/tty/serial/omap-serial.c index d00b38eb268e..0121486ac4fa 100644 --- a/trunk/drivers/tty/serial/omap-serial.c +++ b/trunk/drivers/tty/serial/omap-serial.c @@ -1381,24 +1381,29 @@ static int serial_omap_probe(struct platform_device *pdev) return -ENODEV; } - if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem), + if (!request_mem_region(mem->start, resource_size(mem), pdev->dev.driver->name)) { dev_err(&pdev->dev, "memory region already claimed\n"); return -EBUSY; } dma_rx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); - if (!dma_rx) - return -ENXIO; + if (!dma_rx) { + ret = -EINVAL; + goto err; + } dma_tx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); - if (!dma_tx) - return -ENXIO; - - up = devm_kzalloc(&pdev->dev, sizeof(*up), GFP_KERNEL); - if (!up) - return -ENOMEM; + if (!dma_tx) { + ret = -EINVAL; + goto err; + } + up = kzalloc(sizeof(*up), GFP_KERNEL); + if (up == NULL) { + ret = -ENOMEM; + goto do_release_region; + } up->pdev = pdev; up->port.dev = &pdev->dev; up->port.type = PORT_OMAP; @@ -1418,17 +1423,16 @@ static int serial_omap_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n", up->port.line); ret = -ENODEV; - goto err_port_line; + goto err; } sprintf(up->name, "OMAP UART%d", up->port.line); up->port.mapbase = mem->start; - up->port.membase = devm_ioremap(&pdev->dev, mem->start, - resource_size(mem)); + up->port.membase = ioremap(mem->start, resource_size(mem)); if (!up->port.membase) { dev_err(&pdev->dev, "can't ioremap UART\n"); ret = -ENOMEM; - goto err_ioremap; + goto err; } up->port.flags = omap_up_info->flags; @@ -1474,19 +1478,16 @@ static int serial_omap_probe(struct platform_device *pdev) ret = uart_add_one_port(&serial_omap_reg, &up->port); if (ret != 0) - goto err_add_port; + goto do_release_region; pm_runtime_put(&pdev->dev); platform_set_drvdata(pdev, up); return 0; - -err_add_port: - pm_runtime_put(&pdev->dev); - pm_runtime_disable(&pdev->dev); -err_ioremap: -err_port_line: +err: dev_err(&pdev->dev, "[UART%d]: failure [%s]: %d\n", pdev->id, __func__, ret); +do_release_region: + release_mem_region(mem->start, resource_size(mem)); return ret; } @@ -1498,6 +1499,8 @@ static int serial_omap_remove(struct platform_device *dev) pm_runtime_disable(&up->pdev->dev); uart_remove_one_port(&serial_omap_reg, &up->port); pm_qos_remove_request(&up->pm_qos_request); + + kfree(up); } platform_set_drvdata(dev, NULL); diff --git a/trunk/drivers/tty/serial/pch_uart.c b/trunk/drivers/tty/serial/pch_uart.c index c2816f494807..e825460478be 100644 --- a/trunk/drivers/tty/serial/pch_uart.c +++ b/trunk/drivers/tty/serial/pch_uart.c @@ -210,7 +210,6 @@ enum { #define CMITC_UARTCLK 192000000 /* 192.0000 MHz */ #define FRI2_64_UARTCLK 64000000 /* 64.0000 MHz */ #define FRI2_48_UARTCLK 48000000 /* 48.0000 MHz */ -#define NTC1_UARTCLK 64000000 /* 64.0000 MHz */ struct pch_uart_buffer { unsigned char *buf; @@ -305,7 +304,11 @@ static const int trigger_level_1[4] = { 1, 1, 1, 1 }; #ifdef CONFIG_DEBUG_FS #define PCH_REGS_BUFSIZE 1024 - +static int pch_show_regs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} static ssize_t port_show_regs(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -359,7 +362,7 @@ static ssize_t port_show_regs(struct file *file, char __user *user_buf, static const struct file_operations port_regs_ops = { .owner = THIS_MODULE, - .open = simple_open, + .open = pch_show_regs_open, .read = port_show_regs, .llseek = default_llseek, }; @@ -385,12 +388,6 @@ static int pch_uart_get_uartclk(void) if (cmp && strstr(cmp, "Fish River Island II")) return FRI2_48_UARTCLK; - /* Kontron COMe-mTT10 (nanoETXexpress-TT) */ - cmp = dmi_get_system_info(DMI_BOARD_NAME); - if (cmp && (strstr(cmp, "COMe-mTT") || - strstr(cmp, "nanoETXexpress-TT"))) - return NTC1_UARTCLK; - return DEFAULT_UARTCLK; } @@ -1447,11 +1444,9 @@ static int pch_uart_verify_port(struct uart_port *port, __func__); return -EOPNOTSUPP; #endif + priv->use_dma = 1; priv->use_dma_flag = 1; dev_info(priv->port.dev, "PCH UART : Use DMA Mode\n"); - if (!priv->use_dma) - pch_request_dma(port); - priv->use_dma = 1; } return 0; @@ -1660,7 +1655,6 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, } pci_enable_msi(pdev); - pci_set_master(pdev); iobase = pci_resource_start(pdev, 0); mapbase = pci_resource_start(pdev, 1); diff --git a/trunk/drivers/tty/serial/pmac_zilog.c b/trunk/drivers/tty/serial/pmac_zilog.c index 654755a990df..08ebe901bb59 100644 --- a/trunk/drivers/tty/serial/pmac_zilog.c +++ b/trunk/drivers/tty/serial/pmac_zilog.c @@ -469,7 +469,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) tty = NULL; if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { if (!ZS_IS_OPEN(uap_a)) { - pmz_debug("ChanA interrupt while not open !\n"); + pmz_debug("ChanA interrupt while open !\n"); goto skip_a; } write_zsreg(uap_a, R0, RES_H_IUS); @@ -493,8 +493,8 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) spin_lock(&uap_b->port.lock); tty = NULL; if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { - if (!ZS_IS_OPEN(uap_b)) { - pmz_debug("ChanB interrupt while not open !\n"); + if (!ZS_IS_OPEN(uap_a)) { + pmz_debug("ChanB interrupt while open !\n"); goto skip_b; } write_zsreg(uap_b, R0, RES_H_IUS); diff --git a/trunk/drivers/tty/serial/samsung.c b/trunk/drivers/tty/serial/samsung.c index d8b0aee35632..de249d265bec 100644 --- a/trunk/drivers/tty/serial/samsung.c +++ b/trunk/drivers/tty/serial/samsung.c @@ -982,7 +982,6 @@ static void s3c24xx_serial_resetport(struct uart_port *port, ucon &= ucon_mask; wr_regl(port, S3C2410_UCON, ucon | cfg->ucon); - wr_regl(port, S3C2410_ULCON, cfg->ulcon); /* reset both fifos */ wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH); diff --git a/trunk/drivers/tty/serial/sh-sci.c b/trunk/drivers/tty/serial/sh-sci.c index 3158e17b665c..bf461cf99616 100644 --- a/trunk/drivers/tty/serial/sh-sci.c +++ b/trunk/drivers/tty/serial/sh-sci.c @@ -355,6 +355,9 @@ static void sci_serial_out(struct uart_port *p, int offset, int value) WARN(1, "Invalid register access\n"); } +#define sci_in(up, offset) (up->serial_in(up, offset)) +#define sci_out(up, offset, value) (up->serial_out(up, offset, value)) + static int sci_probe_regmap(struct plat_sci_port *cfg) { switch (cfg->type) { @@ -419,9 +422,9 @@ static int sci_poll_get_char(struct uart_port *port) int c; do { - status = serial_port_in(port, SCxSR); + status = sci_in(port, SCxSR); if (status & SCxSR_ERRORS(port)) { - serial_port_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); + sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); continue; } break; @@ -430,11 +433,11 @@ static int sci_poll_get_char(struct uart_port *port) if (!(status & SCxSR_RDxF(port))) return NO_POLL_CHAR; - c = serial_port_in(port, SCxRDR); + c = sci_in(port, SCxRDR); /* Dummy read */ - serial_port_in(port, SCxSR); - serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); + sci_in(port, SCxSR); + sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); return c; } @@ -445,11 +448,11 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c) unsigned short status; do { - status = serial_port_in(port, SCxSR); + status = sci_in(port, SCxSR); } while (!(status & SCxSR_TDxE(port))); - serial_port_out(port, SCxTDR, c); - serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port)); + sci_out(port, SCxTDR, c); + sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port)); } #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */ @@ -477,10 +480,10 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag) ((!(cflag & CRTSCTS)))) { unsigned short status; - status = serial_port_in(port, SCSPTR); + status = sci_in(port, SCSPTR); status &= ~SCSPTR_CTSIO; status |= SCSPTR_RTSIO; - serial_port_out(port, SCSPTR, status); /* Set RTS = 1 */ + sci_out(port, SCSPTR, status); /* Set RTS = 1 */ } } @@ -490,13 +493,13 @@ static int sci_txfill(struct uart_port *port) reg = sci_getreg(port, SCTFDR); if (reg->size) - return serial_port_in(port, SCTFDR) & 0xff; + return sci_in(port, SCTFDR) & 0xff; reg = sci_getreg(port, SCFDR); if (reg->size) - return serial_port_in(port, SCFDR) >> 8; + return sci_in(port, SCFDR) >> 8; - return !(serial_port_in(port, SCxSR) & SCI_TDRE); + return !(sci_in(port, SCxSR) & SCI_TDRE); } static int sci_txroom(struct uart_port *port) @@ -510,13 +513,13 @@ static int sci_rxfill(struct uart_port *port) reg = sci_getreg(port, SCRFDR); if (reg->size) - return serial_port_in(port, SCRFDR) & 0xff; + return sci_in(port, SCRFDR) & 0xff; reg = sci_getreg(port, SCFDR); if (reg->size) - return serial_port_in(port, SCFDR) & ((port->fifosize << 1) - 1); + return sci_in(port, SCFDR) & ((port->fifosize << 1) - 1); - return (serial_port_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; + return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; } /* @@ -544,14 +547,14 @@ static void sci_transmit_chars(struct uart_port *port) unsigned short ctrl; int count; - status = serial_port_in(port, SCxSR); + status = sci_in(port, SCxSR); if (!(status & SCxSR_TDxE(port))) { - ctrl = serial_port_in(port, SCSCR); + ctrl = sci_in(port, SCSCR); if (uart_circ_empty(xmit)) ctrl &= ~SCSCR_TIE; else ctrl |= SCSCR_TIE; - serial_port_out(port, SCSCR, ctrl); + sci_out(port, SCSCR, ctrl); return; } @@ -570,27 +573,27 @@ static void sci_transmit_chars(struct uart_port *port) break; } - serial_port_out(port, SCxTDR, c); + sci_out(port, SCxTDR, c); port->icount.tx++; } while (--count > 0); - serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port)); + sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port)); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); if (uart_circ_empty(xmit)) { sci_stop_tx(port); } else { - ctrl = serial_port_in(port, SCSCR); + ctrl = sci_in(port, SCSCR); if (port->type != PORT_SCI) { - serial_port_in(port, SCxSR); /* Dummy read */ - serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port)); + sci_in(port, SCxSR); /* Dummy read */ + sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port)); } ctrl |= SCSCR_TIE; - serial_port_out(port, SCSCR, ctrl); + sci_out(port, SCSCR, ctrl); } } @@ -605,7 +608,7 @@ static void sci_receive_chars(struct uart_port *port) unsigned short status; unsigned char flag; - status = serial_port_in(port, SCxSR); + status = sci_in(port, SCxSR); if (!(status & SCxSR_RDxF(port))) return; @@ -618,7 +621,7 @@ static void sci_receive_chars(struct uart_port *port) break; if (port->type == PORT_SCI) { - char c = serial_port_in(port, SCxRDR); + char c = sci_in(port, SCxRDR); if (uart_handle_sysrq_char(port, c) || sci_port->break_flag) count = 0; @@ -626,9 +629,9 @@ static void sci_receive_chars(struct uart_port *port) tty_insert_flip_char(tty, c, TTY_NORMAL); } else { for (i = 0; i < count; i++) { - char c = serial_port_in(port, SCxRDR); + char c = sci_in(port, SCxRDR); - status = serial_port_in(port, SCxSR); + status = sci_in(port, SCxSR); #if defined(CONFIG_CPU_SH3) /* Skip "chars" during break */ if (sci_port->break_flag) { @@ -669,8 +672,8 @@ static void sci_receive_chars(struct uart_port *port) } } - serial_port_in(port, SCxSR); /* dummy read */ - serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); + sci_in(port, SCxSR); /* dummy read */ + sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); copied += count; port->icount.rx += count; @@ -680,8 +683,8 @@ static void sci_receive_chars(struct uart_port *port) /* Tell the rest of the system the news. New characters! */ tty_flip_buffer_push(tty); } else { - serial_port_in(port, SCxSR); /* dummy read */ - serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); + sci_in(port, SCxSR); /* dummy read */ + sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); } } @@ -723,7 +726,7 @@ static void sci_break_timer(unsigned long data) static int sci_handle_errors(struct uart_port *port) { int copied = 0; - unsigned short status = serial_port_in(port, SCxSR); + unsigned short status = sci_in(port, SCxSR); struct tty_struct *tty = port->state->port.tty; struct sci_port *s = to_sci_port(port); @@ -801,8 +804,8 @@ static int sci_handle_fifo_overrun(struct uart_port *port) if (!reg->size) return 0; - if ((serial_port_in(port, SCLSR) & (1 << s->cfg->overrun_bit))) { - serial_port_out(port, SCLSR, 0); + if ((sci_in(port, SCLSR) & (1 << s->cfg->overrun_bit))) { + sci_out(port, SCLSR, 0); port->icount.overrun++; @@ -819,7 +822,7 @@ static int sci_handle_fifo_overrun(struct uart_port *port) static int sci_handle_breaks(struct uart_port *port) { int copied = 0; - unsigned short status = serial_port_in(port, SCxSR); + unsigned short status = sci_in(port, SCxSR); struct tty_struct *tty = port->state->port.tty; struct sci_port *s = to_sci_port(port); @@ -856,8 +859,8 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr) struct sci_port *s = to_sci_port(port); if (s->chan_rx) { - u16 scr = serial_port_in(port, SCSCR); - u16 ssr = serial_port_in(port, SCxSR); + u16 scr = sci_in(port, SCSCR); + u16 ssr = sci_in(port, SCxSR); /* Disable future Rx interrupts */ if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { @@ -866,9 +869,9 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr) } else { scr &= ~SCSCR_RIE; } - serial_port_out(port, SCSCR, scr); + sci_out(port, SCSCR, scr); /* Clear current interrupt */ - serial_port_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port))); + sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port))); dev_dbg(port->dev, "Rx IRQ %lu: setup t-out in %u jiffies\n", jiffies, s->rx_timeout); mod_timer(&s->rx_timer, jiffies + s->rx_timeout); @@ -906,15 +909,15 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr) if (port->type == PORT_SCI) { if (sci_handle_errors(port)) { /* discard character in rx buffer */ - serial_port_in(port, SCxSR); - serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); + sci_in(port, SCxSR); + sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); } } else { sci_handle_fifo_overrun(port); sci_rx_interrupt(irq, ptr); } - serial_port_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); + sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); /* Kick the transmission */ sci_tx_interrupt(irq, ptr); @@ -928,7 +931,7 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr) /* Handle BREAKs */ sci_handle_breaks(port); - serial_port_out(port, SCxSR, SCxSR_BREAK_CLEAR(port)); + sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port)); return IRQ_HANDLED; } @@ -952,8 +955,8 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) struct sci_port *s = to_sci_port(port); irqreturn_t ret = IRQ_NONE; - ssr_status = serial_port_in(port, SCxSR); - scr_status = serial_port_in(port, SCSCR); + ssr_status = sci_in(port, SCxSR); + scr_status = sci_in(port, SCSCR); err_enabled = scr_status & port_rx_irq_mask(port); /* Tx Interrupt */ @@ -1167,7 +1170,7 @@ static void sci_free_gpios(struct sci_port *port) static unsigned int sci_tx_empty(struct uart_port *port) { - unsigned short status = serial_port_in(port, SCxSR); + unsigned short status = sci_in(port, SCxSR); unsigned short in_tx_fifo = sci_txfill(port); return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0; @@ -1195,7 +1198,7 @@ static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) */ reg = sci_getreg(port, SCFCR); if (reg->size) - serial_port_out(port, SCFCR, serial_port_in(port, SCFCR) | 1); + sci_out(port, SCFCR, sci_in(port, SCFCR) | 1); } } @@ -1237,8 +1240,8 @@ static void sci_dma_tx_complete(void *arg) } else { s->cookie_tx = -EINVAL; if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { - u16 ctrl = serial_port_in(port, SCSCR); - serial_port_out(port, SCSCR, ctrl & ~SCSCR_TIE); + u16 ctrl = sci_in(port, SCSCR); + sci_out(port, SCSCR, ctrl & ~SCSCR_TIE); } } @@ -1491,13 +1494,13 @@ static void sci_start_tx(struct uart_port *port) #ifdef CONFIG_SERIAL_SH_SCI_DMA if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { - u16 new, scr = serial_port_in(port, SCSCR); + u16 new, scr = sci_in(port, SCSCR); if (s->chan_tx) new = scr | 0x8000; else new = scr & ~0x8000; if (new != scr) - serial_port_out(port, SCSCR, new); + sci_out(port, SCSCR, new); } if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) && @@ -1509,8 +1512,8 @@ static void sci_start_tx(struct uart_port *port) if (!s->chan_tx || port->type == PORT_SCIFA || port->type == PORT_SCIFB) { /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ - ctrl = serial_port_in(port, SCSCR); - serial_port_out(port, SCSCR, ctrl | SCSCR_TIE); + ctrl = sci_in(port, SCSCR); + sci_out(port, SCSCR, ctrl | SCSCR_TIE); } } @@ -1519,40 +1522,40 @@ static void sci_stop_tx(struct uart_port *port) unsigned short ctrl; /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */ - ctrl = serial_port_in(port, SCSCR); + ctrl = sci_in(port, SCSCR); if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) ctrl &= ~0x8000; ctrl &= ~SCSCR_TIE; - serial_port_out(port, SCSCR, ctrl); + sci_out(port, SCSCR, ctrl); } static void sci_start_rx(struct uart_port *port) { unsigned short ctrl; - ctrl = serial_port_in(port, SCSCR) | port_rx_irq_mask(port); + ctrl = sci_in(port, SCSCR) | port_rx_irq_mask(port); if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) ctrl &= ~0x4000; - serial_port_out(port, SCSCR, ctrl); + sci_out(port, SCSCR, ctrl); } static void sci_stop_rx(struct uart_port *port) { unsigned short ctrl; - ctrl = serial_port_in(port, SCSCR); + ctrl = sci_in(port, SCSCR); if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) ctrl &= ~0x4000; ctrl &= ~port_rx_irq_mask(port); - serial_port_out(port, SCSCR, ctrl); + sci_out(port, SCSCR, ctrl); } static void sci_enable_ms(struct uart_port *port) @@ -1586,13 +1589,13 @@ static void rx_timer_fn(unsigned long arg) { struct sci_port *s = (struct sci_port *)arg; struct uart_port *port = &s->port; - u16 scr = serial_port_in(port, SCSCR); + u16 scr = sci_in(port, SCSCR); if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) { scr &= ~0x4000; enable_irq(s->cfg->irqs[1]); } - serial_port_out(port, SCSCR, scr | SCSCR_RIE); + sci_out(port, SCSCR, scr | SCSCR_RIE); dev_dbg(port->dev, "DMA Rx timed out\n"); schedule_work(&s->work_rx); } @@ -1773,14 +1776,14 @@ static void sci_reset(struct uart_port *port) unsigned int status; do { - status = serial_port_in(port, SCxSR); + status = sci_in(port, SCxSR); } while (!(status & SCxSR_TEND(port))); - serial_port_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ + sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ reg = sci_getreg(port, SCFCR); if (reg->size) - serial_port_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); + sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); } static void sci_set_termios(struct uart_port *port, struct ktermios *termios, @@ -1809,7 +1812,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, sci_reset(port); - smr_val = serial_port_in(port, SCSMR) & 3; + smr_val = sci_in(port, SCSMR) & 3; if ((termios->c_cflag & CSIZE) == CS7) smr_val |= 0x40; @@ -1822,19 +1825,19 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, uart_update_timeout(port, termios->c_cflag, baud); - serial_port_out(port, SCSMR, smr_val); + sci_out(port, SCSMR, smr_val); dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t, s->cfg->scscr); if (t > 0) { if (t >= 256) { - serial_port_out(port, SCSMR, (serial_port_in(port, SCSMR) & ~3) | 1); + sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1); t >>= 2; } else - serial_port_out(port, SCSMR, serial_port_in(port, SCSMR) & ~3); + sci_out(port, SCSMR, sci_in(port, SCSMR) & ~3); - serial_port_out(port, SCBRR, t); + sci_out(port, SCBRR, t); udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ } @@ -1842,7 +1845,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, reg = sci_getreg(port, SCFCR); if (reg->size) { - unsigned short ctrl = serial_port_in(port, SCFCR); + unsigned short ctrl = sci_in(port, SCFCR); if (s->cfg->capabilities & SCIx_HAVE_RTSCTS) { if (termios->c_cflag & CRTSCTS) @@ -1858,10 +1861,10 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, */ ctrl &= ~(SCFCR_RFRST | SCFCR_TFRST); - serial_port_out(port, SCFCR, ctrl); + sci_out(port, SCFCR, ctrl); } - serial_port_out(port, SCSCR, s->cfg->scscr); + sci_out(port, SCSCR, s->cfg->scscr); #ifdef CONFIG_SERIAL_SH_SCI_DMA /* @@ -2163,7 +2166,7 @@ static void serial_console_write(struct console *co, const char *s, /* wait until fifo is empty and last bit has been transmitted */ bits = SCxSR_TDxE(port) | SCxSR_TEND(port); - while ((serial_port_in(port, SCxSR) & bits) != bits) + while ((sci_in(port, SCxSR) & bits) != bits) cpu_relax(); sci_port_disable(sci_port); @@ -2257,12 +2260,12 @@ static int sci_runtime_suspend(struct device *dev) if (uart_console(port)) { struct plat_sci_reg *reg; - sci_port->saved_smr = serial_port_in(port, SCSMR); - sci_port->saved_brr = serial_port_in(port, SCBRR); + sci_port->saved_smr = sci_in(port, SCSMR); + sci_port->saved_brr = sci_in(port, SCBRR); reg = sci_getreg(port, SCFCR); if (reg->size) - sci_port->saved_fcr = serial_port_in(port, SCFCR); + sci_port->saved_fcr = sci_in(port, SCFCR); else sci_port->saved_fcr = 0; } @@ -2276,13 +2279,13 @@ static int sci_runtime_resume(struct device *dev) if (uart_console(port)) { sci_reset(port); - serial_port_out(port, SCSMR, sci_port->saved_smr); - serial_port_out(port, SCBRR, sci_port->saved_brr); + sci_out(port, SCSMR, sci_port->saved_smr); + sci_out(port, SCBRR, sci_port->saved_brr); if (sci_port->saved_fcr) - serial_port_out(port, SCFCR, sci_port->saved_fcr); + sci_out(port, SCFCR, sci_port->saved_fcr); - serial_port_out(port, SCSCR, sci_port->cfg->scscr); + sci_out(port, SCSCR, sci_port->cfg->scscr); } return 0; } diff --git a/trunk/drivers/tty/serial/sh-sci.h b/trunk/drivers/tty/serial/sh-sci.h index 4c22a1529aac..a1a2d364f92b 100644 --- a/trunk/drivers/tty/serial/sh-sci.h +++ b/trunk/drivers/tty/serial/sh-sci.h @@ -20,10 +20,10 @@ defined(CONFIG_ARCH_SH7372) || \ defined(CONFIG_ARCH_R8A7740) -# define SCxSR_RDxF_CLEAR(port) (serial_port_in(port, SCxSR) & 0xfffc) -# define SCxSR_ERROR_CLEAR(port) (serial_port_in(port, SCxSR) & 0xfd73) -# define SCxSR_TDxE_CLEAR(port) (serial_port_in(port, SCxSR) & 0xffdf) -# define SCxSR_BREAK_CLEAR(port) (serial_port_in(port, SCxSR) & 0xffe3) +# define SCxSR_RDxF_CLEAR(port) (sci_in(port, SCxSR) & 0xfffc) +# define SCxSR_ERROR_CLEAR(port) (sci_in(port, SCxSR) & 0xfd73) +# define SCxSR_TDxE_CLEAR(port) (sci_in(port, SCxSR) & 0xffdf) +# define SCxSR_BREAK_CLEAR(port) (sci_in(port, SCxSR) & 0xffe3) #else # define SCxSR_RDxF_CLEAR(port) (((port)->type == PORT_SCI) ? 0xbc : 0x00fc) # define SCxSR_ERROR_CLEAR(port) (((port)->type == PORT_SCI) ? 0xc4 : 0x0073) diff --git a/trunk/drivers/tty/serial/sunzilog.c b/trunk/drivers/tty/serial/sunzilog.c index babd9470982b..b3b70b0bf85b 100644 --- a/trunk/drivers/tty/serial/sunzilog.c +++ b/trunk/drivers/tty/serial/sunzilog.c @@ -1581,7 +1581,7 @@ static int __init sunzilog_init(void) if (err) goto out_unregister_uart; - if (zilog_irq) { + if (!zilog_irq) { struct uart_sunzilog_port *up = sunzilog_irq_chain; err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED, "zs", sunzilog_irq_chain); @@ -1622,7 +1622,7 @@ static void __exit sunzilog_exit(void) { platform_driver_unregister(&zs_driver); - if (zilog_irq) { + if (!zilog_irq) { struct uart_sunzilog_port *up = sunzilog_irq_chain; /* Disable Interrupts */ diff --git a/trunk/drivers/tty/sysrq.c b/trunk/drivers/tty/sysrq.c index 05728894a88c..136e86faa1e1 100644 --- a/trunk/drivers/tty/sysrq.c +++ b/trunk/drivers/tty/sysrq.c @@ -327,7 +327,7 @@ static void send_sig_all(int sig) if (is_global_init(p)) continue; - do_send_sig_info(sig, SEND_SIG_FORCED, p, true); + force_sig(sig, p); } read_unlock(&tasklist_lock); } diff --git a/trunk/drivers/tty/vt/keyboard.c b/trunk/drivers/tty/vt/keyboard.c index 29ca20dbd335..86dd1e302bb3 100644 --- a/trunk/drivers/tty/vt/keyboard.c +++ b/trunk/drivers/tty/vt/keyboard.c @@ -1085,21 +1085,15 @@ void vt_set_led_state(int console, int leds) * * Handle console start. This is a wrapper for the VT layer * so that we can keep kbd knowledge internal - * - * FIXME: We eventually need to hold the kbd lock here to protect - * the LED updating. We can't do it yet because fn_hold calls stop_tty - * and start_tty under the kbd_event_lock, while normal tty paths - * don't hold the lock. We probably need to split out an LED lock - * but not during an -rc release! */ void vt_kbd_con_start(int console) { struct kbd_struct * kbd = kbd_table + console; -/* unsigned long flags; */ -/* spin_lock_irqsave(&kbd_event_lock, flags); */ + unsigned long flags; + spin_lock_irqsave(&kbd_event_lock, flags); clr_vc_kbd_led(kbd, VC_SCROLLOCK); set_leds(); -/* spin_unlock_irqrestore(&kbd_event_lock, flags); */ + spin_unlock_irqrestore(&kbd_event_lock, flags); } /** @@ -1108,28 +1102,22 @@ void vt_kbd_con_start(int console) * * Handle console stop. This is a wrapper for the VT layer * so that we can keep kbd knowledge internal - * - * FIXME: We eventually need to hold the kbd lock here to protect - * the LED updating. We can't do it yet because fn_hold calls stop_tty - * and start_tty under the kbd_event_lock, while normal tty paths - * don't hold the lock. We probably need to split out an LED lock - * but not during an -rc release! */ void vt_kbd_con_stop(int console) { struct kbd_struct * kbd = kbd_table + console; -/* unsigned long flags; */ -/* spin_lock_irqsave(&kbd_event_lock, flags); */ + unsigned long flags; + spin_lock_irqsave(&kbd_event_lock, flags); set_vc_kbd_led(kbd, VC_SCROLLOCK); set_leds(); -/* spin_unlock_irqrestore(&kbd_event_lock, flags); */ + spin_unlock_irqrestore(&kbd_event_lock, flags); } /* * This is the tasklet that updates LED state on all keyboards * attached to the box. The reason we use tasklet is that we * need to handle the scenario when keyboard handler is not - * registered yet but we already getting updates from the VT to + * registered yet but we already getting updates form VT to * update led state. */ static void kbd_bh(unsigned long dummy) diff --git a/trunk/drivers/tty/vt/vt.c b/trunk/drivers/tty/vt/vt.c index 2156188db4a6..3bdd4b19dd06 100644 --- a/trunk/drivers/tty/vt/vt.c +++ b/trunk/drivers/tty/vt/vt.c @@ -2932,10 +2932,11 @@ static int __init con_init(void) gotoxy(vc, vc->vc_x, vc->vc_y); csi_J(vc, 0); update_screen(vc); - pr_info("Console: %s %s %dx%d\n", + pr_info("Console: %s %s %dx%d", vc->vc_can_do_color ? "colour" : "mono", display_desc, vc->vc_cols, vc->vc_rows); printable = 1; + printk("\n"); console_unlock(); diff --git a/trunk/drivers/usb/Kconfig b/trunk/drivers/usb/Kconfig index 76316a33061b..cbd8f5f80596 100644 --- a/trunk/drivers/usb/Kconfig +++ b/trunk/drivers/usb/Kconfig @@ -2,6 +2,14 @@ # USB device configuration # +menuconfig USB_SUPPORT + bool "USB support" + depends on HAS_IOMEM + default y + ---help--- + This option adds core support for Universal Serial Bus (USB). + You will also need drivers from the following menu to make use of it. + # many non-PCI SOC chips embed OHCI config USB_ARCH_HAS_OHCI boolean @@ -55,14 +63,6 @@ config USB_ARCH_HAS_XHCI boolean default PCI -menuconfig USB_SUPPORT - bool "USB support" - depends on HAS_IOMEM - default y - ---help--- - This option adds core support for Universal Serial Bus (USB). - You will also need drivers from the following menu to make use of it. - if USB_SUPPORT config USB_COMMON diff --git a/trunk/drivers/usb/class/cdc-wdm.c b/trunk/drivers/usb/class/cdc-wdm.c index 0bb2b3248dad..c6f6560d436c 100644 --- a/trunk/drivers/usb/class/cdc-wdm.c +++ b/trunk/drivers/usb/class/cdc-wdm.c @@ -157,9 +157,8 @@ static void wdm_out_callback(struct urb *urb) spin_lock(&desc->iuspin); desc->werr = urb->status; spin_unlock(&desc->iuspin); - kfree(desc->outbuf); - desc->outbuf = NULL; clear_bit(WDM_IN_USE, &desc->flags); + kfree(desc->outbuf); wake_up(&desc->wait); } @@ -339,7 +338,7 @@ static ssize_t wdm_write if (we < 0) return -EIO; - buf = kmalloc(count, GFP_KERNEL); + desc->outbuf = buf = kmalloc(count, GFP_KERNEL); if (!buf) { rv = -ENOMEM; goto outnl; @@ -407,12 +406,10 @@ static ssize_t wdm_write req->wIndex = desc->inum; req->wLength = cpu_to_le16(count); set_bit(WDM_IN_USE, &desc->flags); - desc->outbuf = buf; rv = usb_submit_urb(desc->command, GFP_KERNEL); if (rv < 0) { kfree(buf); - desc->outbuf = NULL; clear_bit(WDM_IN_USE, &desc->flags); dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv); } else { diff --git a/trunk/drivers/usb/core/driver.c b/trunk/drivers/usb/core/driver.c index 9a56635dc19c..f8e2d6d52e5c 100644 --- a/trunk/drivers/usb/core/driver.c +++ b/trunk/drivers/usb/core/driver.c @@ -1189,13 +1189,8 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) if (status == 0) { status = usb_suspend_device(udev, msg); - /* - * Ignore errors from non-root-hub devices during - * system sleep transitions. For the most part, - * these devices should go to low power anyway when - * the entire bus is suspended. - */ - if (udev->parent && !PMSG_IS_AUTO(msg)) + /* Again, ignore errors during system sleep transitions */ + if (!PMSG_IS_AUTO(msg)) status = 0; } diff --git a/trunk/drivers/usb/core/hcd-pci.c b/trunk/drivers/usb/core/hcd-pci.c index 57ed9e400c06..622b4a48e732 100644 --- a/trunk/drivers/usb/core/hcd-pci.c +++ b/trunk/drivers/usb/core/hcd-pci.c @@ -493,15 +493,6 @@ static int hcd_pci_suspend_noirq(struct device *dev) pci_save_state(pci_dev); - /* - * Some systems crash if an EHCI controller is in D3 during - * a sleep transition. We have to leave such controllers in D0. - */ - if (hcd->broken_pci_sleep) { - dev_dbg(dev, "Staying in PCI D0\n"); - return retval; - } - /* If the root hub is dead rather than suspended, disallow remote * wakeup. usb_hc_died() should ensure that both hosts are marked as * dying, so we only need to check the primary roothub. diff --git a/trunk/drivers/usb/core/hcd.c b/trunk/drivers/usb/core/hcd.c index 140d3e11f212..9d7fc9a39933 100644 --- a/trunk/drivers/usb/core/hcd.c +++ b/trunk/drivers/usb/core/hcd.c @@ -1978,18 +1978,6 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg) if (status == 0) { usb_set_device_state(rhdev, USB_STATE_SUSPENDED); hcd->state = HC_STATE_SUSPENDED; - - /* Did we race with a root-hub wakeup event? */ - if (rhdev->do_remote_wakeup) { - char buffer[6]; - - status = hcd->driver->hub_status_data(hcd, buffer); - if (status != 0) { - dev_dbg(&rhdev->dev, "suspend raced with wakeup event\n"); - hcd_bus_resume(rhdev, PMSG_AUTO_RESUME); - status = -EBUSY; - } - } } else { spin_lock_irq(&hcd_root_hub_lock); if (!HCD_DEAD(hcd)) { diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index ec6c97dadbe4..28664eb7f555 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -1667,6 +1667,7 @@ void usb_disconnect(struct usb_device **pdev) { struct usb_device *udev = *pdev; int i; + struct usb_hcd *hcd = bus_to_hcd(udev->bus); /* mark the device as inactive, so any further urb submissions for * this device (and any of its children) will fail immediately. @@ -1689,7 +1690,9 @@ void usb_disconnect(struct usb_device **pdev) * so that the hardware is now fully quiesced. */ dev_dbg (&udev->dev, "unregistering device\n"); + mutex_lock(hcd->bandwidth_mutex); usb_disable_device(udev, 0); + mutex_unlock(hcd->bandwidth_mutex); usb_hcd_synchronize_unlinks(udev); usb_remove_ep_devs(&udev->ep0); @@ -3160,22 +3163,6 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, if (retval) goto fail; - /* - * Some superspeed devices have finished the link training process - * and attached to a superspeed hub port, but the device descriptor - * got from those devices show they aren't superspeed devices. Warm - * reset the port attached by the devices can fix them. - */ - if ((udev->speed == USB_SPEED_SUPER) && - (le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) { - dev_err(&udev->dev, "got a wrong device descriptor, " - "warm reset device\n"); - hub_port_reset(hub, port1, udev, - HUB_BH_RESET_TIME, true); - retval = -EINVAL; - goto fail; - } - if (udev->descriptor.bMaxPacketSize0 == 0xff || udev->speed == USB_SPEED_SUPER) i = 512; diff --git a/trunk/drivers/usb/core/inode.c b/trunk/drivers/usb/core/inode.c index d2b9af59cba9..cefa0c8b5b6a 100644 --- a/trunk/drivers/usb/core/inode.c +++ b/trunk/drivers/usb/core/inode.c @@ -428,10 +428,18 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig) return retval; } +static int default_open (struct inode *inode, struct file *file) +{ + if (inode->i_private) + file->private_data = inode->i_private; + + return 0; +} + static const struct file_operations default_file_operations = { .read = default_read_file, .write = default_write_file, - .open = simple_open, + .open = default_open, .llseek = default_file_lseek, }; diff --git a/trunk/drivers/usb/core/message.c b/trunk/drivers/usb/core/message.c index ca717da3be95..b3bdfede45e6 100644 --- a/trunk/drivers/usb/core/message.c +++ b/trunk/drivers/usb/core/message.c @@ -308,8 +308,7 @@ static void sg_complete(struct urb *urb) retval = usb_unlink_urb(io->urbs [i]); if (retval != -EINPROGRESS && retval != -ENODEV && - retval != -EBUSY && - retval != -EIDRM) + retval != -EBUSY) dev_err(&io->dev->dev, "%s, unlink --> %d\n", __func__, retval); @@ -318,6 +317,7 @@ static void sg_complete(struct urb *urb) } spin_lock(&io->lock); } + urb->dev = NULL; /* on the last completion, signal usb_sg_wait() */ io->bytes += urb->actual_length; @@ -524,6 +524,7 @@ void usb_sg_wait(struct usb_sg_request *io) case -ENXIO: /* hc didn't queue this one */ case -EAGAIN: case -ENOMEM: + io->urbs[i]->dev = NULL; retval = 0; yield(); break; @@ -541,6 +542,7 @@ void usb_sg_wait(struct usb_sg_request *io) /* fail any uncompleted urbs */ default: + io->urbs[i]->dev = NULL; io->urbs[i]->status = retval; dev_dbg(&io->dev->dev, "%s, submit --> %d\n", __func__, retval); @@ -591,10 +593,7 @@ void usb_sg_cancel(struct usb_sg_request *io) if (!io->urbs [i]->dev) continue; retval = usb_unlink_urb(io->urbs [i]); - if (retval != -EINPROGRESS - && retval != -ENODEV - && retval != -EBUSY - && retval != -EIDRM) + if (retval != -EINPROGRESS && retval != -EBUSY) dev_warn(&io->dev->dev, "%s, unlink --> %d\n", __func__, retval); } @@ -1136,6 +1135,8 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, * Deallocates hcd/hardware state for the endpoints (nuking all or most * pending urbs) and usbcore state for the interfaces, so that usbcore * must usb_set_configuration() before any interfaces could be used. + * + * Must be called with hcd->bandwidth_mutex held. */ void usb_disable_device(struct usb_device *dev, int skip_ep0) { @@ -1188,9 +1189,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) usb_disable_endpoint(dev, i + USB_DIR_IN, false); } /* Remove endpoints from the host controller internal state */ - mutex_lock(hcd->bandwidth_mutex); usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); - mutex_unlock(hcd->bandwidth_mutex); /* Second pass: remove endpoint pointers */ } for (i = skip_ep0; i < 16; ++i) { @@ -1750,6 +1749,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) /* if it's already configured, clear out old state first. * getting rid of old interfaces means unbinding their drivers. */ + mutex_lock(hcd->bandwidth_mutex); if (dev->state != USB_STATE_ADDRESS) usb_disable_device(dev, 1); /* Skip ep0 */ @@ -1762,7 +1762,6 @@ int usb_set_configuration(struct usb_device *dev, int configuration) * host controller will not allow submissions to dropped endpoints. If * this call fails, the device state is unchanged. */ - mutex_lock(hcd->bandwidth_mutex); ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); if (ret < 0) { mutex_unlock(hcd->bandwidth_mutex); diff --git a/trunk/drivers/usb/core/urb.c b/trunk/drivers/usb/core/urb.c index cd9b3a2cd8a7..7239a73c1b8c 100644 --- a/trunk/drivers/usb/core/urb.c +++ b/trunk/drivers/usb/core/urb.c @@ -539,10 +539,6 @@ EXPORT_SYMBOL_GPL(usb_submit_urb); * never submitted, or it was unlinked before, or the hardware is already * finished with it), even if the completion handler has not yet run. * - * The URB must not be deallocated while this routine is running. In - * particular, when a driver calls this routine, it must insure that the - * completion handler cannot deallocate the URB. - * * Unlinking and Endpoint Queues: * * [The behaviors and guarantees described below do not apply to virtual @@ -607,10 +603,6 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb); * with error -EPERM. Thus even if the URB's completion handler always * tries to resubmit, it will not succeed and the URB will become idle. * - * The URB must not be deallocated while this routine is running. In - * particular, when a driver calls this routine, it must insure that the - * completion handler cannot deallocate the URB. - * * This routine may not be used in an interrupt context (such as a bottom * half or a completion handler), or when holding a spinlock, or in other * situations where the caller can't schedule(). @@ -648,10 +640,6 @@ EXPORT_SYMBOL_GPL(usb_kill_urb); * with error -EPERM. Thus even if the URB's completion handler always * tries to resubmit, it will not succeed and the URB will become idle. * - * The URB must not be deallocated while this routine is running. In - * particular, when a driver calls this routine, it must insure that the - * completion handler cannot deallocate the URB. - * * This routine may not be used in an interrupt context (such as a bottom * half or a completion handler), or when holding a spinlock, or in other * situations where the caller can't schedule(). diff --git a/trunk/drivers/usb/dwc3/core.c b/trunk/drivers/usb/dwc3/core.c index 99b58d84553a..7bd815a507e8 100644 --- a/trunk/drivers/usb/dwc3/core.c +++ b/trunk/drivers/usb/dwc3/core.c @@ -206,11 +206,11 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc) for (i = 0; i < dwc->num_event_buffers; i++) { evt = dwc->ev_buffs[i]; - if (evt) + if (evt) { dwc3_free_one_event_buffer(dwc, evt); + dwc->ev_buffs[i] = NULL; + } } - - kfree(dwc->ev_buffs); } /** diff --git a/trunk/drivers/usb/dwc3/ep0.c b/trunk/drivers/usb/dwc3/ep0.c index 3584a169886f..25910e251c04 100644 --- a/trunk/drivers/usb/dwc3/ep0.c +++ b/trunk/drivers/usb/dwc3/ep0.c @@ -353,9 +353,6 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, dwc->test_mode_nr = wIndex >> 8; dwc->test_mode = true; - break; - default: - return -EINVAL; } break; @@ -562,20 +559,15 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, length = trb->size & DWC3_TRB_SIZE_MASK; if (dwc->ep0_bounced) { - unsigned transfer_size = ur->length; - unsigned maxp = ep0->endpoint.maxpacket; - - transfer_size += (maxp - (transfer_size % maxp)); transferred = min_t(u32, ur->length, - transfer_size - length); + ep0->endpoint.maxpacket - length); memcpy(ur->buf, dwc->ep0_bounce, transferred); dwc->ep0_bounced = false; } else { transferred = ur->length - length; + ur->actual += transferred; } - ur->actual += transferred; - if ((epnum & 1) && ur->actual < ur->length) { /* for some reason we did not get everything out */ diff --git a/trunk/drivers/usb/gadget/at91_udc.c b/trunk/drivers/usb/gadget/at91_udc.c index 9d7bcd910074..0c935d7c65bd 100644 --- a/trunk/drivers/usb/gadget/at91_udc.c +++ b/trunk/drivers/usb/gadget/at91_udc.c @@ -1863,8 +1863,8 @@ static int __devinit at91udc_probe(struct platform_device *pdev) mod_timer(&udc->vbus_timer, jiffies + VBUS_POLL_TIMEOUT); } else { - if (request_irq(gpio_to_irq(udc->board.vbus_pin), - at91_vbus_irq, 0, driver_name, udc)) { + if (request_irq(udc->board.vbus_pin, at91_vbus_irq, + 0, driver_name, udc)) { DBG("request vbus irq %d failed\n", udc->board.vbus_pin); retval = -EBUSY; @@ -1886,7 +1886,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev) return 0; fail4: if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled) - free_irq(gpio_to_irq(udc->board.vbus_pin), udc); + free_irq(udc->board.vbus_pin, udc); fail3: if (gpio_is_valid(udc->board.vbus_pin)) gpio_free(udc->board.vbus_pin); @@ -1924,7 +1924,7 @@ static int __exit at91udc_remove(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 0); remove_debug_file(udc); if (gpio_is_valid(udc->board.vbus_pin)) { - free_irq(gpio_to_irq(udc->board.vbus_pin), udc); + free_irq(udc->board.vbus_pin, udc); gpio_free(udc->board.vbus_pin); } free_irq(udc->udp_irq, udc); diff --git a/trunk/drivers/usb/gadget/dummy_hcd.c b/trunk/drivers/usb/gadget/dummy_hcd.c index 170cbe89d9f8..a6dfd2164166 100644 --- a/trunk/drivers/usb/gadget/dummy_hcd.c +++ b/trunk/drivers/usb/gadget/dummy_hcd.c @@ -927,6 +927,7 @@ static int dummy_udc_stop(struct usb_gadget *g, dum->driver = NULL; + dummy_pullup(&dum->gadget, 0); return 0; } diff --git a/trunk/drivers/usb/gadget/f_fs.c b/trunk/drivers/usb/gadget/f_fs.c index f52cb1ae45d9..1cbba70836bc 100644 --- a/trunk/drivers/usb/gadget/f_fs.c +++ b/trunk/drivers/usb/gadget/f_fs.c @@ -712,7 +712,7 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value) if (code == FUNCTIONFS_INTERFACE_REVMAP) { struct ffs_function *func = ffs->func; ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV; - } else if (gadget && gadget->ops->ioctl) { + } else if (gadget->ops->ioctl) { ret = gadget->ops->ioctl(gadget, code, value); } else { ret = -ENOTTY; @@ -1382,7 +1382,6 @@ static void functionfs_unbind(struct ffs_data *ffs) ffs->ep0req = NULL; ffs->gadget = NULL; ffs_data_put(ffs); - clear_bit(FFS_FL_BOUND, &ffs->flags); } } diff --git a/trunk/drivers/usb/gadget/f_mass_storage.c b/trunk/drivers/usb/gadget/f_mass_storage.c index cb8c162cae5a..a371e966425f 100644 --- a/trunk/drivers/usb/gadget/f_mass_storage.c +++ b/trunk/drivers/usb/gadget/f_mass_storage.c @@ -2189,7 +2189,7 @@ static int do_scsi_command(struct fsg_common *common) common->data_size_from_cmnd = 0; sprintf(unknown, "Unknown x%02x", common->cmnd[0]); reply = check_command(common, common->cmnd_size, - DATA_DIR_UNKNOWN, ~0, 0, unknown); + DATA_DIR_UNKNOWN, 0xff, 0, unknown); if (reply == 0) { common->curlun->sense_data = SS_INVALID_COMMAND; reply = -EINVAL; diff --git a/trunk/drivers/usb/gadget/f_phonet.c b/trunk/drivers/usb/gadget/f_phonet.c index 965a6293206a..85a5cebe96b3 100644 --- a/trunk/drivers/usb/gadget/f_phonet.c +++ b/trunk/drivers/usb/gadget/f_phonet.c @@ -345,7 +345,7 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req) } skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, - skb->len <= 1, req->actual, PAGE_SIZE); + skb->len <= 1, req->actual, req->actual); page = NULL; if (req->actual < req->length) { /* Last fragment */ diff --git a/trunk/drivers/usb/gadget/f_rndis.c b/trunk/drivers/usb/gadget/f_rndis.c index 52343654f5df..7b1cf18df5e3 100644 --- a/trunk/drivers/usb/gadget/f_rndis.c +++ b/trunk/drivers/usb/gadget/f_rndis.c @@ -500,7 +500,6 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) if (buf) { memcpy(req->buf, buf, n); req->complete = rndis_response_complete; - req->context = rndis; rndis_free_response(rndis->config, buf); value = n; } diff --git a/trunk/drivers/usb/gadget/file_storage.c b/trunk/drivers/usb/gadget/file_storage.c index a896d73f7a93..4fac56927741 100644 --- a/trunk/drivers/usb/gadget/file_storage.c +++ b/trunk/drivers/usb/gadget/file_storage.c @@ -2579,7 +2579,7 @@ static int do_scsi_command(struct fsg_dev *fsg) fsg->data_size_from_cmnd = 0; sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]); if ((reply = check_command(fsg, fsg->cmnd_size, - DATA_DIR_UNKNOWN, ~0, 0, unknown)) == 0) { + DATA_DIR_UNKNOWN, 0xff, 0, unknown)) == 0) { fsg->curlun->sense_data = SS_INVALID_COMMAND; reply = -EINVAL; } diff --git a/trunk/drivers/usb/gadget/fsl_udc_core.c b/trunk/drivers/usb/gadget/fsl_udc_core.c index 55abfb6bd612..5f94e79cd6b9 100644 --- a/trunk/drivers/usb/gadget/fsl_udc_core.c +++ b/trunk/drivers/usb/gadget/fsl_udc_core.c @@ -730,7 +730,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) : (1 << (ep_index(ep))); /* check if the pipe is empty */ - if (!(list_empty(&ep->queue)) && !(ep_index(ep) == 0)) { + if (!(list_empty(&ep->queue))) { /* Add td to the end */ struct fsl_req *lastreq; lastreq = list_entry(ep->queue.prev, struct fsl_req, queue); @@ -918,6 +918,10 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) return -ENOMEM; } + /* Update ep0 state */ + if ((ep_index(ep) == 0)) + udc->ep0_state = DATA_STATE_XMIT; + /* irq handler advances the queue */ if (req != NULL) list_add_tail(&req->queue, &ep->queue); @@ -1275,8 +1279,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction) udc->ep0_dir = USB_DIR_OUT; ep = &udc->eps[0]; - if (udc->ep0_state != DATA_STATE_XMIT) - udc->ep0_state = WAIT_FOR_OUT_STATUS; + udc->ep0_state = WAIT_FOR_OUT_STATUS; req->ep = ep; req->req.length = 0; @@ -1381,9 +1384,6 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, list_add_tail(&req->queue, &ep->queue); udc->ep0_state = DATA_STATE_XMIT; - if (ep0_prime_status(udc, EP_DIR_OUT)) - ep0stall(udc); - return; stall: ep0stall(udc); @@ -1492,14 +1492,6 @@ static void setup_received_irq(struct fsl_udc *udc, spin_lock(&udc->lock); udc->ep0_state = (setup->bRequestType & USB_DIR_IN) ? DATA_STATE_XMIT : DATA_STATE_RECV; - /* - * If the data stage is IN, send status prime immediately. - * See 2.0 Spec chapter 8.5.3.3 for detail. - */ - if (udc->ep0_state == DATA_STATE_XMIT) - if (ep0_prime_status(udc, EP_DIR_OUT)) - ep0stall(udc); - } else { /* No data phase, IN status from gadget */ udc->ep0_dir = USB_DIR_IN; @@ -1528,8 +1520,9 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0, switch (udc->ep0_state) { case DATA_STATE_XMIT: - /* already primed at setup_received_irq */ - udc->ep0_state = WAIT_FOR_OUT_STATUS; + /* receive status phase */ + if (ep0_prime_status(udc, EP_DIR_OUT)) + ep0stall(udc); break; case DATA_STATE_RECV: /* send status phase */ diff --git a/trunk/drivers/usb/gadget/g_ffs.c b/trunk/drivers/usb/gadget/g_ffs.c index a85eaf40b948..331cd6729d3c 100644 --- a/trunk/drivers/usb/gadget/g_ffs.c +++ b/trunk/drivers/usb/gadget/g_ffs.c @@ -161,7 +161,7 @@ static struct usb_composite_driver gfs_driver = { static struct ffs_data *gfs_ffs_data; static unsigned long gfs_registered; -static int __init gfs_init(void) +static int gfs_init(void) { ENTER(); @@ -169,7 +169,7 @@ static int __init gfs_init(void) } module_init(gfs_init); -static void __exit gfs_exit(void) +static void gfs_exit(void) { ENTER(); diff --git a/trunk/drivers/usb/gadget/inode.c b/trunk/drivers/usb/gadget/inode.c index e58b16442971..8793f32bab11 100644 --- a/trunk/drivers/usb/gadget/inode.c +++ b/trunk/drivers/usb/gadget/inode.c @@ -1574,6 +1574,7 @@ static void destroy_ep_files (struct dev_data *dev) DBG (dev, "%s %d\n", __func__, dev->state); /* dev->state must prevent interference */ +restart: spin_lock_irq (&dev->lock); while (!list_empty(&dev->epfiles)) { struct ep_data *ep; diff --git a/trunk/drivers/usb/gadget/s3c-hsotg.c b/trunk/drivers/usb/gadget/s3c-hsotg.c index 105b206cd844..69295ba9d99a 100644 --- a/trunk/drivers/usb/gadget/s3c-hsotg.c +++ b/trunk/drivers/usb/gadget/s3c-hsotg.c @@ -340,7 +340,7 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) /* currently we allocate TX FIFOs for all possible endpoints, * and assume that they are all the same size. */ - for (ep = 1; ep <= 15; ep++) { + for (ep = 0; ep <= 15; ep++) { val = addr; val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT; addr += size; @@ -741,7 +741,7 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg, /* write size / packets */ writel(epsize, hsotg->regs + epsize_reg); - if (using_dma(hsotg) && !continuing) { + if (using_dma(hsotg)) { unsigned int dma_reg; /* write DMA address to control register, buffer already @@ -1696,12 +1696,10 @@ static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg, reg |= mpsval; writel(reg, regs + S3C_DIEPCTL(ep)); - if (ep) { - reg = readl(regs + S3C_DOEPCTL(ep)); - reg &= ~S3C_DxEPCTL_MPS_MASK; - reg |= mpsval; - writel(reg, regs + S3C_DOEPCTL(ep)); - } + reg = readl(regs + S3C_DOEPCTL(ep)); + reg &= ~S3C_DxEPCTL_MPS_MASK; + reg |= mpsval; + writel(reg, regs + S3C_DOEPCTL(ep)); return; @@ -1921,8 +1919,7 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, ints & S3C_DIEPMSK_TxFIFOEmpty) { dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n", __func__, idx); - if (!using_dma(hsotg)) - s3c_hsotg_trytx(hsotg, hs_ep); + s3c_hsotg_trytx(hsotg, hs_ep); } } } diff --git a/trunk/drivers/usb/gadget/udc-core.c b/trunk/drivers/usb/gadget/udc-core.c index e5e44f8cde9a..56da49f31d6c 100644 --- a/trunk/drivers/usb/gadget/udc-core.c +++ b/trunk/drivers/usb/gadget/udc-core.c @@ -263,9 +263,9 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) if (udc_is_newstyle(udc)) { udc->driver->disconnect(udc->gadget); - usb_gadget_disconnect(udc->gadget); udc->driver->unbind(udc->gadget); usb_gadget_udc_stop(udc->gadget, udc->driver); + usb_gadget_disconnect(udc->gadget); } else { usb_gadget_stop(udc->gadget, udc->driver); } @@ -411,13 +411,9 @@ static ssize_t usb_udc_softconn_store(struct device *dev, struct usb_udc *udc = container_of(dev, struct usb_udc, dev); if (sysfs_streq(buf, "connect")) { - if (udc_is_newstyle(udc)) - usb_gadget_udc_start(udc->gadget, udc->driver); usb_gadget_connect(udc->gadget); } else if (sysfs_streq(buf, "disconnect")) { usb_gadget_disconnect(udc->gadget); - if (udc_is_newstyle(udc)) - usb_gadget_udc_stop(udc->gadget, udc->driver); } else { dev_err(dev, "unsupported command '%s'\n", buf); return -EINVAL; diff --git a/trunk/drivers/usb/gadget/uvc.h b/trunk/drivers/usb/gadget/uvc.h index ca4e03a1c73a..bc78c606c12b 100644 --- a/trunk/drivers/usb/gadget/uvc.h +++ b/trunk/drivers/usb/gadget/uvc.h @@ -28,7 +28,7 @@ struct uvc_request_data { - __s32 length; + unsigned int length; __u8 data[60]; }; diff --git a/trunk/drivers/usb/gadget/uvc_queue.c b/trunk/drivers/usb/gadget/uvc_queue.c index 0cdf89d32a15..d776adb2da67 100644 --- a/trunk/drivers/usb/gadget/uvc_queue.c +++ b/trunk/drivers/usb/gadget/uvc_queue.c @@ -543,11 +543,11 @@ static int uvc_queue_enable(struct uvc_video_queue *queue, int enable) return ret; } -/* called with queue->irqlock held.. */ static struct uvc_buffer * uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf) { struct uvc_buffer *nextbuf; + unsigned long flags; if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) && buf->buf.length != buf->buf.bytesused) { @@ -556,12 +556,14 @@ uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf) return buf; } + spin_lock_irqsave(&queue->irqlock, flags); list_del(&buf->queue); if (!list_empty(&queue->irqqueue)) nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, queue); else nextbuf = NULL; + spin_unlock_irqrestore(&queue->irqlock, flags); buf->buf.sequence = queue->sequence++; do_gettimeofday(&buf->buf.timestamp); diff --git a/trunk/drivers/usb/gadget/uvc_v4l2.c b/trunk/drivers/usb/gadget/uvc_v4l2.c index 54d7ca559cb2..f6e083b50191 100644 --- a/trunk/drivers/usb/gadget/uvc_v4l2.c +++ b/trunk/drivers/usb/gadget/uvc_v4l2.c @@ -39,7 +39,7 @@ uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data) if (data->length < 0) return usb_ep_set_halt(cdev->gadget->ep0); - req->length = min_t(unsigned int, uvc->event_length, data->length); + req->length = min(uvc->event_length, data->length); req->zero = data->length < uvc->event_length; req->dma = DMA_ADDR_INVALID; diff --git a/trunk/drivers/usb/host/ehci-atmel.c b/trunk/drivers/usb/host/ehci-atmel.c index cf14c95a6700..19f318ababa2 100644 --- a/trunk/drivers/usb/host/ehci-atmel.c +++ b/trunk/drivers/usb/host/ehci-atmel.c @@ -13,7 +13,6 @@ #include #include -#include #include /* interface and function clocks */ diff --git a/trunk/drivers/usb/host/ehci-dbg.c b/trunk/drivers/usb/host/ehci-dbg.c index 680e1a31fb87..fd9109d7eb0e 100644 --- a/trunk/drivers/usb/host/ehci-dbg.c +++ b/trunk/drivers/usb/host/ehci-dbg.c @@ -352,6 +352,7 @@ static int debug_async_open(struct inode *, struct file *); static int debug_periodic_open(struct inode *, struct file *); static int debug_registers_open(struct inode *, struct file *); static int debug_async_open(struct inode *, struct file *); +static int debug_lpm_open(struct inode *, struct file *); static ssize_t debug_lpm_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos); static ssize_t debug_lpm_write(struct file *file, const char __user *buffer, @@ -384,7 +385,7 @@ static const struct file_operations debug_registers_fops = { }; static const struct file_operations debug_lpm_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = debug_lpm_open, .read = debug_lpm_read, .write = debug_lpm_write, .release = debug_lpm_close, @@ -969,6 +970,12 @@ static int debug_registers_open(struct inode *inode, struct file *file) return file->private_data ? 0 : -ENOMEM; } +static int debug_lpm_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static int debug_lpm_close(struct inode *inode, struct file *file) { return 0; diff --git a/trunk/drivers/usb/host/ehci-fsl.c b/trunk/drivers/usb/host/ehci-fsl.c index d0a84bd3f3eb..3e7345172e03 100644 --- a/trunk/drivers/usb/host/ehci-fsl.c +++ b/trunk/drivers/usb/host/ehci-fsl.c @@ -218,9 +218,6 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, u32 portsc; struct usb_hcd *hcd = ehci_to_hcd(ehci); void __iomem *non_ehci = hcd->regs; - struct fsl_usb2_platform_data *pdata; - - pdata = hcd->self.controller->platform_data; portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]); portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); @@ -237,9 +234,7 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, /* fall through */ case FSL_USB2_PHY_UTMI: /* enable UTMI PHY */ - if (pdata->have_sysif_regs) - setbits32(non_ehci + FSL_SOC_USB_CTRL, - CTRL_UTMI_PHY_EN); + setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN); portsc |= PORT_PTS_UTMI; break; case FSL_USB2_PHY_NONE: diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index 4a3bc5b7a06f..057cdda7a489 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -347,8 +347,6 @@ static int ehci_reset (struct ehci_hcd *ehci) if (ehci->debug) dbgp_external_startup(); - ehci->port_c_suspend = ehci->suspended_ports = - ehci->resuming_ports = 0; return retval; } @@ -858,13 +856,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) goto dead; } - /* - * We don't use STS_FLR, but some controllers don't like it to - * remain on, so mask it out along with the other status bits. - */ - masked_status = status & (INTR_MASK | STS_FLR); - /* Shared IRQ? */ + masked_status = status & INTR_MASK; if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) { spin_unlock(&ehci->lock); return IRQ_NONE; @@ -915,7 +908,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) pcd_status = status; /* resume root hub? */ - if (ehci->rh_state == EHCI_RH_SUSPENDED) + if (!(cmd & CMD_RUN)) usb_hcd_resume_root_hub(hcd); /* get per-port change detect bits */ @@ -946,7 +939,6 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) * like usb_port_resume() does. */ ehci->reset_done[i] = jiffies + msecs_to_jiffies(25); - set_bit(i, &ehci->resuming_ports); ehci_dbg (ehci, "port %d remote wakeup\n", i + 1); mod_timer(&hcd->rh_timer, ehci->reset_done[i]); } diff --git a/trunk/drivers/usb/host/ehci-hub.c b/trunk/drivers/usb/host/ehci-hub.c index 38fe07623152..256fbd42e48c 100644 --- a/trunk/drivers/usb/host/ehci-hub.c +++ b/trunk/drivers/usb/host/ehci-hub.c @@ -223,10 +223,15 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) * remote wakeup, we must fail the suspend. */ if (hcd->self.root_hub->do_remote_wakeup) { - if (ehci->resuming_ports) { - spin_unlock_irq(&ehci->lock); - ehci_dbg(ehci, "suspend failed because a port is resuming\n"); - return -EBUSY; + port = HCS_N_PORTS(ehci->hcs_params); + while (port--) { + if (ehci->reset_done[port] != 0) { + spin_unlock_irq(&ehci->lock); + ehci_dbg(ehci, "suspend failed because " + "port %d is resuming\n", + port + 1); + return -EBUSY; + } } } @@ -549,12 +554,16 @@ static int ehci_hub_status_data (struct usb_hcd *hcd, char *buf) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); - u32 temp, status; + u32 temp, status = 0; u32 mask; int ports, i, retval = 1; unsigned long flags; u32 ppcd = 0; + /* if !USB_SUSPEND, root hub timers won't get shut down ... */ + if (ehci->rh_state != EHCI_RH_RUNNING) + return 0; + /* init status to no-changes */ buf [0] = 0; ports = HCS_N_PORTS (ehci->hcs_params); @@ -563,11 +572,6 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) retval++; } - /* Inform the core about resumes-in-progress by returning - * a non-zero value even if there are no status changes. - */ - status = ehci->resuming_ports; - /* Some boards (mostly VIA?) report bogus overcurrent indications, * causing massive log spam unless we completely ignore them. It * may be relevant that VIA VT8235 controllers, where PORT_POWER is @@ -842,7 +846,6 @@ static int ehci_hub_control ( ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESUME), status_reg); - clear_bit(wIndex, &ehci->resuming_ports); retval = handshake(ehci, status_reg, PORT_RESUME, 0, 2000 /* 2msec */); if (retval != 0) { @@ -861,7 +864,6 @@ static int ehci_hub_control ( ehci->reset_done[wIndex])) { status |= USB_PORT_STAT_C_RESET << 16; ehci->reset_done [wIndex] = 0; - clear_bit(wIndex, &ehci->resuming_ports); /* force reset to complete */ ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET), @@ -882,10 +884,8 @@ static int ehci_hub_control ( ehci_readl(ehci, status_reg)); } - if (!(temp & (PORT_RESUME|PORT_RESET))) { + if (!(temp & (PORT_RESUME|PORT_RESET))) ehci->reset_done[wIndex] = 0; - clear_bit(wIndex, &ehci->resuming_ports); - } /* transfer dedicated ports to the companion hc */ if ((temp & PORT_CONNECT) && @@ -920,7 +920,6 @@ static int ehci_hub_control ( status |= USB_PORT_STAT_SUSPEND; } else if (test_bit(wIndex, &ehci->suspended_ports)) { clear_bit(wIndex, &ehci->suspended_ports); - clear_bit(wIndex, &ehci->resuming_ports); ehci->reset_done[wIndex] = 0; if (temp & PORT_PE) set_bit(wIndex, &ehci->port_c_suspend); diff --git a/trunk/drivers/usb/host/ehci-omap.c b/trunk/drivers/usb/host/ehci-omap.c index 5c78f9e71466..bba9850f32f0 100644 --- a/trunk/drivers/usb/host/ehci-omap.c +++ b/trunk/drivers/usb/host/ehci-omap.c @@ -42,7 +42,6 @@ #include #include #include -#include /* EHCI Register Set */ #define EHCI_INSNREG04 (0xA0) @@ -192,19 +191,6 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) } } - if (pdata->phy_reset) { - if (gpio_is_valid(pdata->reset_gpio_port[0])) - gpio_request_one(pdata->reset_gpio_port[0], - GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); - - if (gpio_is_valid(pdata->reset_gpio_port[1])) - gpio_request_one(pdata->reset_gpio_port[1], - GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); - - /* Hold the PHY in RESET for enough time till DIR is high */ - udelay(10); - } - pm_runtime_enable(dev); pm_runtime_get_sync(dev); @@ -251,19 +237,6 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) /* root ports should always stay powered */ ehci_port_power(omap_ehci, 1); - if (pdata->phy_reset) { - /* Hold the PHY in RESET for enough time till - * PHY is settled and ready - */ - udelay(10); - - if (gpio_is_valid(pdata->reset_gpio_port[0])) - gpio_set_value(pdata->reset_gpio_port[0], 1); - - if (gpio_is_valid(pdata->reset_gpio_port[1])) - gpio_set_value(pdata->reset_gpio_port[1], 1); - } - return 0; err_add_hcd: @@ -286,9 +259,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) */ static int ehci_hcd_omap_remove(struct platform_device *pdev) { - struct device *dev = &pdev->dev; - struct usb_hcd *hcd = dev_get_drvdata(dev); - struct ehci_hcd_omap_platform_data *pdata = dev->platform_data; + struct device *dev = &pdev->dev; + struct usb_hcd *hcd = dev_get_drvdata(dev); usb_remove_hcd(hcd); disable_put_regulator(dev->platform_data); @@ -297,13 +269,6 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) pm_runtime_put_sync(dev); pm_runtime_disable(dev); - if (pdata->phy_reset) { - if (gpio_is_valid(pdata->reset_gpio_port[0])) - gpio_free(pdata->reset_gpio_port[0]); - - if (gpio_is_valid(pdata->reset_gpio_port[1])) - gpio_free(pdata->reset_gpio_port[1]); - } return 0; } diff --git a/trunk/drivers/usb/host/ehci-pci.c b/trunk/drivers/usb/host/ehci-pci.c index fe8dc069164e..01bb7241d6ef 100644 --- a/trunk/drivers/usb/host/ehci-pci.c +++ b/trunk/drivers/usb/host/ehci-pci.c @@ -144,14 +144,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) hcd->has_tt = 1; tdi_reset(ehci); } - if (pdev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK) { - /* EHCI #1 or #2 on 6 Series/C200 Series chipset */ - if (pdev->device == 0x1c26 || pdev->device == 0x1c2d) { - ehci_info(ehci, "broken D3 during system sleep on ASUS\n"); - hcd->broken_pci_sleep = 1; - device_set_wakeup_capable(&pdev->dev, false); - } - } break; case PCI_VENDOR_ID_TDI: if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { diff --git a/trunk/drivers/usb/host/ehci-tegra.c b/trunk/drivers/usb/host/ehci-tegra.c index f214a80cdee2..3de48a2d7955 100644 --- a/trunk/drivers/usb/host/ehci-tegra.c +++ b/trunk/drivers/usb/host/ehci-tegra.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -38,7 +37,9 @@ struct tegra_ehci_hcd { struct clk *emc_clk; struct usb_phy *transceiver; int host_resumed; + int bus_suspended; int port_resuming; + int power_down_on_bus_suspend; enum tegra_usb_phy_port_speed port_speed; }; @@ -223,7 +224,6 @@ static int tegra_ehci_hub_control( temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); /* start resume signalling */ ehci_writel(ehci, temp | PORT_RESUME, status_reg); - set_bit(wIndex-1, &ehci->resuming_ports); spin_unlock_irqrestore(&ehci->lock, flags); msleep(20); @@ -236,7 +236,6 @@ static int tegra_ehci_hub_control( pr_err("%s: timeout waiting for SUSPEND\n", __func__); ehci->reset_done[wIndex-1] = 0; - clear_bit(wIndex-1, &ehci->resuming_ports); tegra->port_resuming = 1; goto done; @@ -272,6 +271,120 @@ static void tegra_ehci_restart(struct usb_hcd *hcd) up_write(&ehci_cf_port_reset_rwsem); } +static int tegra_usb_suspend(struct usb_hcd *hcd) +{ + struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + struct ehci_regs __iomem *hw = tegra->ehci->regs; + unsigned long flags; + + spin_lock_irqsave(&tegra->ehci->lock, flags); + + tegra->port_speed = (readl(&hw->port_status[0]) >> 26) & 0x3; + ehci_halt(tegra->ehci); + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + + spin_unlock_irqrestore(&tegra->ehci->lock, flags); + + tegra_ehci_power_down(hcd); + return 0; +} + +static int tegra_usb_resume(struct usb_hcd *hcd) +{ + struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + struct ehci_regs __iomem *hw = ehci->regs; + unsigned long val; + + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + tegra_ehci_power_up(hcd); + + if (tegra->port_speed > TEGRA_USB_PHY_PORT_SPEED_HIGH) { + /* Wait for the phy to detect new devices + * before we restart the controller */ + msleep(10); + goto restart; + } + + /* Force the phy to keep data lines in suspend state */ + tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed); + + /* Enable host mode */ + tdi_reset(ehci); + + /* Enable Port Power */ + val = readl(&hw->port_status[0]); + val |= PORT_POWER; + writel(val, &hw->port_status[0]); + udelay(10); + + /* Check if the phy resume from LP0. When the phy resume from LP0 + * USB register will be reset. */ + if (!readl(&hw->async_next)) { + /* Program the field PTC based on the saved speed mode */ + val = readl(&hw->port_status[0]); + val &= ~PORT_TEST(~0); + if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_HIGH) + val |= PORT_TEST_FORCE; + else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_FULL) + val |= PORT_TEST(6); + else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) + val |= PORT_TEST(7); + writel(val, &hw->port_status[0]); + udelay(10); + + /* Disable test mode by setting PTC field to NORMAL_OP */ + val = readl(&hw->port_status[0]); + val &= ~PORT_TEST(~0); + writel(val, &hw->port_status[0]); + udelay(10); + } + + /* Poll until CCS is enabled */ + if (handshake(ehci, &hw->port_status[0], PORT_CONNECT, + PORT_CONNECT, 2000)) { + pr_err("%s: timeout waiting for PORT_CONNECT\n", __func__); + goto restart; + } + + /* Poll until PE is enabled */ + if (handshake(ehci, &hw->port_status[0], PORT_PE, + PORT_PE, 2000)) { + pr_err("%s: timeout waiting for USB_PORTSC1_PE\n", __func__); + goto restart; + } + + /* Clear the PCI status, to avoid an interrupt taken upon resume */ + val = readl(&hw->status); + val |= STS_PCD; + writel(val, &hw->status); + + /* Put controller in suspend mode by writing 1 to SUSP bit of PORTSC */ + val = readl(&hw->port_status[0]); + if ((val & PORT_POWER) && (val & PORT_PE)) { + val |= PORT_SUSPEND; + writel(val, &hw->port_status[0]); + + /* Wait until port suspend completes */ + if (handshake(ehci, &hw->port_status[0], PORT_SUSPEND, + PORT_SUSPEND, 1000)) { + pr_err("%s: timeout waiting for PORT_SUSPEND\n", + __func__); + goto restart; + } + } + + tegra_ehci_phy_restore_end(tegra->phy); + return 0; + +restart: + if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH) + tegra_ehci_phy_restore_end(tegra->phy); + + tegra_ehci_restart(hcd); + return 0; +} + static void tegra_ehci_shutdown(struct usb_hcd *hcd) { struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); @@ -319,6 +432,36 @@ static int tegra_ehci_setup(struct usb_hcd *hcd) return retval; } +#ifdef CONFIG_PM +static int tegra_ehci_bus_suspend(struct usb_hcd *hcd) +{ + struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + int error_status = 0; + + error_status = ehci_bus_suspend(hcd); + if (!error_status && tegra->power_down_on_bus_suspend) { + tegra_usb_suspend(hcd); + tegra->bus_suspended = 1; + } + + return error_status; +} + +static int tegra_ehci_bus_resume(struct usb_hcd *hcd) +{ + struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + + if (tegra->bus_suspended && tegra->power_down_on_bus_suspend) { + tegra_usb_resume(hcd); + tegra->bus_suspended = 0; + } + + tegra_usb_phy_preresume(tegra->phy); + tegra->port_resuming = 1; + return ehci_bus_resume(hcd); +} +#endif + struct temp_buffer { void *kmalloc_ptr; void *old_xfer_buffer; @@ -429,8 +572,8 @@ static const struct hc_driver tegra_ehci_hc_driver = { .hub_control = tegra_ehci_hub_control, .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, #ifdef CONFIG_PM - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, + .bus_suspend = tegra_ehci_bus_suspend, + .bus_resume = tegra_ehci_bus_resume, #endif .relinquish_port = ehci_relinquish_port, .port_handed_over = ehci_port_handed_over, @@ -458,187 +601,11 @@ static int setup_vbus_gpio(struct platform_device *pdev) dev_err(&pdev->dev, "can't enable vbus\n"); return err; } + gpio_set_value(gpio, 1); return err; } -#ifdef CONFIG_PM - -static int controller_suspend(struct device *dev) -{ - struct tegra_ehci_hcd *tegra = - platform_get_drvdata(to_platform_device(dev)); - struct ehci_hcd *ehci = tegra->ehci; - struct usb_hcd *hcd = ehci_to_hcd(ehci); - struct ehci_regs __iomem *hw = ehci->regs; - unsigned long flags; - - if (time_before(jiffies, ehci->next_statechange)) - msleep(10); - - spin_lock_irqsave(&ehci->lock, flags); - - tegra->port_speed = (readl(&hw->port_status[0]) >> 26) & 0x3; - ehci_halt(ehci); - clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - - spin_unlock_irqrestore(&ehci->lock, flags); - - tegra_ehci_power_down(hcd); - return 0; -} - -static int controller_resume(struct device *dev) -{ - struct tegra_ehci_hcd *tegra = - platform_get_drvdata(to_platform_device(dev)); - struct ehci_hcd *ehci = tegra->ehci; - struct usb_hcd *hcd = ehci_to_hcd(ehci); - struct ehci_regs __iomem *hw = ehci->regs; - unsigned long val; - - set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - tegra_ehci_power_up(hcd); - - if (tegra->port_speed > TEGRA_USB_PHY_PORT_SPEED_HIGH) { - /* Wait for the phy to detect new devices - * before we restart the controller */ - msleep(10); - goto restart; - } - - /* Force the phy to keep data lines in suspend state */ - tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed); - - /* Enable host mode */ - tdi_reset(ehci); - - /* Enable Port Power */ - val = readl(&hw->port_status[0]); - val |= PORT_POWER; - writel(val, &hw->port_status[0]); - udelay(10); - - /* Check if the phy resume from LP0. When the phy resume from LP0 - * USB register will be reset. */ - if (!readl(&hw->async_next)) { - /* Program the field PTC based on the saved speed mode */ - val = readl(&hw->port_status[0]); - val &= ~PORT_TEST(~0); - if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_HIGH) - val |= PORT_TEST_FORCE; - else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_FULL) - val |= PORT_TEST(6); - else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) - val |= PORT_TEST(7); - writel(val, &hw->port_status[0]); - udelay(10); - - /* Disable test mode by setting PTC field to NORMAL_OP */ - val = readl(&hw->port_status[0]); - val &= ~PORT_TEST(~0); - writel(val, &hw->port_status[0]); - udelay(10); - } - - /* Poll until CCS is enabled */ - if (handshake(ehci, &hw->port_status[0], PORT_CONNECT, - PORT_CONNECT, 2000)) { - pr_err("%s: timeout waiting for PORT_CONNECT\n", __func__); - goto restart; - } - - /* Poll until PE is enabled */ - if (handshake(ehci, &hw->port_status[0], PORT_PE, - PORT_PE, 2000)) { - pr_err("%s: timeout waiting for USB_PORTSC1_PE\n", __func__); - goto restart; - } - - /* Clear the PCI status, to avoid an interrupt taken upon resume */ - val = readl(&hw->status); - val |= STS_PCD; - writel(val, &hw->status); - - /* Put controller in suspend mode by writing 1 to SUSP bit of PORTSC */ - val = readl(&hw->port_status[0]); - if ((val & PORT_POWER) && (val & PORT_PE)) { - val |= PORT_SUSPEND; - writel(val, &hw->port_status[0]); - - /* Wait until port suspend completes */ - if (handshake(ehci, &hw->port_status[0], PORT_SUSPEND, - PORT_SUSPEND, 1000)) { - pr_err("%s: timeout waiting for PORT_SUSPEND\n", - __func__); - goto restart; - } - } - - tegra_ehci_phy_restore_end(tegra->phy); - goto done; - - restart: - if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH) - tegra_ehci_phy_restore_end(tegra->phy); - - tegra_ehci_restart(hcd); - - done: - tegra_usb_phy_preresume(tegra->phy); - tegra->port_resuming = 1; - return 0; -} - -static int tegra_ehci_suspend(struct device *dev) -{ - struct tegra_ehci_hcd *tegra = - platform_get_drvdata(to_platform_device(dev)); - struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); - int rc = 0; - - /* - * When system sleep is supported and USB controller wakeup is - * implemented: If the controller is runtime-suspended and the - * wakeup setting needs to be changed, call pm_runtime_resume(). - */ - if (HCD_HW_ACCESSIBLE(hcd)) - rc = controller_suspend(dev); - return rc; -} - -static int tegra_ehci_resume(struct device *dev) -{ - int rc; - - rc = controller_resume(dev); - if (rc == 0) { - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - } - return rc; -} - -static int tegra_ehci_runtime_suspend(struct device *dev) -{ - return controller_suspend(dev); -} - -static int tegra_ehci_runtime_resume(struct device *dev) -{ - return controller_resume(dev); -} - -static const struct dev_pm_ops tegra_ehci_pm_ops = { - .suspend = tegra_ehci_suspend, - .resume = tegra_ehci_resume, - .runtime_suspend = tegra_ehci_runtime_suspend, - .runtime_resume = tegra_ehci_runtime_resume, -}; - -#endif - static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32); static int tegra_ehci_probe(struct platform_device *pdev) @@ -753,6 +720,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) } tegra->host_resumed = 1; + tegra->power_down_on_bus_suspend = pdata->power_down_on_bus_suspend; tegra->ehci = hcd_to_ehci(hcd); irq = platform_get_irq(pdev, 0); @@ -761,6 +729,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) err = -ENODEV; goto fail; } + set_irq_flags(irq, IRQF_VALID); #ifdef CONFIG_USB_OTG_UTILS if (pdata->operating_mode == TEGRA_USB_OTG) { @@ -776,14 +745,6 @@ static int tegra_ehci_probe(struct platform_device *pdev) goto fail; } - pm_runtime_set_active(&pdev->dev); - pm_runtime_get_noresume(&pdev->dev); - - /* Don't skip the pm_runtime_forbid call if wakeup isn't working */ - /* if (!pdata->power_down_on_bus_suspend) */ - pm_runtime_forbid(&pdev->dev); - pm_runtime_enable(&pdev->dev); - pm_runtime_put_sync(&pdev->dev); return err; fail: @@ -810,6 +771,33 @@ static int tegra_ehci_probe(struct platform_device *pdev) return err; } +#ifdef CONFIG_PM +static int tegra_ehci_resume(struct platform_device *pdev) +{ + struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); + struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); + + if (tegra->bus_suspended) + return 0; + + return tegra_usb_resume(hcd); +} + +static int tegra_ehci_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); + struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); + + if (tegra->bus_suspended) + return 0; + + if (time_before(jiffies, tegra->ehci->next_statechange)) + msleep(10); + + return tegra_usb_suspend(hcd); +} +#endif + static int tegra_ehci_remove(struct platform_device *pdev) { struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); @@ -818,10 +806,6 @@ static int tegra_ehci_remove(struct platform_device *pdev) if (tegra == NULL || hcd == NULL) return -EINVAL; - pm_runtime_get_sync(&pdev->dev); - pm_runtime_disable(&pdev->dev); - pm_runtime_put_noidle(&pdev->dev); - #ifdef CONFIG_USB_OTG_UTILS if (tegra->transceiver) { otg_set_host(tegra->transceiver->otg, NULL); @@ -862,12 +846,13 @@ static struct of_device_id tegra_ehci_of_match[] __devinitdata = { static struct platform_driver tegra_ehci_driver = { .probe = tegra_ehci_probe, .remove = tegra_ehci_remove, +#ifdef CONFIG_PM + .suspend = tegra_ehci_suspend, + .resume = tegra_ehci_resume, +#endif .shutdown = tegra_ehci_hcd_shutdown, .driver = { .name = "tegra-ehci", .of_match_table = tegra_ehci_of_match, -#ifdef CONFIG_PM - .pm = &tegra_ehci_pm_ops, -#endif } }; diff --git a/trunk/drivers/usb/host/ehci.h b/trunk/drivers/usb/host/ehci.h index 2694ed6558d2..8f9acbc96fde 100644 --- a/trunk/drivers/usb/host/ehci.h +++ b/trunk/drivers/usb/host/ehci.h @@ -117,8 +117,6 @@ struct ehci_hcd { /* one per controller */ the change-suspend feature turned on */ unsigned long suspended_ports; /* which ports are suspended */ - unsigned long resuming_ports; /* which ports have - started to resume */ /* per-HC memory pools (could be per-bus, but ...) */ struct dma_pool *qh_pool; /* qh per active urb */ diff --git a/trunk/drivers/usb/host/ohci-at91.c b/trunk/drivers/usb/host/ohci-at91.c index 13ebeca8e73e..db8963f5fbce 100644 --- a/trunk/drivers/usb/host/ohci-at91.c +++ b/trunk/drivers/usb/host/ohci-at91.c @@ -27,10 +27,6 @@ #error "CONFIG_ARCH_AT91 must be defined." #endif -#define valid_port(index) ((index) >= 0 && (index) < AT91_MAX_USBH_PORTS) -#define at91_for_each_port(index) \ - for ((index) = 0; (index) < AT91_MAX_USBH_PORTS; (index)++) - /* interface and function clocks; sometimes also an AHB clock */ static struct clk *iclk, *fclk, *hclk; static int clocked; @@ -94,7 +90,7 @@ static void at91_stop_hc(struct platform_device *pdev) /*-------------------------------------------------------------------------*/ -static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); +static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ @@ -108,7 +104,7 @@ static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_dev * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. */ -static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver, +static int usb_hcd_at91_probe(const struct hc_driver *driver, struct platform_device *pdev) { int retval; @@ -203,7 +199,7 @@ static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver, * context, "rmmod" or something similar. * */ -static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd, +static void usb_hcd_at91_remove(struct usb_hcd *hcd, struct platform_device *pdev) { usb_remove_hcd(hcd); @@ -244,26 +240,26 @@ ohci_at91_start (struct usb_hcd *hcd) static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable) { - if (!valid_port(port)) + if (port < 0 || port >= 2) return; if (!gpio_is_valid(pdata->vbus_pin[port])) return; gpio_set_value(pdata->vbus_pin[port], - pdata->vbus_pin_active_low[port] ^ enable); + !pdata->vbus_pin_active_low[port] ^ enable); } static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port) { - if (!valid_port(port)) + if (port < 0 || port >= 2) return -EINVAL; if (!gpio_is_valid(pdata->vbus_pin[port])) return -EINVAL; return gpio_get_value(pdata->vbus_pin[port]) ^ - pdata->vbus_pin_active_low[port]; + !pdata->vbus_pin_active_low[port]; } /* @@ -275,9 +271,9 @@ static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf) int length = ohci_hub_status_data(hcd, buf); int port; - at91_for_each_port(port) { + for (port = 0; port < ARRAY_SIZE(pdata->overcurrent_pin); port++) { if (pdata->overcurrent_changed[port]) { - if (!length) + if (! length) length = 1; buf[0] |= 1 << (port + 1); } @@ -301,17 +297,11 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, "ohci_at91_hub_control(%p,0x%04x,0x%04x,0x%04x,%p,%04x)\n", hcd, typeReq, wValue, wIndex, buf, wLength); - wIndex--; - switch (typeReq) { case SetPortFeature: if (wValue == USB_PORT_FEAT_POWER) { dev_dbg(hcd->self.controller, "SetPortFeat: POWER\n"); - if (valid_port(wIndex)) { - ohci_at91_usb_set_power(pdata, wIndex, 1); - ret = 0; - } - + ohci_at91_usb_set_power(pdata, wIndex - 1, 1); goto out; } break; @@ -322,9 +312,9 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, dev_dbg(hcd->self.controller, "ClearPortFeature: C_OVER_CURRENT\n"); - if (valid_port(wIndex)) { - pdata->overcurrent_changed[wIndex] = 0; - pdata->overcurrent_status[wIndex] = 0; + if (wIndex == 1 || wIndex == 2) { + pdata->overcurrent_changed[wIndex-1] = 0; + pdata->overcurrent_status[wIndex-1] = 0; } goto out; @@ -333,8 +323,9 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, dev_dbg(hcd->self.controller, "ClearPortFeature: OVER_CURRENT\n"); - if (valid_port(wIndex)) - pdata->overcurrent_status[wIndex] = 0; + if (wIndex == 1 || wIndex == 2) { + pdata->overcurrent_status[wIndex-1] = 0; + } goto out; @@ -342,15 +333,15 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, dev_dbg(hcd->self.controller, "ClearPortFeature: POWER\n"); - if (valid_port(wIndex)) { - ohci_at91_usb_set_power(pdata, wIndex, 0); + if (wIndex == 1 || wIndex == 2) { + ohci_at91_usb_set_power(pdata, wIndex - 1, 0); return 0; } } break; } - ret = ohci_hub_control(hcd, typeReq, wValue, wIndex + 1, buf, wLength); + ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); if (ret) goto out; @@ -386,15 +377,18 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", wIndex); - if (valid_port(wIndex)) { - if (!ohci_at91_usb_get_power(pdata, wIndex)) + if (wIndex == 1 || wIndex == 2) { + if (! ohci_at91_usb_get_power(pdata, wIndex-1)) { *data &= ~cpu_to_le32(RH_PS_PPS); + } - if (pdata->overcurrent_changed[wIndex]) + if (pdata->overcurrent_changed[wIndex-1]) { *data |= cpu_to_le32(RH_PS_OCIC); + } - if (pdata->overcurrent_status[wIndex]) + if (pdata->overcurrent_status[wIndex-1]) { *data |= cpu_to_le32(RH_PS_POCI); + } } } @@ -456,14 +450,14 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data) /* From the GPIO notifying the over-current situation, find * out the corresponding port */ - at91_for_each_port(port) { + for (port = 0; port < ARRAY_SIZE(pdata->overcurrent_pin); port++) { if (gpio_to_irq(pdata->overcurrent_pin[port]) == irq) { gpio = pdata->overcurrent_pin[port]; break; } } - if (port == AT91_MAX_USBH_PORTS) { + if (port == ARRAY_SIZE(pdata->overcurrent_pin)) { dev_err(& pdev->dev, "overcurrent interrupt from unknown GPIO\n"); return IRQ_HANDLED; } @@ -473,7 +467,7 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data) /* When notified of an over-current situation, disable power on the corresponding port, and mark this port in over-current. */ - if (!val) { + if (! val) { ohci_at91_usb_set_power(pdata, port, 0); pdata->overcurrent_status[port] = 1; pdata->overcurrent_changed[port] = 1; @@ -498,7 +492,7 @@ static u64 at91_ohci_dma_mask = DMA_BIT_MASK(32); static int __devinit ohci_at91_of_init(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; - int i, gpio; + int i, ret, gpio; enum of_gpio_flags flags; struct at91_usbh_data *pdata; u32 ports; @@ -520,17 +514,48 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev) if (!of_property_read_u32(np, "num-ports", &ports)) pdata->ports = ports; - at91_for_each_port(i) { + for (i = 0; i < 2; i++) { gpio = of_get_named_gpio_flags(np, "atmel,vbus-gpio", i, &flags); pdata->vbus_pin[i] = gpio; if (!gpio_is_valid(gpio)) continue; pdata->vbus_pin_active_low[i] = flags & OF_GPIO_ACTIVE_LOW; + ret = gpio_request(gpio, "ohci_vbus"); + if (ret) { + dev_warn(&pdev->dev, "can't request vbus gpio %d", gpio); + continue; + } + ret = gpio_direction_output(gpio, !(flags & OF_GPIO_ACTIVE_LOW) ^ 1); + if (ret) + dev_warn(&pdev->dev, "can't put vbus gpio %d as output %d", + !(flags & OF_GPIO_ACTIVE_LOW) ^ 1, gpio); } - at91_for_each_port(i) - pdata->overcurrent_pin[i] = - of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags); + for (i = 0; i < 2; i++) { + gpio = of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags); + pdata->overcurrent_pin[i] = gpio; + if (!gpio_is_valid(gpio)) + continue; + ret = gpio_request(gpio, "ohci_overcurrent"); + if (ret) { + dev_err(&pdev->dev, "can't request overcurrent gpio %d", gpio); + continue; + } + + ret = gpio_direction_input(gpio); + if (ret) { + dev_err(&pdev->dev, "can't configure overcurrent gpio %d as input", gpio); + continue; + } + + ret = request_irq(gpio_to_irq(gpio), + ohci_hcd_at91_overcurrent_irq, + IRQF_SHARED, "ohci_overcurrent", pdev); + if (ret) { + gpio_free(gpio); + dev_warn(& pdev->dev, "cannot get GPIO IRQ for overcurrent\n"); + } + } pdev->dev.platform_data = pdata; @@ -545,73 +570,39 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev) /*-------------------------------------------------------------------------*/ -static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev) +static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) { struct at91_usbh_data *pdata; int i; - int gpio; - int ret; - ret = ohci_at91_of_init(pdev); - if (ret) - return ret; + i = ohci_at91_of_init(pdev); + + if (i) + return i; pdata = pdev->dev.platform_data; if (pdata) { - at91_for_each_port(i) { + for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) { if (!gpio_is_valid(pdata->vbus_pin[i])) continue; - gpio = pdata->vbus_pin[i]; - - ret = gpio_request(gpio, "ohci_vbus"); - if (ret) { - dev_err(&pdev->dev, - "can't request vbus gpio %d\n", gpio); - continue; - } - ret = gpio_direction_output(gpio, - !pdata->vbus_pin_active_low[i]); - if (ret) { - dev_err(&pdev->dev, - "can't put vbus gpio %d as output %d\n", - gpio, !pdata->vbus_pin_active_low[i]); - gpio_free(gpio); - continue; - } - + gpio_request(pdata->vbus_pin[i], "ohci_vbus"); ohci_at91_usb_set_power(pdata, i, 1); } - at91_for_each_port(i) { - if (!gpio_is_valid(pdata->overcurrent_pin[i])) - continue; - gpio = pdata->overcurrent_pin[i]; - - ret = gpio_request(gpio, "ohci_overcurrent"); - if (ret) { - dev_err(&pdev->dev, - "can't request overcurrent gpio %d\n", - gpio); - continue; - } + for (i = 0; i < ARRAY_SIZE(pdata->overcurrent_pin); i++) { + int ret; - ret = gpio_direction_input(gpio); - if (ret) { - dev_err(&pdev->dev, - "can't configure overcurrent gpio %d as input\n", - gpio); - gpio_free(gpio); + if (!gpio_is_valid(pdata->overcurrent_pin[i])) continue; - } + gpio_request(pdata->overcurrent_pin[i], "ohci_overcurrent"); - ret = request_irq(gpio_to_irq(gpio), + ret = request_irq(gpio_to_irq(pdata->overcurrent_pin[i]), ohci_hcd_at91_overcurrent_irq, IRQF_SHARED, "ohci_overcurrent", pdev); if (ret) { - gpio_free(gpio); - dev_err(&pdev->dev, - "can't get gpio IRQ for overcurrent\n"); + gpio_free(pdata->overcurrent_pin[i]); + dev_warn(& pdev->dev, "cannot get GPIO IRQ for overcurrent\n"); } } } @@ -620,20 +611,20 @@ static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev) return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev); } -static int __devexit ohci_hcd_at91_drv_remove(struct platform_device *pdev) +static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) { struct at91_usbh_data *pdata = pdev->dev.platform_data; int i; if (pdata) { - at91_for_each_port(i) { + for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) { if (!gpio_is_valid(pdata->vbus_pin[i])) continue; ohci_at91_usb_set_power(pdata, i, 0); gpio_free(pdata->vbus_pin[i]); } - at91_for_each_port(i) { + for (i = 0; i < ARRAY_SIZE(pdata->overcurrent_pin); i++) { if (!gpio_is_valid(pdata->overcurrent_pin[i])) continue; free_irq(gpio_to_irq(pdata->overcurrent_pin[i]), pdev); @@ -696,7 +687,7 @@ MODULE_ALIAS("platform:at91_ohci"); static struct platform_driver ohci_hcd_at91_driver = { .probe = ohci_hcd_at91_drv_probe, - .remove = __devexit_p(ohci_hcd_at91_drv_remove), + .remove = ohci_hcd_at91_drv_remove, .shutdown = usb_hcd_platform_shutdown, .suspend = ohci_hcd_at91_drv_suspend, .resume = ohci_hcd_at91_drv_resume, diff --git a/trunk/drivers/usb/host/pci-quirks.c b/trunk/drivers/usb/host/pci-quirks.c index 32dada8c8b4f..11de5f1be981 100644 --- a/trunk/drivers/usb/host/pci-quirks.c +++ b/trunk/drivers/usb/host/pci-quirks.c @@ -825,13 +825,9 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) } } - val = readl(base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); - /* Mask off (turn off) any enabled SMIs */ - val &= XHCI_LEGACY_DISABLE_SMI; - /* Mask all SMI events bits, RW1C */ - val |= XHCI_LEGACY_SMI_EVENTS; - /* Disable any BIOS SMIs and clear all SMI events*/ - writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); + /* Disable any BIOS SMIs */ + writel(XHCI_LEGACY_DISABLE_SMI, + base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); if (usb_is_intel_switchable_xhci(pdev)) usb_enable_xhci_ports(pdev); diff --git a/trunk/drivers/usb/host/uhci-hub.c b/trunk/drivers/usb/host/uhci-hub.c index 768d54295a20..045cde4cbc3d 100644 --- a/trunk/drivers/usb/host/uhci-hub.c +++ b/trunk/drivers/usb/host/uhci-hub.c @@ -196,12 +196,11 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf) status = get_hub_status_data(uhci, buf); switch (uhci->rh_state) { + case UHCI_RH_SUSPENDING: case UHCI_RH_SUSPENDED: /* if port change, ask to be resumed */ - if (status || uhci->resuming_ports) { - status = 1; + if (status || uhci->resuming_ports) usb_hcd_resume_root_hub(hcd); - } break; case UHCI_RH_AUTO_STOPPED: diff --git a/trunk/drivers/usb/host/xhci-dbg.c b/trunk/drivers/usb/host/xhci-dbg.c index 4b436f5a4171..e9b0f043455d 100644 --- a/trunk/drivers/usb/host/xhci-dbg.c +++ b/trunk/drivers/usb/host/xhci-dbg.c @@ -119,7 +119,7 @@ static void xhci_print_command_reg(struct xhci_hcd *xhci) xhci_dbg(xhci, " Event Interrupts %s\n", (temp & CMD_EIE) ? "enabled " : "disabled"); xhci_dbg(xhci, " Host System Error Interrupts %s\n", - (temp & CMD_HSEIE) ? "enabled " : "disabled"); + (temp & CMD_EIE) ? "enabled " : "disabled"); xhci_dbg(xhci, " HC has %sfinished light reset\n", (temp & CMD_LRESET) ? "not " : ""); } diff --git a/trunk/drivers/usb/host/xhci-ext-caps.h b/trunk/drivers/usb/host/xhci-ext-caps.h index 377f4242dabb..c7f33123d4c0 100644 --- a/trunk/drivers/usb/host/xhci-ext-caps.h +++ b/trunk/drivers/usb/host/xhci-ext-caps.h @@ -62,9 +62,8 @@ /* USB Legacy Support Control and Status Register - section 7.1.2 */ /* Add this offset, plus the value of xECP in HCCPARAMS to the base address */ #define XHCI_LEGACY_CONTROL_OFFSET (0x04) -/* bits 1:3, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */ -#define XHCI_LEGACY_DISABLE_SMI ((0x7 << 1) + (0xff << 5) + (0x7 << 17)) -#define XHCI_LEGACY_SMI_EVENTS (0x7 << 29) +/* bits 1:2, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */ +#define XHCI_LEGACY_DISABLE_SMI ((0x3 << 1) + (0xff << 5) + (0x7 << 17)) /* USB 2.0 xHCI 0.96 L1C capability - section 7.2.2.1.3.2 */ #define XHCI_L1C (1 << 16) diff --git a/trunk/drivers/usb/host/xhci-mem.c b/trunk/drivers/usb/host/xhci-mem.c index 68eaa908ac8e..cae4c6f2845a 100644 --- a/trunk/drivers/usb/host/xhci-mem.c +++ b/trunk/drivers/usb/host/xhci-mem.c @@ -1796,6 +1796,11 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) int i; /* Free the Event Ring Segment Table and the actual Event Ring */ + if (xhci->ir_set) { + xhci_writel(xhci, 0, &xhci->ir_set->erst_size); + xhci_write_64(xhci, 0, &xhci->ir_set->erst_base); + xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue); + } size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); if (xhci->erst.entries) dma_free_coherent(&pdev->dev, size, @@ -1807,6 +1812,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) xhci->event_ring = NULL; xhci_dbg(xhci, "Freed event ring\n"); + xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring); if (xhci->cmd_ring) xhci_ring_free(xhci, xhci->cmd_ring); xhci->cmd_ring = NULL; @@ -1835,6 +1841,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) xhci->medium_streams_pool = NULL; xhci_dbg(xhci, "Freed medium stream array pool\n"); + xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr); if (xhci->dcbaa) dma_free_coherent(&pdev->dev, sizeof(*xhci->dcbaa), xhci->dcbaa, xhci->dcbaa->dma); @@ -2452,8 +2459,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) fail: xhci_warn(xhci, "Couldn't initialize memory\n"); - xhci_halt(xhci); - xhci_reset(xhci); xhci_mem_cleanup(xhci); return -ENOMEM; } diff --git a/trunk/drivers/usb/host/xhci-pci.c b/trunk/drivers/usb/host/xhci-pci.c index 7a856a767e77..ef98b38626fb 100644 --- a/trunk/drivers/usb/host/xhci-pci.c +++ b/trunk/drivers/usb/host/xhci-pci.c @@ -95,8 +95,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |= XHCI_RESET_ON_RESUME; xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); } - if (pdev->vendor == PCI_VENDOR_ID_VIA) - xhci->quirks |= XHCI_RESET_ON_RESUME; } /* called during probe() after chip reset completes */ @@ -328,7 +326,7 @@ int __init xhci_register_pci(void) return pci_register_driver(&xhci_pci_driver); } -void xhci_unregister_pci(void) +void __exit xhci_unregister_pci(void) { pci_unregister_driver(&xhci_pci_driver); } diff --git a/trunk/drivers/usb/host/xhci-ring.c b/trunk/drivers/usb/host/xhci-ring.c index 3d9422f16a20..6bd9d53062eb 100644 --- a/trunk/drivers/usb/host/xhci-ring.c +++ b/trunk/drivers/usb/host/xhci-ring.c @@ -2417,7 +2417,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) u32 irq_pending; /* Acknowledge the PCI interrupt */ irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); - irq_pending |= IMAN_IP; + irq_pending |= 0x3; xhci_writel(xhci, irq_pending, &xhci->ir_set->irq_pending); } @@ -2734,7 +2734,7 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags, urb->dev->speed == USB_SPEED_FULL) urb->interval /= 8; } - return xhci_queue_bulk_tx(xhci, mem_flags, urb, slot_id, ep_index); + return xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); } /* @@ -3514,7 +3514,7 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags, } ep_ring->num_trbs_free_temp = ep_ring->num_trbs_free; - return xhci_queue_isoc_tx(xhci, mem_flags, urb, slot_id, ep_index); + return xhci_queue_isoc_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); } /**** Command Ring Operations ****/ diff --git a/trunk/drivers/usb/host/xhci.c b/trunk/drivers/usb/host/xhci.c index 36641a7f2371..e1963d4a430f 100644 --- a/trunk/drivers/usb/host/xhci.c +++ b/trunk/drivers/usb/host/xhci.c @@ -106,9 +106,6 @@ int xhci_halt(struct xhci_hcd *xhci) STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); if (!ret) xhci->xhc_state |= XHCI_STATE_HALTED; - else - xhci_warn(xhci, "Host not halted after %u microseconds.\n", - XHCI_MAX_HALT_USEC); return ret; } @@ -667,11 +664,11 @@ static void xhci_save_registers(struct xhci_hcd *xhci) xhci->s3.dev_nt = xhci_readl(xhci, &xhci->op_regs->dev_notification); xhci->s3.dcbaa_ptr = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); xhci->s3.config_reg = xhci_readl(xhci, &xhci->op_regs->config_reg); + xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); + xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control); xhci->s3.erst_size = xhci_readl(xhci, &xhci->ir_set->erst_size); xhci->s3.erst_base = xhci_read_64(xhci, &xhci->ir_set->erst_base); xhci->s3.erst_dequeue = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); - xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); - xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control); } static void xhci_restore_registers(struct xhci_hcd *xhci) @@ -680,11 +677,10 @@ static void xhci_restore_registers(struct xhci_hcd *xhci) xhci_writel(xhci, xhci->s3.dev_nt, &xhci->op_regs->dev_notification); xhci_write_64(xhci, xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr); xhci_writel(xhci, xhci->s3.config_reg, &xhci->op_regs->config_reg); - xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size); - xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); - xhci_write_64(xhci, xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue); xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending); xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control); + xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size); + xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); } static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci) diff --git a/trunk/drivers/usb/host/xhci.h b/trunk/drivers/usb/host/xhci.h index 3d69c4b2b542..91074fdab3eb 100644 --- a/trunk/drivers/usb/host/xhci.h +++ b/trunk/drivers/usb/host/xhci.h @@ -205,10 +205,6 @@ struct xhci_op_regs { #define CMD_PM_INDEX (1 << 11) /* 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) - /* USBSTS - USB status - status bitmasks */ /* HC not running - set to 1 when run/stop bit is cleared. */ #define STS_HALT XHCI_STS_HALT diff --git a/trunk/drivers/usb/misc/usbtest.c b/trunk/drivers/usb/misc/usbtest.c index 9dcb68f04f03..959145baf3cf 100644 --- a/trunk/drivers/usb/misc/usbtest.c +++ b/trunk/drivers/usb/misc/usbtest.c @@ -423,7 +423,7 @@ alloc_sglist(int nents, int max, int vary) unsigned i; unsigned size = max; - sg = kmalloc_array(nents, sizeof *sg, GFP_KERNEL); + sg = kmalloc(nents * sizeof *sg, GFP_KERNEL); if (!sg) return NULL; sg_init_table(sg, nents); @@ -904,9 +904,6 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param) struct ctrl_ctx context; int i; - if (param->sglen == 0 || param->iterations > UINT_MAX / param->sglen) - return -EOPNOTSUPP; - spin_lock_init(&context.lock); context.dev = dev; init_completion(&context.complete); @@ -1984,6 +1981,8 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) /* queued control messaging */ case 10: + if (param->sglen == 0) + break; retval = 0; dev_info(&intf->dev, "TEST 10: queue %d control calls, %d times\n", @@ -2277,8 +2276,6 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id) if (status < 0) { WARNING(dev, "couldn't get endpoints, %d\n", status); - kfree(dev->buf); - kfree(dev); return status; } /* may find bulk or ISO pipes */ diff --git a/trunk/drivers/usb/misc/yurex.c b/trunk/drivers/usb/misc/yurex.c index 70201462e19c..897edda42270 100644 --- a/trunk/drivers/usb/misc/yurex.c +++ b/trunk/drivers/usb/misc/yurex.c @@ -99,7 +99,9 @@ static void yurex_delete(struct kref *kref) usb_put_dev(dev->udev); if (dev->cntl_urb) { usb_kill_urb(dev->cntl_urb); - kfree(dev->cntl_req); + if (dev->cntl_req) + usb_free_coherent(dev->udev, YUREX_BUF_SIZE, + dev->cntl_req, dev->cntl_urb->setup_dma); if (dev->cntl_buffer) usb_free_coherent(dev->udev, YUREX_BUF_SIZE, dev->cntl_buffer, dev->cntl_urb->transfer_dma); @@ -232,7 +234,9 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ } /* allocate buffer for control req */ - dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL); + dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE, + GFP_KERNEL, + &dev->cntl_urb->setup_dma); if (!dev->cntl_req) { err("Could not allocate cntl_req"); goto error; @@ -282,7 +286,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr), dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt, dev, 1); - dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; if (usb_submit_urb(dev->urb, GFP_KERNEL)) { retval = -EIO; err("Could not submitting URB"); diff --git a/trunk/drivers/usb/musb/davinci.c b/trunk/drivers/usb/musb/davinci.c index 768b4b55c816..97ab975fa442 100644 --- a/trunk/drivers/usb/musb/davinci.c +++ b/trunk/drivers/usb/musb/davinci.c @@ -386,7 +386,7 @@ static int davinci_musb_init(struct musb *musb) usb_nop_xceiv_register(); musb->xceiv = usb_get_transceiver(); if (!musb->xceiv) - goto unregister; + return -ENODEV; musb->mregs += DAVINCI_BASE_OFFSET; @@ -444,7 +444,6 @@ static int davinci_musb_init(struct musb *musb) fail: usb_put_transceiver(musb->xceiv); -unregister: usb_nop_xceiv_unregister(); return -ENODEV; } diff --git a/trunk/drivers/usb/musb/musb_core.c b/trunk/drivers/usb/musb/musb_core.c index 66aaccf04490..0f8b82918a40 100644 --- a/trunk/drivers/usb/musb/musb_core.c +++ b/trunk/drivers/usb/musb/musb_core.c @@ -137,9 +137,6 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset) int i = 0; u8 r; u8 power; - int ret; - - pm_runtime_get_sync(phy->io_dev); /* Make sure the transceiver is not in low power mode */ power = musb_readb(addr, MUSB_POWER); @@ -157,22 +154,15 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset) while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL) & MUSB_ULPI_REG_CMPLT)) { i++; - if (i == 10000) { - ret = -ETIMEDOUT; - goto out; - } + if (i == 10000) + return -ETIMEDOUT; } r = musb_readb(addr, MUSB_ULPI_REG_CONTROL); r &= ~MUSB_ULPI_REG_CMPLT; musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); - ret = musb_readb(addr, MUSB_ULPI_REG_DATA); - -out: - pm_runtime_put(phy->io_dev); - - return ret; + return musb_readb(addr, MUSB_ULPI_REG_DATA); } static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) @@ -181,9 +171,6 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) int i = 0; u8 r = 0; u8 power; - int ret = 0; - - pm_runtime_get_sync(phy->io_dev); /* Make sure the transceiver is not in low power mode */ power = musb_readb(addr, MUSB_POWER); @@ -197,20 +184,15 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL) & MUSB_ULPI_REG_CMPLT)) { i++; - if (i == 10000) { - ret = -ETIMEDOUT; - goto out; - } + if (i == 10000) + return -ETIMEDOUT; } r = musb_readb(addr, MUSB_ULPI_REG_CONTROL); r &= ~MUSB_ULPI_REG_CMPLT; musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); -out: - pm_runtime_put(phy->io_dev); - - return ret; + return 0; } #else #define musb_ulpi_read NULL @@ -1922,17 +1904,14 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) if (!musb->isr) { status = -ENODEV; - goto fail2; + goto fail3; } if (!musb->xceiv->io_ops) { - musb->xceiv->io_dev = musb->controller; musb->xceiv->io_priv = musb->mregs; musb->xceiv->io_ops = &musb_ulpi_access; } - pm_runtime_get_sync(musb->controller); - #ifndef CONFIG_MUSB_PIO_ONLY if (use_dma && dev->dma_mask) { struct dma_controller *c; @@ -2044,8 +2023,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) goto fail5; #endif - pm_runtime_put(musb->controller); - dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n", ({char *s; switch (musb->board_mode) { @@ -2070,9 +2047,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) musb_gadget_cleanup(musb); fail3: - pm_runtime_put_sync(musb->controller); - -fail2: if (musb->irq_wake) device_init_wakeup(dev, 0); musb_platform_exit(musb); diff --git a/trunk/drivers/usb/musb/musb_core.h b/trunk/drivers/usb/musb/musb_core.h index f4a40f001c88..93de517a32a0 100644 --- a/trunk/drivers/usb/musb/musb_core.h +++ b/trunk/drivers/usb/musb/musb_core.h @@ -449,7 +449,7 @@ struct musb { * We added this flag to forcefully disable double * buffering until we get it working. */ - unsigned double_buffer_not_ok:1; + unsigned double_buffer_not_ok:1 __deprecated; struct musb_hdrc_config *config; diff --git a/trunk/drivers/usb/musb/musb_host.c b/trunk/drivers/usb/musb/musb_host.c index ef8d744800ac..79cb0af779fa 100644 --- a/trunk/drivers/usb/musb/musb_host.c +++ b/trunk/drivers/usb/musb/musb_host.c @@ -2098,7 +2098,7 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh) } /* turn off DMA requests, discard state, stop polling ... */ - if (ep->epnum && is_in) { + if (is_in) { /* giveback saves bulk toggle */ csr = musb_h_flush_rxfifo(ep, 0); diff --git a/trunk/drivers/usb/musb/omap2430.c b/trunk/drivers/usb/musb/omap2430.c index c7785e81254c..2ae0bb309994 100644 --- a/trunk/drivers/usb/musb/omap2430.c +++ b/trunk/drivers/usb/musb/omap2430.c @@ -282,8 +282,7 @@ static void musb_otg_notifier_work(struct work_struct *data_notifier_work) static int omap2430_musb_init(struct musb *musb) { - u32 l; - int status = 0; + u32 l, status = 0; struct device *dev = musb->controller; struct musb_hdrc_platform_data *plat = dev->platform_data; struct omap_musb_board_data *data = plat->board_data; @@ -302,7 +301,7 @@ static int omap2430_musb_init(struct musb *musb) status = pm_runtime_get_sync(dev); if (status < 0) { - dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status); + dev_err(dev, "pm_runtime_get_sync FAILED"); goto err1; } @@ -334,7 +333,6 @@ static int omap2430_musb_init(struct musb *musb) setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); - pm_runtime_put_noidle(musb->controller); return 0; err1: @@ -454,14 +452,14 @@ static int __devinit omap2430_probe(struct platform_device *pdev) goto err2; } - pm_runtime_enable(&pdev->dev); - ret = platform_device_add(musb); if (ret) { dev_err(&pdev->dev, "failed to register musb device\n"); goto err2; } + pm_runtime_enable(&pdev->dev); + return 0; err2: @@ -480,6 +478,7 @@ static int __devexit omap2430_remove(struct platform_device *pdev) platform_device_del(glue->musb); platform_device_put(glue->musb); + pm_runtime_put(&pdev->dev); kfree(glue); return 0; @@ -492,13 +491,11 @@ static int omap2430_runtime_suspend(struct device *dev) struct omap2430_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); - if (musb) { - musb->context.otg_interfsel = musb_readl(musb->mregs, - OTG_INTERFSEL); + musb->context.otg_interfsel = musb_readl(musb->mregs, + OTG_INTERFSEL); - omap2430_low_level_exit(musb); - usb_phy_set_suspend(musb->xceiv, 1); - } + omap2430_low_level_exit(musb); + usb_phy_set_suspend(musb->xceiv, 1); return 0; } @@ -508,13 +505,11 @@ static int omap2430_runtime_resume(struct device *dev) struct omap2430_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); - if (musb) { - omap2430_low_level_init(musb); - musb_writel(musb->mregs, OTG_INTERFSEL, - musb->context.otg_interfsel); + omap2430_low_level_init(musb); + musb_writel(musb->mregs, OTG_INTERFSEL, + musb->context.otg_interfsel); - usb_phy_set_suspend(musb->xceiv, 0); - } + usb_phy_set_suspend(musb->xceiv, 0); return 0; } diff --git a/trunk/drivers/usb/otg/gpio_vbus.c b/trunk/drivers/usb/otg/gpio_vbus.c index a0a2178974fe..3ece43a2e4c1 100644 --- a/trunk/drivers/usb/otg/gpio_vbus.c +++ b/trunk/drivers/usb/otg/gpio_vbus.c @@ -96,7 +96,7 @@ static void gpio_vbus_work(struct work_struct *work) struct gpio_vbus_data *gpio_vbus = container_of(work, struct gpio_vbus_data, work); struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data; - int gpio, status; + int gpio; if (!gpio_vbus->phy.otg->gadget) return; @@ -108,9 +108,7 @@ static void gpio_vbus_work(struct work_struct *work) */ gpio = pdata->gpio_pullup; if (is_vbus_powered(pdata)) { - status = USB_EVENT_VBUS; gpio_vbus->phy.state = OTG_STATE_B_PERIPHERAL; - gpio_vbus->phy.last_event = status; usb_gadget_vbus_connect(gpio_vbus->phy.otg->gadget); /* drawing a "unit load" is *always* OK, except for OTG */ @@ -119,9 +117,6 @@ static void gpio_vbus_work(struct work_struct *work) /* optionally enable D+ pullup */ if (gpio_is_valid(gpio)) gpio_set_value(gpio, !pdata->gpio_pullup_inverted); - - atomic_notifier_call_chain(&gpio_vbus->phy.notifier, - status, gpio_vbus->phy.otg->gadget); } else { /* optionally disable D+ pullup */ if (gpio_is_valid(gpio)) @@ -130,12 +125,7 @@ static void gpio_vbus_work(struct work_struct *work) set_vbus_draw(gpio_vbus, 0); usb_gadget_vbus_disconnect(gpio_vbus->phy.otg->gadget); - status = USB_EVENT_NONE; gpio_vbus->phy.state = OTG_STATE_B_IDLE; - gpio_vbus->phy.last_event = status; - - atomic_notifier_call_chain(&gpio_vbus->phy.notifier, - status, gpio_vbus->phy.otg->gadget); } } @@ -297,9 +287,6 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) irq, err); goto err_irq; } - - ATOMIC_INIT_NOTIFIER_HEAD(&gpio_vbus->phy.notifier); - INIT_WORK(&gpio_vbus->work, gpio_vbus_work); gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw"); diff --git a/trunk/drivers/usb/serial/bus.c b/trunk/drivers/usb/serial/bus.c index ed8adb052ca7..7f547dc3a590 100644 --- a/trunk/drivers/usb/serial/bus.c +++ b/trunk/drivers/usb/serial/bus.c @@ -60,6 +60,8 @@ static int usb_serial_device_probe(struct device *dev) retval = -ENODEV; goto exit; } + if (port->dev_state != PORT_REGISTERING) + goto exit; driver = port->serial->type; if (driver->port_probe) { @@ -96,6 +98,9 @@ static int usb_serial_device_remove(struct device *dev) if (!port) return -ENODEV; + if (port->dev_state != PORT_UNREGISTERING) + return retval; + device_remove_file(&port->dev, &dev_attr_port_number); driver = port->serial->type; diff --git a/trunk/drivers/usb/serial/cp210x.c b/trunk/drivers/usb/serial/cp210x.c index ec30f95ef399..0310e2df59f5 100644 --- a/trunk/drivers/usb/serial/cp210x.c +++ b/trunk/drivers/usb/serial/cp210x.c @@ -287,8 +287,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, /* Issue the request, attempting to read 'size' bytes */ result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), request, REQTYPE_DEVICE_TO_HOST, 0x0000, - port_priv->bInterfaceNumber, buf, size, - USB_CTRL_GET_TIMEOUT); + port_priv->bInterfaceNumber, buf, size, 300); /* Convert data into an array of integers */ for (i = 0; i < length; i++) @@ -341,14 +340,12 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_DEVICE, 0x0000, - port_priv->bInterfaceNumber, buf, size, - USB_CTRL_SET_TIMEOUT); + port_priv->bInterfaceNumber, buf, size, 300); } else { result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_DEVICE, data[0], - port_priv->bInterfaceNumber, NULL, 0, - USB_CTRL_SET_TIMEOUT); + port_priv->bInterfaceNumber, NULL, 0, 300); } kfree(buf); diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index 02e7f2d32d52..7c229d304684 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -75,8 +75,7 @@ struct ftdi_private { 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 prev_status, diff_status; /* Used for TIOCMIWAIT */ char transmit_empty; /* If transmitter is empty or not */ struct usb_serial_port *port; __u16 interface; /* FT2232C, FT2232H or FT4232H port interface @@ -1682,7 +1681,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) 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); @@ -1726,8 +1724,7 @@ static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv) /* * Module parameter to control latency timer for NDI FTDI-based USB devices. - * If this value is not set in /etc/modprobe.d/ its value will be set - * to 1ms. + * If this value is not set in modprobe.conf.local its value will be set to 1ms. */ static int ndi_latency_timer = 1; @@ -1841,9 +1838,6 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port) dbg("%s", __func__); - priv->dev_gone = true; - wake_up_interruptible_all(&priv->delta_msr_wait); - remove_sysfs_attrs(port); kref_put(&priv->kref, ftdi_sio_priv_release); @@ -1987,19 +1981,17 @@ static int ftdi_process_packet(struct tty_struct *tty, N.B. packet may be processed more than once, but differences are only processed once. */ status = packet[0] & FTDI_STATUS_B0_MASK; + if (status & FTDI_RS0_CTS) + priv->icount.cts++; + if (status & FTDI_RS0_DSR) + priv->icount.dsr++; + if (status & FTDI_RS0_RI) + priv->icount.rng++; + if (status & FTDI_RS0_RLSD) + priv->icount.dcd++; if (status != priv->prev_status) { - char diff_status = status ^ priv->prev_status; - - if (diff_status & FTDI_RS0_CTS) - priv->icount.cts++; - if (diff_status & FTDI_RS0_DSR) - priv->icount.dsr++; - if (diff_status & FTDI_RS0_RI) - priv->icount.rng++; - if (diff_status & FTDI_RS0_RLSD) - priv->icount.dcd++; - - wake_up_interruptible_all(&priv->delta_msr_wait); + priv->diff_status |= status ^ priv->prev_status; + wake_up_interruptible(&priv->delta_msr_wait); priv->prev_status = status; } @@ -2402,12 +2394,15 @@ static int ftdi_ioctl(struct tty_struct *tty, */ case TIOCMIWAIT: cprev = priv->icount; - while (!priv->dev_gone) { + while (1) { interruptible_sleep_on(&priv->delta_msr_wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; cnow = priv->icount; + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) + return -EIO; /* no change => error */ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || @@ -2416,7 +2411,7 @@ static int ftdi_ioctl(struct tty_struct *tty, } cprev = cnow; } - return -EIO; + /* not reached */ break; case TIOCSERGETLSR: return get_lsr_info(port, (struct serial_struct __user *)arg); diff --git a/trunk/drivers/usb/serial/metro-usb.c b/trunk/drivers/usb/serial/metro-usb.c index 08d16e8c002d..6e1622f2a297 100644 --- a/trunk/drivers/usb/serial/metro-usb.c +++ b/trunk/drivers/usb/serial/metro-usb.c @@ -27,8 +27,8 @@ /* Product information. */ #define FOCUS_VENDOR_ID 0x0C2E -#define FOCUS_PRODUCT_ID_BI 0x0720 -#define FOCUS_PRODUCT_ID_UNI 0x0700 +#define FOCUS_PRODUCT_ID 0x0720 +#define FOCUS_PRODUCT_ID_UNI 0x0710 #define METROUSB_SET_REQUEST_TYPE 0x40 #define METROUSB_SET_MODEM_CTRL_REQUEST 10 @@ -47,7 +47,7 @@ struct metrousb_private { /* Device table list. */ static struct usb_device_id id_table[] = { - { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_BI) }, + { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID) }, { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) }, { }, /* Terminating entry. */ }; diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index f4465ccddc35..836cfa9a515f 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -708,7 +708,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED3) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED4) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED5) }, diff --git a/trunk/drivers/usb/serial/pl2303.c b/trunk/drivers/usb/serial/pl2303.c index a1a9062954c4..ff4a174fa5de 100644 --- a/trunk/drivers/usb/serial/pl2303.c +++ b/trunk/drivers/usb/serial/pl2303.c @@ -420,7 +420,7 @@ static void pl2303_set_termios(struct tty_struct *tty, control = priv->line_control; if ((cflag & CBAUD) == B0) priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS); - else if ((old_termios->c_cflag & CBAUD) == B0) + else priv->line_control |= (CONTROL_DTR | CONTROL_RTS); if (control != priv->line_control) { control = priv->line_control; diff --git a/trunk/drivers/usb/serial/sierra.c b/trunk/drivers/usb/serial/sierra.c index 8c8bf806f6fa..f14465a83dd1 100644 --- a/trunk/drivers/usb/serial/sierra.c +++ b/trunk/drivers/usb/serial/sierra.c @@ -221,7 +221,7 @@ static const struct sierra_iface_info typeB_interface_list = { }; /* 'blacklist' of interfaces not served by this driver */ -static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 }; +static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 }; static const struct sierra_iface_info direct_ip_interface_blacklist = { .infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces), .ifaceinfo = direct_ip_non_serial_ifaces, @@ -298,9 +298,6 @@ static const struct usb_device_id id_table[] = { /* Sierra Wireless HSPA Non-Composite Device */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */ - { USB_DEVICE(0x1199, 0x68A2), /* Sierra Wireless MC77xx in QMI mode */ - .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist - }, { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist }, diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index 97355a15bbea..69230f01056a 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -1059,12 +1059,6 @@ int usb_serial_probe(struct usb_interface *interface, serial->attached = 1; } - /* Avoid race with tty_open and serial_install by setting the - * disconnected flag and not clearing it until all ports have been - * registered. - */ - serial->disconnected = 1; - if (get_free_serial(serial, num_ports, &minor) == NULL) { dev_err(&interface->dev, "No more free serial devices\n"); goto probe_error; @@ -1076,16 +1070,19 @@ int usb_serial_probe(struct usb_interface *interface, port = serial->port[i]; dev_set_name(&port->dev, "ttyUSB%d", port->number); dbg ("%s - registering %s", __func__, dev_name(&port->dev)); + port->dev_state = PORT_REGISTERING; device_enable_async_suspend(&port->dev); retval = device_add(&port->dev); - if (retval) + if (retval) { dev_err(&port->dev, "Error registering port device, " "continuing\n"); + port->dev_state = PORT_UNREGISTERED; + } else { + port->dev_state = PORT_REGISTERED; + } } - serial->disconnected = 0; - usb_serial_console_init(debug, minor); exit: @@ -1127,8 +1124,22 @@ void usb_serial_disconnect(struct usb_interface *interface) } kill_traffic(port); cancel_work_sync(&port->work); - if (device_is_registered(&port->dev)) + if (port->dev_state == PORT_REGISTERED) { + + /* Make sure the port is bound so that the + * driver's port_remove method is called. + */ + if (!port->dev.driver) { + int rc; + + port->dev.driver = + &serial->type->driver; + rc = device_bind_driver(&port->dev); + } + port->dev_state = PORT_UNREGISTERING; device_del(&port->dev); + port->dev_state = PORT_UNREGISTERED; + } } } serial->type->disconnect(serial); diff --git a/trunk/drivers/usb/storage/Kconfig b/trunk/drivers/usb/storage/Kconfig index 7691c866637b..fe2d803a6347 100644 --- a/trunk/drivers/usb/storage/Kconfig +++ b/trunk/drivers/usb/storage/Kconfig @@ -222,7 +222,7 @@ config USB_LIBUSUAL for usb-storage and ub drivers, and allows to switch binding of these devices without rebuilding modules. - Typical syntax of /etc/modprobe.d/*conf is: + Typical syntax of /etc/modprobe.conf is: options libusual bias="ub" diff --git a/trunk/drivers/usb/storage/usb.c b/trunk/drivers/usb/storage/usb.c index 2653e73db623..c18538e4a6db 100644 --- a/trunk/drivers/usb/storage/usb.c +++ b/trunk/drivers/usb/storage/usb.c @@ -132,35 +132,6 @@ static struct us_unusual_dev for_dynamic_ids = #undef COMPLIANT_DEV #undef USUAL_DEV -#ifdef CONFIG_LOCKDEP - -static struct lock_class_key us_interface_key[USB_MAXINTERFACES]; - -static void us_set_lock_class(struct mutex *mutex, - struct usb_interface *intf) -{ - struct usb_device *udev = interface_to_usbdev(intf); - struct usb_host_config *config = udev->actconfig; - int i; - - for (i = 0; i < config->desc.bNumInterfaces; i++) { - if (config->interface[i] == intf) - break; - } - - BUG_ON(i == config->desc.bNumInterfaces); - - lockdep_set_class(mutex, &us_interface_key[i]); -} - -#else - -static void us_set_lock_class(struct mutex *mutex, - struct usb_interface *intf) -{ -} - -#endif #ifdef CONFIG_PM /* Minimal support for suspend and resume */ @@ -924,7 +895,6 @@ int usb_stor_probe1(struct us_data **pus, *pus = us = host_to_us(host); memset(us, 0, sizeof(struct us_data)); mutex_init(&(us->dev_mutex)); - us_set_lock_class(&us->dev_mutex, intf); init_completion(&us->cmnd_ready); init_completion(&(us->notify)); init_waitqueue_head(&us->delay_wait); diff --git a/trunk/drivers/uwb/hwa-rc.c b/trunk/drivers/uwb/hwa-rc.c index 810c90ae2c55..66797e9c5010 100644 --- a/trunk/drivers/uwb/hwa-rc.c +++ b/trunk/drivers/uwb/hwa-rc.c @@ -645,8 +645,7 @@ void hwarc_neep_cb(struct urb *urb) dev_err(dev, "NEEP: URB error %d\n", urb->status); } result = usb_submit_urb(urb, GFP_ATOMIC); - if (result < 0 && result != -ENODEV && result != -EPERM) { - /* ignoring unrecoverable errors */ + if (result < 0) { dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n", result); goto error; diff --git a/trunk/drivers/uwb/neh.c b/trunk/drivers/uwb/neh.c index 8cb71bb333c2..a269937be1b8 100644 --- a/trunk/drivers/uwb/neh.c +++ b/trunk/drivers/uwb/neh.c @@ -107,7 +107,6 @@ struct uwb_rc_neh { u8 evt_type; __le16 evt; u8 context; - u8 completed; uwb_rc_cmd_cb_f cb; void *arg; @@ -410,7 +409,6 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size struct device *dev = &rc->uwb_dev.dev; struct uwb_rc_neh *neh; struct uwb_rceb *notif; - unsigned long flags; if (rceb->bEventContext == 0) { notif = kmalloc(size, GFP_ATOMIC); @@ -424,11 +422,7 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size } else { neh = uwb_rc_neh_lookup(rc, rceb); if (neh) { - spin_lock_irqsave(&rc->neh_lock, flags); - /* to guard against a timeout */ - neh->completed = 1; - del_timer(&neh->timer); - spin_unlock_irqrestore(&rc->neh_lock, flags); + del_timer_sync(&neh->timer); uwb_rc_neh_cb(neh, rceb, size); } else dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n", @@ -574,10 +568,6 @@ static void uwb_rc_neh_timer(unsigned long arg) unsigned long flags; spin_lock_irqsave(&rc->neh_lock, flags); - if (neh->completed) { - spin_unlock_irqrestore(&rc->neh_lock, flags); - return; - } if (neh->context) __uwb_rc_neh_rm(rc, neh); else diff --git a/trunk/drivers/uwb/uwb-debug.c b/trunk/drivers/uwb/uwb-debug.c index 6ec45beb7af5..2eecec0c13c9 100644 --- a/trunk/drivers/uwb/uwb-debug.c +++ b/trunk/drivers/uwb/uwb-debug.c @@ -159,6 +159,13 @@ static int cmd_ie_rm(struct uwb_rc *rc, struct uwb_dbg_cmd_ie *ie_to_rm) return uwb_rc_ie_rm(rc, ie_to_rm->data[0]); } +static int command_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + + return 0; +} + static ssize_t command_write(struct file *file, const char __user *buf, size_t len, loff_t *off) { @@ -199,7 +206,7 @@ static ssize_t command_write(struct file *file, const char __user *buf, } static const struct file_operations command_fops = { - .open = simple_open, + .open = command_open, .write = command_write, .read = NULL, .llseek = no_llseek, diff --git a/trunk/drivers/vhost/net.c b/trunk/drivers/vhost/net.c index 1f21d2a1e528..f0da2c32fbde 100644 --- a/trunk/drivers/vhost/net.c +++ b/trunk/drivers/vhost/net.c @@ -238,7 +238,7 @@ static void handle_tx(struct vhost_net *net) vq->heads[vq->upend_idx].len = len; ubuf->callback = vhost_zerocopy_callback; - ubuf->ctx = vq->ubufs; + ubuf->arg = vq->ubufs; ubuf->desc = vq->upend_idx; msg.msg_control = ubuf; msg.msg_controllen = sizeof(ubuf); diff --git a/trunk/drivers/vhost/test.c b/trunk/drivers/vhost/test.c index 3de00d9fae2e..fc9a1d75281f 100644 --- a/trunk/drivers/vhost/test.c +++ b/trunk/drivers/vhost/test.c @@ -155,7 +155,7 @@ static int vhost_test_release(struct inode *inode, struct file *f) vhost_test_stop(n, &private); vhost_test_flush(n); - vhost_dev_cleanup(&n->dev, false); + vhost_dev_cleanup(&n->dev); /* We do an extra flush before freeing memory, * since jobs can re-queue themselves. */ vhost_test_flush(n); diff --git a/trunk/drivers/vhost/vhost.c b/trunk/drivers/vhost/vhost.c index 51e4c1eeec4f..947f00d8e091 100644 --- a/trunk/drivers/vhost/vhost.c +++ b/trunk/drivers/vhost/vhost.c @@ -1598,9 +1598,10 @@ void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *ubufs) kfree(ubufs); } -void vhost_zerocopy_callback(struct ubuf_info *ubuf) +void vhost_zerocopy_callback(void *arg) { - struct vhost_ubuf_ref *ubufs = ubuf->ctx; + struct ubuf_info *ubuf = arg; + struct vhost_ubuf_ref *ubufs = ubuf->arg; struct vhost_virtqueue *vq = ubufs->vq; /* set len = 1 to mark this desc buffers done DMA */ diff --git a/trunk/drivers/vhost/vhost.h b/trunk/drivers/vhost/vhost.h index 8de1fd5b8efb..8dcf4cca6bf2 100644 --- a/trunk/drivers/vhost/vhost.h +++ b/trunk/drivers/vhost/vhost.h @@ -188,7 +188,7 @@ bool vhost_enable_notify(struct vhost_dev *, struct vhost_virtqueue *); int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, unsigned int log_num, u64 len); -void vhost_zerocopy_callback(struct ubuf_info *); +void vhost_zerocopy_callback(void *arg); int vhost_zerocopy_signal_used(struct vhost_virtqueue *vq); #define vq_err(vq, fmt, ...) do { \ diff --git a/trunk/drivers/video/au1100fb.c b/trunk/drivers/video/au1100fb.c index ffbce4525468..befcbd8ef019 100644 --- a/trunk/drivers/video/au1100fb.c +++ b/trunk/drivers/video/au1100fb.c @@ -499,8 +499,7 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev) au1100fb_fix.mmio_start = regs_res->start; au1100fb_fix.mmio_len = resource_size(regs_res); - if (!devm_request_mem_region(&dev->dev, - au1100fb_fix.mmio_start, + if (!devm_request_mem_region(au1100fb_fix.mmio_start, au1100fb_fix.mmio_len, DRIVER_NAME)) { print_err("fail to lock memory region at 0x%08lx", @@ -517,7 +516,7 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev) fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres * (fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS; - fbdev->fb_mem = dmam_alloc_coherent(&dev->dev, + fbdev->fb_mem = dmam_alloc_coherent(&dev->dev, &dev->dev, PAGE_ALIGN(fbdev->fb_len), &fbdev->fb_phys, GFP_KERNEL); if (!fbdev->fb_mem) { diff --git a/trunk/drivers/video/au1200fb.c b/trunk/drivers/video/au1200fb.c index 7ca79f02056e..3e9a773db09f 100644 --- a/trunk/drivers/video/au1200fb.c +++ b/trunk/drivers/video/au1200fb.c @@ -1724,7 +1724,7 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev) /* Allocate the framebuffer to the maximum screen size */ fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8; - fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev, + fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev, &dev->dev, PAGE_ALIGN(fbdev->fb_len), &fbdev->fb_phys, GFP_KERNEL); if (!fbdev->fb_mem) { diff --git a/trunk/drivers/video/backlight/Kconfig b/trunk/drivers/video/backlight/Kconfig index af16884491ed..7ed9991fa747 100644 --- a/trunk/drivers/video/backlight/Kconfig +++ b/trunk/drivers/video/backlight/Kconfig @@ -245,12 +245,6 @@ config BACKLIGHT_DA903X If you have a LCD backlight connected to the WLED output of DA9030 or DA9034 WLED output, say Y here to enable this driver. -config BACKLIGHT_DA9052 - tristate "Dialog DA9052/DA9053 WLED" - depends on PMIC_DA9052 - help - Enable the Backlight Driver for DA9052-BC and DA9053-AA/Bx PMICs. - config BACKLIGHT_MAX8925 tristate "Backlight driver for MAX8925" depends on MFD_MAX8925 diff --git a/trunk/drivers/video/backlight/Makefile b/trunk/drivers/video/backlight/Makefile index 36855ae887d6..8071eb656147 100644 --- a/trunk/drivers/video/backlight/Makefile +++ b/trunk/drivers/video/backlight/Makefile @@ -29,7 +29,6 @@ obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o -obj-$(CONFIG_BACKLIGHT_DA9052) += da9052_bl.o obj-$(CONFIG_BACKLIGHT_MAX8925) += max8925_bl.o obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o diff --git a/trunk/drivers/video/backlight/da9052_bl.c b/trunk/drivers/video/backlight/da9052_bl.c deleted file mode 100644 index b628d68f5162..000000000000 --- a/trunk/drivers/video/backlight/da9052_bl.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Backlight Driver for Dialog DA9052 PMICs - * - * Copyright(c) 2012 Dialog Semiconductor Ltd. - * - * Author: David Dajun Chen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include - -#include -#include - -#define DA9052_MAX_BRIGHTNESS 0xFF - -enum { - DA9052_WLEDS_OFF, - DA9052_WLEDS_ON, -}; - -enum { - DA9052_TYPE_WLED1, - DA9052_TYPE_WLED2, - DA9052_TYPE_WLED3, -}; - -static unsigned char wled_bank[] = { - DA9052_LED1_CONF_REG, - DA9052_LED2_CONF_REG, - DA9052_LED3_CONF_REG, -}; - -struct da9052_bl { - struct da9052 *da9052; - uint brightness; - uint state; - uint led_reg; -}; - -static int da9052_adjust_wled_brightness(struct da9052_bl *wleds) -{ - unsigned char boost_en; - unsigned char i_sink; - int ret; - - boost_en = 0x3F; - i_sink = 0xFF; - if (wleds->state == DA9052_WLEDS_OFF) { - boost_en = 0x00; - i_sink = 0x00; - } - - ret = da9052_reg_write(wleds->da9052, DA9052_BOOST_REG, boost_en); - if (ret < 0) - return ret; - - ret = da9052_reg_write(wleds->da9052, DA9052_LED_CONT_REG, i_sink); - if (ret < 0) - return ret; - - ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg], 0x0); - if (ret < 0) - return ret; - - msleep(10); - - if (wleds->brightness) { - ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg], - wleds->brightness); - if (ret < 0) - return ret; - } - - return 0; -} - -static int da9052_backlight_update_status(struct backlight_device *bl) -{ - int brightness = bl->props.brightness; - struct da9052_bl *wleds = bl_get_data(bl); - - wleds->brightness = brightness; - wleds->state = DA9052_WLEDS_ON; - - return da9052_adjust_wled_brightness(wleds); -} - -static int da9052_backlight_get_brightness(struct backlight_device *bl) -{ - struct da9052_bl *wleds = bl_get_data(bl); - - return wleds->brightness; -} - -static const struct backlight_ops da9052_backlight_ops = { - .update_status = da9052_backlight_update_status, - .get_brightness = da9052_backlight_get_brightness, -}; - -static int da9052_backlight_probe(struct platform_device *pdev) -{ - struct backlight_device *bl; - struct backlight_properties props; - struct da9052_bl *wleds; - - wleds = devm_kzalloc(&pdev->dev, sizeof(struct da9052_bl), GFP_KERNEL); - if (!wleds) - return -ENOMEM; - - wleds->da9052 = dev_get_drvdata(pdev->dev.parent); - wleds->brightness = 0; - wleds->led_reg = platform_get_device_id(pdev)->driver_data; - wleds->state = DA9052_WLEDS_OFF; - - props.type = BACKLIGHT_RAW; - props.max_brightness = DA9052_MAX_BRIGHTNESS; - - bl = backlight_device_register(pdev->name, wleds->da9052->dev, wleds, - &da9052_backlight_ops, &props); - if (IS_ERR(bl)) { - dev_err(&pdev->dev, "Failed to register backlight\n"); - devm_kfree(&pdev->dev, wleds); - return PTR_ERR(bl); - } - - bl->props.max_brightness = DA9052_MAX_BRIGHTNESS; - bl->props.brightness = 0; - platform_set_drvdata(pdev, bl); - - return da9052_adjust_wled_brightness(wleds); -} - -static int da9052_backlight_remove(struct platform_device *pdev) -{ - struct backlight_device *bl = platform_get_drvdata(pdev); - struct da9052_bl *wleds = bl_get_data(bl); - - wleds->brightness = 0; - wleds->state = DA9052_WLEDS_OFF; - da9052_adjust_wled_brightness(wleds); - backlight_device_unregister(bl); - devm_kfree(&pdev->dev, wleds); - - return 0; -} - -static struct platform_device_id da9052_wled_ids[] = { - { - .name = "da9052-wled1", - .driver_data = DA9052_TYPE_WLED1, - }, - { - .name = "da9052-wled2", - .driver_data = DA9052_TYPE_WLED2, - }, - { - .name = "da9052-wled3", - .driver_data = DA9052_TYPE_WLED3, - }, -}; - -static struct platform_driver da9052_wled_driver = { - .probe = da9052_backlight_probe, - .remove = da9052_backlight_remove, - .id_table = da9052_wled_ids, - .driver = { - .name = "da9052-wled", - .owner = THIS_MODULE, - }, -}; - -module_platform_driver(da9052_wled_driver); - -MODULE_AUTHOR("David Dajun Chen "); -MODULE_DESCRIPTION("Backlight driver for DA9052 PMIC"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:da9052-backlight"); diff --git a/trunk/drivers/video/backlight/locomolcd.c b/trunk/drivers/video/backlight/locomolcd.c index 3a6d5419e3e3..be20b5cbe26c 100644 --- a/trunk/drivers/video/backlight/locomolcd.c +++ b/trunk/drivers/video/backlight/locomolcd.c @@ -229,7 +229,14 @@ static struct locomo_driver poodle_lcd_driver = { static int __init locomolcd_init(void) { - return locomo_driver_register(&poodle_lcd_driver); + int ret = locomo_driver_register(&poodle_lcd_driver); + if (ret) + return ret; + +#ifdef CONFIG_SA1100_COLLIE + sa1100fb_lcd_power = locomolcd_power; +#endif + return 0; } static void __exit locomolcd_exit(void) diff --git a/trunk/drivers/video/bfin-lq035q1-fb.c b/trunk/drivers/video/bfin-lq035q1-fb.c index 353c02fe8a95..86922ac84412 100644 --- a/trunk/drivers/video/bfin-lq035q1-fb.c +++ b/trunk/drivers/video/bfin-lq035q1-fb.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/video/kyro/STG4000Reg.h b/trunk/drivers/video/kyro/STG4000Reg.h index 50f4670e9252..5d6269882589 100644 --- a/trunk/drivers/video/kyro/STG4000Reg.h +++ b/trunk/drivers/video/kyro/STG4000Reg.h @@ -73,210 +73,210 @@ typedef enum _OVRL_PIX_FORMAT { /* Register Table */ typedef struct { /* 0h */ - volatile u32 Thread0Enable; /* 0x0000 */ - volatile u32 Thread1Enable; /* 0x0004 */ - volatile u32 Thread0Recover; /* 0x0008 */ - volatile u32 Thread1Recover; /* 0x000C */ - volatile u32 Thread0Step; /* 0x0010 */ - volatile u32 Thread1Step; /* 0x0014 */ - volatile u32 VideoInStatus; /* 0x0018 */ - volatile u32 Core2InSignStart; /* 0x001C */ - volatile u32 Core1ResetVector; /* 0x0020 */ - volatile u32 Core1ROMOffset; /* 0x0024 */ - volatile u32 Core1ArbiterPriority; /* 0x0028 */ - volatile u32 VideoInControl; /* 0x002C */ - volatile u32 VideoInReg0CtrlA; /* 0x0030 */ - volatile u32 VideoInReg0CtrlB; /* 0x0034 */ - volatile u32 VideoInReg1CtrlA; /* 0x0038 */ - volatile u32 VideoInReg1CtrlB; /* 0x003C */ - volatile u32 Thread0Kicker; /* 0x0040 */ - volatile u32 Core2InputSign; /* 0x0044 */ - volatile u32 Thread0ProgCtr; /* 0x0048 */ - volatile u32 Thread1ProgCtr; /* 0x004C */ - volatile u32 Thread1Kicker; /* 0x0050 */ - volatile u32 GPRegister1; /* 0x0054 */ - volatile u32 GPRegister2; /* 0x0058 */ - volatile u32 GPRegister3; /* 0x005C */ - volatile u32 GPRegister4; /* 0x0060 */ - volatile u32 SerialIntA; /* 0x0064 */ - - volatile u32 Fill0[6]; /* GAP 0x0068 - 0x007C */ - - volatile u32 SoftwareReset; /* 0x0080 */ - volatile u32 SerialIntB; /* 0x0084 */ - - volatile u32 Fill1[37]; /* GAP 0x0088 - 0x011C */ - - volatile u32 ROMELQV; /* 0x011C */ - volatile u32 WLWH; /* 0x0120 */ - volatile u32 ROMELWL; /* 0x0124 */ - - volatile u32 dwFill_1; /* GAP 0x0128 */ - - volatile u32 IntStatus; /* 0x012C */ - volatile u32 IntMask; /* 0x0130 */ - volatile u32 IntClear; /* 0x0134 */ - - volatile u32 Fill2[6]; /* GAP 0x0138 - 0x014C */ - - volatile u32 ROMGPIOA; /* 0x0150 */ - volatile u32 ROMGPIOB; /* 0x0154 */ - volatile u32 ROMGPIOC; /* 0x0158 */ - volatile u32 ROMGPIOD; /* 0x015C */ - - volatile u32 Fill3[2]; /* GAP 0x0160 - 0x0168 */ - - volatile u32 AGPIntID; /* 0x0168 */ - volatile u32 AGPIntClassCode; /* 0x016C */ - volatile u32 AGPIntBIST; /* 0x0170 */ - volatile u32 AGPIntSSID; /* 0x0174 */ - volatile u32 AGPIntPMCSR; /* 0x0178 */ - volatile u32 VGAFrameBufBase; /* 0x017C */ - volatile u32 VGANotify; /* 0x0180 */ - volatile u32 DACPLLMode; /* 0x0184 */ - volatile u32 Core1VideoClockDiv; /* 0x0188 */ - volatile u32 AGPIntStat; /* 0x018C */ + volatile unsigned long Thread0Enable; /* 0x0000 */ + volatile unsigned long Thread1Enable; /* 0x0004 */ + volatile unsigned long Thread0Recover; /* 0x0008 */ + volatile unsigned long Thread1Recover; /* 0x000C */ + volatile unsigned long Thread0Step; /* 0x0010 */ + volatile unsigned long Thread1Step; /* 0x0014 */ + volatile unsigned long VideoInStatus; /* 0x0018 */ + volatile unsigned long Core2InSignStart; /* 0x001C */ + volatile unsigned long Core1ResetVector; /* 0x0020 */ + volatile unsigned long Core1ROMOffset; /* 0x0024 */ + volatile unsigned long Core1ArbiterPriority; /* 0x0028 */ + volatile unsigned long VideoInControl; /* 0x002C */ + volatile unsigned long VideoInReg0CtrlA; /* 0x0030 */ + volatile unsigned long VideoInReg0CtrlB; /* 0x0034 */ + volatile unsigned long VideoInReg1CtrlA; /* 0x0038 */ + volatile unsigned long VideoInReg1CtrlB; /* 0x003C */ + volatile unsigned long Thread0Kicker; /* 0x0040 */ + volatile unsigned long Core2InputSign; /* 0x0044 */ + volatile unsigned long Thread0ProgCtr; /* 0x0048 */ + volatile unsigned long Thread1ProgCtr; /* 0x004C */ + volatile unsigned long Thread1Kicker; /* 0x0050 */ + volatile unsigned long GPRegister1; /* 0x0054 */ + volatile unsigned long GPRegister2; /* 0x0058 */ + volatile unsigned long GPRegister3; /* 0x005C */ + volatile unsigned long GPRegister4; /* 0x0060 */ + volatile unsigned long SerialIntA; /* 0x0064 */ + + volatile unsigned long Fill0[6]; /* GAP 0x0068 - 0x007C */ + + volatile unsigned long SoftwareReset; /* 0x0080 */ + volatile unsigned long SerialIntB; /* 0x0084 */ + + volatile unsigned long Fill1[37]; /* GAP 0x0088 - 0x011C */ + + volatile unsigned long ROMELQV; /* 0x011C */ + volatile unsigned long WLWH; /* 0x0120 */ + volatile unsigned long ROMELWL; /* 0x0124 */ + + volatile unsigned long dwFill_1; /* GAP 0x0128 */ + + volatile unsigned long IntStatus; /* 0x012C */ + volatile unsigned long IntMask; /* 0x0130 */ + volatile unsigned long IntClear; /* 0x0134 */ + + volatile unsigned long Fill2[6]; /* GAP 0x0138 - 0x014C */ + + volatile unsigned long ROMGPIOA; /* 0x0150 */ + volatile unsigned long ROMGPIOB; /* 0x0154 */ + volatile unsigned long ROMGPIOC; /* 0x0158 */ + volatile unsigned long ROMGPIOD; /* 0x015C */ + + volatile unsigned long Fill3[2]; /* GAP 0x0160 - 0x0168 */ + + volatile unsigned long AGPIntID; /* 0x0168 */ + volatile unsigned long AGPIntClassCode; /* 0x016C */ + volatile unsigned long AGPIntBIST; /* 0x0170 */ + volatile unsigned long AGPIntSSID; /* 0x0174 */ + volatile unsigned long AGPIntPMCSR; /* 0x0178 */ + volatile unsigned long VGAFrameBufBase; /* 0x017C */ + volatile unsigned long VGANotify; /* 0x0180 */ + volatile unsigned long DACPLLMode; /* 0x0184 */ + volatile unsigned long Core1VideoClockDiv; /* 0x0188 */ + volatile unsigned long AGPIntStat; /* 0x018C */ /* - volatile u32 Fill4[0x0400/4 - 0x0190/4]; //GAP 0x0190 - 0x0400 - volatile u32 Fill5[0x05FC/4 - 0x0400/4]; //GAP 0x0400 - 0x05FC Fog Table - volatile u32 Fill6[0x0604/4 - 0x0600/4]; //GAP 0x0600 - 0x0604 - volatile u32 Fill7[0x0680/4 - 0x0608/4]; //GAP 0x0608 - 0x0680 - volatile u32 Fill8[0x07FC/4 - 0x0684/4]; //GAP 0x0684 - 0x07FC + volatile unsigned long Fill4[0x0400/4 - 0x0190/4]; //GAP 0x0190 - 0x0400 + volatile unsigned long Fill5[0x05FC/4 - 0x0400/4]; //GAP 0x0400 - 0x05FC Fog Table + volatile unsigned long Fill6[0x0604/4 - 0x0600/4]; //GAP 0x0600 - 0x0604 + volatile unsigned long Fill7[0x0680/4 - 0x0608/4]; //GAP 0x0608 - 0x0680 + volatile unsigned long Fill8[0x07FC/4 - 0x0684/4]; //GAP 0x0684 - 0x07FC */ - volatile u32 Fill4[412]; /* 0x0190 - 0x07FC */ - - volatile u32 TACtrlStreamBase; /* 0x0800 */ - volatile u32 TAObjDataBase; /* 0x0804 */ - volatile u32 TAPtrDataBase; /* 0x0808 */ - volatile u32 TARegionDataBase; /* 0x080C */ - volatile u32 TATailPtrBase; /* 0x0810 */ - volatile u32 TAPtrRegionSize; /* 0x0814 */ - volatile u32 TAConfiguration; /* 0x0818 */ - volatile u32 TAObjDataStartAddr; /* 0x081C */ - volatile u32 TAObjDataEndAddr; /* 0x0820 */ - volatile u32 TAXScreenClip; /* 0x0824 */ - volatile u32 TAYScreenClip; /* 0x0828 */ - volatile u32 TARHWClamp; /* 0x082C */ - volatile u32 TARHWCompare; /* 0x0830 */ - volatile u32 TAStart; /* 0x0834 */ - volatile u32 TAObjReStart; /* 0x0838 */ - volatile u32 TAPtrReStart; /* 0x083C */ - volatile u32 TAStatus1; /* 0x0840 */ - volatile u32 TAStatus2; /* 0x0844 */ - volatile u32 TAIntStatus; /* 0x0848 */ - volatile u32 TAIntMask; /* 0x084C */ - - volatile u32 Fill5[235]; /* GAP 0x0850 - 0x0BF8 */ - - volatile u32 TextureAddrThresh; /* 0x0BFC */ - volatile u32 Core1Translation; /* 0x0C00 */ - volatile u32 TextureAddrReMap; /* 0x0C04 */ - volatile u32 RenderOutAGPRemap; /* 0x0C08 */ - volatile u32 _3DRegionReadTrans; /* 0x0C0C */ - volatile u32 _3DPtrReadTrans; /* 0x0C10 */ - volatile u32 _3DParamReadTrans; /* 0x0C14 */ - volatile u32 _3DRegionReadThresh; /* 0x0C18 */ - volatile u32 _3DPtrReadThresh; /* 0x0C1C */ - volatile u32 _3DParamReadThresh; /* 0x0C20 */ - volatile u32 _3DRegionReadAGPRemap; /* 0x0C24 */ - volatile u32 _3DPtrReadAGPRemap; /* 0x0C28 */ - volatile u32 _3DParamReadAGPRemap; /* 0x0C2C */ - volatile u32 ZBufferAGPRemap; /* 0x0C30 */ - volatile u32 TAIndexAGPRemap; /* 0x0C34 */ - volatile u32 TAVertexAGPRemap; /* 0x0C38 */ - volatile u32 TAUVAddrTrans; /* 0x0C3C */ - volatile u32 TATailPtrCacheTrans; /* 0x0C40 */ - volatile u32 TAParamWriteTrans; /* 0x0C44 */ - volatile u32 TAPtrWriteTrans; /* 0x0C48 */ - volatile u32 TAParamWriteThresh; /* 0x0C4C */ - volatile u32 TAPtrWriteThresh; /* 0x0C50 */ - volatile u32 TATailPtrCacheAGPRe; /* 0x0C54 */ - volatile u32 TAParamWriteAGPRe; /* 0x0C58 */ - volatile u32 TAPtrWriteAGPRe; /* 0x0C5C */ - volatile u32 SDRAMArbiterConf; /* 0x0C60 */ - volatile u32 SDRAMConf0; /* 0x0C64 */ - volatile u32 SDRAMConf1; /* 0x0C68 */ - volatile u32 SDRAMConf2; /* 0x0C6C */ - volatile u32 SDRAMRefresh; /* 0x0C70 */ - volatile u32 SDRAMPowerStat; /* 0x0C74 */ - - volatile u32 Fill6[2]; /* GAP 0x0C78 - 0x0C7C */ - - volatile u32 RAMBistData; /* 0x0C80 */ - volatile u32 RAMBistCtrl; /* 0x0C84 */ - volatile u32 FIFOBistKey; /* 0x0C88 */ - volatile u32 RAMBistResult; /* 0x0C8C */ - volatile u32 FIFOBistResult; /* 0x0C90 */ + volatile unsigned long Fill4[412]; /* 0x0190 - 0x07FC */ + + volatile unsigned long TACtrlStreamBase; /* 0x0800 */ + volatile unsigned long TAObjDataBase; /* 0x0804 */ + volatile unsigned long TAPtrDataBase; /* 0x0808 */ + volatile unsigned long TARegionDataBase; /* 0x080C */ + volatile unsigned long TATailPtrBase; /* 0x0810 */ + volatile unsigned long TAPtrRegionSize; /* 0x0814 */ + volatile unsigned long TAConfiguration; /* 0x0818 */ + volatile unsigned long TAObjDataStartAddr; /* 0x081C */ + volatile unsigned long TAObjDataEndAddr; /* 0x0820 */ + volatile unsigned long TAXScreenClip; /* 0x0824 */ + volatile unsigned long TAYScreenClip; /* 0x0828 */ + volatile unsigned long TARHWClamp; /* 0x082C */ + volatile unsigned long TARHWCompare; /* 0x0830 */ + volatile unsigned long TAStart; /* 0x0834 */ + volatile unsigned long TAObjReStart; /* 0x0838 */ + volatile unsigned long TAPtrReStart; /* 0x083C */ + volatile unsigned long TAStatus1; /* 0x0840 */ + volatile unsigned long TAStatus2; /* 0x0844 */ + volatile unsigned long TAIntStatus; /* 0x0848 */ + volatile unsigned long TAIntMask; /* 0x084C */ + + volatile unsigned long Fill5[235]; /* GAP 0x0850 - 0x0BF8 */ + + volatile unsigned long TextureAddrThresh; /* 0x0BFC */ + volatile unsigned long Core1Translation; /* 0x0C00 */ + volatile unsigned long TextureAddrReMap; /* 0x0C04 */ + volatile unsigned long RenderOutAGPRemap; /* 0x0C08 */ + volatile unsigned long _3DRegionReadTrans; /* 0x0C0C */ + volatile unsigned long _3DPtrReadTrans; /* 0x0C10 */ + volatile unsigned long _3DParamReadTrans; /* 0x0C14 */ + volatile unsigned long _3DRegionReadThresh; /* 0x0C18 */ + volatile unsigned long _3DPtrReadThresh; /* 0x0C1C */ + volatile unsigned long _3DParamReadThresh; /* 0x0C20 */ + volatile unsigned long _3DRegionReadAGPRemap; /* 0x0C24 */ + volatile unsigned long _3DPtrReadAGPRemap; /* 0x0C28 */ + volatile unsigned long _3DParamReadAGPRemap; /* 0x0C2C */ + volatile unsigned long ZBufferAGPRemap; /* 0x0C30 */ + volatile unsigned long TAIndexAGPRemap; /* 0x0C34 */ + volatile unsigned long TAVertexAGPRemap; /* 0x0C38 */ + volatile unsigned long TAUVAddrTrans; /* 0x0C3C */ + volatile unsigned long TATailPtrCacheTrans; /* 0x0C40 */ + volatile unsigned long TAParamWriteTrans; /* 0x0C44 */ + volatile unsigned long TAPtrWriteTrans; /* 0x0C48 */ + volatile unsigned long TAParamWriteThresh; /* 0x0C4C */ + volatile unsigned long TAPtrWriteThresh; /* 0x0C50 */ + volatile unsigned long TATailPtrCacheAGPRe; /* 0x0C54 */ + volatile unsigned long TAParamWriteAGPRe; /* 0x0C58 */ + volatile unsigned long TAPtrWriteAGPRe; /* 0x0C5C */ + volatile unsigned long SDRAMArbiterConf; /* 0x0C60 */ + volatile unsigned long SDRAMConf0; /* 0x0C64 */ + volatile unsigned long SDRAMConf1; /* 0x0C68 */ + volatile unsigned long SDRAMConf2; /* 0x0C6C */ + volatile unsigned long SDRAMRefresh; /* 0x0C70 */ + volatile unsigned long SDRAMPowerStat; /* 0x0C74 */ + + volatile unsigned long Fill6[2]; /* GAP 0x0C78 - 0x0C7C */ + + volatile unsigned long RAMBistData; /* 0x0C80 */ + volatile unsigned long RAMBistCtrl; /* 0x0C84 */ + volatile unsigned long FIFOBistKey; /* 0x0C88 */ + volatile unsigned long RAMBistResult; /* 0x0C8C */ + volatile unsigned long FIFOBistResult; /* 0x0C90 */ /* - volatile u32 Fill11[0x0CBC/4 - 0x0C94/4]; //GAP 0x0C94 - 0x0CBC - volatile u32 Fill12[0x0CD0/4 - 0x0CC0/4]; //GAP 0x0CC0 - 0x0CD0 3DRegisters + volatile unsigned long Fill11[0x0CBC/4 - 0x0C94/4]; //GAP 0x0C94 - 0x0CBC + volatile unsigned long Fill12[0x0CD0/4 - 0x0CC0/4]; //GAP 0x0CC0 - 0x0CD0 3DRegisters */ - volatile u32 Fill7[16]; /* 0x0c94 - 0x0cd0 */ + volatile unsigned long Fill7[16]; /* 0x0c94 - 0x0cd0 */ - volatile u32 SDRAMAddrSign; /* 0x0CD4 */ - volatile u32 SDRAMDataSign; /* 0x0CD8 */ - volatile u32 SDRAMSignConf; /* 0x0CDC */ + volatile unsigned long SDRAMAddrSign; /* 0x0CD4 */ + volatile unsigned long SDRAMDataSign; /* 0x0CD8 */ + volatile unsigned long SDRAMSignConf; /* 0x0CDC */ /* DWFILL; //GAP 0x0CE0 */ - volatile u32 dwFill_2; - - volatile u32 ISPSignature; /* 0x0CE4 */ - - volatile u32 Fill8[454]; /*GAP 0x0CE8 - 0x13FC */ - - volatile u32 DACPrimAddress; /* 0x1400 */ - volatile u32 DACPrimSize; /* 0x1404 */ - volatile u32 DACCursorAddr; /* 0x1408 */ - volatile u32 DACCursorCtrl; /* 0x140C */ - volatile u32 DACOverlayAddr; /* 0x1410 */ - volatile u32 DACOverlayUAddr; /* 0x1414 */ - volatile u32 DACOverlayVAddr; /* 0x1418 */ - volatile u32 DACOverlaySize; /* 0x141C */ - volatile u32 DACOverlayVtDec; /* 0x1420 */ - - volatile u32 Fill9[9]; /* GAP 0x1424 - 0x1444 */ - - volatile u32 DACVerticalScal; /* 0x1448 */ - volatile u32 DACPixelFormat; /* 0x144C */ - volatile u32 DACHorizontalScal; /* 0x1450 */ - volatile u32 DACVidWinStart; /* 0x1454 */ - volatile u32 DACVidWinEnd; /* 0x1458 */ - volatile u32 DACBlendCtrl; /* 0x145C */ - volatile u32 DACHorTim1; /* 0x1460 */ - volatile u32 DACHorTim2; /* 0x1464 */ - volatile u32 DACHorTim3; /* 0x1468 */ - volatile u32 DACVerTim1; /* 0x146C */ - volatile u32 DACVerTim2; /* 0x1470 */ - volatile u32 DACVerTim3; /* 0x1474 */ - volatile u32 DACBorderColor; /* 0x1478 */ - volatile u32 DACSyncCtrl; /* 0x147C */ - volatile u32 DACStreamCtrl; /* 0x1480 */ - volatile u32 DACLUTAddress; /* 0x1484 */ - volatile u32 DACLUTData; /* 0x1488 */ - volatile u32 DACBurstCtrl; /* 0x148C */ - volatile u32 DACCrcTrigger; /* 0x1490 */ - volatile u32 DACCrcDone; /* 0x1494 */ - volatile u32 DACCrcResult1; /* 0x1498 */ - volatile u32 DACCrcResult2; /* 0x149C */ - volatile u32 DACLinecount; /* 0x14A0 */ - - volatile u32 Fill10[151]; /*GAP 0x14A4 - 0x16FC */ - - volatile u32 DigVidPortCtrl; /* 0x1700 */ - volatile u32 DigVidPortStat; /* 0x1704 */ + volatile unsigned long dwFill_2; + + volatile unsigned long ISPSignature; /* 0x0CE4 */ + + volatile unsigned long Fill8[454]; /*GAP 0x0CE8 - 0x13FC */ + + volatile unsigned long DACPrimAddress; /* 0x1400 */ + volatile unsigned long DACPrimSize; /* 0x1404 */ + volatile unsigned long DACCursorAddr; /* 0x1408 */ + volatile unsigned long DACCursorCtrl; /* 0x140C */ + volatile unsigned long DACOverlayAddr; /* 0x1410 */ + volatile unsigned long DACOverlayUAddr; /* 0x1414 */ + volatile unsigned long DACOverlayVAddr; /* 0x1418 */ + volatile unsigned long DACOverlaySize; /* 0x141C */ + volatile unsigned long DACOverlayVtDec; /* 0x1420 */ + + volatile unsigned long Fill9[9]; /* GAP 0x1424 - 0x1444 */ + + volatile unsigned long DACVerticalScal; /* 0x1448 */ + volatile unsigned long DACPixelFormat; /* 0x144C */ + volatile unsigned long DACHorizontalScal; /* 0x1450 */ + volatile unsigned long DACVidWinStart; /* 0x1454 */ + volatile unsigned long DACVidWinEnd; /* 0x1458 */ + volatile unsigned long DACBlendCtrl; /* 0x145C */ + volatile unsigned long DACHorTim1; /* 0x1460 */ + volatile unsigned long DACHorTim2; /* 0x1464 */ + volatile unsigned long DACHorTim3; /* 0x1468 */ + volatile unsigned long DACVerTim1; /* 0x146C */ + volatile unsigned long DACVerTim2; /* 0x1470 */ + volatile unsigned long DACVerTim3; /* 0x1474 */ + volatile unsigned long DACBorderColor; /* 0x1478 */ + volatile unsigned long DACSyncCtrl; /* 0x147C */ + volatile unsigned long DACStreamCtrl; /* 0x1480 */ + volatile unsigned long DACLUTAddress; /* 0x1484 */ + volatile unsigned long DACLUTData; /* 0x1488 */ + volatile unsigned long DACBurstCtrl; /* 0x148C */ + volatile unsigned long DACCrcTrigger; /* 0x1490 */ + volatile unsigned long DACCrcDone; /* 0x1494 */ + volatile unsigned long DACCrcResult1; /* 0x1498 */ + volatile unsigned long DACCrcResult2; /* 0x149C */ + volatile unsigned long DACLinecount; /* 0x14A0 */ + + volatile unsigned long Fill10[151]; /*GAP 0x14A4 - 0x16FC */ + + volatile unsigned long DigVidPortCtrl; /* 0x1700 */ + volatile unsigned long DigVidPortStat; /* 0x1704 */ /* - volatile u32 Fill11[0x1FFC/4 - 0x1708/4]; //GAP 0x1708 - 0x1FFC - volatile u32 Fill17[0x3000/4 - 0x2FFC/4]; //GAP 0x2000 - 0x2FFC ALUT + volatile unsigned long Fill11[0x1FFC/4 - 0x1708/4]; //GAP 0x1708 - 0x1FFC + volatile unsigned long Fill17[0x3000/4 - 0x2FFC/4]; //GAP 0x2000 - 0x2FFC ALUT */ - volatile u32 Fill11[1598]; + volatile unsigned long Fill11[1598]; /* DWFILL; //GAP 0x3000 ALUT 256MB offset */ - volatile u32 Fill_3; + volatile unsigned long Fill_3; } STG4000REG; diff --git a/trunk/drivers/video/msm/mddi.c b/trunk/drivers/video/msm/mddi.c index b061d709bc44..4527cbf0a4ec 100644 --- a/trunk/drivers/video/msm/mddi.c +++ b/trunk/drivers/video/msm/mddi.c @@ -420,7 +420,7 @@ static void mddi_resume(struct msm_mddi_client_data *cdata) mddi_set_auto_hibernate(&mddi->client_data, 1); } -static int __devinit mddi_get_client_caps(struct mddi_info *mddi) +static int __init mddi_get_client_caps(struct mddi_info *mddi) { int i, j; @@ -622,9 +622,9 @@ uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg) static struct mddi_info mddi_info[2]; -static int __devinit mddi_clk_setup(struct platform_device *pdev, - struct mddi_info *mddi, - unsigned long clk_rate) +static int __init mddi_clk_setup(struct platform_device *pdev, + struct mddi_info *mddi, + unsigned long clk_rate) { int ret; diff --git a/trunk/drivers/video/uvesafb.c b/trunk/drivers/video/uvesafb.c index 26e83d7fdd6f..260cca7ddb41 100644 --- a/trunk/drivers/video/uvesafb.c +++ b/trunk/drivers/video/uvesafb.c @@ -815,15 +815,8 @@ static int __devinit uvesafb_vbe_init(struct fb_info *info) par->pmi_setpal = pmi_setpal; par->ypan = ypan; - if (par->pmi_setpal || par->ypan) { - if (__supported_pte_mask & _PAGE_NX) { - par->pmi_setpal = par->ypan = 0; - printk(KERN_WARNING "uvesafb: NX protection is actively." - "We have better not to use the PMI.\n"); - } else { - uvesafb_vbe_getpmi(task, par); - } - } + if (par->pmi_setpal || par->ypan) + uvesafb_vbe_getpmi(task, par); #else /* The protected mode interface is not available on non-x86. */ par->pmi_setpal = par->ypan = 0; diff --git a/trunk/drivers/virtio/virtio_balloon.c b/trunk/drivers/virtio/virtio_balloon.c index c2d05a8279fd..958e5129c601 100644 --- a/trunk/drivers/virtio/virtio_balloon.c +++ b/trunk/drivers/virtio/virtio_balloon.c @@ -28,13 +28,6 @@ #include #include -/* - * Balloon device works in 4K page units. So each page is pointed to by - * multiple balloon pages. All memory counters in this driver are in balloon - * page units. - */ -#define VIRTIO_BALLOON_PAGES_PER_PAGE (PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT) - struct virtio_balloon { struct virtio_device *vdev; @@ -49,13 +42,8 @@ struct virtio_balloon /* Waiting for host to ack the pages we released. */ struct completion acked; - /* Number of balloon pages we've told the Host we're not using. */ + /* The pages we've told the Host we're not using. */ unsigned int num_pages; - /* - * The pages we've told the Host we're not using. - * Each page on this list adds VIRTIO_BALLOON_PAGES_PER_PAGE - * to num_pages above. - */ struct list_head pages; /* The array of pfns we tell the Host about. */ @@ -78,13 +66,7 @@ static u32 page_to_balloon_pfn(struct page *page) BUILD_BUG_ON(PAGE_SHIFT < VIRTIO_BALLOON_PFN_SHIFT); /* Convert pfn from Linux page size to balloon page size. */ - return pfn * VIRTIO_BALLOON_PAGES_PER_PAGE; -} - -static struct page *balloon_pfn_to_page(u32 pfn) -{ - BUG_ON(pfn % VIRTIO_BALLOON_PAGES_PER_PAGE); - return pfn_to_page(pfn / VIRTIO_BALLOON_PAGES_PER_PAGE); + return pfn >> (PAGE_SHIFT - VIRTIO_BALLOON_PFN_SHIFT); } static void balloon_ack(struct virtqueue *vq) @@ -114,23 +96,12 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq) wait_for_completion(&vb->acked); } -static void set_page_pfns(u32 pfns[], struct page *page) -{ - unsigned int i; - - /* Set balloon pfns pointing at this page. - * Note that the first pfn points at start of the page. */ - for (i = 0; i < VIRTIO_BALLOON_PAGES_PER_PAGE; i++) - pfns[i] = page_to_balloon_pfn(page) + i; -} - static void fill_balloon(struct virtio_balloon *vb, size_t num) { /* We can only do one array worth at a time. */ num = min(num, ARRAY_SIZE(vb->pfns)); - for (vb->num_pfns = 0; vb->num_pfns < num; - vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) { + for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) { struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); if (!page) { @@ -142,9 +113,9 @@ static void fill_balloon(struct virtio_balloon *vb, size_t num) msleep(200); break; } - set_page_pfns(vb->pfns + vb->num_pfns, page); - vb->num_pages += VIRTIO_BALLOON_PAGES_PER_PAGE; + vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page); totalram_pages--; + vb->num_pages++; list_add(&page->lru, &vb->pages); } @@ -159,9 +130,8 @@ static void release_pages_by_pfn(const u32 pfns[], unsigned int num) { unsigned int i; - /* Find pfns pointing at start of each page, get pages and free them. */ - for (i = 0; i < num; i += VIRTIO_BALLOON_PAGES_PER_PAGE) { - __free_page(balloon_pfn_to_page(pfns[i])); + for (i = 0; i < num; i++) { + __free_page(pfn_to_page(pfns[i])); totalram_pages++; } } @@ -173,12 +143,11 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num) /* We can only do one array worth at a time. */ num = min(num, ARRAY_SIZE(vb->pfns)); - for (vb->num_pfns = 0; vb->num_pfns < num; - vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) { + for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) { page = list_first_entry(&vb->pages, struct page, lru); list_del(&page->lru); - set_page_pfns(vb->pfns + vb->num_pfns, page); - vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE; + vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page); + vb->num_pages--; } /* @@ -265,14 +234,11 @@ static void virtballoon_changed(struct virtio_device *vdev) static inline s64 towards_target(struct virtio_balloon *vb) { - __le32 v; - s64 target; - + u32 v; vb->vdev->config->get(vb->vdev, offsetof(struct virtio_balloon_config, num_pages), &v, sizeof(v)); - target = le32_to_cpu(v); - return target - vb->num_pages; + return (s64)v - vb->num_pages; } static void update_balloon_size(struct virtio_balloon *vb) @@ -432,8 +398,21 @@ static int restore_common(struct virtio_device *vdev) return 0; } +static int virtballoon_thaw(struct virtio_device *vdev) +{ + return restore_common(vdev); +} + static int virtballoon_restore(struct virtio_device *vdev) { + struct virtio_balloon *vb = vdev->priv; + + /* + * If a request wasn't complete at the time of freezing, this + * could have been set. + */ + vb->need_stats_update = 0; + return restore_common(vdev); } #endif @@ -455,6 +434,7 @@ static struct virtio_driver virtio_balloon_driver = { #ifdef CONFIG_PM .freeze = virtballoon_freeze, .restore = virtballoon_restore, + .thaw = virtballoon_thaw, #endif }; diff --git a/trunk/drivers/virtio/virtio_pci.c b/trunk/drivers/virtio/virtio_pci.c index 2e03d416b9af..635e1efb3792 100644 --- a/trunk/drivers/virtio/virtio_pci.c +++ b/trunk/drivers/virtio/virtio_pci.c @@ -720,6 +720,24 @@ static void __devexit virtio_pci_remove(struct pci_dev *pci_dev) } #ifdef CONFIG_PM +static int virtio_pci_suspend(struct device *dev) +{ + struct pci_dev *pci_dev = to_pci_dev(dev); + + pci_save_state(pci_dev); + pci_set_power_state(pci_dev, PCI_D3hot); + return 0; +} + +static int virtio_pci_resume(struct device *dev) +{ + struct pci_dev *pci_dev = to_pci_dev(dev); + + pci_restore_state(pci_dev); + pci_set_power_state(pci_dev, PCI_D0); + return 0; +} + static int virtio_pci_freeze(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); @@ -740,24 +758,59 @@ static int virtio_pci_freeze(struct device *dev) return ret; } -static int virtio_pci_restore(struct device *dev) +static int restore_common(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); - struct virtio_driver *drv; int ret; - drv = container_of(vp_dev->vdev.dev.driver, - struct virtio_driver, driver); - ret = pci_enable_device(pci_dev); if (ret) return ret; - pci_set_master(pci_dev); vp_finalize_features(&vp_dev->vdev); - if (drv && drv->restore) + return ret; +} + +static int virtio_pci_thaw(struct device *dev) +{ + struct pci_dev *pci_dev = to_pci_dev(dev); + struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); + struct virtio_driver *drv; + int ret; + + ret = restore_common(dev); + if (ret) + return ret; + + drv = container_of(vp_dev->vdev.dev.driver, + struct virtio_driver, driver); + + if (drv && drv->thaw) + ret = drv->thaw(&vp_dev->vdev); + else if (drv && drv->restore) + ret = drv->restore(&vp_dev->vdev); + + /* Finally, tell the device we're all set */ + if (!ret) + vp_set_status(&vp_dev->vdev, vp_dev->saved_status); + + return ret; +} + +static int virtio_pci_restore(struct device *dev) +{ + struct pci_dev *pci_dev = to_pci_dev(dev); + struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); + struct virtio_driver *drv; + int ret; + + drv = container_of(vp_dev->vdev.dev.driver, + struct virtio_driver, driver); + + ret = restore_common(dev); + if (!ret && drv && drv->restore) ret = drv->restore(&vp_dev->vdev); /* Finally, tell the device we're all set */ @@ -768,7 +821,12 @@ static int virtio_pci_restore(struct device *dev) } static const struct dev_pm_ops virtio_pci_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(virtio_pci_freeze, virtio_pci_restore) + .suspend = virtio_pci_suspend, + .resume = virtio_pci_resume, + .freeze = virtio_pci_freeze, + .thaw = virtio_pci_thaw, + .restore = virtio_pci_restore, + .poweroff = virtio_pci_suspend, }; #endif diff --git a/trunk/drivers/watchdog/hpwdt.c b/trunk/drivers/watchdog/hpwdt.c index 9f13b897fd64..cbc7ceef2786 100644 --- a/trunk/drivers/watchdog/hpwdt.c +++ b/trunk/drivers/watchdog/hpwdt.c @@ -435,16 +435,16 @@ static void hpwdt_start(void) { reload = SECS_TO_TICKS(soft_margin); iowrite16(reload, hpwdt_timer_reg); - iowrite8(0x85, hpwdt_timer_con); + iowrite16(0x85, hpwdt_timer_con); } static void hpwdt_stop(void) { unsigned long data; - data = ioread8(hpwdt_timer_con); + data = ioread16(hpwdt_timer_con); data &= 0xFE; - iowrite8(data, hpwdt_timer_con); + iowrite16(data, hpwdt_timer_con); } static void hpwdt_ping(void) diff --git a/trunk/drivers/xen/events.c b/trunk/drivers/xen/events.c index 0a8a17cd80be..4b33acd8ed4e 100644 --- a/trunk/drivers/xen/events.c +++ b/trunk/drivers/xen/events.c @@ -274,7 +274,7 @@ static unsigned int cpu_from_evtchn(unsigned int evtchn) static bool pirq_check_eoi_map(unsigned irq) { - return test_bit(pirq_from_irq(irq), pirq_eoi_map); + return test_bit(irq, pirq_eoi_map); } static bool pirq_needs_eoi_flag(unsigned irq) diff --git a/trunk/drivers/xen/gntdev.c b/trunk/drivers/xen/gntdev.c index 1ffd03bf8e10..99d8151c824a 100644 --- a/trunk/drivers/xen/gntdev.c +++ b/trunk/drivers/xen/gntdev.c @@ -722,7 +722,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND; if (use_ptemod) - vma->vm_flags |= VM_DONTCOPY; + vma->vm_flags |= VM_DONTCOPY|VM_PFNMAP; vma->vm_private_data = map; diff --git a/trunk/drivers/xen/grant-table.c b/trunk/drivers/xen/grant-table.c index f100ce20b16b..b4d4eac761db 100644 --- a/trunk/drivers/xen/grant-table.c +++ b/trunk/drivers/xen/grant-table.c @@ -1029,7 +1029,6 @@ int gnttab_init(void) int i; unsigned int max_nr_glist_frames, nr_glist_frames; unsigned int nr_init_grefs; - int ret; nr_grant_frames = 1; boot_max_nr_grant_frames = __max_nr_grant_frames(); @@ -1048,16 +1047,12 @@ int gnttab_init(void) nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP; for (i = 0; i < nr_glist_frames; i++) { gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL); - if (gnttab_list[i] == NULL) { - ret = -ENOMEM; + if (gnttab_list[i] == NULL) goto ini_nomem; - } } - if (gnttab_resume() < 0) { - ret = -ENODEV; - goto ini_nomem; - } + if (gnttab_resume() < 0) + return -ENODEV; nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME; @@ -1075,7 +1070,7 @@ int gnttab_init(void) for (i--; i >= 0; i--) free_page((unsigned long)gnttab_list[i]); kfree(gnttab_list); - return ret; + return -ENOMEM; } EXPORT_SYMBOL_GPL(gnttab_init); diff --git a/trunk/drivers/xen/manage.c b/trunk/drivers/xen/manage.c index 412b96cc5305..9e14ae6cd49c 100644 --- a/trunk/drivers/xen/manage.c +++ b/trunk/drivers/xen/manage.c @@ -132,7 +132,6 @@ static void do_suspend(void) err = dpm_suspend_end(PMSG_FREEZE); if (err) { printk(KERN_ERR "dpm_suspend_end failed: %d\n", err); - si.cancelled = 0; goto out_resume; } diff --git a/trunk/drivers/xen/swiotlb-xen.c b/trunk/drivers/xen/swiotlb-xen.c index 1afb4fba11b4..19e6a2041371 100644 --- a/trunk/drivers/xen/swiotlb-xen.c +++ b/trunk/drivers/xen/swiotlb-xen.c @@ -204,8 +204,7 @@ void __init xen_swiotlb_init(int verbose) void * xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size, - dma_addr_t *dma_handle, gfp_t flags, - struct dma_attrs *attrs) + dma_addr_t *dma_handle, gfp_t flags) { void *ret; int order = get_order(size); @@ -254,7 +253,7 @@ EXPORT_SYMBOL_GPL(xen_swiotlb_alloc_coherent); void xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, - dma_addr_t dev_addr, struct dma_attrs *attrs) + dma_addr_t dev_addr) { int order = get_order(size); phys_addr_t phys; diff --git a/trunk/drivers/xen/xen-acpi-processor.c b/trunk/drivers/xen/xen-acpi-processor.c index 0b48579a9cd6..174b5653cd8a 100644 --- a/trunk/drivers/xen/xen-acpi-processor.c +++ b/trunk/drivers/xen/xen-acpi-processor.c @@ -128,10 +128,7 @@ static int push_cxx_to_hypervisor(struct acpi_processor *_pr) pr_debug(" C%d: %s %d uS\n", cx->type, cx->desc, (u32)cx->latency); } - } else if (ret != -EINVAL) - /* EINVAL means the ACPI ID is incorrect - meaning the ACPI - * table is referencing a non-existing CPU - which can happen - * with broken ACPI tables. */ + } else pr_err(DRV_NAME "(CX): Hypervisor error (%d) for ACPI CPU%u\n", ret, _pr->acpi_id); diff --git a/trunk/drivers/xen/xen-pciback/pciback_ops.c b/trunk/drivers/xen/xen-pciback/pciback_ops.c index 97f5d264c31e..63616d7453e6 100644 --- a/trunk/drivers/xen/xen-pciback/pciback_ops.c +++ b/trunk/drivers/xen/xen-pciback/pciback_ops.c @@ -234,7 +234,7 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev, if (dev_data) dev_data->ack_intr = 0; - return result > 0 ? 0 : result; + return result; } static diff --git a/trunk/drivers/xen/xenbus/xenbus_probe_frontend.c b/trunk/drivers/xen/xenbus/xenbus_probe_frontend.c index a31b54d48839..f20c5f178b40 100644 --- a/trunk/drivers/xen/xenbus/xenbus_probe_frontend.c +++ b/trunk/drivers/xen/xenbus/xenbus_probe_frontend.c @@ -135,7 +135,7 @@ static int read_backend_details(struct xenbus_device *xendev) return xenbus_read_otherend_details(xendev, "backend-id", "backend"); } -static int is_device_connecting(struct device *dev, void *data, bool ignore_nonessential) +static int is_device_connecting(struct device *dev, void *data) { struct xenbus_device *xendev = to_xenbus_device(dev); struct device_driver *drv = data; @@ -152,41 +152,16 @@ static int is_device_connecting(struct device *dev, void *data, bool ignore_none if (drv && (dev->driver != drv)) return 0; - if (ignore_nonessential) { - /* With older QEMU, for PVonHVM guests the guest config files - * could contain: vfb = [ 'vnc=1, vnclisten=0.0.0.0'] - * which is nonsensical as there is no PV FB (there can be - * a PVKB) running as HVM guest. */ - - if ((strncmp(xendev->nodename, "device/vkbd", 11) == 0)) - return 0; - - if ((strncmp(xendev->nodename, "device/vfb", 10) == 0)) - return 0; - } xendrv = to_xenbus_driver(dev->driver); return (xendev->state < XenbusStateConnected || (xendev->state == XenbusStateConnected && xendrv->is_ready && !xendrv->is_ready(xendev))); } -static int essential_device_connecting(struct device *dev, void *data) -{ - return is_device_connecting(dev, data, true /* ignore PV[KBB+FB] */); -} -static int non_essential_device_connecting(struct device *dev, void *data) -{ - return is_device_connecting(dev, data, false); -} -static int exists_essential_connecting_device(struct device_driver *drv) +static int exists_connecting_device(struct device_driver *drv) { return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, - essential_device_connecting); -} -static int exists_non_essential_connecting_device(struct device_driver *drv) -{ - return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, - non_essential_device_connecting); + is_device_connecting); } static int print_device_status(struct device *dev, void *data) @@ -217,23 +192,6 @@ static int print_device_status(struct device *dev, void *data) /* We only wait for device setup after most initcalls have run. */ static int ready_to_wait_for_devices; -static bool wait_loop(unsigned long start, unsigned int max_delay, - unsigned int *seconds_waited) -{ - if (time_after(jiffies, start + (*seconds_waited+5)*HZ)) { - if (!*seconds_waited) - printk(KERN_WARNING "XENBUS: Waiting for " - "devices to initialise: "); - *seconds_waited += 5; - printk("%us...", max_delay - *seconds_waited); - if (*seconds_waited == max_delay) - return true; - } - - schedule_timeout_interruptible(HZ/10); - - return false; -} /* * On a 5-minute timeout, wait for all devices currently configured. We need * to do this to guarantee that the filesystems and / or network devices @@ -257,14 +215,19 @@ static void wait_for_devices(struct xenbus_driver *xendrv) if (!ready_to_wait_for_devices || !xen_domain()) return; - while (exists_non_essential_connecting_device(drv)) - if (wait_loop(start, 30, &seconds_waited)) - break; - - /* Skips PVKB and PVFB check.*/ - while (exists_essential_connecting_device(drv)) - if (wait_loop(start, 270, &seconds_waited)) - break; + while (exists_connecting_device(drv)) { + if (time_after(jiffies, start + (seconds_waited+5)*HZ)) { + if (!seconds_waited) + printk(KERN_WARNING "XENBUS: Waiting for " + "devices to initialise: "); + seconds_waited += 5; + printk("%us...", 300 - seconds_waited); + if (seconds_waited == 300) + break; + } + + schedule_timeout_interruptible(HZ/10); + } if (seconds_waited) printk("\n"); diff --git a/trunk/fs/aio.c b/trunk/fs/aio.c index 67a6db3e1b6f..4f71627264fd 100644 --- a/trunk/fs/aio.c +++ b/trunk/fs/aio.c @@ -93,8 +93,9 @@ static void aio_free_ring(struct kioctx *ctx) put_page(info->ring_pages[i]); if (info->mmap_size) { - BUG_ON(ctx->mm != current->mm); - vm_munmap(info->mmap_base, info->mmap_size); + down_write(&ctx->mm->mmap_sem); + do_munmap(ctx->mm, info->mmap_base, info->mmap_size); + up_write(&ctx->mm->mmap_sem); } if (info->ring_pages && info->ring_pages != info->internal_pages) @@ -304,18 +305,15 @@ static struct kioctx *ioctx_alloc(unsigned nr_events) return ERR_PTR(err); } -/* kill_ctx +/* aio_cancel_all * Cancels all outstanding aio requests on an aio context. Used * when the processes owning a context have all exited to encourage * the rapid destruction of the kioctx. */ -static void kill_ctx(struct kioctx *ctx) +static void aio_cancel_all(struct kioctx *ctx) { int (*cancel)(struct kiocb *, struct io_event *); - struct task_struct *tsk = current; - DECLARE_WAITQUEUE(wait, tsk); struct io_event res; - spin_lock_irq(&ctx->ctx_lock); ctx->dead = 1; while (!list_empty(&ctx->active_reqs)) { @@ -331,7 +329,15 @@ static void kill_ctx(struct kioctx *ctx) spin_lock_irq(&ctx->ctx_lock); } } + spin_unlock_irq(&ctx->ctx_lock); +} + +static void wait_for_all_aios(struct kioctx *ctx) +{ + struct task_struct *tsk = current; + DECLARE_WAITQUEUE(wait, tsk); + spin_lock_irq(&ctx->ctx_lock); if (!ctx->reqs_active) goto out; @@ -381,24 +387,15 @@ void exit_aio(struct mm_struct *mm) ctx = hlist_entry(mm->ioctx_list.first, struct kioctx, list); hlist_del_rcu(&ctx->list); - kill_ctx(ctx); + aio_cancel_all(ctx); + + wait_for_all_aios(ctx); if (1 != atomic_read(&ctx->users)) printk(KERN_DEBUG "exit_aio:ioctx still alive: %d %d %d\n", atomic_read(&ctx->users), ctx->dead, ctx->reqs_active); - /* - * We don't need to bother with munmap() here - - * exit_mmap(mm) is coming and it'll unmap everything. - * Since aio_free_ring() uses non-zero ->mmap_size - * as indicator that it needs to unmap the area, - * just set it to 0; aio_free_ring() is the only - * place that uses ->mmap_size, so it's safe. - * That way we get all munmap done to current->mm - - * all other callers have ctx->mm == current->mm. - */ - ctx->ring_info.mmap_size = 0; put_ioctx(ctx); } } @@ -1272,7 +1269,8 @@ static void io_destroy(struct kioctx *ioctx) if (likely(!was_dead)) put_ioctx(ioctx); /* twice for the list */ - kill_ctx(ioctx); + aio_cancel_all(ioctx); + wait_for_all_aios(ioctx); /* * Wake up any waiters. The setting of ctx->dead must be seen @@ -1280,6 +1278,7 @@ static void io_destroy(struct kioctx *ioctx) * locking done by the above calls to ensure this consistency. */ wake_up_all(&ioctx->wait); + put_ioctx(ioctx); /* once for the lookup */ } /* sys_io_setup: @@ -1316,9 +1315,11 @@ SYSCALL_DEFINE2(io_setup, unsigned, nr_events, aio_context_t __user *, ctxp) ret = PTR_ERR(ioctx); if (!IS_ERR(ioctx)) { ret = put_user(ioctx->user_id, ctxp); - if (ret) - io_destroy(ioctx); - put_ioctx(ioctx); + if (!ret) { + put_ioctx(ioctx); + return 0; + } + io_destroy(ioctx); } out: @@ -1336,7 +1337,6 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx) struct kioctx *ioctx = lookup_ioctx(ctx); if (likely(NULL != ioctx)) { io_destroy(ioctx); - put_ioctx(ioctx); return 0; } pr_debug("EINVAL: io_destroy: invalid context id\n"); diff --git a/trunk/fs/autofs4/autofs_i.h b/trunk/fs/autofs4/autofs_i.h index 908e18455413..eb1cc92cd67d 100644 --- a/trunk/fs/autofs4/autofs_i.h +++ b/trunk/fs/autofs4/autofs_i.h @@ -110,6 +110,7 @@ struct autofs_sb_info { int sub_version; int min_proto; int max_proto; + int compat_daemon; unsigned long exp_timeout; unsigned int type; int reghost_enabled; @@ -269,17 +270,6 @@ int autofs4_fill_super(struct super_block *, void *, int); struct autofs_info *autofs4_new_ino(struct autofs_sb_info *); void autofs4_clean_ino(struct autofs_info *); -static inline int autofs_prepare_pipe(struct file *pipe) -{ - if (!pipe->f_op || !pipe->f_op->write) - return -EINVAL; - if (!S_ISFIFO(pipe->f_dentry->d_inode->i_mode)) - return -EINVAL; - /* We want a packet pipe */ - pipe->f_flags |= O_DIRECT; - return 0; -} - /* Queue management functions */ int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify); diff --git a/trunk/fs/autofs4/dev-ioctl.c b/trunk/fs/autofs4/dev-ioctl.c index aa9103f8f01b..9dacb8586701 100644 --- a/trunk/fs/autofs4/dev-ioctl.c +++ b/trunk/fs/autofs4/dev-ioctl.c @@ -376,7 +376,7 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp, err = -EBADF; goto out; } - if (autofs_prepare_pipe(pipe) < 0) { + if (!pipe->f_op || !pipe->f_op->write) { err = -EPIPE; fput(pipe); goto out; @@ -385,6 +385,7 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp, sbi->pipefd = pipefd; sbi->pipe = pipe; sbi->catatonic = 0; + sbi->compat_daemon = is_compat_task(); } out: mutex_unlock(&sbi->wq_mutex); diff --git a/trunk/fs/autofs4/inode.c b/trunk/fs/autofs4/inode.c index 6e488ebe7784..d8dc002e9cc3 100644 --- a/trunk/fs/autofs4/inode.c +++ b/trunk/fs/autofs4/inode.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "autofs_i.h" #include @@ -224,6 +225,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) set_autofs_type_indirect(&sbi->type); sbi->min_proto = 0; sbi->max_proto = 0; + sbi->compat_daemon = is_compat_task(); mutex_init(&sbi->wq_mutex); mutex_init(&sbi->pipe_mutex); spin_lock_init(&sbi->fs_lock); @@ -290,7 +292,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) printk("autofs: could not open pipe file descriptor\n"); goto fail_dput; } - if (autofs_prepare_pipe(pipe) < 0) + if (!pipe->f_op || !pipe->f_op->write) goto fail_fput; sbi->pipe = pipe; sbi->pipefd = pipefd; diff --git a/trunk/fs/autofs4/waitq.c b/trunk/fs/autofs4/waitq.c index da8876d38a7b..9c098db43344 100644 --- a/trunk/fs/autofs4/waitq.c +++ b/trunk/fs/autofs4/waitq.c @@ -91,7 +91,24 @@ static int autofs4_write(struct autofs_sb_info *sbi, return (bytes > 0); } - + +/* + * The autofs_v5 packet was misdesigned. + * + * The packets are identical on x86-32 and x86-64, but have different + * alignment. Which means that 'sizeof()' will give different results. + * Fix it up for the case of running 32-bit user mode on a 64-bit kernel. + */ +static noinline size_t autofs_v5_packet_size(struct autofs_sb_info *sbi) +{ + size_t pktsz = sizeof(struct autofs_v5_packet); +#if defined(CONFIG_X86_64) && defined(CONFIG_COMPAT) + if (sbi->compat_daemon > 0) + pktsz -= 4; +#endif + return pktsz; +} + static void autofs4_notify_daemon(struct autofs_sb_info *sbi, struct autofs_wait_queue *wq, int type) @@ -155,8 +172,7 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi, { struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet; - pktsz = sizeof(*packet); - + pktsz = autofs_v5_packet_size(sbi); packet->wait_queue_token = wq->wait_queue_token; packet->len = wq->name.len; memcpy(packet->name, wq->name.name, wq->name.len); diff --git a/trunk/fs/binfmt_aout.c b/trunk/fs/binfmt_aout.c index d146e181d10d..2eb12f13593d 100644 --- a/trunk/fs/binfmt_aout.c +++ b/trunk/fs/binfmt_aout.c @@ -50,7 +50,9 @@ static int set_brk(unsigned long start, unsigned long end) end = PAGE_ALIGN(end); if (end > start) { unsigned long addr; - addr = vm_brk(start, end - start); + down_write(¤t->mm->mmap_sem); + addr = do_brk(start, end - start); + up_write(¤t->mm->mmap_sem); if (BAD_ADDR(addr)) return addr; } @@ -278,7 +280,9 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) pos = 32; map_size = ex.a_text+ex.a_data; #endif - error = vm_brk(text_addr & PAGE_MASK, map_size); + down_write(¤t->mm->mmap_sem); + error = do_brk(text_addr & PAGE_MASK, map_size); + up_write(¤t->mm->mmap_sem); if (error != (text_addr & PAGE_MASK)) { send_sig(SIGKILL, current, 0); return error; @@ -309,7 +313,9 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) 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); + down_write(¤t->mm->mmap_sem); + do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); + up_write(¤t->mm->mmap_sem); bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex), ex.a_text+ex.a_data, &pos); @@ -319,20 +325,24 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) goto beyond_if; } - error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, + down_write(¤t->mm->mmap_sem); + error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, fd_offset); + up_write(¤t->mm->mmap_sem); if (error != N_TXTADDR(ex)) { send_sig(SIGKILL, current, 0); return error; } - error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, + down_write(¤t->mm->mmap_sem); + error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, fd_offset + ex.a_text); + up_write(¤t->mm->mmap_sem); if (error != N_DATADDR(ex)) { send_sig(SIGKILL, current, 0); return error; @@ -402,7 +412,9 @@ static int load_aout_library(struct file *file) "N_TXTOFF is not page aligned. Please convert library: %s\n", file->f_path.dentry->d_name.name); } - vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); + down_write(¤t->mm->mmap_sem); + do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); + up_write(¤t->mm->mmap_sem); file->f_op->read(file, (char __user *)start_addr, ex.a_text + ex.a_data, &pos); @@ -413,10 +425,12 @@ static int load_aout_library(struct file *file) goto out; } /* Now use mmap to map the library into memory. */ - error = vm_mmap(file, start_addr, ex.a_text + ex.a_data, + down_write(¤t->mm->mmap_sem); + error = do_mmap(file, start_addr, ex.a_text + ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, N_TXTOFF(ex)); + up_write(¤t->mm->mmap_sem); retval = error; if (error != start_addr) goto out; @@ -424,7 +438,9 @@ static int load_aout_library(struct file *file) len = PAGE_ALIGN(ex.a_text + ex.a_data); bss = ex.a_text + ex.a_data + ex.a_bss; if (bss > len) { - error = vm_brk(start_addr + len, bss - len); + down_write(¤t->mm->mmap_sem); + error = do_brk(start_addr + len, bss - len); + up_write(¤t->mm->mmap_sem); retval = error; if (error != start_addr + len) goto out; diff --git a/trunk/fs/binfmt_elf.c b/trunk/fs/binfmt_elf.c index 16f735417072..48ffb3dc610a 100644 --- a/trunk/fs/binfmt_elf.c +++ b/trunk/fs/binfmt_elf.c @@ -82,7 +82,9 @@ static int set_brk(unsigned long start, unsigned long end) end = ELF_PAGEALIGN(end); if (end > start) { unsigned long addr; - addr = vm_brk(start, end - start); + down_write(¤t->mm->mmap_sem); + addr = do_brk(start, end - start); + up_write(¤t->mm->mmap_sem); if (BAD_ADDR(addr)) return addr; } @@ -512,7 +514,9 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1); /* Map the last of the bss segment */ - error = vm_brk(elf_bss, last_bss - elf_bss); + down_write(¤t->mm->mmap_sem); + error = do_brk(elf_bss, last_bss - elf_bss); + up_write(¤t->mm->mmap_sem); if (BAD_ADDR(error)) goto out_close; } @@ -958,8 +962,10 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) and some applications "depend" upon this behavior. Since we do not have the power to recompile these, we emulate the SVr4 behavior. Sigh. */ - error = vm_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC, + down_write(¤t->mm->mmap_sem); + error = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, 0); + up_write(¤t->mm->mmap_sem); } #ifdef ELF_PLAT_INIT @@ -1044,7 +1050,8 @@ static int load_elf_library(struct file *file) eppnt++; /* Now use mmap to map the library into memory. */ - error = vm_mmap(file, + down_write(¤t->mm->mmap_sem); + error = do_mmap(file, ELF_PAGESTART(eppnt->p_vaddr), (eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr)), @@ -1052,6 +1059,7 @@ static int load_elf_library(struct file *file) MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, (eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr))); + up_write(¤t->mm->mmap_sem); if (error != ELF_PAGESTART(eppnt->p_vaddr)) goto out_free_ph; @@ -1064,8 +1072,11 @@ static int load_elf_library(struct file *file) len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr + ELF_MIN_ALIGN - 1); bss = eppnt->p_memsz + eppnt->p_vaddr; - if (bss > len) - vm_brk(len, bss - len); + if (bss > len) { + down_write(¤t->mm->mmap_sem); + do_brk(len, bss - len); + up_write(¤t->mm->mmap_sem); + } error = 0; out_free_ph: diff --git a/trunk/fs/binfmt_elf_fdpic.c b/trunk/fs/binfmt_elf_fdpic.c index d390a0fffc65..9bd5612a8224 100644 --- a/trunk/fs/binfmt_elf_fdpic.c +++ b/trunk/fs/binfmt_elf_fdpic.c @@ -390,17 +390,21 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, (executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC)) stack_prot |= PROT_EXEC; - current->mm->start_brk = vm_mmap(NULL, 0, stack_size, stack_prot, + down_write(¤t->mm->mmap_sem); + current->mm->start_brk = do_mmap(NULL, 0, stack_size, stack_prot, MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZED | MAP_GROWSDOWN, 0); if (IS_ERR_VALUE(current->mm->start_brk)) { + up_write(¤t->mm->mmap_sem); retval = current->mm->start_brk; current->mm->start_brk = 0; goto error_kill; } + up_write(¤t->mm->mmap_sem); + current->mm->brk = current->mm->start_brk; current->mm->context.end_brk = current->mm->start_brk; current->mm->context.end_brk += @@ -951,8 +955,10 @@ static int elf_fdpic_map_file_constdisp_on_uclinux( if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE) mflags |= MAP_EXECUTABLE; - maddr = vm_mmap(NULL, load_addr, top - base, + down_write(&mm->mmap_sem); + maddr = do_mmap(NULL, load_addr, top - base, PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0); + up_write(&mm->mmap_sem); if (IS_ERR_VALUE(maddr)) return (int) maddr; @@ -1090,8 +1096,10 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, /* create the mapping */ disp = phdr->p_vaddr & ~PAGE_MASK; - maddr = vm_mmap(file, maddr, phdr->p_memsz + disp, prot, flags, + down_write(&mm->mmap_sem); + maddr = do_mmap(file, maddr, phdr->p_memsz + disp, prot, flags, phdr->p_offset - disp); + up_write(&mm->mmap_sem); kdebug("mmap[%d] sz=%lx pr=%x fl=%x of=%lx --> %08lx", loop, phdr->p_memsz + disp, prot, flags, @@ -1135,8 +1143,10 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, unsigned long xmaddr; flags |= MAP_FIXED | MAP_ANONYMOUS; - xmaddr = vm_mmap(NULL, xaddr, excess - excess1, + down_write(&mm->mmap_sem); + xmaddr = do_mmap(NULL, xaddr, excess - excess1, prot, flags, 0); + up_write(&mm->mmap_sem); kdebug("mmap[%d] " " ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx", diff --git a/trunk/fs/binfmt_flat.c b/trunk/fs/binfmt_flat.c index 6b2daf99fab8..024d20ee3ca3 100644 --- a/trunk/fs/binfmt_flat.c +++ b/trunk/fs/binfmt_flat.c @@ -542,8 +542,10 @@ static int load_flat_file(struct linux_binprm * bprm, */ DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); - textpos = vm_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, + down_write(¤t->mm->mmap_sem); + textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_EXECUTABLE, 0); + up_write(¤t->mm->mmap_sem); if (!textpos || IS_ERR_VALUE(textpos)) { if (!textpos) textpos = (unsigned long) -ENOMEM; @@ -554,8 +556,10 @@ static int load_flat_file(struct linux_binprm * bprm, len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); len = PAGE_ALIGN(len); - realdatastart = vm_mmap(0, 0, len, + down_write(¤t->mm->mmap_sem); + realdatastart = do_mmap(0, 0, len, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); + up_write(¤t->mm->mmap_sem); if (realdatastart == 0 || IS_ERR_VALUE(realdatastart)) { if (!realdatastart) @@ -599,8 +603,10 @@ static int load_flat_file(struct linux_binprm * bprm, len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); len = PAGE_ALIGN(len); - textpos = vm_mmap(0, 0, len, + down_write(¤t->mm->mmap_sem); + textpos = do_mmap(0, 0, len, PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); + up_write(¤t->mm->mmap_sem); if (!textpos || IS_ERR_VALUE(textpos)) { if (!textpos) diff --git a/trunk/fs/binfmt_som.c b/trunk/fs/binfmt_som.c index 4517aaff61b4..e4fc746629a7 100644 --- a/trunk/fs/binfmt_som.c +++ b/trunk/fs/binfmt_som.c @@ -147,8 +147,10 @@ static int map_som_binary(struct file *file, code_size = SOM_PAGEALIGN(hpuxhdr->exec_tsize); current->mm->start_code = code_start; current->mm->end_code = code_start + code_size; - retval = vm_mmap(file, code_start, code_size, prot, + down_write(¤t->mm->mmap_sem); + retval = do_mmap(file, code_start, code_size, prot, flags, SOM_PAGESTART(hpuxhdr->exec_tfile)); + up_write(¤t->mm->mmap_sem); if (retval < 0 && retval > -1024) goto out; @@ -156,16 +158,20 @@ static int map_som_binary(struct file *file, data_size = SOM_PAGEALIGN(hpuxhdr->exec_dsize); current->mm->start_data = data_start; current->mm->end_data = bss_start = data_start + data_size; - retval = vm_mmap(file, data_start, data_size, + down_write(¤t->mm->mmap_sem); + retval = do_mmap(file, data_start, data_size, prot | PROT_WRITE, flags, SOM_PAGESTART(hpuxhdr->exec_dfile)); + up_write(¤t->mm->mmap_sem); if (retval < 0 && retval > -1024) goto out; som_brk = bss_start + SOM_PAGEALIGN(hpuxhdr->exec_bsize); current->mm->start_brk = current->mm->brk = som_brk; - retval = vm_mmap(NULL, bss_start, som_brk - bss_start, + down_write(¤t->mm->mmap_sem); + retval = do_mmap(NULL, bss_start, som_brk - bss_start, prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, 0); + up_write(¤t->mm->mmap_sem); if (retval > 0 || retval < -1024) retval = 0; out: diff --git a/trunk/fs/btrfs/async-thread.c b/trunk/fs/btrfs/async-thread.c index 42704149b723..0cc20b35c1c4 100644 --- a/trunk/fs/btrfs/async-thread.c +++ b/trunk/fs/btrfs/async-thread.c @@ -171,11 +171,11 @@ static void check_pending_worker_creates(struct btrfs_worker_thread *worker) spin_unlock_irqrestore(&workers->lock, flags); } -static noinline void run_ordered_completions(struct btrfs_workers *workers, +static noinline int run_ordered_completions(struct btrfs_workers *workers, struct btrfs_work *work) { if (!workers->ordered) - return; + return 0; set_bit(WORK_DONE_BIT, &work->flags); @@ -213,6 +213,7 @@ static noinline void run_ordered_completions(struct btrfs_workers *workers, } spin_unlock(&workers->order_lock); + return 0; } static void put_worker(struct btrfs_worker_thread *worker) @@ -398,7 +399,7 @@ static int worker_loop(void *arg) /* * this will wait for all the worker threads to shutdown */ -void btrfs_stop_workers(struct btrfs_workers *workers) +int btrfs_stop_workers(struct btrfs_workers *workers) { struct list_head *cur; struct btrfs_worker_thread *worker; @@ -426,6 +427,7 @@ void btrfs_stop_workers(struct btrfs_workers *workers) put_worker(worker); } spin_unlock_irq(&workers->lock); + return 0; } /* @@ -613,14 +615,14 @@ static struct btrfs_worker_thread *find_worker(struct btrfs_workers *workers) * it was taken from. It is intended for use with long running work functions * that make some progress and want to give the cpu up for others. */ -void btrfs_requeue_work(struct btrfs_work *work) +int btrfs_requeue_work(struct btrfs_work *work) { struct btrfs_worker_thread *worker = work->worker; unsigned long flags; int wake = 0; if (test_and_set_bit(WORK_QUEUED_BIT, &work->flags)) - return; + goto out; spin_lock_irqsave(&worker->lock, flags); if (test_bit(WORK_HIGH_PRIO_BIT, &work->flags)) @@ -647,6 +649,9 @@ void btrfs_requeue_work(struct btrfs_work *work) if (wake) wake_up_process(worker->task); spin_unlock_irqrestore(&worker->lock, flags); +out: + + return 0; } void btrfs_set_work_high_prio(struct btrfs_work *work) diff --git a/trunk/fs/btrfs/async-thread.h b/trunk/fs/btrfs/async-thread.h index 063698b90ce2..f34cc31fa3c9 100644 --- a/trunk/fs/btrfs/async-thread.h +++ b/trunk/fs/btrfs/async-thread.h @@ -111,9 +111,9 @@ struct btrfs_workers { void btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work); int btrfs_start_workers(struct btrfs_workers *workers); -void btrfs_stop_workers(struct btrfs_workers *workers); +int btrfs_stop_workers(struct btrfs_workers *workers); void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max, struct btrfs_workers *async_starter); -void btrfs_requeue_work(struct btrfs_work *work); +int btrfs_requeue_work(struct btrfs_work *work); void btrfs_set_work_high_prio(struct btrfs_work *work); #endif diff --git a/trunk/fs/btrfs/backref.c b/trunk/fs/btrfs/backref.c index bcec06750232..0436c12da8c2 100644 --- a/trunk/fs/btrfs/backref.c +++ b/trunk/fs/btrfs/backref.c @@ -22,7 +22,6 @@ #include "ulist.h" #include "transaction.h" #include "delayed-ref.h" -#include "locking.h" /* * this structure records all encountered refs on the way up to the root @@ -117,7 +116,6 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, * to a logical address */ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, - int search_commit_root, struct __prelim_ref *ref, struct ulist *parents) { @@ -133,7 +131,6 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, path = btrfs_alloc_path(); if (!path) return -ENOMEM; - path->search_commit_root = !!search_commit_root; root_key.objectid = ref->root_id; root_key.type = BTRFS_ROOT_ITEM_KEY; @@ -191,7 +188,6 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, * resolve all indirect backrefs from the list */ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info, - int search_commit_root, struct list_head *head) { int err; @@ -216,8 +212,7 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info, continue; if (ref->count == 0) continue; - err = __resolve_indirect_ref(fs_info, search_commit_root, - ref, parents); + err = __resolve_indirect_ref(fs_info, ref, parents); if (err) { if (ret == 0) ret = err; @@ -591,7 +586,6 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, struct btrfs_delayed_ref_head *head; int info_level = 0; int ret; - int search_commit_root = (trans == BTRFS_BACKREF_SEARCH_COMMIT_ROOT); struct list_head prefs_delayed; struct list_head prefs; struct __prelim_ref *ref; @@ -606,7 +600,6 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, path = btrfs_alloc_path(); if (!path) return -ENOMEM; - path->search_commit_root = !!search_commit_root; /* * grab both a lock on the path and a lock on the delayed ref head. @@ -621,39 +614,35 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, goto out; BUG_ON(ret == 0); - if (trans != BTRFS_BACKREF_SEARCH_COMMIT_ROOT) { - /* - * look if there are updates for this ref queued and lock the - * head - */ - delayed_refs = &trans->transaction->delayed_refs; - spin_lock(&delayed_refs->lock); - head = btrfs_find_delayed_ref_head(trans, bytenr); - if (head) { - if (!mutex_trylock(&head->mutex)) { - atomic_inc(&head->node.refs); - spin_unlock(&delayed_refs->lock); - - btrfs_release_path(path); - - /* - * Mutex was contended, block until it's - * released and try again - */ - mutex_lock(&head->mutex); - mutex_unlock(&head->mutex); - btrfs_put_delayed_ref(&head->node); - goto again; - } - ret = __add_delayed_refs(head, seq, &info_key, - &prefs_delayed); - if (ret) { - spin_unlock(&delayed_refs->lock); - goto out; - } + /* + * look if there are updates for this ref queued and lock the head + */ + delayed_refs = &trans->transaction->delayed_refs; + spin_lock(&delayed_refs->lock); + head = btrfs_find_delayed_ref_head(trans, bytenr); + if (head) { + if (!mutex_trylock(&head->mutex)) { + atomic_inc(&head->node.refs); + spin_unlock(&delayed_refs->lock); + + btrfs_release_path(path); + + /* + * Mutex was contended, block until it's + * released and try again + */ + mutex_lock(&head->mutex); + mutex_unlock(&head->mutex); + btrfs_put_delayed_ref(&head->node); + goto again; + } + ret = __add_delayed_refs(head, seq, &info_key, &prefs_delayed); + if (ret) { + spin_unlock(&delayed_refs->lock); + goto out; } - spin_unlock(&delayed_refs->lock); } + spin_unlock(&delayed_refs->lock); if (path->slots[0]) { struct extent_buffer *leaf; @@ -690,7 +679,7 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans, if (ret) goto out; - ret = __resolve_indirect_refs(fs_info, search_commit_root, &prefs); + ret = __resolve_indirect_refs(fs_info, &prefs); if (ret) goto out; @@ -894,22 +883,18 @@ static char *iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path, s64 bytes_left = size - 1; struct extent_buffer *eb = eb_in; struct btrfs_key found_key; - int leave_spinning = path->leave_spinning; if (bytes_left >= 0) dest[bytes_left] = '\0'; - path->leave_spinning = 1; while (1) { len = btrfs_inode_ref_name_len(eb, iref); bytes_left -= len; if (bytes_left >= 0) read_extent_buffer(eb, dest + bytes_left, (unsigned long)(iref + 1), len); - if (eb != eb_in) { - btrfs_tree_read_unlock_blocking(eb); + if (eb != eb_in) free_extent_buffer(eb); - } ret = inode_ref_info(parent, 0, fs_root, path, &found_key); if (ret > 0) ret = -ENOENT; @@ -924,11 +909,8 @@ static char *iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path, slot = path->slots[0]; eb = path->nodes[0]; /* make sure we can use eb after releasing the path */ - if (eb != eb_in) { + if (eb != eb_in) atomic_inc(&eb->refs); - btrfs_tree_read_lock(eb); - btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); - } btrfs_release_path(path); iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref); @@ -939,7 +921,6 @@ static char *iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path, } btrfs_release_path(path); - path->leave_spinning = leave_spinning; if (ret) return ERR_PTR(ret); @@ -1093,7 +1074,8 @@ int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb, return 0; } -static int iterate_leaf_refs(struct btrfs_fs_info *fs_info, u64 logical, +static int iterate_leaf_refs(struct btrfs_fs_info *fs_info, + struct btrfs_path *path, u64 logical, u64 orig_extent_item_objectid, u64 extent_item_pos, u64 root, iterate_extent_inodes_t *iterate, void *ctx) @@ -1161,38 +1143,35 @@ static int iterate_leaf_refs(struct btrfs_fs_info *fs_info, u64 logical, * calls iterate() for every inode that references the extent identified by * the given parameters. * when the iterator function returns a non-zero value, iteration stops. + * path is guaranteed to be in released state when iterate() is called. */ int iterate_extent_inodes(struct btrfs_fs_info *fs_info, + struct btrfs_path *path, u64 extent_item_objectid, u64 extent_item_pos, - int search_commit_root, iterate_extent_inodes_t *iterate, void *ctx) { int ret; struct list_head data_refs = LIST_HEAD_INIT(data_refs); struct list_head shared_refs = LIST_HEAD_INIT(shared_refs); struct btrfs_trans_handle *trans; - struct ulist *refs = NULL; - struct ulist *roots = NULL; + struct ulist *refs; + struct ulist *roots; struct ulist_node *ref_node = NULL; struct ulist_node *root_node = NULL; struct seq_list seq_elem; - struct btrfs_delayed_ref_root *delayed_refs = NULL; + struct btrfs_delayed_ref_root *delayed_refs; + + trans = btrfs_join_transaction(fs_info->extent_root); + if (IS_ERR(trans)) + return PTR_ERR(trans); pr_debug("resolving all inodes for extent %llu\n", extent_item_objectid); - if (search_commit_root) { - trans = BTRFS_BACKREF_SEARCH_COMMIT_ROOT; - } else { - trans = btrfs_join_transaction(fs_info->extent_root); - if (IS_ERR(trans)) - return PTR_ERR(trans); - - delayed_refs = &trans->transaction->delayed_refs; - spin_lock(&delayed_refs->lock); - btrfs_get_delayed_seq(delayed_refs, &seq_elem); - spin_unlock(&delayed_refs->lock); - } + delayed_refs = &trans->transaction->delayed_refs; + spin_lock(&delayed_refs->lock); + btrfs_get_delayed_seq(delayed_refs, &seq_elem); + spin_unlock(&delayed_refs->lock); ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid, extent_item_pos, seq_elem.seq, @@ -1209,7 +1188,7 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info, while (!ret && (root_node = ulist_next(roots, root_node))) { pr_debug("root %llu references leaf %llu\n", root_node->val, ref_node->val); - ret = iterate_leaf_refs(fs_info, ref_node->val, + ret = iterate_leaf_refs(fs_info, path, ref_node->val, extent_item_objectid, extent_item_pos, root_node->val, iterate, ctx); @@ -1219,11 +1198,8 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info, ulist_free(refs); ulist_free(roots); out: - if (!search_commit_root) { - btrfs_put_delayed_seq(delayed_refs, &seq_elem); - btrfs_end_transaction(trans, fs_info->extent_root); - } - + btrfs_put_delayed_seq(delayed_refs, &seq_elem); + btrfs_end_transaction(trans, fs_info->extent_root); return ret; } @@ -1234,7 +1210,6 @@ int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info, int ret; u64 extent_item_pos; struct btrfs_key found_key; - int search_commit_root = path->search_commit_root; ret = extent_from_logical(fs_info, logical, path, &found_key); @@ -1245,9 +1220,8 @@ int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info, return ret; extent_item_pos = logical - found_key.objectid; - ret = iterate_extent_inodes(fs_info, found_key.objectid, - extent_item_pos, search_commit_root, - iterate, ctx); + ret = iterate_extent_inodes(fs_info, path, found_key.objectid, + extent_item_pos, iterate, ctx); return ret; } @@ -1256,7 +1230,7 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root, struct btrfs_path *path, iterate_irefs_t *iterate, void *ctx) { - int ret = 0; + int ret; int slot; u32 cur; u32 len; @@ -1268,8 +1242,7 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root, struct btrfs_inode_ref *iref; struct btrfs_key found_key; - while (!ret) { - path->leave_spinning = 1; + while (1) { ret = inode_ref_info(inum, parent ? parent+1 : 0, fs_root, path, &found_key); if (ret < 0) @@ -1285,8 +1258,6 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root, eb = path->nodes[0]; /* make sure we can use eb after releasing the path */ atomic_inc(&eb->refs); - btrfs_tree_read_lock(eb); - btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); btrfs_release_path(path); item = btrfs_item_nr(eb, slot); @@ -1300,12 +1271,13 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root, (unsigned long long)found_key.objectid, (unsigned long long)fs_root->objectid); ret = iterate(parent, iref, eb, ctx); - if (ret) + if (ret) { + free_extent_buffer(eb); break; + } len = sizeof(*iref) + name_len; iref = (struct btrfs_inode_ref *)((char *)iref + len); } - btrfs_tree_read_unlock_blocking(eb); free_extent_buffer(eb); } @@ -1370,6 +1342,12 @@ int paths_from_inode(u64 inum, struct inode_fs_paths *ipath) inode_to_path, ipath); } +/* + * allocates space to return multiple file system paths for an inode. + * total_bytes to allocate are passed, note that space usable for actual path + * information will be total_bytes - sizeof(struct inode_fs_paths). + * the returned pointer must be freed with free_ipath() in the end. + */ struct btrfs_data_container *init_data_container(u32 total_bytes) { struct btrfs_data_container *data; @@ -1425,8 +1403,5 @@ struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root, void free_ipath(struct inode_fs_paths *ipath) { - if (!ipath) - return; - kfree(ipath->fspath); kfree(ipath); } diff --git a/trunk/fs/btrfs/backref.h b/trunk/fs/btrfs/backref.h index 57ea2e959e4d..d00dfa9ca934 100644 --- a/trunk/fs/btrfs/backref.h +++ b/trunk/fs/btrfs/backref.h @@ -22,8 +22,6 @@ #include "ioctl.h" #include "ulist.h" -#define BTRFS_BACKREF_SEARCH_COMMIT_ROOT ((struct btrfs_trans_handle *)0) - struct inode_fs_paths { struct btrfs_path *btrfs_path; struct btrfs_root *fs_root; @@ -46,8 +44,9 @@ int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb, u64 *out_root, u8 *out_level); int iterate_extent_inodes(struct btrfs_fs_info *fs_info, + struct btrfs_path *path, u64 extent_item_objectid, - u64 extent_offset, int search_commit_root, + u64 extent_offset, iterate_extent_inodes_t *iterate, void *ctx); int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info, diff --git a/trunk/fs/btrfs/compression.c b/trunk/fs/btrfs/compression.c index 86eff48dab78..b805afb37fa8 100644 --- a/trunk/fs/btrfs/compression.c +++ b/trunk/fs/btrfs/compression.c @@ -226,8 +226,8 @@ static void end_compressed_bio_read(struct bio *bio, int err) * Clear the writeback bits on all of the file * pages for a compressed write */ -static noinline void end_compressed_writeback(struct inode *inode, u64 start, - unsigned long ram_size) +static noinline int end_compressed_writeback(struct inode *inode, u64 start, + unsigned long ram_size) { unsigned long index = start >> PAGE_CACHE_SHIFT; unsigned long end_index = (start + ram_size - 1) >> PAGE_CACHE_SHIFT; @@ -253,6 +253,7 @@ static noinline void end_compressed_writeback(struct inode *inode, u64 start, index += ret; } /* the inode may be gone now */ + return 0; } /* @@ -391,21 +392,20 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, */ atomic_inc(&cb->pending_bios); ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); if (!skip_sum) { ret = btrfs_csum_one_bio(root, inode, bio, start, 1); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } ret = btrfs_map_bio(root, WRITE, bio, 0, 1); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); bio_put(bio); bio = compressed_bio_alloc(bdev, first_byte, GFP_NOFS); - BUG_ON(!bio); bio->bi_private = cb; bio->bi_end_io = end_compressed_bio_write; bio_add_page(bio, page, PAGE_CACHE_SIZE, 0); @@ -421,15 +421,15 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, bio_get(bio); ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); if (!skip_sum) { ret = btrfs_csum_one_bio(root, inode, bio, start, 1); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } ret = btrfs_map_bio(root, WRITE, bio, 0, 1); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); bio_put(bio); return 0; @@ -497,7 +497,7 @@ static noinline int add_ra_bio_pages(struct inode *inode, * sure they map to this compressed extent on disk. */ set_page_extent_mapped(page); - lock_extent(tree, last_offset, end); + lock_extent(tree, last_offset, end, GFP_NOFS); read_lock(&em_tree->lock); em = lookup_extent_mapping(em_tree, last_offset, PAGE_CACHE_SIZE); @@ -507,7 +507,7 @@ static noinline int add_ra_bio_pages(struct inode *inode, (last_offset + PAGE_CACHE_SIZE > extent_map_end(em)) || (em->block_start >> 9) != cb->orig_bio->bi_sector) { free_extent_map(em); - unlock_extent(tree, last_offset, end); + unlock_extent(tree, last_offset, end, GFP_NOFS); unlock_page(page); page_cache_release(page); break; @@ -535,7 +535,7 @@ static noinline int add_ra_bio_pages(struct inode *inode, nr_pages++; page_cache_release(page); } else { - unlock_extent(tree, last_offset, end); + unlock_extent(tree, last_offset, end, GFP_NOFS); unlock_page(page); page_cache_release(page); break; @@ -662,7 +662,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, bio_get(comp_bio); ret = btrfs_bio_wq_end_io(root->fs_info, comp_bio, 0); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); /* * inc the count before we submit the bio so @@ -675,20 +675,19 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) { ret = btrfs_lookup_bio_sums(root, inode, comp_bio, sums); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } sums += (comp_bio->bi_size + root->sectorsize - 1) / root->sectorsize; ret = btrfs_map_bio(root, READ, comp_bio, mirror_num, 0); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); bio_put(comp_bio); comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, GFP_NOFS); - BUG_ON(!comp_bio); comp_bio->bi_private = cb; comp_bio->bi_end_io = end_compressed_bio_read; @@ -699,15 +698,15 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, bio_get(comp_bio); ret = btrfs_bio_wq_end_io(root->fs_info, comp_bio, 0); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) { ret = btrfs_lookup_bio_sums(root, inode, comp_bio, sums); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } ret = btrfs_map_bio(root, READ, comp_bio, mirror_num, 0); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); bio_put(comp_bio); return 0; @@ -735,7 +734,7 @@ struct btrfs_compress_op *btrfs_compress_op[] = { &btrfs_lzo_compress, }; -void __init btrfs_init_compress(void) +int __init btrfs_init_compress(void) { int i; @@ -745,6 +744,7 @@ void __init btrfs_init_compress(void) atomic_set(&comp_alloc_workspace[i], 0); init_waitqueue_head(&comp_workspace_wait[i]); } + return 0; } /* diff --git a/trunk/fs/btrfs/compression.h b/trunk/fs/btrfs/compression.h index 9afb0a62ae82..a12059f4f0fd 100644 --- a/trunk/fs/btrfs/compression.h +++ b/trunk/fs/btrfs/compression.h @@ -19,7 +19,7 @@ #ifndef __BTRFS_COMPRESSION_ #define __BTRFS_COMPRESSION_ -void btrfs_init_compress(void); +int btrfs_init_compress(void); void btrfs_exit_compress(void); int btrfs_compress_pages(int type, struct address_space *mapping, diff --git a/trunk/fs/btrfs/ctree.c b/trunk/fs/btrfs/ctree.c index 4106264fbc65..0639a555e16e 100644 --- a/trunk/fs/btrfs/ctree.c +++ b/trunk/fs/btrfs/ctree.c @@ -36,7 +36,7 @@ static int balance_node_right(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *dst_buf, struct extent_buffer *src_buf); -static void del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, +static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, int level, int slot); struct btrfs_path *btrfs_alloc_path(void) @@ -156,23 +156,10 @@ struct extent_buffer *btrfs_root_node(struct btrfs_root *root) { struct extent_buffer *eb; - while (1) { - rcu_read_lock(); - eb = rcu_dereference(root->node); - - /* - * RCU really hurts here, we could free up the root node because - * it was cow'ed but we may not get the new root node yet so do - * the inc_not_zero dance and if it doesn't work then - * synchronize_rcu and try again. - */ - if (atomic_inc_not_zero(&eb->refs)) { - rcu_read_unlock(); - break; - } - rcu_read_unlock(); - synchronize_rcu(); - } + rcu_read_lock(); + eb = rcu_dereference(root->node); + extent_buffer_get(eb); + rcu_read_unlock(); return eb; } @@ -220,12 +207,10 @@ struct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root *root) */ static void add_root_to_dirty_list(struct btrfs_root *root) { - spin_lock(&root->fs_info->trans_lock); if (root->track_dirty && list_empty(&root->dirty_list)) { list_add(&root->dirty_list, &root->fs_info->dirty_cowonly_roots); } - spin_unlock(&root->fs_info->trans_lock); } /* @@ -346,13 +331,8 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, if (btrfs_block_can_be_shared(root, buf)) { ret = btrfs_lookup_extent_info(trans, root, buf->start, buf->len, &refs, &flags); - if (ret) - return ret; - if (refs == 0) { - ret = -EROFS; - btrfs_std_error(root->fs_info, ret); - return ret; - } + BUG_ON(ret); + BUG_ON(refs == 0); } else { refs = 1; if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID || @@ -371,14 +351,14 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && !(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) { ret = btrfs_inc_ref(trans, root, buf, 1, 1); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); if (root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) { ret = btrfs_dec_ref(trans, root, buf, 0, 1); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); ret = btrfs_inc_ref(trans, root, cow, 1, 1); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF; } else { @@ -388,15 +368,14 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, ret = btrfs_inc_ref(trans, root, cow, 1, 1); else ret = btrfs_inc_ref(trans, root, cow, 0, 1); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } if (new_flags != 0) { ret = btrfs_set_disk_extent_flags(trans, root, buf->start, buf->len, new_flags, 0); - if (ret) - return ret; + BUG_ON(ret); } } else { if (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF) { @@ -405,9 +384,9 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, ret = btrfs_inc_ref(trans, root, cow, 1, 1); else ret = btrfs_inc_ref(trans, root, cow, 0, 1); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); ret = btrfs_dec_ref(trans, root, buf, 1, 1); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } clean_tree_block(trans, root, buf); *last_ref = 1; @@ -436,7 +415,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, { struct btrfs_disk_key disk_key; struct extent_buffer *cow; - int level, ret; + int level; int last_ref = 0; int unlock_orig = 0; u64 parent_start; @@ -488,11 +467,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, (unsigned long)btrfs_header_fsid(cow), BTRFS_FSID_SIZE); - ret = update_ref_for_cow(trans, root, buf, cow, &last_ref); - if (ret) { - btrfs_abort_transaction(trans, root, ret); - return ret; - } + update_ref_for_cow(trans, root, buf, cow, &last_ref); if (root->ref_cows) btrfs_reloc_cow_block(trans, root, buf, cow); @@ -529,7 +504,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, } if (unlock_orig) btrfs_tree_unlock(buf); - free_extent_buffer_stale(buf); + free_extent_buffer(buf); btrfs_mark_buffer_dirty(cow); *cow_ret = cow; return 0; @@ -725,7 +700,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, cur = btrfs_find_tree_block(root, blocknr, blocksize); if (cur) - uptodate = btrfs_buffer_uptodate(cur, gen, 0); + uptodate = btrfs_buffer_uptodate(cur, gen); else uptodate = 0; if (!cur || !uptodate) { @@ -959,12 +934,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, /* promote the child to a root */ child = read_node_slot(root, mid, 0); - if (!child) { - ret = -EROFS; - btrfs_std_error(root->fs_info, ret); - goto enospc; - } - + BUG_ON(!child); btrfs_tree_lock(child); btrfs_set_lock_blocking(child); ret = btrfs_cow_block(trans, root, child, mid, 0, &child); @@ -989,7 +959,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, root_sub_used(root, mid->len); btrfs_free_tree_block(trans, root, mid, 0, 1, 0); /* once for the root ptr */ - free_extent_buffer_stale(mid); + free_extent_buffer(mid); return 0; } if (btrfs_header_nritems(mid) > @@ -1040,10 +1010,13 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, if (btrfs_header_nritems(right) == 0) { clean_tree_block(trans, root, right); btrfs_tree_unlock(right); - del_ptr(trans, root, path, level + 1, pslot + 1); + wret = del_ptr(trans, root, path, level + 1, pslot + + 1); + if (wret) + ret = wret; root_sub_used(root, right->len); btrfs_free_tree_block(trans, root, right, 0, 1, 0); - free_extent_buffer_stale(right); + free_extent_buffer(right); right = NULL; } else { struct btrfs_disk_key right_key; @@ -1062,11 +1035,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, * otherwise we would have pulled some pointers from the * right */ - if (!left) { - ret = -EROFS; - btrfs_std_error(root->fs_info, ret); - goto enospc; - } + BUG_ON(!left); wret = balance_node_right(trans, root, mid, left); if (wret < 0) { ret = wret; @@ -1082,10 +1051,12 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, if (btrfs_header_nritems(mid) == 0) { clean_tree_block(trans, root, mid); btrfs_tree_unlock(mid); - del_ptr(trans, root, path, level + 1, pslot); + wret = del_ptr(trans, root, path, level + 1, pslot); + if (wret) + ret = wret; root_sub_used(root, mid->len); btrfs_free_tree_block(trans, root, mid, 0, 1, 0); - free_extent_buffer_stale(mid); + free_extent_buffer(mid); mid = NULL; } else { /* update the parent key to reflect our changes */ @@ -1360,12 +1331,7 @@ static noinline int reada_for_balance(struct btrfs_root *root, block1 = btrfs_node_blockptr(parent, slot - 1); gen = btrfs_node_ptr_generation(parent, slot - 1); eb = btrfs_find_tree_block(root, block1, blocksize); - /* - * if we get -eagain from btrfs_buffer_uptodate, we - * don't want to return eagain here. That will loop - * forever - */ - if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0) + if (eb && btrfs_buffer_uptodate(eb, gen)) block1 = 0; free_extent_buffer(eb); } @@ -1373,7 +1339,7 @@ static noinline int reada_for_balance(struct btrfs_root *root, block2 = btrfs_node_blockptr(parent, slot + 1); gen = btrfs_node_ptr_generation(parent, slot + 1); eb = btrfs_find_tree_block(root, block2, blocksize); - if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0) + if (eb && btrfs_buffer_uptodate(eb, gen)) block2 = 0; free_extent_buffer(eb); } @@ -1416,8 +1382,7 @@ static noinline int reada_for_balance(struct btrfs_root *root, * if lowest_unlock is 1, level 0 won't be unlocked */ static noinline void unlock_up(struct btrfs_path *path, int level, - int lowest_unlock, int min_write_lock_level, - int *write_lock_level) + int lowest_unlock) { int i; int skip_level = level; @@ -1449,11 +1414,6 @@ static noinline void unlock_up(struct btrfs_path *path, int level, if (i >= lowest_unlock && i > skip_level && path->locks[i]) { btrfs_tree_unlock_rw(t, path->locks[i]); path->locks[i] = 0; - if (write_lock_level && - i > min_write_lock_level && - i <= *write_lock_level) { - *write_lock_level = i - 1; - } } } } @@ -1511,9 +1471,8 @@ read_block_for_search(struct btrfs_trans_handle *trans, tmp = btrfs_find_tree_block(root, blocknr, blocksize); if (tmp) { - /* first we do an atomic uptodate check */ - if (btrfs_buffer_uptodate(tmp, 0, 1) > 0) { - if (btrfs_buffer_uptodate(tmp, gen, 1) > 0) { + if (btrfs_buffer_uptodate(tmp, 0)) { + if (btrfs_buffer_uptodate(tmp, gen)) { /* * we found an up to date block without * sleeping, return @@ -1531,9 +1490,8 @@ read_block_for_search(struct btrfs_trans_handle *trans, free_extent_buffer(tmp); btrfs_set_path_blocking(p); - /* now we're allowed to do a blocking uptodate check */ tmp = read_tree_block(root, blocknr, blocksize, gen); - if (tmp && btrfs_buffer_uptodate(tmp, gen, 0) > 0) { + if (tmp && btrfs_buffer_uptodate(tmp, gen)) { *eb_ret = tmp; return 0; } @@ -1568,7 +1526,7 @@ read_block_for_search(struct btrfs_trans_handle *trans, * and give up so that our caller doesn't loop forever * on our EAGAINs. */ - if (!btrfs_buffer_uptodate(tmp, 0, 0)) + if (!btrfs_buffer_uptodate(tmp, 0)) ret = -EIO; free_extent_buffer(tmp); } @@ -1679,7 +1637,6 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root /* everything at write_lock_level or lower must be write locked */ int write_lock_level = 0; u8 lowest_level = 0; - int min_write_lock_level; lowest_level = p->lowest_level; WARN_ON(lowest_level && ins_len > 0); @@ -1707,8 +1664,6 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root if (cow && (p->keep_locks || p->lowest_level)) write_lock_level = BTRFS_MAX_LEVEL; - min_write_lock_level = write_lock_level; - again: /* * we try very hard to do read locks on the root @@ -1840,8 +1795,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root goto again; } - unlock_up(p, level, lowest_unlock, - min_write_lock_level, &write_lock_level); + unlock_up(p, level, lowest_unlock); if (level == lowest_level) { if (dec) @@ -1903,8 +1857,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root } } if (!p->search_for_split) - unlock_up(p, level, lowest_unlock, - min_write_lock_level, &write_lock_level); + unlock_up(p, level, lowest_unlock); goto done; } } @@ -1928,12 +1881,15 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root * fixing up pointers when a given leaf/node is not in slot 0 of the * higher levels * + * If this fails to write a tree block, it returns -1, but continues + * fixing up the blocks in ram so the tree is consistent. */ -static void fixup_low_keys(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct btrfs_path *path, - struct btrfs_disk_key *key, int level) +static int fixup_low_keys(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct btrfs_path *path, + struct btrfs_disk_key *key, int level) { int i; + int ret = 0; struct extent_buffer *t; for (i = level; i < BTRFS_MAX_LEVEL; i++) { @@ -1946,6 +1902,7 @@ static void fixup_low_keys(struct btrfs_trans_handle *trans, if (tslot != 0) break; } + return ret; } /* @@ -1954,9 +1911,9 @@ static void fixup_low_keys(struct btrfs_trans_handle *trans, * This function isn't completely safe. It's the caller's responsibility * that the new key won't break the order */ -void btrfs_set_item_key_safe(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct btrfs_path *path, - struct btrfs_key *new_key) +int btrfs_set_item_key_safe(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct btrfs_path *path, + struct btrfs_key *new_key) { struct btrfs_disk_key disk_key; struct extent_buffer *eb; @@ -1966,11 +1923,13 @@ void btrfs_set_item_key_safe(struct btrfs_trans_handle *trans, slot = path->slots[0]; if (slot > 0) { btrfs_item_key(eb, &disk_key, slot - 1); - BUG_ON(comp_keys(&disk_key, new_key) >= 0); + if (comp_keys(&disk_key, new_key) >= 0) + return -1; } if (slot < btrfs_header_nritems(eb) - 1) { btrfs_item_key(eb, &disk_key, slot + 1); - BUG_ON(comp_keys(&disk_key, new_key) <= 0); + if (comp_keys(&disk_key, new_key) <= 0) + return -1; } btrfs_cpu_key_to_disk(&disk_key, new_key); @@ -1978,6 +1937,7 @@ void btrfs_set_item_key_safe(struct btrfs_trans_handle *trans, btrfs_mark_buffer_dirty(eb); if (slot == 0) fixup_low_keys(trans, root, path, &disk_key, 1); + return 0; } /* @@ -2180,11 +2140,12 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, * * slot and level indicate where you want the key to go, and * blocknr is the block the key points to. + * + * returns zero on success and < 0 on any error */ -static void insert_ptr(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct btrfs_path *path, - struct btrfs_disk_key *key, u64 bytenr, - int slot, int level) +static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root + *root, struct btrfs_path *path, struct btrfs_disk_key + *key, u64 bytenr, int slot, int level) { struct extent_buffer *lower; int nritems; @@ -2194,7 +2155,8 @@ static void insert_ptr(struct btrfs_trans_handle *trans, lower = path->nodes[level]; nritems = btrfs_header_nritems(lower); BUG_ON(slot > nritems); - BUG_ON(nritems == BTRFS_NODEPTRS_PER_BLOCK(root)); + if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root)) + BUG(); if (slot != nritems) { memmove_extent_buffer(lower, btrfs_node_key_ptr_offset(slot + 1), @@ -2207,6 +2169,7 @@ static void insert_ptr(struct btrfs_trans_handle *trans, btrfs_set_node_ptr_generation(lower, slot, trans->transid); btrfs_set_header_nritems(lower, nritems + 1); btrfs_mark_buffer_dirty(lower); + return 0; } /* @@ -2227,6 +2190,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans, struct btrfs_disk_key disk_key; int mid; int ret; + int wret; u32 c_nritems; c = path->nodes[level]; @@ -2283,8 +2247,11 @@ static noinline int split_node(struct btrfs_trans_handle *trans, btrfs_mark_buffer_dirty(c); btrfs_mark_buffer_dirty(split); - insert_ptr(trans, root, path, &disk_key, split->start, - path->slots[level + 1] + 1, level + 1); + wret = insert_ptr(trans, root, path, &disk_key, split->start, + path->slots[level + 1] + 1, + level + 1); + if (wret) + ret = wret; if (path->slots[level] >= mid) { path->slots[level] -= mid; @@ -2353,7 +2320,6 @@ static noinline int __push_leaf_right(struct btrfs_trans_handle *trans, { struct extent_buffer *left = path->nodes[0]; struct extent_buffer *upper = path->nodes[1]; - struct btrfs_map_token token; struct btrfs_disk_key disk_key; int slot; u32 i; @@ -2365,8 +2331,6 @@ static noinline int __push_leaf_right(struct btrfs_trans_handle *trans, u32 data_end; u32 this_item_size; - btrfs_init_map_token(&token); - if (empty) nr = 0; else @@ -2444,8 +2408,8 @@ static noinline int __push_leaf_right(struct btrfs_trans_handle *trans, push_space = BTRFS_LEAF_DATA_SIZE(root); for (i = 0; i < right_nritems; i++) { item = btrfs_item_nr(right, i); - push_space -= btrfs_token_item_size(right, item, &token); - btrfs_set_token_item_offset(right, item, push_space, &token); + push_space -= btrfs_item_size(right, item); + btrfs_set_item_offset(right, item, push_space); } left_nritems -= push_items; @@ -2573,11 +2537,9 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans, u32 old_left_nritems; u32 nr; int ret = 0; + int wret; u32 this_item_size; u32 old_left_item_size; - struct btrfs_map_token token; - - btrfs_init_map_token(&token); if (empty) nr = min(right_nritems, max_slot); @@ -2638,10 +2600,9 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans, item = btrfs_item_nr(left, i); - ioff = btrfs_token_item_offset(left, item, &token); - btrfs_set_token_item_offset(left, item, - ioff - (BTRFS_LEAF_DATA_SIZE(root) - old_left_item_size), - &token); + ioff = btrfs_item_offset(left, item); + btrfs_set_item_offset(left, item, + ioff - (BTRFS_LEAF_DATA_SIZE(root) - old_left_item_size)); } btrfs_set_header_nritems(left, old_left_nritems + push_items); @@ -2671,9 +2632,8 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans, for (i = 0; i < right_nritems; i++) { item = btrfs_item_nr(right, i); - push_space = push_space - btrfs_token_item_size(right, - item, &token); - btrfs_set_token_item_offset(right, item, push_space, &token); + push_space = push_space - btrfs_item_size(right, item); + btrfs_set_item_offset(right, item, push_space); } btrfs_mark_buffer_dirty(left); @@ -2683,7 +2643,9 @@ static noinline int __push_leaf_left(struct btrfs_trans_handle *trans, clean_tree_block(trans, root, right); btrfs_item_key(right, &disk_key, 0); - fixup_low_keys(trans, root, path, &disk_key, 1); + wret = fixup_low_keys(trans, root, path, &disk_key, 1); + if (wret) + ret = wret; /* then fixup the leaf pointer in the path */ if (path->slots[0] < push_items) { @@ -2754,8 +2716,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root path->nodes[1], slot - 1, &left); if (ret) { /* we hit -ENOSPC, but it isn't fatal here */ - if (ret == -ENOSPC) - ret = 1; + ret = 1; goto out; } @@ -2777,21 +2738,22 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root /* * split the path's leaf in two, making sure there is at least data_size * available for the resulting leaf level of the path. + * + * returns 0 if all went well and < 0 on failure. */ -static noinline void copy_for_split(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, - struct extent_buffer *l, - struct extent_buffer *right, - int slot, int mid, int nritems) +static noinline int copy_for_split(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + struct extent_buffer *l, + struct extent_buffer *right, + int slot, int mid, int nritems) { int data_copy_size; int rt_data_off; int i; + int ret = 0; + int wret; struct btrfs_disk_key disk_key; - struct btrfs_map_token token; - - btrfs_init_map_token(&token); nritems = nritems - mid; btrfs_set_header_nritems(right, nritems); @@ -2813,15 +2775,17 @@ static noinline void copy_for_split(struct btrfs_trans_handle *trans, struct btrfs_item *item = btrfs_item_nr(right, i); u32 ioff; - ioff = btrfs_token_item_offset(right, item, &token); - btrfs_set_token_item_offset(right, item, - ioff + rt_data_off, &token); + ioff = btrfs_item_offset(right, item); + btrfs_set_item_offset(right, item, ioff + rt_data_off); } btrfs_set_header_nritems(l, mid); + ret = 0; btrfs_item_key(right, &disk_key, 0); - insert_ptr(trans, root, path, &disk_key, right->start, - path->slots[1] + 1, 1); + wret = insert_ptr(trans, root, path, &disk_key, right->start, + path->slots[1] + 1, 1); + if (wret) + ret = wret; btrfs_mark_buffer_dirty(right); btrfs_mark_buffer_dirty(l); @@ -2839,6 +2803,8 @@ static noinline void copy_for_split(struct btrfs_trans_handle *trans, } BUG_ON(path->slots[0] < 0); + + return ret; } /* @@ -3027,8 +2993,12 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, if (split == 0) { if (mid <= slot) { btrfs_set_header_nritems(right, 0); - insert_ptr(trans, root, path, &disk_key, right->start, - path->slots[1] + 1, 1); + wret = insert_ptr(trans, root, path, + &disk_key, right->start, + path->slots[1] + 1, 1); + if (wret) + ret = wret; + btrfs_tree_unlock(path->nodes[0]); free_extent_buffer(path->nodes[0]); path->nodes[0] = right; @@ -3036,21 +3006,29 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, path->slots[1] += 1; } else { btrfs_set_header_nritems(right, 0); - insert_ptr(trans, root, path, &disk_key, right->start, + wret = insert_ptr(trans, root, path, + &disk_key, + right->start, path->slots[1], 1); + if (wret) + ret = wret; btrfs_tree_unlock(path->nodes[0]); free_extent_buffer(path->nodes[0]); path->nodes[0] = right; path->slots[0] = 0; - if (path->slots[1] == 0) - fixup_low_keys(trans, root, path, - &disk_key, 1); + if (path->slots[1] == 0) { + wret = fixup_low_keys(trans, root, + path, &disk_key, 1); + if (wret) + ret = wret; + } } btrfs_mark_buffer_dirty(right); return ret; } - copy_for_split(trans, root, path, l, right, slot, mid, nritems); + ret = copy_for_split(trans, root, path, l, right, slot, mid, nritems); + BUG_ON(ret); if (split == 2) { BUG_ON(num_doubles != 0); @@ -3058,7 +3036,7 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, goto again; } - return 0; + return ret; push_for_double: push_for_double_split(trans, root, path, data_size); @@ -3260,9 +3238,11 @@ int btrfs_duplicate_item(struct btrfs_trans_handle *trans, return ret; path->slots[0]++; - setup_items_for_insert(trans, root, path, new_key, &item_size, - item_size, item_size + - sizeof(struct btrfs_item), 1); + ret = setup_items_for_insert(trans, root, path, new_key, &item_size, + item_size, item_size + + sizeof(struct btrfs_item), 1); + BUG_ON(ret); + leaf = path->nodes[0]; memcpy_extent_buffer(leaf, btrfs_item_ptr_offset(leaf, path->slots[0]), @@ -3277,10 +3257,10 @@ int btrfs_duplicate_item(struct btrfs_trans_handle *trans, * off the end of the item or if we shift the item to chop bytes off * the front. */ -void btrfs_truncate_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, - u32 new_size, int from_end) +int btrfs_truncate_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + u32 new_size, int from_end) { int slot; struct extent_buffer *leaf; @@ -3291,16 +3271,13 @@ void btrfs_truncate_item(struct btrfs_trans_handle *trans, unsigned int old_size; unsigned int size_diff; int i; - struct btrfs_map_token token; - - btrfs_init_map_token(&token); leaf = path->nodes[0]; slot = path->slots[0]; old_size = btrfs_item_size_nr(leaf, slot); if (old_size == new_size) - return; + return 0; nritems = btrfs_header_nritems(leaf); data_end = leaf_data_end(root, leaf); @@ -3320,9 +3297,8 @@ void btrfs_truncate_item(struct btrfs_trans_handle *trans, u32 ioff; item = btrfs_item_nr(leaf, i); - ioff = btrfs_token_item_offset(leaf, item, &token); - btrfs_set_token_item_offset(leaf, item, - ioff + size_diff, &token); + ioff = btrfs_item_offset(leaf, item); + btrfs_set_item_offset(leaf, item, ioff + size_diff); } /* shift the data */ @@ -3374,14 +3350,15 @@ void btrfs_truncate_item(struct btrfs_trans_handle *trans, btrfs_print_leaf(root, leaf); BUG(); } + return 0; } /* * make the item pointed to by the path bigger, data_size is the new size. */ -void btrfs_extend_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct btrfs_path *path, - u32 data_size) +int btrfs_extend_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct btrfs_path *path, + u32 data_size) { int slot; struct extent_buffer *leaf; @@ -3391,9 +3368,6 @@ void btrfs_extend_item(struct btrfs_trans_handle *trans, unsigned int old_data; unsigned int old_size; int i; - struct btrfs_map_token token; - - btrfs_init_map_token(&token); leaf = path->nodes[0]; @@ -3423,9 +3397,8 @@ void btrfs_extend_item(struct btrfs_trans_handle *trans, u32 ioff; item = btrfs_item_nr(leaf, i); - ioff = btrfs_token_item_offset(leaf, item, &token); - btrfs_set_token_item_offset(leaf, item, - ioff - data_size, &token); + ioff = btrfs_item_offset(leaf, item); + btrfs_set_item_offset(leaf, item, ioff - data_size); } /* shift the data */ @@ -3443,6 +3416,7 @@ void btrfs_extend_item(struct btrfs_trans_handle *trans, btrfs_print_leaf(root, leaf); BUG(); } + return 0; } /* @@ -3467,9 +3441,6 @@ int btrfs_insert_some_items(struct btrfs_trans_handle *trans, unsigned int data_end; struct btrfs_disk_key disk_key; struct btrfs_key found_key; - struct btrfs_map_token token; - - btrfs_init_map_token(&token); for (i = 0; i < nr; i++) { if (total_size + data_size[i] + sizeof(struct btrfs_item) > @@ -3535,9 +3506,8 @@ int btrfs_insert_some_items(struct btrfs_trans_handle *trans, u32 ioff; item = btrfs_item_nr(leaf, i); - ioff = btrfs_token_item_offset(leaf, item, &token); - btrfs_set_token_item_offset(leaf, item, - ioff - total_data, &token); + ioff = btrfs_item_offset(leaf, item); + btrfs_set_item_offset(leaf, item, ioff - total_data); } /* shift the items */ memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + nr), @@ -3564,10 +3534,9 @@ int btrfs_insert_some_items(struct btrfs_trans_handle *trans, btrfs_cpu_key_to_disk(&disk_key, cpu_key + i); btrfs_set_item_key(leaf, &disk_key, slot + i); item = btrfs_item_nr(leaf, slot + i); - btrfs_set_token_item_offset(leaf, item, - data_end - data_size[i], &token); + btrfs_set_item_offset(leaf, item, data_end - data_size[i]); data_end -= data_size[i]; - btrfs_set_token_item_size(leaf, item, data_size[i], &token); + btrfs_set_item_size(leaf, item, data_size[i]); } btrfs_set_header_nritems(leaf, nritems + nr); btrfs_mark_buffer_dirty(leaf); @@ -3575,7 +3544,7 @@ int btrfs_insert_some_items(struct btrfs_trans_handle *trans, ret = 0; if (slot == 0) { btrfs_cpu_key_to_disk(&disk_key, cpu_key); - fixup_low_keys(trans, root, path, &disk_key, 1); + ret = fixup_low_keys(trans, root, path, &disk_key, 1); } if (btrfs_leaf_free_space(root, leaf) < 0) { @@ -3593,21 +3562,19 @@ int btrfs_insert_some_items(struct btrfs_trans_handle *trans, * to save stack depth by doing the bulk of the work in a function * that doesn't call btrfs_search_slot */ -void setup_items_for_insert(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct btrfs_path *path, - struct btrfs_key *cpu_key, u32 *data_size, - u32 total_data, u32 total_size, int nr) +int setup_items_for_insert(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct btrfs_path *path, + struct btrfs_key *cpu_key, u32 *data_size, + u32 total_data, u32 total_size, int nr) { struct btrfs_item *item; int i; u32 nritems; unsigned int data_end; struct btrfs_disk_key disk_key; + int ret; struct extent_buffer *leaf; int slot; - struct btrfs_map_token token; - - btrfs_init_map_token(&token); leaf = path->nodes[0]; slot = path->slots[0]; @@ -3639,9 +3606,8 @@ void setup_items_for_insert(struct btrfs_trans_handle *trans, u32 ioff; item = btrfs_item_nr(leaf, i); - ioff = btrfs_token_item_offset(leaf, item, &token); - btrfs_set_token_item_offset(leaf, item, - ioff - total_data, &token); + ioff = btrfs_item_offset(leaf, item); + btrfs_set_item_offset(leaf, item, ioff - total_data); } /* shift the items */ memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + nr), @@ -3660,17 +3626,17 @@ void setup_items_for_insert(struct btrfs_trans_handle *trans, btrfs_cpu_key_to_disk(&disk_key, cpu_key + i); btrfs_set_item_key(leaf, &disk_key, slot + i); item = btrfs_item_nr(leaf, slot + i); - btrfs_set_token_item_offset(leaf, item, - data_end - data_size[i], &token); + btrfs_set_item_offset(leaf, item, data_end - data_size[i]); data_end -= data_size[i]; - btrfs_set_token_item_size(leaf, item, data_size[i], &token); + btrfs_set_item_size(leaf, item, data_size[i]); } btrfs_set_header_nritems(leaf, nritems + nr); + ret = 0; if (slot == 0) { btrfs_cpu_key_to_disk(&disk_key, cpu_key); - fixup_low_keys(trans, root, path, &disk_key, 1); + ret = fixup_low_keys(trans, root, path, &disk_key, 1); } btrfs_unlock_up_safe(path, 1); btrfs_mark_buffer_dirty(leaf); @@ -3679,6 +3645,7 @@ void setup_items_for_insert(struct btrfs_trans_handle *trans, btrfs_print_leaf(root, leaf); BUG(); } + return ret; } /* @@ -3705,14 +3672,16 @@ int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, if (ret == 0) return -EEXIST; if (ret < 0) - return ret; + goto out; slot = path->slots[0]; BUG_ON(slot < 0); - setup_items_for_insert(trans, root, path, cpu_key, data_size, + ret = setup_items_for_insert(trans, root, path, cpu_key, data_size, total_data, total_size, nr); - return 0; + +out: + return ret; } /* @@ -3748,11 +3717,13 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root * the tree should have been previously balanced so the deletion does not * empty a node. */ -static void del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, - struct btrfs_path *path, int level, int slot) +static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct btrfs_path *path, int level, int slot) { struct extent_buffer *parent = path->nodes[level]; u32 nritems; + int ret = 0; + int wret; nritems = btrfs_header_nritems(parent); if (slot != nritems - 1) { @@ -3772,9 +3743,12 @@ static void del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_disk_key disk_key; btrfs_node_key(parent, &disk_key, 0); - fixup_low_keys(trans, root, path, &disk_key, level + 1); + wret = fixup_low_keys(trans, root, path, &disk_key, level + 1); + if (wret) + ret = wret; } btrfs_mark_buffer_dirty(parent); + return ret; } /* @@ -3787,13 +3761,17 @@ static void del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, * The path must have already been setup for deleting the leaf, including * all the proper balancing. path->nodes[1] must be locked. */ -static noinline void btrfs_del_leaf(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, - struct extent_buffer *leaf) +static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + struct extent_buffer *leaf) { + int ret; + WARN_ON(btrfs_header_generation(leaf) != trans->transid); - del_ptr(trans, root, path, 1, path->slots[1]); + ret = del_ptr(trans, root, path, 1, path->slots[1]); + if (ret) + return ret; /* * btrfs_free_extent is expensive, we want to make sure we @@ -3803,9 +3781,8 @@ static noinline void btrfs_del_leaf(struct btrfs_trans_handle *trans, root_sub_used(root, leaf->len); - extent_buffer_get(leaf); btrfs_free_tree_block(trans, root, leaf, 0, 1, 0); - free_extent_buffer_stale(leaf); + return 0; } /* * delete the item at the leaf level in path. If that empties @@ -3822,9 +3799,6 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, int wret; int i; u32 nritems; - struct btrfs_map_token token; - - btrfs_init_map_token(&token); leaf = path->nodes[0]; last_off = btrfs_item_offset_nr(leaf, slot + nr - 1); @@ -3846,9 +3820,8 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, u32 ioff; item = btrfs_item_nr(leaf, i); - ioff = btrfs_token_item_offset(leaf, item, &token); - btrfs_set_token_item_offset(leaf, item, - ioff + dsize, &token); + ioff = btrfs_item_offset(leaf, item); + btrfs_set_item_offset(leaf, item, ioff + dsize); } memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot), @@ -3866,7 +3839,8 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, } else { btrfs_set_path_blocking(path); clean_tree_block(trans, root, leaf); - btrfs_del_leaf(trans, root, path, leaf); + ret = btrfs_del_leaf(trans, root, path, leaf); + BUG_ON(ret); } } else { int used = leaf_space_used(leaf, 0, nritems); @@ -3874,7 +3848,10 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_disk_key disk_key; btrfs_item_key(leaf, &disk_key, 0); - fixup_low_keys(trans, root, path, &disk_key, 1); + wret = fixup_low_keys(trans, root, path, + &disk_key, 1); + if (wret) + ret = wret; } /* delete the leaf if it is mostly empty */ @@ -3902,9 +3879,9 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, if (btrfs_header_nritems(leaf) == 0) { path->slots[1] = slot; - btrfs_del_leaf(trans, root, path, leaf); + ret = btrfs_del_leaf(trans, root, path, leaf); + BUG_ON(ret); free_extent_buffer(leaf); - ret = 0; } else { /* if we're still in the path, make sure * we're dirty. Otherwise, one of the @@ -4052,7 +4029,7 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, tmp = btrfs_find_tree_block(root, blockptr, btrfs_level_size(root, level - 1)); - if (tmp && btrfs_buffer_uptodate(tmp, gen, 1) > 0) { + if (tmp && btrfs_buffer_uptodate(tmp, gen)) { free_extent_buffer(tmp); break; } @@ -4082,18 +4059,18 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, path->slots[level] = slot; if (level == path->lowest_level) { ret = 0; - unlock_up(path, level, 1, 0, NULL); + unlock_up(path, level, 1); goto out; } btrfs_set_path_blocking(path); cur = read_node_slot(root, cur, slot); - BUG_ON(!cur); /* -ENOMEM */ + BUG_ON(!cur); btrfs_tree_read_lock(cur); path->locks[level - 1] = BTRFS_READ_LOCK; path->nodes[level - 1] = cur; - unlock_up(path, level, 1, 0, NULL); + unlock_up(path, level, 1); btrfs_clear_path_blocking(path, NULL, 0); } out: @@ -4175,8 +4152,7 @@ int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path, struct extent_buffer *cur; cur = btrfs_find_tree_block(root, blockptr, btrfs_level_size(root, level - 1)); - if (!cur || - btrfs_buffer_uptodate(cur, gen, 1) <= 0) { + if (!cur || !btrfs_buffer_uptodate(cur, gen)) { slot++; if (cur) free_extent_buffer(cur); @@ -4330,7 +4306,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) } ret = 0; done: - unlock_up(path, 0, 1, 0, NULL); + unlock_up(path, 0, 1); path->leave_spinning = old_spinning; if (!old_spinning) btrfs_set_path_blocking(path); diff --git a/trunk/fs/btrfs/ctree.h b/trunk/fs/btrfs/ctree.h index 8fd72331d600..80b6486fd5e6 100644 --- a/trunk/fs/btrfs/ctree.h +++ b/trunk/fs/btrfs/ctree.h @@ -48,8 +48,6 @@ struct btrfs_ordered_sum; #define BTRFS_MAGIC "_BHRfS_M" -#define BTRFS_MAX_MIRRORS 2 - #define BTRFS_MAX_LEVEL 8 #define BTRFS_COMPAT_EXTENT_TREE_V0 @@ -139,12 +137,6 @@ struct btrfs_ordered_sum; #define BTRFS_EMPTY_SUBVOL_DIR_OBJECTID 2 -/* - * the max metadata block size. This limit is somewhat artificial, - * but the memmove costs go through the roof for larger blocks. - */ -#define BTRFS_MAX_METADATA_BLOCKSIZE 65536 - /* * we can actually store much bigger names, but lets not confuse the rest * of linux @@ -469,19 +461,6 @@ struct btrfs_super_block { #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1) #define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS (1ULL << 2) #define BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO (1ULL << 3) -/* - * some patches floated around with a second compression method - * lets save that incompat here for when they do get in - * Note we don't actually support it, we're just reserving the - * number - */ -#define BTRFS_FEATURE_INCOMPAT_COMPRESS_LZOv2 (1ULL << 4) - -/* - * older kernels tried to do bigger metadata blocks, but the - * code was pretty buggy. Lets not let them try anymore. - */ -#define BTRFS_FEATURE_INCOMPAT_BIG_METADATA (1ULL << 5) #define BTRFS_FEATURE_COMPAT_SUPP 0ULL #define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL @@ -489,7 +468,6 @@ struct btrfs_super_block { (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \ BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL | \ BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS | \ - BTRFS_FEATURE_INCOMPAT_BIG_METADATA | \ BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO) /* @@ -851,21 +829,6 @@ struct btrfs_csum_item { */ #define BTRFS_AVAIL_ALLOC_BIT_SINGLE (1ULL << 48) -#define BTRFS_EXTENDED_PROFILE_MASK (BTRFS_BLOCK_GROUP_PROFILE_MASK | \ - BTRFS_AVAIL_ALLOC_BIT_SINGLE) - -static inline u64 chunk_to_extended(u64 flags) -{ - if ((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0) - flags |= BTRFS_AVAIL_ALLOC_BIT_SINGLE; - - return flags; -} -static inline u64 extended_to_chunk(u64 flags) -{ - return flags & ~BTRFS_AVAIL_ALLOC_BIT_SINGLE; -} - struct btrfs_block_group_item { __le64 used; __le64 chunk_objectid; @@ -1078,7 +1041,7 @@ struct btrfs_fs_info { * is required instead of the faster short fsync log commits */ u64 last_trans_log_full_commit; - unsigned long mount_opt; + unsigned long mount_opt:21; unsigned long compress_type:4; u64 max_inline; u64 alloc_start; @@ -1540,7 +1503,6 @@ struct btrfs_ioctl_defrag_range_args { #define BTRFS_MOUNT_SKIP_BALANCE (1 << 19) #define BTRFS_MOUNT_CHECK_INTEGRITY (1 << 20) #define BTRFS_MOUNT_CHECK_INTEGRITY_INCLUDING_EXTENT_DATA (1 << 21) -#define BTRFS_MOUNT_PANIC_ON_FATAL_ERROR (1 << 22) #define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt) #define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt) @@ -1564,17 +1526,6 @@ struct btrfs_ioctl_defrag_range_args { #define BTRFS_INODE_ROOT_ITEM_INIT (1 << 31) -struct btrfs_map_token { - struct extent_buffer *eb; - char *kaddr; - unsigned long offset; -}; - -static inline void btrfs_init_map_token (struct btrfs_map_token *token) -{ - memset(token, 0, sizeof(*token)); -} - /* some macros to generate set/get funcs for the struct fields. This * assumes there is a lefoo_to_cpu for every type, so lets make a simple * one for u8: @@ -1598,22 +1549,20 @@ static inline void btrfs_init_map_token (struct btrfs_map_token *token) #ifndef BTRFS_SETGET_FUNCS #define BTRFS_SETGET_FUNCS(name, type, member, bits) \ u##bits btrfs_##name(struct extent_buffer *eb, type *s); \ -u##bits btrfs_token_##name(struct extent_buffer *eb, type *s, struct btrfs_map_token *token); \ -void btrfs_set_token_##name(struct extent_buffer *eb, type *s, u##bits val, struct btrfs_map_token *token);\ void btrfs_set_##name(struct extent_buffer *eb, type *s, u##bits val); #endif #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \ static inline u##bits btrfs_##name(struct extent_buffer *eb) \ { \ - type *p = page_address(eb->pages[0]); \ + type *p = page_address(eb->first_page); \ u##bits res = le##bits##_to_cpu(p->member); \ return res; \ } \ static inline void btrfs_set_##name(struct extent_buffer *eb, \ u##bits val) \ { \ - type *p = page_address(eb->pages[0]); \ + type *p = page_address(eb->first_page); \ p->member = cpu_to_le##bits(val); \ } @@ -2166,7 +2115,7 @@ BTRFS_SETGET_STACK_FUNCS(root_last_snapshot, struct btrfs_root_item, static inline bool btrfs_root_readonly(struct btrfs_root *root) { - return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_RDONLY)) != 0; + return root->root_item.flags & BTRFS_ROOT_SUBVOL_RDONLY; } /* struct btrfs_root_backup */ @@ -2517,7 +2466,8 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 num_bytes, u64 min_alloc_size, u64 empty_size, u64 hint_byte, - struct btrfs_key *ins, u64 data); + u64 search_end, struct btrfs_key *ins, + u64 data); int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf, int full_backref, int for_cow); int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, @@ -2534,8 +2484,8 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len); int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root, u64 start, u64 len); -void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, - struct btrfs_root *root); +int btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, + struct btrfs_root *root); int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct btrfs_root *root); int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, @@ -2598,8 +2548,8 @@ void btrfs_block_rsv_release(struct btrfs_root *root, u64 num_bytes); int btrfs_set_block_group_ro(struct btrfs_root *root, struct btrfs_block_group_cache *cache); -void btrfs_set_block_group_rw(struct btrfs_root *root, - struct btrfs_block_group_cache *cache); +int btrfs_set_block_group_rw(struct btrfs_root *root, + struct btrfs_block_group_cache *cache); void btrfs_put_block_group_cache(struct btrfs_fs_info *info); u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo); int btrfs_error_unpin_extent_range(struct btrfs_root *root, @@ -2618,9 +2568,9 @@ int btrfs_comp_cpu_keys(struct btrfs_key *k1, struct btrfs_key *k2); int btrfs_previous_item(struct btrfs_root *root, struct btrfs_path *path, u64 min_objectid, int type); -void btrfs_set_item_key_safe(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct btrfs_path *path, - struct btrfs_key *new_key); +int btrfs_set_item_key_safe(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct btrfs_path *path, + struct btrfs_key *new_key); struct extent_buffer *btrfs_root_node(struct btrfs_root *root); struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root); int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path, @@ -2640,13 +2590,12 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, struct extent_buffer **cow_ret, u64 new_root_objectid); int btrfs_block_can_be_shared(struct btrfs_root *root, struct extent_buffer *buf); -void btrfs_extend_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct btrfs_path *path, - u32 data_size); -void btrfs_truncate_item(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, - u32 new_size, int from_end); +int btrfs_extend_item(struct btrfs_trans_handle *trans, struct btrfs_root + *root, struct btrfs_path *path, u32 data_size); +int btrfs_truncate_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + u32 new_size, int from_end); int btrfs_split_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, @@ -2680,10 +2629,10 @@ static inline int btrfs_del_item(struct btrfs_trans_handle *trans, return btrfs_del_items(trans, root, path, path->slots[0], 1); } -void setup_items_for_insert(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct btrfs_path *path, - struct btrfs_key *cpu_key, u32 *data_size, - u32 total_data, u32 total_size, int nr); +int setup_items_for_insert(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct btrfs_path *path, + struct btrfs_key *cpu_key, u32 *data_size, + u32 total_data, u32 total_size, int nr); int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_key *key, void *data, u32 data_size); int btrfs_insert_empty_items(struct btrfs_trans_handle *trans, @@ -2710,9 +2659,9 @@ static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p) } int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf); -int __must_check btrfs_drop_snapshot(struct btrfs_root *root, - struct btrfs_block_rsv *block_rsv, - int update_ref, int for_reloc); +void btrfs_drop_snapshot(struct btrfs_root *root, + struct btrfs_block_rsv *block_rsv, int update_ref, + int for_reloc); int btrfs_drop_subtree(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *node, @@ -2738,6 +2687,24 @@ static inline void free_fs_info(struct btrfs_fs_info *fs_info) kfree(fs_info->super_for_commit); kfree(fs_info); } +/** + * profile_is_valid - tests whether a given profile is valid and reduced + * @flags: profile to validate + * @extended: if true @flags is treated as an extended profile + */ +static inline int profile_is_valid(u64 flags, int extended) +{ + u64 mask = ~BTRFS_BLOCK_GROUP_PROFILE_MASK; + + flags &= ~BTRFS_BLOCK_GROUP_TYPE_MASK; + if (extended) + mask &= ~BTRFS_AVAIL_ALLOC_BIT_SINGLE; + + if (flags & mask) + return 0; + /* true if zero or exactly one bit set */ + return (flags & (~flags + 1)) == flags; +} /* root-item.c */ int btrfs_find_root_ref(struct btrfs_root *tree_root, @@ -2756,10 +2723,9 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_key *key, struct btrfs_root_item *item); -int __must_check btrfs_update_root(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_key *key, - struct btrfs_root_item *item); +int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root + *root, struct btrfs_key *key, struct btrfs_root_item + *item); int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, struct btrfs_root_item *item, struct btrfs_key *key); int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid); @@ -2943,7 +2909,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root); void btrfs_orphan_commit_root(struct btrfs_trans_handle *trans, struct btrfs_root *root); int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size); -void btrfs_invalidate_inodes(struct btrfs_root *root); +int btrfs_invalidate_inodes(struct btrfs_root *root); void btrfs_add_delayed_iput(struct inode *inode); void btrfs_run_delayed_iputs(struct btrfs_root *root); int btrfs_prealloc_file_range(struct inode *inode, int mode, @@ -2995,41 +2961,13 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size); /* super.c */ int btrfs_parse_options(struct btrfs_root *root, char *options); int btrfs_sync_fs(struct super_block *sb, int wait); -void btrfs_printk(struct btrfs_fs_info *fs_info, const char *fmt, ...); void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, - unsigned int line, int errno, const char *fmt, ...); - -void __btrfs_abort_transaction(struct btrfs_trans_handle *trans, - struct btrfs_root *root, const char *function, - unsigned int line, int errno); - -#define btrfs_abort_transaction(trans, root, errno) \ -do { \ - __btrfs_abort_transaction(trans, root, __func__, \ - __LINE__, errno); \ -} while (0) + unsigned int line, int errno); #define btrfs_std_error(fs_info, errno) \ do { \ if ((errno)) \ - __btrfs_std_error((fs_info), __func__, \ - __LINE__, (errno), NULL); \ -} while (0) - -#define btrfs_error(fs_info, errno, fmt, args...) \ -do { \ - __btrfs_std_error((fs_info), __func__, __LINE__, \ - (errno), fmt, ##args); \ -} while (0) - -void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function, - unsigned int line, int errno, const char *fmt, ...); - -#define btrfs_panic(fs_info, errno, fmt, args...) \ -do { \ - struct btrfs_fs_info *_i = (fs_info); \ - __btrfs_panic(_i, __func__, __LINE__, errno, fmt, ##args); \ - BUG_ON(!(_i->mount_opt & BTRFS_MOUNT_PANIC_ON_FATAL_ERROR)); \ + __btrfs_std_error((fs_info), __func__, __LINE__, (errno));\ } while (0) /* acl.c */ @@ -3065,17 +3003,16 @@ void btrfs_reloc_cow_block(struct btrfs_trans_handle *trans, void btrfs_reloc_pre_snapshot(struct btrfs_trans_handle *trans, struct btrfs_pending_snapshot *pending, u64 *bytes_to_reserve); -int btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans, +void btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans, struct btrfs_pending_snapshot *pending); /* scrub.c */ int btrfs_scrub_dev(struct btrfs_root *root, u64 devid, u64 start, u64 end, struct btrfs_scrub_progress *progress, int readonly); -void btrfs_scrub_pause(struct btrfs_root *root); -void btrfs_scrub_pause_super(struct btrfs_root *root); -void btrfs_scrub_continue(struct btrfs_root *root); -void btrfs_scrub_continue_super(struct btrfs_root *root); -int __btrfs_scrub_cancel(struct btrfs_fs_info *info); +int btrfs_scrub_pause(struct btrfs_root *root); +int btrfs_scrub_pause_super(struct btrfs_root *root); +int btrfs_scrub_continue(struct btrfs_root *root); +int btrfs_scrub_continue_super(struct btrfs_root *root); int btrfs_scrub_cancel(struct btrfs_root *root); int btrfs_scrub_cancel_dev(struct btrfs_root *root, struct btrfs_device *dev); int btrfs_scrub_cancel_devid(struct btrfs_root *root, u64 devid); diff --git a/trunk/fs/btrfs/delayed-inode.c b/trunk/fs/btrfs/delayed-inode.c index 03e3748d84d0..fe4cd0f1cef1 100644 --- a/trunk/fs/btrfs/delayed-inode.c +++ b/trunk/fs/btrfs/delayed-inode.c @@ -115,7 +115,6 @@ static struct btrfs_delayed_node *btrfs_get_delayed_node(struct inode *inode) return NULL; } -/* Will return either the node or PTR_ERR(-ENOMEM) */ static struct btrfs_delayed_node *btrfs_get_or_create_delayed_node( struct inode *inode) { @@ -837,8 +836,10 @@ static int btrfs_batch_insert_items(struct btrfs_trans_handle *trans, btrfs_clear_path_blocking(path, NULL, 0); /* insert the keys of the items */ - setup_items_for_insert(trans, root, path, keys, data_size, - total_data_size, total_size, nitems); + ret = setup_items_for_insert(trans, root, path, keys, data_size, + total_data_size, total_size, nitems); + if (ret) + goto error; /* insert the dir index items */ slot = path->slots[0]; @@ -1107,25 +1108,16 @@ static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, return 0; } -/* - * Called when committing the transaction. - * Returns 0 on success. - * Returns < 0 on error and returns with an aborted transaction with any - * outstanding delayed items cleaned up. - */ +/* Called when committing the transaction. */ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, struct btrfs_root *root) { - struct btrfs_root *curr_root = root; struct btrfs_delayed_root *delayed_root; struct btrfs_delayed_node *curr_node, *prev_node; struct btrfs_path *path; struct btrfs_block_rsv *block_rsv; int ret = 0; - if (trans->aborted) - return -EIO; - path = btrfs_alloc_path(); if (!path) return -ENOMEM; @@ -1138,18 +1130,17 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, curr_node = btrfs_first_delayed_node(delayed_root); while (curr_node) { - curr_root = curr_node->root; - ret = btrfs_insert_delayed_items(trans, path, curr_root, + root = curr_node->root; + ret = btrfs_insert_delayed_items(trans, path, root, curr_node); if (!ret) - ret = btrfs_delete_delayed_items(trans, path, - curr_root, curr_node); + ret = btrfs_delete_delayed_items(trans, path, root, + curr_node); if (!ret) - ret = btrfs_update_delayed_inode(trans, curr_root, - path, curr_node); + ret = btrfs_update_delayed_inode(trans, root, path, + curr_node); if (ret) { btrfs_release_delayed_node(curr_node); - btrfs_abort_transaction(trans, root, ret); break; } @@ -1160,7 +1151,6 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, btrfs_free_path(path); trans->block_rsv = block_rsv; - return ret; } @@ -1381,7 +1371,6 @@ void btrfs_balance_delayed_items(struct btrfs_root *root) btrfs_wq_run_delayed_node(delayed_root, root, 0); } -/* Will return 0 or -ENOMEM */ int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, struct btrfs_root *root, const char *name, int name_len, struct inode *dir, diff --git a/trunk/fs/btrfs/delayed-ref.c b/trunk/fs/btrfs/delayed-ref.c index 69f22e3ab3bc..66e4f29505a3 100644 --- a/trunk/fs/btrfs/delayed-ref.c +++ b/trunk/fs/btrfs/delayed-ref.c @@ -420,7 +420,7 @@ update_existing_head_ref(struct btrfs_delayed_ref_node *existing, * this does all the dirty work in terms of maintaining the correct * overall modification count. */ -static noinline void add_delayed_ref_head(struct btrfs_fs_info *fs_info, +static noinline int add_delayed_ref_head(struct btrfs_fs_info *fs_info, struct btrfs_trans_handle *trans, struct btrfs_delayed_ref_node *ref, u64 bytenr, u64 num_bytes, @@ -487,19 +487,20 @@ static noinline void add_delayed_ref_head(struct btrfs_fs_info *fs_info, * we've updated the existing ref, free the newly * allocated ref */ - kfree(head_ref); + kfree(ref); } else { delayed_refs->num_heads++; delayed_refs->num_heads_ready++; delayed_refs->num_entries++; trans->delayed_ref_updates++; } + return 0; } /* * helper to insert a delayed tree ref into the rbtree. */ -static noinline void add_delayed_tree_ref(struct btrfs_fs_info *fs_info, +static noinline int add_delayed_tree_ref(struct btrfs_fs_info *fs_info, struct btrfs_trans_handle *trans, struct btrfs_delayed_ref_node *ref, u64 bytenr, u64 num_bytes, u64 parent, @@ -548,17 +549,18 @@ static noinline void add_delayed_tree_ref(struct btrfs_fs_info *fs_info, * we've updated the existing ref, free the newly * allocated ref */ - kfree(full_ref); + kfree(ref); } else { delayed_refs->num_entries++; trans->delayed_ref_updates++; } + return 0; } /* * helper to insert a delayed data ref into the rbtree. */ -static noinline void add_delayed_data_ref(struct btrfs_fs_info *fs_info, +static noinline int add_delayed_data_ref(struct btrfs_fs_info *fs_info, struct btrfs_trans_handle *trans, struct btrfs_delayed_ref_node *ref, u64 bytenr, u64 num_bytes, u64 parent, @@ -609,11 +611,12 @@ static noinline void add_delayed_data_ref(struct btrfs_fs_info *fs_info, * we've updated the existing ref, free the newly * allocated ref */ - kfree(full_ref); + kfree(ref); } else { delayed_refs->num_entries++; trans->delayed_ref_updates++; } + return 0; } /* @@ -631,6 +634,7 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info, struct btrfs_delayed_tree_ref *ref; struct btrfs_delayed_ref_head *head_ref; struct btrfs_delayed_ref_root *delayed_refs; + int ret; BUG_ON(extent_op && extent_op->is_data); ref = kmalloc(sizeof(*ref), GFP_NOFS); @@ -652,12 +656,14 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info, * insert both the head node and the new ref without dropping * the spin lock */ - add_delayed_ref_head(fs_info, trans, &head_ref->node, bytenr, + ret = add_delayed_ref_head(fs_info, trans, &head_ref->node, bytenr, num_bytes, action, 0); + BUG_ON(ret); - add_delayed_tree_ref(fs_info, trans, &ref->node, bytenr, + ret = add_delayed_tree_ref(fs_info, trans, &ref->node, bytenr, num_bytes, parent, ref_root, level, action, for_cow); + BUG_ON(ret); if (!need_ref_seq(for_cow, ref_root) && waitqueue_active(&delayed_refs->seq_wait)) wake_up(&delayed_refs->seq_wait); @@ -679,6 +685,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, struct btrfs_delayed_data_ref *ref; struct btrfs_delayed_ref_head *head_ref; struct btrfs_delayed_ref_root *delayed_refs; + int ret; BUG_ON(extent_op && !extent_op->is_data); ref = kmalloc(sizeof(*ref), GFP_NOFS); @@ -700,12 +707,14 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, * insert both the head node and the new ref without dropping * the spin lock */ - add_delayed_ref_head(fs_info, trans, &head_ref->node, bytenr, + ret = add_delayed_ref_head(fs_info, trans, &head_ref->node, bytenr, num_bytes, action, 1); + BUG_ON(ret); - add_delayed_data_ref(fs_info, trans, &ref->node, bytenr, + ret = add_delayed_data_ref(fs_info, trans, &ref->node, bytenr, num_bytes, parent, ref_root, owner, offset, action, for_cow); + BUG_ON(ret); if (!need_ref_seq(for_cow, ref_root) && waitqueue_active(&delayed_refs->seq_wait)) wake_up(&delayed_refs->seq_wait); @@ -720,6 +729,7 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, { struct btrfs_delayed_ref_head *head_ref; struct btrfs_delayed_ref_root *delayed_refs; + int ret; head_ref = kmalloc(sizeof(*head_ref), GFP_NOFS); if (!head_ref) @@ -730,9 +740,10 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, delayed_refs = &trans->transaction->delayed_refs; spin_lock(&delayed_refs->lock); - add_delayed_ref_head(fs_info, trans, &head_ref->node, bytenr, + ret = add_delayed_ref_head(fs_info, trans, &head_ref->node, bytenr, num_bytes, BTRFS_UPDATE_DELAYED_HEAD, extent_op->is_data); + BUG_ON(ret); if (waitqueue_active(&delayed_refs->seq_wait)) wake_up(&delayed_refs->seq_wait); diff --git a/trunk/fs/btrfs/dir-item.c b/trunk/fs/btrfs/dir-item.c index c1a074d0696f..31d84e78129b 100644 --- a/trunk/fs/btrfs/dir-item.c +++ b/trunk/fs/btrfs/dir-item.c @@ -49,8 +49,9 @@ static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle di = btrfs_match_dir_item_name(root, path, name, name_len); if (di) return ERR_PTR(-EEXIST); - btrfs_extend_item(trans, root, path, data_size); - } else if (ret < 0) + ret = btrfs_extend_item(trans, root, path, data_size); + } + if (ret < 0) return ERR_PTR(ret); WARN_ON(ret > 0); leaf = path->nodes[0]; @@ -115,7 +116,6 @@ int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans, * 'location' is the key to stuff into the directory item, 'type' is the * type of the inode we're pointing to, and 'index' is the sequence number * to use for the second index (if one is created). - * Will return 0 or -ENOMEM */ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, const char *name, int name_len, @@ -383,8 +383,8 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans, start = btrfs_item_ptr_offset(leaf, path->slots[0]); memmove_extent_buffer(leaf, ptr, ptr + sub_item_len, item_len - (ptr + sub_item_len - start)); - btrfs_truncate_item(trans, root, path, - item_len - sub_item_len, 1); + ret = btrfs_truncate_item(trans, root, path, + item_len - sub_item_len, 1); } return ret; } diff --git a/trunk/fs/btrfs/disk-io.c b/trunk/fs/btrfs/disk-io.c index a7ffc88a7dbe..534266fe505f 100644 --- a/trunk/fs/btrfs/disk-io.c +++ b/trunk/fs/btrfs/disk-io.c @@ -48,19 +48,20 @@ static struct extent_io_ops btree_extent_io_ops; static void end_workqueue_fn(struct btrfs_work *work); static void free_fs_root(struct btrfs_root *root); -static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info, +static void btrfs_check_super_valid(struct btrfs_fs_info *fs_info, int read_only); -static void btrfs_destroy_ordered_operations(struct btrfs_root *root); -static void btrfs_destroy_ordered_extents(struct btrfs_root *root); +static int btrfs_destroy_ordered_operations(struct btrfs_root *root); +static int 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_destroy_delalloc_inodes(struct btrfs_root *root); +static int btrfs_destroy_pending_snapshots(struct btrfs_transaction *t); +static int btrfs_destroy_delalloc_inodes(struct btrfs_root *root); static int btrfs_destroy_marked_extents(struct btrfs_root *root, struct extent_io_tree *dirty_pages, int mark); static int btrfs_destroy_pinned_extent(struct btrfs_root *root, struct extent_io_tree *pinned_extents); +static int btrfs_cleanup_transaction(struct btrfs_root *root); /* * end_io_wq structs are used to do processing in task context when an IO is @@ -98,7 +99,6 @@ struct async_submit_bio { */ u64 bio_offset; struct btrfs_work work; - int error; }; /* @@ -323,8 +323,7 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf, * in the wrong place. */ static int verify_parent_transid(struct extent_io_tree *io_tree, - struct extent_buffer *eb, u64 parent_transid, - int atomic) + struct extent_buffer *eb, u64 parent_transid) { struct extent_state *cached_state = NULL; int ret; @@ -332,12 +331,9 @@ static int verify_parent_transid(struct extent_io_tree *io_tree, if (!parent_transid || btrfs_header_generation(eb) == parent_transid) return 0; - if (atomic) - return -EAGAIN; - lock_extent_bits(io_tree, eb->start, eb->start + eb->len - 1, - 0, &cached_state); - if (extent_buffer_uptodate(eb) && + 0, &cached_state, GFP_NOFS); + if (extent_buffer_uptodate(io_tree, eb, cached_state) && btrfs_header_generation(eb) == parent_transid) { ret = 0; goto out; @@ -348,7 +344,7 @@ static int verify_parent_transid(struct extent_io_tree *io_tree, (unsigned long long)parent_transid, (unsigned long long)btrfs_header_generation(eb)); ret = 1; - clear_extent_buffer_uptodate(eb); + clear_extent_buffer_uptodate(io_tree, eb, &cached_state); out: unlock_extent_cached(io_tree, eb->start, eb->start + eb->len - 1, &cached_state, GFP_NOFS); @@ -364,11 +360,9 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root, u64 start, u64 parent_transid) { struct extent_io_tree *io_tree; - int failed = 0; int ret; int num_copies = 0; int mirror_num = 0; - int failed_mirror = 0; clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags); io_tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree; @@ -376,9 +370,9 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root, ret = read_extent_buffer_pages(io_tree, eb, start, WAIT_COMPLETE, btree_get_extent, mirror_num); - if (!ret && !verify_parent_transid(io_tree, eb, - parent_transid, 0)) - break; + if (!ret && + !verify_parent_transid(io_tree, eb, parent_transid)) + return ret; /* * This buffer's crc is fine, but its contents are corrupted, so @@ -386,30 +380,18 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root, * any less wrong. */ if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags)) - break; + return ret; num_copies = btrfs_num_copies(&root->fs_info->mapping_tree, eb->start, eb->len); if (num_copies == 1) - break; - - if (!failed_mirror) { - failed = 1; - failed_mirror = eb->read_mirror; - } + return ret; mirror_num++; - if (mirror_num == failed_mirror) - mirror_num++; - if (mirror_num > num_copies) - break; + return ret; } - - if (failed && !ret) - repair_eb_io_failure(root, eb, failed_mirror); - - return ret; + return -EIO; } /* @@ -422,27 +404,50 @@ static int csum_dirty_buffer(struct btrfs_root *root, struct page *page) struct extent_io_tree *tree; u64 start = (u64)page->index << PAGE_CACHE_SHIFT; u64 found_start; + unsigned long len; struct extent_buffer *eb; + int ret; tree = &BTRFS_I(page->mapping->host)->io_tree; - eb = (struct extent_buffer *)page->private; - if (page != eb->pages[0]) - return 0; + if (page->private == EXTENT_PAGE_PRIVATE) { + WARN_ON(1); + goto out; + } + if (!page->private) { + WARN_ON(1); + goto out; + } + len = page->private >> 2; + WARN_ON(len == 0); + + eb = alloc_extent_buffer(tree, start, len, page); + if (eb == NULL) { + WARN_ON(1); + goto out; + } + ret = btree_read_extent_buffer_pages(root, eb, start + PAGE_CACHE_SIZE, + btrfs_header_generation(eb)); + BUG_ON(ret); + WARN_ON(!btrfs_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN)); + found_start = btrfs_header_bytenr(eb); if (found_start != start) { WARN_ON(1); - return 0; + goto err; } - if (eb->pages[0] != page) { + if (eb->first_page != page) { WARN_ON(1); - return 0; + goto err; } if (!PageUptodate(page)) { WARN_ON(1); - return 0; + goto err; } csum_tree_block(root, eb, 0); +err: + free_extent_buffer(eb); +out: return 0; } @@ -532,75 +537,34 @@ static noinline int check_leaf(struct btrfs_root *root, return 0; } -struct extent_buffer *find_eb_for_page(struct extent_io_tree *tree, - struct page *page, int max_walk) -{ - struct extent_buffer *eb; - u64 start = page_offset(page); - u64 target = start; - u64 min_start; - - if (start < max_walk) - min_start = 0; - else - min_start = start - max_walk; - - while (start >= min_start) { - eb = find_extent_buffer(tree, start, 0); - if (eb) { - /* - * we found an extent buffer and it contains our page - * horray! - */ - if (eb->start <= target && - eb->start + eb->len > target) - return eb; - - /* we found an extent buffer that wasn't for us */ - free_extent_buffer(eb); - return NULL; - } - if (start == 0) - break; - start -= PAGE_CACHE_SIZE; - } - return NULL; -} - static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, - struct extent_state *state, int mirror) + struct extent_state *state) { struct extent_io_tree *tree; u64 found_start; int found_level; + unsigned long len; struct extent_buffer *eb; struct btrfs_root *root = BTRFS_I(page->mapping->host)->root; int ret = 0; - int reads_done; + tree = &BTRFS_I(page->mapping->host)->io_tree; + if (page->private == EXTENT_PAGE_PRIVATE) + goto out; if (!page->private) goto out; - tree = &BTRFS_I(page->mapping->host)->io_tree; - eb = (struct extent_buffer *)page->private; - - /* the pending IO might have been the only thing that kept this buffer - * in memory. Make sure we have a ref for all this other checks - */ - extent_buffer_get(eb); - - reads_done = atomic_dec_and_test(&eb->io_pages); - if (!reads_done) - goto err; + len = page->private >> 2; + WARN_ON(len == 0); - eb->read_mirror = mirror; - if (test_bit(EXTENT_BUFFER_IOERR, &eb->bflags)) { + eb = alloc_extent_buffer(tree, start, len, page); + if (eb == NULL) { ret = -EIO; - goto err; + goto out; } found_start = btrfs_header_bytenr(eb); - if (found_start != eb->start) { + if (found_start != start) { printk_ratelimited(KERN_INFO "btrfs bad tree block start " "%llu %llu\n", (unsigned long long)found_start, @@ -608,6 +572,13 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, ret = -EIO; goto err; } + if (eb->first_page != page) { + printk(KERN_INFO "btrfs bad first page %lu %lu\n", + eb->first_page->index, page->index); + WARN_ON(1); + ret = -EIO; + goto err; + } if (check_tree_block_fsid(root, eb)) { printk_ratelimited(KERN_INFO "btrfs bad fsid on block %llu\n", (unsigned long long)eb->start); @@ -635,31 +606,48 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, ret = -EIO; } - if (!ret) - set_extent_buffer_uptodate(eb); + end = min_t(u64, eb->len, PAGE_CACHE_SIZE); + end = eb->start + end - 1; err: if (test_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) { clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags); btree_readahead_hook(root, eb, eb->start, ret); } - if (ret) - clear_extent_buffer_uptodate(eb); free_extent_buffer(eb); out: return ret; } -static int btree_io_failed_hook(struct page *page, int failed_mirror) +static int btree_io_failed_hook(struct bio *failed_bio, + struct page *page, u64 start, u64 end, + int mirror_num, struct extent_state *state) { + struct extent_io_tree *tree; + unsigned long len; struct extent_buffer *eb; struct btrfs_root *root = BTRFS_I(page->mapping->host)->root; - eb = (struct extent_buffer *)page->private; - set_bit(EXTENT_BUFFER_IOERR, &eb->bflags); - eb->read_mirror = failed_mirror; - if (test_and_clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) + tree = &BTRFS_I(page->mapping->host)->io_tree; + if (page->private == EXTENT_PAGE_PRIVATE) + goto out; + if (!page->private) + goto out; + + len = page->private >> 2; + WARN_ON(len == 0); + + eb = alloc_extent_buffer(tree, start, len, page); + if (eb == NULL) + goto out; + + if (test_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) { + clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags); btree_readahead_hook(root, eb, eb->start, -EIO); + } + free_extent_buffer(eb); + +out: return -EIO; /* we fixed nothing */ } @@ -731,14 +719,11 @@ unsigned long btrfs_async_submit_limit(struct btrfs_fs_info *info) static void run_one_async_start(struct btrfs_work *work) { struct async_submit_bio *async; - int ret; async = container_of(work, struct async_submit_bio, work); - ret = async->submit_bio_start(async->inode, async->rw, async->bio, - async->mirror_num, async->bio_flags, - async->bio_offset); - if (ret) - async->error = ret; + async->submit_bio_start(async->inode, async->rw, async->bio, + async->mirror_num, async->bio_flags, + async->bio_offset); } static void run_one_async_done(struct btrfs_work *work) @@ -759,12 +744,6 @@ static void run_one_async_done(struct btrfs_work *work) waitqueue_active(&fs_info->async_submit_wait)) wake_up(&fs_info->async_submit_wait); - /* If an error occured we just want to clean up the bio and move on */ - if (async->error) { - bio_endio(async->bio, async->error); - return; - } - async->submit_bio_done(async->inode, async->rw, async->bio, async->mirror_num, async->bio_flags, async->bio_offset); @@ -806,8 +785,6 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode, async->bio_flags = bio_flags; async->bio_offset = bio_offset; - async->error = 0; - atomic_inc(&fs_info->nr_async_submits); if (rw & REQ_SYNC) @@ -829,18 +806,15 @@ static int btree_csum_one_bio(struct bio *bio) struct bio_vec *bvec = bio->bi_io_vec; int bio_index = 0; struct btrfs_root *root; - int ret = 0; WARN_ON(bio->bi_vcnt <= 0); while (bio_index < bio->bi_vcnt) { root = BTRFS_I(bvec->bv_page->mapping->host)->root; - ret = csum_dirty_buffer(root, bvec->bv_page); - if (ret) - break; + csum_dirty_buffer(root, bvec->bv_page); bio_index++; bvec++; } - return ret; + return 0; } static int __btree_submit_bio_start(struct inode *inode, int rw, @@ -852,7 +826,8 @@ static int __btree_submit_bio_start(struct inode *inode, int rw, * when we're called for a write, we're already in the async * submission context. Just jump into btrfs_map_bio */ - return btree_csum_one_bio(bio); + btree_csum_one_bio(bio); + return 0; } static int __btree_submit_bio_done(struct inode *inode, int rw, struct bio *bio, @@ -872,16 +847,15 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, { int ret; - if (!(rw & REQ_WRITE)) { + ret = btrfs_bio_wq_end_io(BTRFS_I(inode)->root->fs_info, + bio, 1); + BUG_ON(ret); + if (!(rw & REQ_WRITE)) { /* * called for a read, do the setup so that checksum validation * can happen in the async kernel threads */ - ret = btrfs_bio_wq_end_io(BTRFS_I(inode)->root->fs_info, - bio, 1); - if (ret) - return ret; return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, mirror_num, 0); } @@ -919,6 +893,34 @@ static int btree_migratepage(struct address_space *mapping, } #endif +static int btree_writepage(struct page *page, struct writeback_control *wbc) +{ + struct extent_io_tree *tree; + struct btrfs_root *root = BTRFS_I(page->mapping->host)->root; + struct extent_buffer *eb; + int was_dirty; + + tree = &BTRFS_I(page->mapping->host)->io_tree; + if (!(current->flags & PF_MEMALLOC)) { + return extent_write_full_page(tree, page, + btree_get_extent, wbc); + } + + redirty_page_for_writepage(wbc, page); + eb = btrfs_find_tree_block(root, page_offset(page), PAGE_CACHE_SIZE); + WARN_ON(!eb); + + was_dirty = test_and_set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags); + if (!was_dirty) { + spin_lock(&root->fs_info->delalloc_lock); + root->fs_info->dirty_metadata_bytes += PAGE_CACHE_SIZE; + spin_unlock(&root->fs_info->delalloc_lock); + } + free_extent_buffer(eb); + + unlock_page(page); + return 0; +} static int btree_writepages(struct address_space *mapping, struct writeback_control *wbc) @@ -938,7 +940,7 @@ static int btree_writepages(struct address_space *mapping, if (num_dirty < thresh) return 0; } - return btree_write_cache_pages(mapping, wbc); + return extent_writepages(tree, mapping, btree_get_extent, wbc); } static int btree_readpage(struct file *file, struct page *page) @@ -950,8 +952,16 @@ static int btree_readpage(struct file *file, struct page *page) static int btree_releasepage(struct page *page, gfp_t gfp_flags) { + struct extent_io_tree *tree; + struct extent_map_tree *map; + int ret; + if (PageWriteback(page) || PageDirty(page)) return 0; + + tree = &BTRFS_I(page->mapping->host)->io_tree; + map = &BTRFS_I(page->mapping->host)->extent_tree; + /* * We need to mask out eg. __GFP_HIGHMEM and __GFP_DMA32 as we're doing * slab allocation from alloc_extent_state down the callchain where @@ -959,7 +969,18 @@ static int btree_releasepage(struct page *page, gfp_t gfp_flags) */ gfp_flags &= ~GFP_SLAB_BUG_MASK; - return try_release_extent_buffer(page, gfp_flags); + ret = try_release_extent_state(map, tree, page, gfp_flags); + if (!ret) + return 0; + + ret = try_release_extent_buffer(tree, page); + if (ret == 1) { + ClearPagePrivate(page); + set_page_private(page, 0); + page_cache_release(page); + } + + return ret; } static void btree_invalidatepage(struct page *page, unsigned long offset) @@ -977,28 +998,15 @@ static void btree_invalidatepage(struct page *page, unsigned long offset) } } -static int btree_set_page_dirty(struct page *page) -{ - struct extent_buffer *eb; - - BUG_ON(!PagePrivate(page)); - eb = (struct extent_buffer *)page->private; - BUG_ON(!eb); - BUG_ON(!test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)); - BUG_ON(!atomic_read(&eb->refs)); - btrfs_assert_tree_locked(eb); - return __set_page_dirty_nobuffers(page); -} - static const struct address_space_operations btree_aops = { .readpage = btree_readpage, + .writepage = btree_writepage, .writepages = btree_writepages, .releasepage = btree_releasepage, .invalidatepage = btree_invalidatepage, #ifdef CONFIG_MIGRATION .migratepage = btree_migratepage, #endif - .set_page_dirty = btree_set_page_dirty, }; int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize, @@ -1041,7 +1049,7 @@ int reada_tree_block_flagged(struct btrfs_root *root, u64 bytenr, u32 blocksize, if (test_bit(EXTENT_BUFFER_CORRUPT, &buf->bflags)) { free_extent_buffer(buf); return -EIO; - } else if (extent_buffer_uptodate(buf)) { + } else if (extent_buffer_uptodate(io_tree, buf, NULL)) { *eb = buf; } else { free_extent_buffer(buf); @@ -1066,20 +1074,20 @@ struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, struct extent_buffer *eb; eb = alloc_extent_buffer(&BTRFS_I(btree_inode)->io_tree, - bytenr, blocksize); + bytenr, blocksize, NULL); return eb; } int btrfs_write_tree_block(struct extent_buffer *buf) { - return filemap_fdatawrite_range(buf->pages[0]->mapping, buf->start, + return filemap_fdatawrite_range(buf->first_page->mapping, buf->start, buf->start + buf->len - 1); } int btrfs_wait_tree_block_writeback(struct extent_buffer *buf) { - return filemap_fdatawait_range(buf->pages[0]->mapping, + return filemap_fdatawait_range(buf->first_page->mapping, buf->start, buf->start + buf->len - 1); } @@ -1094,13 +1102,17 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, return NULL; ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); + + if (ret == 0) + set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags); return buf; } -void clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, - struct extent_buffer *buf) +int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct extent_buffer *buf) { + struct inode *btree_inode = root->fs_info->btree_inode; if (btrfs_header_generation(buf) == root->fs_info->running_transaction->transid) { btrfs_assert_tree_locked(buf); @@ -1109,27 +1121,23 @@ void clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, spin_lock(&root->fs_info->delalloc_lock); if (root->fs_info->dirty_metadata_bytes >= buf->len) root->fs_info->dirty_metadata_bytes -= buf->len; - else { - spin_unlock(&root->fs_info->delalloc_lock); - btrfs_panic(root->fs_info, -EOVERFLOW, - "Can't clear %lu bytes from " - " dirty_mdatadata_bytes (%lu)", - buf->len, - root->fs_info->dirty_metadata_bytes); - } + else + WARN_ON(1); spin_unlock(&root->fs_info->delalloc_lock); } /* ugh, clear_extent_buffer_dirty needs to lock the page */ btrfs_set_lock_blocking(buf); - clear_extent_buffer_dirty(buf); + clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree, + buf); } + return 0; } -static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, - u32 stripesize, struct btrfs_root *root, - struct btrfs_fs_info *fs_info, - u64 objectid) +static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, + u32 stripesize, struct btrfs_root *root, + struct btrfs_fs_info *fs_info, + u64 objectid) { root->node = NULL; root->commit_root = NULL; @@ -1181,12 +1189,13 @@ static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, root->defrag_running = 0; root->root_key.objectid = objectid; root->anon_dev = 0; + return 0; } -static int __must_check find_and_setup_root(struct btrfs_root *tree_root, - struct btrfs_fs_info *fs_info, - u64 objectid, - struct btrfs_root *root) +static int find_and_setup_root(struct btrfs_root *tree_root, + struct btrfs_fs_info *fs_info, + u64 objectid, + struct btrfs_root *root) { int ret; u32 blocksize; @@ -1199,15 +1208,14 @@ static int __must_check find_and_setup_root(struct btrfs_root *tree_root, &root->root_item, &root->root_key); if (ret > 0) return -ENOENT; - else if (ret < 0) - return ret; + BUG_ON(ret); generation = btrfs_root_generation(&root->root_item); blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); root->commit_root = NULL; root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), blocksize, generation); - if (!root->node || !btrfs_buffer_uptodate(root->node, generation, 0)) { + if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) { free_extent_buffer(root->node); root->node = NULL; return -EIO; @@ -1369,7 +1377,7 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), blocksize, generation); root->commit_root = btrfs_root_node(root); - BUG_ON(!root->node); /* -ENOMEM */ + BUG_ON(!root->node); out: if (location->objectid != BTRFS_TREE_LOG_OBJECTID) { root->ref_cows = 1; @@ -1505,6 +1513,41 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi) return 0; } +static int bio_ready_for_csum(struct bio *bio) +{ + u64 length = 0; + u64 buf_len = 0; + u64 start = 0; + struct page *page; + struct extent_io_tree *io_tree = NULL; + struct bio_vec *bvec; + int i; + int ret; + + bio_for_each_segment(bvec, bio, i) { + page = bvec->bv_page; + if (page->private == EXTENT_PAGE_PRIVATE) { + length += bvec->bv_len; + continue; + } + if (!page->private) { + length += bvec->bv_len; + continue; + } + length = bvec->bv_len; + buf_len = page->private >> 2; + start = page_offset(page) + bvec->bv_offset; + io_tree = &BTRFS_I(page->mapping->host)->io_tree; + } + /* are we fully contained in this bio? */ + if (buf_len <= length) + return 1; + + ret = extent_range_uptodate(io_tree, start + length, + start + buf_len - 1); + return ret; +} + /* * called by the kthread helper functions to finally call the bio end_io * functions. This is where read checksum verification actually happens @@ -1520,6 +1563,17 @@ static void end_workqueue_fn(struct btrfs_work *work) bio = end_io_wq->bio; fs_info = end_io_wq->info; + /* metadata bio reads are special because the whole tree block must + * be checksummed at once. This makes sure the entire block is in + * ram and up to date before trying to verify things. For + * blocksize <= pagesize, it is basically a noop + */ + if (!(bio->bi_rw & REQ_WRITE) && end_io_wq->metadata && + !bio_ready_for_csum(bio)) { + btrfs_queue_worker(&fs_info->endio_meta_workers, + &end_io_wq->work); + return; + } error = end_io_wq->error; bio->bi_private = end_io_wq->private; bio->bi_end_io = end_io_wq->end_io; @@ -1560,10 +1614,9 @@ static int transaction_kthread(void *arg) u64 transid; unsigned long now; unsigned long delay; - bool cannot_commit; + int ret; do { - cannot_commit = false; delay = HZ * 30; vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); mutex_lock(&root->fs_info->transaction_kthread_mutex); @@ -1585,14 +1638,11 @@ static int transaction_kthread(void *arg) transid = cur->transid; spin_unlock(&root->fs_info->trans_lock); - /* If the file system is aborted, this will always fail. */ trans = btrfs_join_transaction(root); - if (IS_ERR(trans)) { - cannot_commit = true; - goto sleep; - } + BUG_ON(IS_ERR(trans)); if (transid == trans->transid) { - btrfs_commit_transaction(trans, root); + ret = btrfs_commit_transaction(trans, root); + BUG_ON(ret); } else { btrfs_end_transaction(trans, root); } @@ -1603,8 +1653,7 @@ static int transaction_kthread(void *arg) if (!try_to_freeze()) { set_current_state(TASK_INTERRUPTIBLE); if (!kthread_should_stop() && - (!btrfs_transaction_blocked(root->fs_info) || - cannot_commit)) + !btrfs_transaction_blocked(root->fs_info)) schedule_timeout(delay); __set_current_state(TASK_RUNNING); } @@ -1993,7 +2042,6 @@ int open_ctree(struct super_block *sb, RB_CLEAR_NODE(&BTRFS_I(fs_info->btree_inode)->rb_node); extent_io_tree_init(&BTRFS_I(fs_info->btree_inode)->io_tree, fs_info->btree_inode->i_mapping); - BTRFS_I(fs_info->btree_inode)->io_tree.track_uptodate = 0; extent_map_tree_init(&BTRFS_I(fs_info->btree_inode)->extent_tree); BTRFS_I(fs_info->btree_inode)->io_tree.ops = &btree_extent_io_ops; @@ -2036,7 +2084,6 @@ int open_ctree(struct super_block *sb, __setup_root(4096, 4096, 4096, 4096, tree_root, fs_info, BTRFS_ROOT_TREE_OBJECTID); - invalidate_bdev(fs_devices->latest_bdev); bh = btrfs_read_dev_super(fs_devices->latest_bdev); if (!bh) { err = -EINVAL; @@ -2057,12 +2104,7 @@ int open_ctree(struct super_block *sb, /* check FS state, whether FS is broken. */ fs_info->fs_state |= btrfs_super_flags(disk_super); - ret = btrfs_check_super_valid(fs_info, sb->s_flags & MS_RDONLY); - if (ret) { - printk(KERN_ERR "btrfs: superblock contains fatal errors\n"); - err = ret; - goto fail_alloc; - } + btrfs_check_super_valid(fs_info, sb->s_flags & MS_RDONLY); /* * run through our array of backup supers and setup @@ -2093,55 +2135,10 @@ int open_ctree(struct super_block *sb, goto fail_alloc; } - if (btrfs_super_leafsize(disk_super) != - btrfs_super_nodesize(disk_super)) { - printk(KERN_ERR "BTRFS: couldn't mount because metadata " - "blocksizes don't match. node %d leaf %d\n", - btrfs_super_nodesize(disk_super), - btrfs_super_leafsize(disk_super)); - err = -EINVAL; - goto fail_alloc; - } - if (btrfs_super_leafsize(disk_super) > BTRFS_MAX_METADATA_BLOCKSIZE) { - printk(KERN_ERR "BTRFS: couldn't mount because metadata " - "blocksize (%d) was too large\n", - btrfs_super_leafsize(disk_super)); - err = -EINVAL; - goto fail_alloc; - } - features = btrfs_super_incompat_flags(disk_super); features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF; if (tree_root->fs_info->compress_type & BTRFS_COMPRESS_LZO) features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO; - - /* - * flag our filesystem as having big metadata blocks if - * they are bigger than the page size - */ - if (btrfs_super_leafsize(disk_super) > PAGE_CACHE_SIZE) { - if (!(features & BTRFS_FEATURE_INCOMPAT_BIG_METADATA)) - printk(KERN_INFO "btrfs flagging fs with big metadata feature\n"); - features |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA; - } - - nodesize = btrfs_super_nodesize(disk_super); - leafsize = btrfs_super_leafsize(disk_super); - sectorsize = btrfs_super_sectorsize(disk_super); - stripesize = btrfs_super_stripesize(disk_super); - - /* - * mixed block groups end up with duplicate but slightly offset - * extent buffers for the same range. It leads to corruptions - */ - if ((features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) && - (sectorsize != leafsize)) { - printk(KERN_WARNING "btrfs: unequal leaf/node/sector sizes " - "are not allowed for mixed block groups on %s\n", - sb->s_id); - goto fail_alloc; - } - btrfs_set_super_incompat_flags(disk_super, features); features = btrfs_super_compat_ro_flags(disk_super) & @@ -2245,6 +2242,10 @@ int open_ctree(struct super_block *sb, fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages, 4 * 1024 * 1024 / PAGE_CACHE_SIZE); + nodesize = btrfs_super_nodesize(disk_super); + leafsize = btrfs_super_leafsize(disk_super); + sectorsize = btrfs_super_sectorsize(disk_super); + stripesize = btrfs_super_stripesize(disk_super); tree_root->nodesize = nodesize; tree_root->leafsize = leafsize; tree_root->sectorsize = sectorsize; @@ -2259,9 +2260,9 @@ int open_ctree(struct super_block *sb, goto fail_sb_buffer; } - if (sectorsize != PAGE_SIZE) { - printk(KERN_WARNING "btrfs: Incompatible sector size(%lu) " - "found on %s\n", (unsigned long)sectorsize, sb->s_id); + if (sectorsize < PAGE_SIZE) { + printk(KERN_WARNING "btrfs: Incompatible sector size " + "found on %s\n", sb->s_id); goto fail_sb_buffer; } @@ -2284,7 +2285,7 @@ int open_ctree(struct super_block *sb, chunk_root->node = read_tree_block(chunk_root, btrfs_super_chunk_root(disk_super), blocksize, generation); - BUG_ON(!chunk_root->node); /* -ENOMEM */ + BUG_ON(!chunk_root->node); if (!test_bit(EXTENT_BUFFER_UPTODATE, &chunk_root->node->bflags)) { printk(KERN_WARNING "btrfs: failed to read chunk root on %s\n", sb->s_id); @@ -2424,31 +2425,21 @@ int open_ctree(struct super_block *sb, log_tree_root->node = read_tree_block(tree_root, bytenr, blocksize, generation + 1); - /* returns with log_tree_root freed on success */ ret = btrfs_recover_log_trees(log_tree_root); - if (ret) { - btrfs_error(tree_root->fs_info, ret, - "Failed to recover log tree"); - free_extent_buffer(log_tree_root->node); - kfree(log_tree_root); - goto fail_trans_kthread; - } + BUG_ON(ret); if (sb->s_flags & MS_RDONLY) { - ret = btrfs_commit_super(tree_root); - if (ret) - goto fail_trans_kthread; + ret = btrfs_commit_super(tree_root); + BUG_ON(ret); } } ret = btrfs_find_orphan_roots(tree_root); - if (ret) - goto fail_trans_kthread; + BUG_ON(ret); if (!(sb->s_flags & MS_RDONLY)) { ret = btrfs_cleanup_fs_roots(fs_info); - if (ret) { - } + BUG_ON(ret); ret = btrfs_recover_relocation(tree_root); if (ret < 0) { @@ -2868,8 +2859,6 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors) if (total_errors > max_errors) { printk(KERN_ERR "btrfs: %d errors while writing supers\n", total_errors); - - /* This shouldn't happen. FUA is masked off if unsupported */ BUG(); } @@ -2886,9 +2875,9 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors) } mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); if (total_errors > max_errors) { - btrfs_error(root->fs_info, -EIO, - "%d errors while writing supers", total_errors); - return -EIO; + printk(KERN_ERR "btrfs: %d errors while writing supers\n", + total_errors); + BUG(); } return 0; } @@ -2902,20 +2891,7 @@ int write_ctree_super(struct btrfs_trans_handle *trans, return ret; } -/* Kill all outstanding I/O */ -void btrfs_abort_devices(struct btrfs_root *root) -{ - struct list_head *head; - struct btrfs_device *dev; - mutex_lock(&root->fs_info->fs_devices->device_list_mutex); - head = &root->fs_info->fs_devices->devices; - list_for_each_entry_rcu(dev, head, dev_list) { - blk_abort_queue(dev->bdev->bd_disk->queue); - } - mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); -} - -void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root) +int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root) { spin_lock(&fs_info->fs_roots_radix_lock); radix_tree_delete(&fs_info->fs_roots_radix, @@ -2928,6 +2904,7 @@ void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root) __btrfs_remove_free_space_cache(root->free_ino_pinned); __btrfs_remove_free_space_cache(root->free_ino_ctl); free_fs_root(root); + return 0; } static void free_fs_root(struct btrfs_root *root) @@ -2944,7 +2921,7 @@ static void free_fs_root(struct btrfs_root *root) kfree(root); } -static void del_fs_roots(struct btrfs_fs_info *fs_info) +static int del_fs_roots(struct btrfs_fs_info *fs_info) { int ret; struct btrfs_root *gang[8]; @@ -2973,6 +2950,7 @@ static void del_fs_roots(struct btrfs_fs_info *fs_info) for (i = 0; i < ret; i++) btrfs_free_fs_root(fs_info, gang[i]); } + return 0; } int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info) @@ -3021,21 +2999,14 @@ int btrfs_commit_super(struct btrfs_root *root) if (IS_ERR(trans)) return PTR_ERR(trans); ret = btrfs_commit_transaction(trans, root); - if (ret) - return ret; + BUG_ON(ret); /* run commit again to drop the original snapshot */ trans = btrfs_join_transaction(root); if (IS_ERR(trans)) return PTR_ERR(trans); - ret = btrfs_commit_transaction(trans, root); - if (ret) - return ret; + btrfs_commit_transaction(trans, root); ret = btrfs_write_and_wait_transaction(NULL, root); - if (ret) { - btrfs_error(root->fs_info, ret, - "Failed to sync btree inode to disk."); - return ret; - } + BUG_ON(ret); ret = write_ctree_super(NULL, root, 0); return ret; @@ -3148,32 +3119,33 @@ int close_ctree(struct btrfs_root *root) return 0; } -int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, - int atomic) +int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid) { int ret; - struct inode *btree_inode = buf->pages[0]->mapping->host; + struct inode *btree_inode = buf->first_page->mapping->host; - ret = extent_buffer_uptodate(buf); + ret = extent_buffer_uptodate(&BTRFS_I(btree_inode)->io_tree, buf, + NULL); if (!ret) return ret; ret = verify_parent_transid(&BTRFS_I(btree_inode)->io_tree, buf, - parent_transid, atomic); - if (ret == -EAGAIN) - return ret; + parent_transid); return !ret; } int btrfs_set_buffer_uptodate(struct extent_buffer *buf) { - return set_extent_buffer_uptodate(buf); + struct inode *btree_inode = buf->first_page->mapping->host; + return set_extent_buffer_uptodate(&BTRFS_I(btree_inode)->io_tree, + buf); } void btrfs_mark_buffer_dirty(struct extent_buffer *buf) { - struct btrfs_root *root = BTRFS_I(buf->pages[0]->mapping->host)->root; + struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root; u64 transid = btrfs_header_generation(buf); + struct inode *btree_inode = root->fs_info->btree_inode; int was_dirty; btrfs_assert_tree_locked(buf); @@ -3185,7 +3157,8 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) (unsigned long long)root->fs_info->generation); WARN_ON(1); } - was_dirty = set_extent_buffer_dirty(buf); + was_dirty = set_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree, + buf); if (!was_dirty) { spin_lock(&root->fs_info->delalloc_lock); root->fs_info->dirty_metadata_bytes += buf->len; @@ -3239,8 +3212,12 @@ void __btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid) { - struct btrfs_root *root = BTRFS_I(buf->pages[0]->mapping->host)->root; - return btree_read_extent_buffer_pages(root, buf, 0, parent_transid); + struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root; + int ret; + ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); + if (ret == 0) + set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags); + return ret; } static int btree_lock_page_hook(struct page *page, void *data, @@ -3248,21 +3225,17 @@ static int btree_lock_page_hook(struct page *page, void *data, { struct inode *inode = page->mapping->host; struct btrfs_root *root = BTRFS_I(inode)->root; + struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; struct extent_buffer *eb; + unsigned long len; + u64 bytenr = page_offset(page); - /* - * We culled this eb but the page is still hanging out on the mapping, - * carry on. - */ - if (!PagePrivate(page)) + if (page->private == EXTENT_PAGE_PRIVATE) goto out; - eb = (struct extent_buffer *)page->private; - if (!eb) { - WARN_ON(1); - goto out; - } - if (page != eb->pages[0]) + len = page->private >> 2; + eb = find_extent_buffer(io_tree, bytenr, len); + if (!eb) goto out; if (!btrfs_try_tree_write_lock(eb)) { @@ -3281,6 +3254,7 @@ static int btree_lock_page_hook(struct page *page, void *data, } btrfs_tree_unlock(eb); + free_extent_buffer(eb); out: if (!trylock_page(page)) { flush_fn(data); @@ -3289,23 +3263,15 @@ static int btree_lock_page_hook(struct page *page, void *data, return 0; } -static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info, +static void btrfs_check_super_valid(struct btrfs_fs_info *fs_info, int read_only) { - if (btrfs_super_csum_type(fs_info->super_copy) >= ARRAY_SIZE(btrfs_csum_sizes)) { - printk(KERN_ERR "btrfs: unsupported checksum algorithm\n"); - return -EINVAL; - } - if (read_only) - return 0; + return; - if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { + if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) printk(KERN_WARNING "warning: mount fs with errors, " "running btrfsck is recommended\n"); - } - - return 0; } int btrfs_error_commit_super(struct btrfs_root *root) @@ -3327,7 +3293,7 @@ int btrfs_error_commit_super(struct btrfs_root *root) return ret; } -static void btrfs_destroy_ordered_operations(struct btrfs_root *root) +static int btrfs_destroy_ordered_operations(struct btrfs_root *root) { struct btrfs_inode *btrfs_inode; struct list_head splice; @@ -3349,9 +3315,11 @@ static void btrfs_destroy_ordered_operations(struct btrfs_root *root) spin_unlock(&root->fs_info->ordered_extent_lock); mutex_unlock(&root->fs_info->ordered_operations_mutex); + + return 0; } -static void btrfs_destroy_ordered_extents(struct btrfs_root *root) +static int btrfs_destroy_ordered_extents(struct btrfs_root *root) { struct list_head splice; struct btrfs_ordered_extent *ordered; @@ -3383,10 +3351,12 @@ static void btrfs_destroy_ordered_extents(struct btrfs_root *root) } spin_unlock(&root->fs_info->ordered_extent_lock); + + return 0; } -int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, - struct btrfs_root *root) +static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, + struct btrfs_root *root) { struct rb_node *node; struct btrfs_delayed_ref_root *delayed_refs; @@ -3395,7 +3365,6 @@ int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, delayed_refs = &trans->delayed_refs; -again: spin_lock(&delayed_refs->lock); if (delayed_refs->num_entries == 0) { spin_unlock(&delayed_refs->lock); @@ -3417,7 +3386,6 @@ int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, struct btrfs_delayed_ref_head *head; head = btrfs_delayed_node_to_head(ref); - spin_unlock(&delayed_refs->lock); mutex_lock(&head->mutex); kfree(head->extent_op); delayed_refs->num_heads--; @@ -3425,9 +3393,8 @@ int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, delayed_refs->num_heads_ready--; list_del_init(&head->cluster); mutex_unlock(&head->mutex); - btrfs_put_delayed_ref(ref); - goto again; } + spin_unlock(&delayed_refs->lock); btrfs_put_delayed_ref(ref); @@ -3440,7 +3407,7 @@ int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, return ret; } -static void btrfs_destroy_pending_snapshots(struct btrfs_transaction *t) +static int btrfs_destroy_pending_snapshots(struct btrfs_transaction *t) { struct btrfs_pending_snapshot *snapshot; struct list_head splice; @@ -3458,9 +3425,11 @@ static void btrfs_destroy_pending_snapshots(struct btrfs_transaction *t) kfree(snapshot); } + + return 0; } -static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root) +static int btrfs_destroy_delalloc_inodes(struct btrfs_root *root) { struct btrfs_inode *btrfs_inode; struct list_head splice; @@ -3480,6 +3449,8 @@ static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root) } spin_unlock(&root->fs_info->delalloc_lock); + + return 0; } static int btrfs_destroy_marked_extents(struct btrfs_root *root, @@ -3570,43 +3541,13 @@ static int btrfs_destroy_pinned_extent(struct btrfs_root *root, return 0; } -void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans, - struct btrfs_root *root) -{ - btrfs_destroy_delayed_refs(cur_trans, root); - btrfs_block_rsv_release(root, &root->fs_info->trans_block_rsv, - cur_trans->dirty_pages.dirty_bytes); - - /* FIXME: cleanup wait for commit */ - cur_trans->in_commit = 1; - cur_trans->blocked = 1; - if (waitqueue_active(&root->fs_info->transaction_blocked_wait)) - wake_up(&root->fs_info->transaction_blocked_wait); - - cur_trans->blocked = 0; - if (waitqueue_active(&root->fs_info->transaction_wait)) - wake_up(&root->fs_info->transaction_wait); - - cur_trans->commit_done = 1; - if (waitqueue_active(&cur_trans->commit_wait)) - wake_up(&cur_trans->commit_wait); - - btrfs_destroy_pending_snapshots(cur_trans); - - btrfs_destroy_marked_extents(root, &cur_trans->dirty_pages, - EXTENT_DIRTY); - - /* - memset(cur_trans, 0, sizeof(*cur_trans)); - kmem_cache_free(btrfs_transaction_cachep, cur_trans); - */ -} - -int btrfs_cleanup_transaction(struct btrfs_root *root) +static int btrfs_cleanup_transaction(struct btrfs_root *root) { struct btrfs_transaction *t; LIST_HEAD(list); + WARN_ON(1); + mutex_lock(&root->fs_info->transaction_kthread_mutex); spin_lock(&root->fs_info->trans_lock); @@ -3671,17 +3612,6 @@ int btrfs_cleanup_transaction(struct btrfs_root *root) return 0; } -static int btree_writepage_io_failed_hook(struct bio *bio, struct page *page, - u64 start, u64 end, - struct extent_state *state) -{ - struct super_block *sb = page->mapping->host->i_sb; - struct btrfs_fs_info *fs_info = btrfs_sb(sb); - btrfs_error(fs_info, -EIO, - "Error occured while writing out btree at %llu", start); - return -EIO; -} - static struct extent_io_ops btree_extent_io_ops = { .write_cache_pages_lock_hook = btree_lock_page_hook, .readpage_end_io_hook = btree_readpage_end_io_hook, @@ -3689,5 +3619,4 @@ static struct extent_io_ops btree_extent_io_ops = { .submit_bio_hook = btree_submit_bio_hook, /* note we're sharing with inode.c for the merge bio hook */ .merge_bio_hook = btrfs_merge_bio_hook, - .writepage_io_failed_hook = btree_writepage_io_failed_hook, }; diff --git a/trunk/fs/btrfs/disk-io.h b/trunk/fs/btrfs/disk-io.h index ab1830aaf0ed..e4bc4741319b 100644 --- a/trunk/fs/btrfs/disk-io.h +++ b/trunk/fs/btrfs/disk-io.h @@ -44,8 +44,8 @@ int reada_tree_block_flagged(struct btrfs_root *root, u64 bytenr, u32 blocksize, int mirror_num, struct extent_buffer **eb); struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize); -void clean_tree_block(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct extent_buffer *buf); +int clean_tree_block(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct extent_buffer *buf); int open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_devices, char *options); @@ -64,10 +64,9 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info, int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info); void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr); void __btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr); -void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root); +int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root); void btrfs_mark_buffer_dirty(struct extent_buffer *buf); -int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, - int atomic); +int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid); int btrfs_set_buffer_uptodate(struct extent_buffer *buf); int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid); u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len); @@ -86,10 +85,6 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info); int btrfs_add_log_tree(struct btrfs_trans_handle *trans, struct btrfs_root *root); -int btrfs_cleanup_transaction(struct btrfs_root *root); -void btrfs_cleanup_one_transaction(struct btrfs_transaction *trans, - struct btrfs_root *root); -void btrfs_abort_devices(struct btrfs_root *root); #ifdef CONFIG_DEBUG_LOCK_ALLOC void btrfs_init_lockdep(void); diff --git a/trunk/fs/btrfs/export.c b/trunk/fs/btrfs/export.c index e887ee62b6d4..5f77166fd01c 100644 --- a/trunk/fs/btrfs/export.c +++ b/trunk/fs/btrfs/export.c @@ -193,7 +193,7 @@ static struct dentry *btrfs_get_parent(struct dentry *child) if (ret < 0) goto fail; - BUG_ON(ret == 0); /* Key with offset of -1 found */ + BUG_ON(ret == 0); if (path->slots[0] == 0) { ret = -ENOENT; goto fail; diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index 49fd7b66d57b..37e0a800d34e 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -245,7 +245,7 @@ static int exclude_super_stripes(struct btrfs_root *root, cache->bytes_super += stripe_len; ret = add_excluded_extent(root, cache->key.objectid, stripe_len); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { @@ -253,13 +253,13 @@ static int exclude_super_stripes(struct btrfs_root *root, ret = btrfs_rmap_block(&root->fs_info->mapping_tree, cache->key.objectid, bytenr, 0, &logical, &nr, &stripe_len); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); while (nr--) { cache->bytes_super += stripe_len; ret = add_excluded_extent(root, logical[nr], stripe_len); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } kfree(logical); @@ -321,7 +321,7 @@ static u64 add_new_free_space(struct btrfs_block_group_cache *block_group, total_added += size; ret = btrfs_add_free_space(block_group, start, size); - BUG_ON(ret); /* -ENOMEM or logic error */ + BUG_ON(ret); start = extent_end + 1; } else { break; @@ -332,7 +332,7 @@ static u64 add_new_free_space(struct btrfs_block_group_cache *block_group, size = end - start; total_added += size; ret = btrfs_add_free_space(block_group, start, size); - BUG_ON(ret); /* -ENOMEM or logic error */ + BUG_ON(ret); } return total_added; @@ -474,8 +474,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, int ret = 0; caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_NOFS); - if (!caching_ctl) - return -ENOMEM; + BUG_ON(!caching_ctl); INIT_LIST_HEAD(&caching_ctl->list); mutex_init(&caching_ctl->mutex); @@ -529,7 +528,9 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, * allocate blocks for the tree root we can't do the fast caching since * we likely hold important locks. */ - if (fs_info->mount_opt & BTRFS_MOUNT_SPACE_CACHE) { + if (trans && (!trans->transaction->in_commit) && + (root && root != root->fs_info->tree_root) && + btrfs_test_opt(root, SPACE_CACHE)) { ret = load_free_space_cache(fs_info, cache); spin_lock(&cache->lock); @@ -981,7 +982,7 @@ static int convert_extent_item_v0(struct btrfs_trans_handle *trans, ret = btrfs_next_leaf(root, path); if (ret < 0) return ret; - BUG_ON(ret > 0); /* Corruption */ + BUG_ON(ret > 0); leaf = path->nodes[0]; } btrfs_item_key_to_cpu(leaf, &found_key, @@ -1007,9 +1008,9 @@ static int convert_extent_item_v0(struct btrfs_trans_handle *trans, new_size + extra_size, 1); if (ret < 0) return ret; - BUG_ON(ret); /* Corruption */ + BUG_ON(ret); - btrfs_extend_item(trans, root, path, new_size); + ret = btrfs_extend_item(trans, root, path, new_size); leaf = path->nodes[0]; item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); @@ -1477,11 +1478,7 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans, err = ret; goto out; } - if (ret && !insert) { - err = -ENOENT; - goto out; - } - BUG_ON(ret); /* Corruption */ + BUG_ON(ret); leaf = path->nodes[0]; item_size = btrfs_item_size_nr(leaf, path->slots[0]); @@ -1595,13 +1592,13 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans, * helper to add new inline back ref */ static noinline_for_stack -void setup_inline_extent_backref(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, - struct btrfs_extent_inline_ref *iref, - u64 parent, u64 root_objectid, - u64 owner, u64 offset, int refs_to_add, - struct btrfs_delayed_extent_op *extent_op) +int setup_inline_extent_backref(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + struct btrfs_extent_inline_ref *iref, + u64 parent, u64 root_objectid, + u64 owner, u64 offset, int refs_to_add, + struct btrfs_delayed_extent_op *extent_op) { struct extent_buffer *leaf; struct btrfs_extent_item *ei; @@ -1611,6 +1608,7 @@ void setup_inline_extent_backref(struct btrfs_trans_handle *trans, u64 refs; int size; int type; + int ret; leaf = path->nodes[0]; ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); @@ -1619,7 +1617,7 @@ void setup_inline_extent_backref(struct btrfs_trans_handle *trans, type = extent_ref_type(parent, owner); size = btrfs_extent_inline_ref_size(type); - btrfs_extend_item(trans, root, path, size); + ret = btrfs_extend_item(trans, root, path, size); ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item); refs = btrfs_extent_refs(leaf, ei); @@ -1654,6 +1652,7 @@ void setup_inline_extent_backref(struct btrfs_trans_handle *trans, btrfs_set_extent_inline_ref_offset(leaf, iref, root_objectid); } btrfs_mark_buffer_dirty(leaf); + return 0; } static int lookup_extent_backref(struct btrfs_trans_handle *trans, @@ -1688,12 +1687,12 @@ static int lookup_extent_backref(struct btrfs_trans_handle *trans, * helper to update/remove inline back ref */ static noinline_for_stack -void update_inline_extent_backref(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, - struct btrfs_extent_inline_ref *iref, - int refs_to_mod, - struct btrfs_delayed_extent_op *extent_op) +int update_inline_extent_backref(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + struct btrfs_extent_inline_ref *iref, + int refs_to_mod, + struct btrfs_delayed_extent_op *extent_op) { struct extent_buffer *leaf; struct btrfs_extent_item *ei; @@ -1704,6 +1703,7 @@ void update_inline_extent_backref(struct btrfs_trans_handle *trans, u32 item_size; int size; int type; + int ret; u64 refs; leaf = path->nodes[0]; @@ -1745,9 +1745,10 @@ void update_inline_extent_backref(struct btrfs_trans_handle *trans, memmove_extent_buffer(leaf, ptr, ptr + size, end - ptr - size); item_size -= size; - btrfs_truncate_item(trans, root, path, item_size, 1); + ret = btrfs_truncate_item(trans, root, path, item_size, 1); } btrfs_mark_buffer_dirty(leaf); + return 0; } static noinline_for_stack @@ -1767,13 +1768,13 @@ int insert_inline_extent_backref(struct btrfs_trans_handle *trans, root_objectid, owner, offset, 1); if (ret == 0) { BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID); - update_inline_extent_backref(trans, root, path, iref, - refs_to_add, extent_op); + ret = update_inline_extent_backref(trans, root, path, iref, + refs_to_add, extent_op); } else if (ret == -ENOENT) { - setup_inline_extent_backref(trans, root, path, iref, parent, - root_objectid, owner, offset, - refs_to_add, extent_op); - ret = 0; + ret = setup_inline_extent_backref(trans, root, path, iref, + parent, root_objectid, + owner, offset, refs_to_add, + extent_op); } return ret; } @@ -1803,12 +1804,12 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans, struct btrfs_extent_inline_ref *iref, int refs_to_drop, int is_data) { - int ret = 0; + int ret; BUG_ON(!is_data && refs_to_drop != 1); if (iref) { - update_inline_extent_backref(trans, root, path, iref, - -refs_to_drop, NULL); + ret = update_inline_extent_backref(trans, root, path, iref, + -refs_to_drop, NULL); } else if (is_data) { ret = remove_extent_data_ref(trans, root, path, refs_to_drop); } else { @@ -1834,7 +1835,6 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, /* Tell the block device(s) that the sectors can be discarded */ ret = btrfs_map_block(&root->fs_info->mapping_tree, REQ_DISCARD, bytenr, &num_bytes, &bbio, 0); - /* Error condition is -ENOMEM */ if (!ret) { struct btrfs_bio_stripe *stripe = bbio->stripes; int i; @@ -1850,7 +1850,7 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, if (!ret) discarded_bytes += stripe->length; else if (ret != -EOPNOTSUPP) - break; /* Logic errors or -ENOMEM, or -EIO but I don't know how that could happen JDM */ + break; /* * Just in case we get back EOPNOTSUPP for some reason, @@ -1869,7 +1869,6 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, return ret; } -/* Can return -ENOMEM */ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytenr, u64 num_bytes, u64 parent, @@ -1945,8 +1944,7 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, ret = insert_extent_backref(trans, root->fs_info->extent_root, path, bytenr, parent, root_objectid, owner, offset, refs_to_add); - if (ret) - btrfs_abort_transaction(trans, root, ret); + BUG_ON(ret); out: btrfs_free_path(path); return err; @@ -2033,9 +2031,6 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans, int ret; int err = 0; - if (trans->aborted) - return 0; - path = btrfs_alloc_path(); if (!path) return -ENOMEM; @@ -2133,11 +2128,7 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans, struct btrfs_delayed_extent_op *extent_op, int insert_reserved) { - int ret = 0; - - if (trans->aborted) - return 0; - + int ret; if (btrfs_delayed_ref_is_head(node)) { struct btrfs_delayed_ref_head *head; /* @@ -2155,10 +2146,11 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans, ret = btrfs_del_csums(trans, root, node->bytenr, node->num_bytes); + BUG_ON(ret); } } mutex_unlock(&head->mutex); - return ret; + return 0; } if (node->type == BTRFS_TREE_BLOCK_REF_KEY || @@ -2205,10 +2197,6 @@ select_delayed_ref(struct btrfs_delayed_ref_head *head) return NULL; } -/* - * Returns 0 on success or if called with an already aborted transaction. - * Returns -ENOMEM or -EIO on failure and will abort the transaction. - */ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct list_head *cluster) @@ -2297,14 +2285,9 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans, ret = run_delayed_extent_op(trans, root, ref, extent_op); + BUG_ON(ret); kfree(extent_op); - if (ret) { - printk(KERN_DEBUG "btrfs: run_delayed_extent_op returned %d\n", ret); - spin_lock(&delayed_refs->lock); - return ret; - } - goto next; } @@ -2325,17 +2308,11 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans, ret = run_one_delayed_ref(trans, root, ref, extent_op, must_insert_reserved); + BUG_ON(ret); btrfs_put_delayed_ref(ref); kfree(extent_op); count++; - - if (ret) { - printk(KERN_DEBUG "btrfs: run_one_delayed_ref returned %d\n", ret); - spin_lock(&delayed_refs->lock); - return ret; - } - next: do_chunk_alloc(trans, root->fs_info->extent_root, 2 * 1024 * 1024, @@ -2370,9 +2347,6 @@ static void wait_for_more_refs(struct btrfs_delayed_ref_root *delayed_refs, * 0, which means to process everything in the tree at the start * of the run (but not newly added entries), or it can be some target * number you'd like to process. - * - * Returns 0 on success or if called with an aborted transaction - * Returns <0 on error and aborts the transaction */ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, struct btrfs_root *root, unsigned long count) @@ -2388,10 +2362,6 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, unsigned long num_refs = 0; int consider_waiting; - /* We'll clean this up in btrfs_cleanup_transaction */ - if (trans->aborted) - return 0; - if (root == root->fs_info->extent_root) root = root->fs_info->tree_root; @@ -2449,11 +2419,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, } ret = run_clustered_refs(trans, root, &cluster); - if (ret < 0) { - spin_unlock(&delayed_refs->lock); - btrfs_abort_transaction(trans, root, ret); - return ret; - } + BUG_ON(ret < 0); count -= min_t(unsigned long, ret, count); @@ -2618,7 +2584,7 @@ static noinline int check_committed_ref(struct btrfs_trans_handle *trans, ret = btrfs_search_slot(NULL, extent_root, &key, path, 0, 0); if (ret < 0) goto out; - BUG_ON(ret == 0); /* Corruption */ + BUG_ON(ret == 0); ret = -ENOENT; if (path->slots[0] == 0) @@ -2772,6 +2738,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, } return 0; fail: + BUG(); return ret; } @@ -2800,7 +2767,7 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans, ret = btrfs_search_slot(trans, extent_root, &cache->key, path, 0, 1); if (ret < 0) goto fail; - BUG_ON(ret); /* Corruption */ + BUG_ON(ret); leaf = path->nodes[0]; bi = btrfs_item_ptr_offset(leaf, path->slots[0]); @@ -2808,10 +2775,8 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans, btrfs_mark_buffer_dirty(leaf); btrfs_release_path(path); fail: - if (ret) { - btrfs_abort_transaction(trans, root, ret); + if (ret) return ret; - } return 0; } @@ -2984,8 +2949,7 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, if (last == 0) { err = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); - if (err) /* File system offline */ - goto out; + BUG_ON(err); } cache = btrfs_lookup_first_block_group(root->fs_info, last); @@ -3012,9 +2976,7 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, last = cache->key.objectid + cache->key.offset; err = write_one_cache_group(trans, root, path, cache); - if (err) /* File system offline */ - goto out; - + BUG_ON(err); btrfs_put_block_group(cache); } @@ -3027,8 +2989,7 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, if (last == 0) { err = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); - if (err) /* File system offline */ - goto out; + BUG_ON(err); } cache = btrfs_lookup_first_block_group(root->fs_info, last); @@ -3053,21 +3014,20 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, continue; } - err = btrfs_write_out_cache(root, trans, cache, path); + btrfs_write_out_cache(root, trans, cache, path); /* * If we didn't have an error then the cache state is still * NEED_WRITE, so we can set it to WRITTEN. */ - if (!err && cache->disk_cache_state == BTRFS_DC_NEED_WRITE) + if (cache->disk_cache_state == BTRFS_DC_NEED_WRITE) cache->disk_cache_state = BTRFS_DC_WRITTEN; last = cache->key.objectid + cache->key.offset; btrfs_put_block_group(cache); } -out: btrfs_free_path(path); - return err; + return 0; } int btrfs_extent_readonly(struct btrfs_root *root, u64 bytenr) @@ -3138,8 +3098,11 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags) { - u64 extra_flags = chunk_to_extended(flags) & - BTRFS_EXTENDED_PROFILE_MASK; + u64 extra_flags = flags & BTRFS_BLOCK_GROUP_PROFILE_MASK; + + /* chunk -> extended profile */ + if (extra_flags == 0) + extra_flags = BTRFS_AVAIL_ALLOC_BIT_SINGLE; if (flags & BTRFS_BLOCK_GROUP_DATA) fs_info->avail_data_alloc_bits |= extra_flags; @@ -3149,34 +3112,6 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags) fs_info->avail_system_alloc_bits |= extra_flags; } -/* - * returns target flags in extended format or 0 if restripe for this - * chunk_type is not in progress - * - * should be called with either volume_mutex or balance_lock held - */ -static u64 get_restripe_target(struct btrfs_fs_info *fs_info, u64 flags) -{ - struct btrfs_balance_control *bctl = fs_info->balance_ctl; - u64 target = 0; - - if (!bctl) - return 0; - - if (flags & BTRFS_BLOCK_GROUP_DATA && - bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT) { - target = BTRFS_BLOCK_GROUP_DATA | bctl->data.target; - } else if (flags & BTRFS_BLOCK_GROUP_SYSTEM && - bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) { - target = BTRFS_BLOCK_GROUP_SYSTEM | bctl->sys.target; - } else if (flags & BTRFS_BLOCK_GROUP_METADATA && - bctl->meta.flags & BTRFS_BALANCE_ARGS_CONVERT) { - target = BTRFS_BLOCK_GROUP_METADATA | bctl->meta.target; - } - - return target; -} - /* * @flags: available profiles in extended format (see ctree.h) * @@ -3193,19 +3128,31 @@ u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) */ u64 num_devices = root->fs_info->fs_devices->rw_devices + root->fs_info->fs_devices->missing_devices; - u64 target; - /* - * see if restripe for this chunk_type is in progress, if so - * try to reduce to the target profile - */ + /* pick restriper's target profile if it's available */ spin_lock(&root->fs_info->balance_lock); - target = get_restripe_target(root->fs_info, flags); - if (target) { - /* pick target profile only if it's already available */ - if ((flags & target) & BTRFS_EXTENDED_PROFILE_MASK) { + if (root->fs_info->balance_ctl) { + struct btrfs_balance_control *bctl = root->fs_info->balance_ctl; + u64 tgt = 0; + + if ((flags & BTRFS_BLOCK_GROUP_DATA) && + (bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT) && + (flags & bctl->data.target)) { + tgt = BTRFS_BLOCK_GROUP_DATA | bctl->data.target; + } else if ((flags & BTRFS_BLOCK_GROUP_SYSTEM) && + (bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) && + (flags & bctl->sys.target)) { + tgt = BTRFS_BLOCK_GROUP_SYSTEM | bctl->sys.target; + } else if ((flags & BTRFS_BLOCK_GROUP_METADATA) && + (bctl->meta.flags & BTRFS_BALANCE_ARGS_CONVERT) && + (flags & bctl->meta.target)) { + tgt = BTRFS_BLOCK_GROUP_METADATA | bctl->meta.target; + } + + if (tgt) { spin_unlock(&root->fs_info->balance_lock); - return extended_to_chunk(target); + flags = tgt; + goto out; } } spin_unlock(&root->fs_info->balance_lock); @@ -3233,7 +3180,10 @@ u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) flags &= ~BTRFS_BLOCK_GROUP_RAID0; } - return extended_to_chunk(flags); +out: + /* extended -> chunk profile */ + flags &= ~BTRFS_AVAIL_ALLOC_BIT_SINGLE; + return flags; } static u64 get_alloc_profile(struct btrfs_root *root, u64 flags) @@ -3362,7 +3312,8 @@ int btrfs_check_data_free_space(struct inode *inode, u64 bytes) } data_sinfo->bytes_may_use += bytes; trace_btrfs_space_reservation(root->fs_info, "space_info", - data_sinfo->flags, bytes, 1); + (u64)(unsigned long)data_sinfo, + bytes, 1); spin_unlock(&data_sinfo->lock); return 0; @@ -3383,7 +3334,8 @@ void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes) spin_lock(&data_sinfo->lock); data_sinfo->bytes_may_use -= bytes; trace_btrfs_space_reservation(root->fs_info, "space_info", - data_sinfo->flags, bytes, 0); + (u64)(unsigned long)data_sinfo, + bytes, 0); spin_unlock(&data_sinfo->lock); } @@ -3444,50 +3396,6 @@ static int should_alloc_chunk(struct btrfs_root *root, return 1; } -static u64 get_system_chunk_thresh(struct btrfs_root *root, u64 type) -{ - u64 num_dev; - - if (type & BTRFS_BLOCK_GROUP_RAID10 || - type & BTRFS_BLOCK_GROUP_RAID0) - num_dev = root->fs_info->fs_devices->rw_devices; - else if (type & BTRFS_BLOCK_GROUP_RAID1) - num_dev = 2; - else - num_dev = 1; /* DUP or single */ - - /* metadata for updaing devices and chunk tree */ - return btrfs_calc_trans_metadata_size(root, num_dev + 1); -} - -static void check_system_chunk(struct btrfs_trans_handle *trans, - struct btrfs_root *root, u64 type) -{ - struct btrfs_space_info *info; - u64 left; - u64 thresh; - - info = __find_space_info(root->fs_info, BTRFS_BLOCK_GROUP_SYSTEM); - spin_lock(&info->lock); - left = info->total_bytes - info->bytes_used - info->bytes_pinned - - info->bytes_reserved - info->bytes_readonly; - spin_unlock(&info->lock); - - thresh = get_system_chunk_thresh(root, type); - if (left < thresh && btrfs_test_opt(root, ENOSPC_DEBUG)) { - printk(KERN_INFO "left=%llu, need=%llu, flags=%llu\n", - left, thresh, type); - dump_space_info(info, 0, 0); - } - - if (left < thresh) { - u64 flags; - - flags = btrfs_get_alloc_profile(root->fs_info->chunk_root, 0); - btrfs_alloc_chunk(trans, root, flags); - } -} - static int do_chunk_alloc(struct btrfs_trans_handle *trans, struct btrfs_root *extent_root, u64 alloc_bytes, u64 flags, int force) @@ -3497,13 +3405,15 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, int wait_for_alloc = 0; int ret = 0; + BUG_ON(!profile_is_valid(flags, 0)); + space_info = __find_space_info(extent_root->fs_info, flags); if (!space_info) { ret = update_space_info(extent_root->fs_info, flags, 0, 0, &space_info); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } - BUG_ON(!space_info); /* Logic error */ + BUG_ON(!space_info); again: spin_lock(&space_info->lock); @@ -3558,12 +3468,6 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, force_metadata_allocation(fs_info); } - /* - * Check if we have enough space in SYSTEM chunk because we may need - * to update devices. - */ - check_system_chunk(trans, extent_root, flags); - ret = btrfs_alloc_chunk(trans, extent_root, flags); if (ret < 0 && ret != -ENOSPC) goto out; @@ -3771,8 +3675,9 @@ static int reserve_metadata_bytes(struct btrfs_root *root, */ if (current->journal_info) return -EAGAIN; - ret = wait_event_killable(space_info->wait, !space_info->flush); - /* Must have been killed, return */ + ret = wait_event_interruptible(space_info->wait, + !space_info->flush); + /* Must have been interrupted, return */ if (ret) return -EINTR; @@ -3795,7 +3700,9 @@ static int reserve_metadata_bytes(struct btrfs_root *root, if (used + orig_bytes <= space_info->total_bytes) { space_info->bytes_may_use += orig_bytes; trace_btrfs_space_reservation(root->fs_info, - "space_info", space_info->flags, orig_bytes, 1); + "space_info", + (u64)(unsigned long)space_info, + orig_bytes, 1); ret = 0; } else { /* @@ -3864,7 +3771,9 @@ static int reserve_metadata_bytes(struct btrfs_root *root, if (used + num_bytes < space_info->total_bytes + avail) { space_info->bytes_may_use += orig_bytes; trace_btrfs_space_reservation(root->fs_info, - "space_info", space_info->flags, orig_bytes, 1); + "space_info", + (u64)(unsigned long)space_info, + orig_bytes, 1); ret = 0; } else { wait_ordered = true; @@ -3927,9 +3836,8 @@ static int reserve_metadata_bytes(struct btrfs_root *root, return ret; } -static struct btrfs_block_rsv *get_block_rsv( - const struct btrfs_trans_handle *trans, - const struct btrfs_root *root) +static struct btrfs_block_rsv *get_block_rsv(struct btrfs_trans_handle *trans, + struct btrfs_root *root) { struct btrfs_block_rsv *block_rsv = NULL; @@ -4010,7 +3918,8 @@ static void block_rsv_release_bytes(struct btrfs_fs_info *fs_info, spin_lock(&space_info->lock); space_info->bytes_may_use -= num_bytes; trace_btrfs_space_reservation(fs_info, "space_info", - space_info->flags, num_bytes, 0); + (u64)(unsigned long)space_info, + num_bytes, 0); space_info->reservation_progress++; spin_unlock(&space_info->lock); } @@ -4201,7 +4110,7 @@ static u64 calc_global_metadata_size(struct btrfs_fs_info *fs_info) num_bytes += div64_u64(data_used + meta_used, 50); if (num_bytes * 3 > meta_used) - num_bytes = div64_u64(meta_used, 3); + num_bytes = div64_u64(meta_used, 3) * 2; return ALIGN(num_bytes, fs_info->extent_root->leafsize << 10); } @@ -4214,8 +4123,8 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info) num_bytes = calc_global_metadata_size(fs_info); - spin_lock(&sinfo->lock); spin_lock(&block_rsv->lock); + spin_lock(&sinfo->lock); block_rsv->size = num_bytes; @@ -4228,21 +4137,21 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info) block_rsv->reserved += num_bytes; sinfo->bytes_may_use += num_bytes; trace_btrfs_space_reservation(fs_info, "space_info", - sinfo->flags, num_bytes, 1); + (u64)(unsigned long)sinfo, num_bytes, 1); } if (block_rsv->reserved >= block_rsv->size) { num_bytes = block_rsv->reserved - block_rsv->size; sinfo->bytes_may_use -= num_bytes; trace_btrfs_space_reservation(fs_info, "space_info", - sinfo->flags, num_bytes, 0); + (u64)(unsigned long)sinfo, num_bytes, 0); sinfo->reservation_progress++; block_rsv->reserved = block_rsv->size; block_rsv->full = 1; } - spin_unlock(&block_rsv->lock); spin_unlock(&sinfo->lock); + spin_unlock(&block_rsv->lock); } static void init_global_block_rsv(struct btrfs_fs_info *fs_info) @@ -4289,12 +4198,12 @@ void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans, return; trace_btrfs_space_reservation(root->fs_info, "transaction", - trans->transid, trans->bytes_reserved, 0); + (u64)(unsigned long)trans, + trans->bytes_reserved, 0); btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved); trans->bytes_reserved = 0; } -/* Can only return 0 or -ENOSPC */ int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans, struct inode *inode) { @@ -4631,7 +4540,7 @@ static int update_block_group(struct btrfs_trans_handle *trans, while (total) { cache = btrfs_lookup_block_group(info, bytenr); if (!cache) - return -ENOENT; + return -1; if (cache->flags & (BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10)) @@ -4734,7 +4643,7 @@ int btrfs_pin_extent(struct btrfs_root *root, struct btrfs_block_group_cache *cache; cache = btrfs_lookup_block_group(root->fs_info, bytenr); - BUG_ON(!cache); /* Logic error */ + BUG_ON(!cache); pin_down_extent(root, cache, bytenr, num_bytes, reserved); @@ -4752,7 +4661,7 @@ int btrfs_pin_extent_for_log_replay(struct btrfs_trans_handle *trans, struct btrfs_block_group_cache *cache; cache = btrfs_lookup_block_group(root->fs_info, bytenr); - BUG_ON(!cache); /* Logic error */ + BUG_ON(!cache); /* * pull in the free space cache (if any) so that our pin @@ -4797,7 +4706,6 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, { struct btrfs_space_info *space_info = cache->space_info; int ret = 0; - spin_lock(&space_info->lock); spin_lock(&cache->lock); if (reserve != RESERVE_FREE) { @@ -4808,8 +4716,9 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, space_info->bytes_reserved += num_bytes; if (reserve == RESERVE_ALLOC) { trace_btrfs_space_reservation(cache->fs_info, - "space_info", space_info->flags, - num_bytes, 0); + "space_info", + (u64)(unsigned long)space_info, + num_bytes, 0); space_info->bytes_may_use -= num_bytes; } } @@ -4825,7 +4734,7 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, return ret; } -void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, +int btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, struct btrfs_root *root) { struct btrfs_fs_info *fs_info = root->fs_info; @@ -4855,6 +4764,7 @@ void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, up_write(&fs_info->extent_commit_sem); update_global_block_rsv(fs_info); + return 0; } static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end) @@ -4869,7 +4779,7 @@ static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end) if (cache) btrfs_put_block_group(cache); cache = btrfs_lookup_block_group(fs_info, start); - BUG_ON(!cache); /* Logic error */ + BUG_ON(!cache); } len = cache->key.objectid + cache->key.offset - start; @@ -4906,9 +4816,6 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, u64 end; int ret; - if (trans->aborted) - return 0; - if (fs_info->pinned_extents == &fs_info->freed_extents[0]) unpin = &fs_info->freed_extents[1]; else @@ -4994,8 +4901,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, ret = remove_extent_backref(trans, extent_root, path, NULL, refs_to_drop, is_data); - if (ret) - goto abort; + BUG_ON(ret); btrfs_release_path(path); path->leave_spinning = 1; @@ -5013,11 +4919,10 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, btrfs_print_leaf(extent_root, path->nodes[0]); } - if (ret < 0) - goto abort; + BUG_ON(ret); extent_slot = path->slots[0]; } - } else if (ret == -ENOENT) { + } else { btrfs_print_leaf(extent_root, path->nodes[0]); WARN_ON(1); printk(KERN_ERR "btrfs unable to find ref byte nr %llu " @@ -5027,8 +4932,6 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, (unsigned long long)root_objectid, (unsigned long long)owner_objectid, (unsigned long long)owner_offset); - } else { - goto abort; } leaf = path->nodes[0]; @@ -5038,8 +4941,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, BUG_ON(found_extent || extent_slot != path->slots[0]); ret = convert_extent_item_v0(trans, extent_root, path, owner_objectid, 0); - if (ret < 0) - goto abort; + BUG_ON(ret < 0); btrfs_release_path(path); path->leave_spinning = 1; @@ -5056,8 +4958,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, (unsigned long long)bytenr); btrfs_print_leaf(extent_root, path->nodes[0]); } - if (ret < 0) - goto abort; + BUG_ON(ret); extent_slot = path->slots[0]; leaf = path->nodes[0]; item_size = btrfs_item_size_nr(leaf, extent_slot); @@ -5094,8 +4995,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, ret = remove_extent_backref(trans, extent_root, path, iref, refs_to_drop, is_data); - if (ret) - goto abort; + BUG_ON(ret); } } else { if (found_extent) { @@ -5112,27 +5012,23 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, ret = btrfs_del_items(trans, extent_root, path, path->slots[0], num_to_del); - if (ret) - goto abort; + BUG_ON(ret); btrfs_release_path(path); if (is_data) { ret = btrfs_del_csums(trans, root, bytenr, num_bytes); - if (ret) - goto abort; + BUG_ON(ret); + } else { + invalidate_mapping_pages(info->btree_inode->i_mapping, + bytenr >> PAGE_CACHE_SHIFT, + (bytenr + num_bytes - 1) >> PAGE_CACHE_SHIFT); } ret = update_block_group(trans, root, bytenr, num_bytes, 0); - if (ret) - goto abort; + BUG_ON(ret); } -out: btrfs_free_path(path); return ret; - -abort: - btrfs_abort_transaction(trans, extent_root, ret); - goto out; } /* @@ -5228,7 +5124,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, parent, root->root_key.objectid, btrfs_header_level(buf), BTRFS_DROP_DELAYED_REF, NULL, for_cow); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } if (!last_ref) @@ -5262,7 +5158,6 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, btrfs_put_block_group(cache); } -/* Can return -ENOMEM */ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, u64 owner, u64 offset, int for_cow) @@ -5284,12 +5179,14 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, num_bytes, parent, root_objectid, (int)owner, BTRFS_DROP_DELAYED_REF, NULL, for_cow); + BUG_ON(ret); } else { ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr, num_bytes, parent, root_objectid, owner, offset, BTRFS_DROP_DELAYED_REF, NULL, for_cow); + BUG_ON(ret); } return ret; } @@ -5346,34 +5243,28 @@ wait_block_group_cache_done(struct btrfs_block_group_cache *cache) return 0; } -static int __get_block_group_index(u64 flags) +static int get_block_group_index(struct btrfs_block_group_cache *cache) { int index; - - if (flags & BTRFS_BLOCK_GROUP_RAID10) + if (cache->flags & BTRFS_BLOCK_GROUP_RAID10) index = 0; - else if (flags & BTRFS_BLOCK_GROUP_RAID1) + else if (cache->flags & BTRFS_BLOCK_GROUP_RAID1) index = 1; - else if (flags & BTRFS_BLOCK_GROUP_DUP) + else if (cache->flags & BTRFS_BLOCK_GROUP_DUP) index = 2; - else if (flags & BTRFS_BLOCK_GROUP_RAID0) + else if (cache->flags & BTRFS_BLOCK_GROUP_RAID0) index = 3; else index = 4; - return index; } -static int get_block_group_index(struct btrfs_block_group_cache *cache) -{ - return __get_block_group_index(cache->flags); -} - enum btrfs_loop_type { - LOOP_CACHING_NOWAIT = 0, - LOOP_CACHING_WAIT = 1, - LOOP_ALLOC_CHUNK = 2, - LOOP_NO_EMPTY_SIZE = 3, + LOOP_FIND_IDEAL = 0, + LOOP_CACHING_NOWAIT = 1, + LOOP_CACHING_WAIT = 2, + LOOP_ALLOC_CHUNK = 3, + LOOP_NO_EMPTY_SIZE = 4, }; /* @@ -5387,6 +5278,7 @@ enum btrfs_loop_type { static noinline int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *orig_root, u64 num_bytes, u64 empty_size, + u64 search_start, u64 search_end, u64 hint_byte, struct btrfs_key *ins, u64 data) { @@ -5395,7 +5287,6 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_free_cluster *last_ptr = NULL; struct btrfs_block_group_cache *block_group = NULL; struct btrfs_block_group_cache *used_block_group; - u64 search_start = 0; int empty_cluster = 2 * 1024 * 1024; int allowed_chunk_alloc = 0; int done_chunk_alloc = 0; @@ -5409,6 +5300,8 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, bool failed_alloc = false; bool use_cluster = true; bool have_caching_bg = false; + u64 ideal_cache_percent = 0; + u64 ideal_cache_offset = 0; WARN_ON(num_bytes < root->sectorsize); btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); @@ -5458,6 +5351,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, empty_cluster = 0; if (search_start == hint_byte) { +ideal_cache: block_group = btrfs_lookup_block_group(root->fs_info, search_start); used_block_group = block_group; @@ -5469,7 +5363,8 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, * picked out then we don't care that the block group is cached. */ if (block_group && block_group_bits(block_group, data) && - block_group->cached != BTRFS_CACHE_NO) { + (block_group->cached != BTRFS_CACHE_NO || + search_start == ideal_cache_offset)) { down_read(&space_info->groups_sem); if (list_empty(&block_group->list) || block_group->ro) { @@ -5523,13 +5418,44 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, have_block_group: cached = block_group_cache_done(block_group); if (unlikely(!cached)) { + u64 free_percent; + found_uncached_bg = true; ret = cache_block_group(block_group, trans, - orig_root, 0); - BUG_ON(ret < 0); - ret = 0; + orig_root, 1); + if (block_group->cached == BTRFS_CACHE_FINISHED) + goto alloc; + + free_percent = btrfs_block_group_used(&block_group->item); + free_percent *= 100; + free_percent = div64_u64(free_percent, + block_group->key.offset); + free_percent = 100 - free_percent; + if (free_percent > ideal_cache_percent && + likely(!block_group->ro)) { + ideal_cache_offset = block_group->key.objectid; + ideal_cache_percent = free_percent; + } + + /* + * The caching workers are limited to 2 threads, so we + * can queue as much work as we care to. + */ + if (loop > LOOP_FIND_IDEAL) { + ret = cache_block_group(block_group, trans, + orig_root, 0); + BUG_ON(ret); + } + + /* + * If loop is set for cached only, try the next block + * group. + */ + if (loop == LOOP_FIND_IDEAL) + goto loop; } +alloc: if (unlikely(block_group->ro)) goto loop; @@ -5680,6 +5606,11 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, } checks: search_start = stripe_align(root, offset); + /* move on to the next group */ + if (search_start + num_bytes >= search_end) { + btrfs_add_free_space(used_block_group, offset, num_bytes); + goto loop; + } /* move on to the next group */ if (search_start + num_bytes > @@ -5730,7 +5661,9 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, if (!ins->objectid && ++index < BTRFS_NR_RAID_TYPES) goto search; - /* + /* LOOP_FIND_IDEAL, only search caching/cached bg's, and don't wait for + * for them to make caching progress. Also + * determine the best possible bg to cache * LOOP_CACHING_NOWAIT, search partially cached block groups, kicking * caching kthreads as we move along * LOOP_CACHING_WAIT, search everything, and wait if our bg is caching @@ -5740,17 +5673,50 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, */ if (!ins->objectid && loop < LOOP_NO_EMPTY_SIZE) { index = 0; + if (loop == LOOP_FIND_IDEAL && found_uncached_bg) { + found_uncached_bg = false; + loop++; + if (!ideal_cache_percent) + goto search; + + /* + * 1 of the following 2 things have happened so far + * + * 1) We found an ideal block group for caching that + * is mostly full and will cache quickly, so we might + * as well wait for it. + * + * 2) We searched for cached only and we didn't find + * anything, and we didn't start any caching kthreads + * either, so chances are we will loop through and + * start a couple caching kthreads, and then come back + * around and just wait for them. This will be slower + * because we will have 2 caching kthreads reading at + * the same time when we could have just started one + * and waited for it to get far enough to give us an + * allocation, so go ahead and go to the wait caching + * loop. + */ + loop = LOOP_CACHING_WAIT; + search_start = ideal_cache_offset; + ideal_cache_percent = 0; + goto ideal_cache; + } else if (loop == LOOP_FIND_IDEAL) { + /* + * Didn't find a uncached bg, wait on anything we find + * next. + */ + loop = LOOP_CACHING_WAIT; + goto search; + } + loop++; + if (loop == LOOP_ALLOC_CHUNK) { if (allowed_chunk_alloc) { ret = do_chunk_alloc(trans, root, num_bytes + 2 * 1024 * 1024, data, CHUNK_ALLOC_LIMITED); - if (ret < 0) { - btrfs_abort_transaction(trans, - root, ret); - goto out; - } allowed_chunk_alloc = 0; if (ret == 1) done_chunk_alloc = 1; @@ -5779,7 +5745,6 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, } else if (ins->objectid) { ret = 0; } -out: return ret; } @@ -5833,10 +5798,12 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 num_bytes, u64 min_alloc_size, u64 empty_size, u64 hint_byte, - struct btrfs_key *ins, u64 data) + u64 search_end, struct btrfs_key *ins, + u64 data) { bool final_tried = false; int ret; + u64 search_start = 0; data = btrfs_get_alloc_profile(root, data); again: @@ -5844,31 +5811,23 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, * the only place that sets empty_size is btrfs_realloc_node, which * is not called recursively on allocations */ - if (empty_size || root->ref_cows) { + if (empty_size || root->ref_cows) ret = do_chunk_alloc(trans, root->fs_info->extent_root, num_bytes + 2 * 1024 * 1024, data, CHUNK_ALLOC_NO_FORCE); - if (ret < 0 && ret != -ENOSPC) { - btrfs_abort_transaction(trans, root, ret); - return ret; - } - } WARN_ON(num_bytes < root->sectorsize); ret = find_free_extent(trans, root, num_bytes, empty_size, - hint_byte, ins, data); + search_start, search_end, hint_byte, + ins, data); if (ret == -ENOSPC) { if (!final_tried) { num_bytes = num_bytes >> 1; num_bytes = num_bytes & ~(root->sectorsize - 1); num_bytes = max(num_bytes, min_alloc_size); - ret = do_chunk_alloc(trans, root->fs_info->extent_root, + do_chunk_alloc(trans, root->fs_info->extent_root, num_bytes, data, CHUNK_ALLOC_FORCE); - if (ret < 0 && ret != -ENOSPC) { - btrfs_abort_transaction(trans, root, ret); - return ret; - } if (num_bytes == min_alloc_size) final_tried = true; goto again; @@ -5879,8 +5838,7 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, printk(KERN_ERR "btrfs allocation failed flags %llu, " "wanted %llu\n", (unsigned long long)data, (unsigned long long)num_bytes); - if (sinfo) - dump_space_info(sinfo, num_bytes, 1); + dump_space_info(sinfo, num_bytes, 1); } } @@ -5959,10 +5917,7 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans, path->leave_spinning = 1; ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path, ins, size); - if (ret) { - btrfs_free_path(path); - return ret; - } + BUG_ON(ret); leaf = path->nodes[0]; extent_item = btrfs_item_ptr(leaf, path->slots[0], @@ -5992,7 +5947,7 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans, btrfs_free_path(path); ret = update_block_group(trans, root, ins->objectid, ins->offset, 1); - if (ret) { /* -ENOENT, logic error */ + if (ret) { printk(KERN_ERR "btrfs update block group failed for %llu " "%llu\n", (unsigned long long)ins->objectid, (unsigned long long)ins->offset); @@ -6023,10 +5978,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, path->leave_spinning = 1; ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path, ins, size); - if (ret) { - btrfs_free_path(path); - return ret; - } + BUG_ON(ret); leaf = path->nodes[0]; extent_item = btrfs_item_ptr(leaf, path->slots[0], @@ -6056,7 +6008,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, btrfs_free_path(path); ret = update_block_group(trans, root, ins->objectid, ins->offset, 1); - if (ret) { /* -ENOENT, logic error */ + if (ret) { printk(KERN_ERR "btrfs update block group failed for %llu " "%llu\n", (unsigned long long)ins->objectid, (unsigned long long)ins->offset); @@ -6104,28 +6056,28 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, if (!caching_ctl) { BUG_ON(!block_group_cache_done(block_group)); ret = btrfs_remove_free_space(block_group, start, num_bytes); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } else { mutex_lock(&caching_ctl->mutex); if (start >= caching_ctl->progress) { ret = add_excluded_extent(root, start, num_bytes); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } else if (start + num_bytes <= caching_ctl->progress) { ret = btrfs_remove_free_space(block_group, start, num_bytes); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } else { num_bytes = caching_ctl->progress - start; ret = btrfs_remove_free_space(block_group, start, num_bytes); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); start = caching_ctl->progress; num_bytes = ins->objectid + ins->offset - caching_ctl->progress; ret = add_excluded_extent(root, start, num_bytes); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } mutex_unlock(&caching_ctl->mutex); @@ -6134,7 +6086,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, ret = btrfs_update_reserved_bytes(block_group, ins->offset, RESERVE_ALLOC_NO_ACCOUNT); - BUG_ON(ret); /* logic error */ + BUG_ON(ret); btrfs_put_block_group(block_group); ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, 0, owner, offset, ins, 1); @@ -6155,7 +6107,6 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, btrfs_set_buffer_lockdep_class(root->root_key.objectid, buf, level); btrfs_tree_lock(buf); clean_tree_block(trans, root, buf); - clear_bit(EXTENT_BUFFER_STALE, &buf->bflags); btrfs_set_lock_blocking(buf); btrfs_set_buffer_uptodate(buf); @@ -6263,7 +6214,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, return ERR_CAST(block_rsv); ret = btrfs_reserve_extent(trans, root, blocksize, blocksize, - empty_size, hint, &ins, 0); + empty_size, hint, (u64)-1, &ins, 0); if (ret) { unuse_block_rsv(root->fs_info, block_rsv, blocksize); return ERR_PTR(ret); @@ -6271,7 +6222,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, buf = btrfs_init_new_buffer(trans, root, ins.objectid, blocksize, level); - BUG_ON(IS_ERR(buf)); /* -ENOMEM */ + BUG_ON(IS_ERR(buf)); if (root_objectid == BTRFS_TREE_RELOC_OBJECTID) { if (parent == 0) @@ -6283,7 +6234,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, if (root_objectid != BTRFS_TREE_LOG_OBJECTID) { struct btrfs_delayed_extent_op *extent_op; extent_op = kmalloc(sizeof(*extent_op), GFP_NOFS); - BUG_ON(!extent_op); /* -ENOMEM */ + BUG_ON(!extent_op); if (key) memcpy(&extent_op->key, key, sizeof(extent_op->key)); else @@ -6298,7 +6249,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, ins.offset, parent, root_objectid, level, BTRFS_ADD_DELAYED_EXTENT, extent_op, for_cow); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } return buf; } @@ -6368,9 +6319,7 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans, /* We don't lock the tree block, it's OK to be racy here */ ret = btrfs_lookup_extent_info(trans, root, bytenr, blocksize, &refs, &flags); - /* We don't care about errors in readahead. */ - if (ret < 0) - continue; + BUG_ON(ret); BUG_ON(refs == 0); if (wc->stage == DROP_REFERENCE) { @@ -6437,9 +6386,7 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, eb->start, eb->len, &wc->refs[level], &wc->flags[level]); - BUG_ON(ret == -ENOMEM); - if (ret) - return ret; + BUG_ON(ret); BUG_ON(wc->refs[level] == 0); } @@ -6458,12 +6405,12 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, if (!(wc->flags[level] & flag)) { BUG_ON(!path->locks[level]); ret = btrfs_inc_ref(trans, root, eb, 1, wc->for_reloc); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); ret = btrfs_dec_ref(trans, root, eb, 0, wc->for_reloc); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); ret = btrfs_set_disk_extent_flags(trans, root, eb->start, eb->len, flag, 0); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); wc->flags[level] |= flag; } @@ -6535,11 +6482,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, ret = btrfs_lookup_extent_info(trans, root, bytenr, blocksize, &wc->refs[level - 1], &wc->flags[level - 1]); - if (ret < 0) { - btrfs_tree_unlock(next); - return ret; - } - + BUG_ON(ret); BUG_ON(wc->refs[level - 1] == 0); *lookup_info = 0; @@ -6568,7 +6511,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, goto skip; } - if (!btrfs_buffer_uptodate(next, generation, 0)) { + if (!btrfs_buffer_uptodate(next, generation)) { btrfs_tree_unlock(next); free_extent_buffer(next); next = NULL; @@ -6608,7 +6551,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent, root->root_key.objectid, level - 1, 0, 0); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } btrfs_tree_unlock(next); free_extent_buffer(next); @@ -6666,10 +6609,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, eb->start, eb->len, &wc->refs[level], &wc->flags[level]); - if (ret < 0) { - btrfs_tree_unlock_rw(eb, path->locks[level]); - return ret; - } + BUG_ON(ret); BUG_ON(wc->refs[level] == 0); if (wc->refs[level] == 1) { btrfs_tree_unlock_rw(eb, path->locks[level]); @@ -6689,7 +6629,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, else ret = btrfs_dec_ref(trans, root, eb, 0, wc->for_reloc); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } /* make block locked assertion in clean_tree_block happy */ if (!path->locks[level] && @@ -6798,7 +6738,7 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans, * also make sure backrefs for the shared block and all lower level * blocks are properly updated. */ -int btrfs_drop_snapshot(struct btrfs_root *root, +void btrfs_drop_snapshot(struct btrfs_root *root, struct btrfs_block_rsv *block_rsv, int update_ref, int for_reloc) { @@ -6826,10 +6766,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, } trans = btrfs_start_transaction(tree_root, 0); - if (IS_ERR(trans)) { - err = PTR_ERR(trans); - goto out_free; - } + BUG_ON(IS_ERR(trans)); if (block_rsv) trans->block_rsv = block_rsv; @@ -6854,7 +6791,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, path->lowest_level = 0; if (ret < 0) { err = ret; - goto out_end_trans; + goto out_free; } WARN_ON(ret > 0); @@ -6874,10 +6811,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, path->nodes[level]->len, &wc->refs[level], &wc->flags[level]); - if (ret < 0) { - err = ret; - goto out_end_trans; - } + BUG_ON(ret); BUG_ON(wc->refs[level] == 0); if (level == root_item->drop_level) @@ -6928,40 +6862,26 @@ int btrfs_drop_snapshot(struct btrfs_root *root, ret = btrfs_update_root(trans, tree_root, &root->root_key, root_item); - if (ret) { - btrfs_abort_transaction(trans, tree_root, ret); - err = ret; - goto out_end_trans; - } + BUG_ON(ret); btrfs_end_transaction_throttle(trans, tree_root); trans = btrfs_start_transaction(tree_root, 0); - if (IS_ERR(trans)) { - err = PTR_ERR(trans); - goto out_free; - } + BUG_ON(IS_ERR(trans)); if (block_rsv) trans->block_rsv = block_rsv; } } btrfs_release_path(path); - if (err) - goto out_end_trans; + BUG_ON(err); ret = btrfs_del_root(trans, tree_root, &root->root_key); - if (ret) { - btrfs_abort_transaction(trans, tree_root, ret); - goto out_end_trans; - } + BUG_ON(ret); if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID) { ret = btrfs_find_last_root(tree_root, root->root_key.objectid, NULL, NULL); - if (ret < 0) { - btrfs_abort_transaction(trans, tree_root, ret); - err = ret; - goto out_end_trans; - } else if (ret > 0) { + BUG_ON(ret < 0); + if (ret > 0) { /* if we fail to delete the orphan item this time * around, it'll get picked up the next time. * @@ -6979,15 +6899,14 @@ int btrfs_drop_snapshot(struct btrfs_root *root, free_extent_buffer(root->commit_root); kfree(root); } -out_end_trans: - btrfs_end_transaction_throttle(trans, tree_root); out_free: + btrfs_end_transaction_throttle(trans, tree_root); kfree(wc); btrfs_free_path(path); out: if (err) btrfs_std_error(root->fs_info, err); - return err; + return; } /* @@ -7064,15 +6983,31 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans, static u64 update_block_group_flags(struct btrfs_root *root, u64 flags) { u64 num_devices; - u64 stripped; + u64 stripped = BTRFS_BLOCK_GROUP_RAID0 | + BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10; - /* - * if restripe for this chunk_type is on pick target profile and - * return, otherwise do the usual balance - */ - stripped = get_restripe_target(root->fs_info, flags); - if (stripped) - return extended_to_chunk(stripped); + if (root->fs_info->balance_ctl) { + struct btrfs_balance_control *bctl = root->fs_info->balance_ctl; + u64 tgt = 0; + + /* pick restriper's target profile and return */ + if (flags & BTRFS_BLOCK_GROUP_DATA && + bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT) { + tgt = BTRFS_BLOCK_GROUP_DATA | bctl->data.target; + } else if (flags & BTRFS_BLOCK_GROUP_SYSTEM && + bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) { + tgt = BTRFS_BLOCK_GROUP_SYSTEM | bctl->sys.target; + } else if (flags & BTRFS_BLOCK_GROUP_METADATA && + bctl->meta.flags & BTRFS_BALANCE_ARGS_CONVERT) { + tgt = BTRFS_BLOCK_GROUP_METADATA | bctl->meta.target; + } + + if (tgt) { + /* extended -> chunk profile */ + tgt &= ~BTRFS_AVAIL_ALLOC_BIT_SINGLE; + return tgt; + } + } /* * we add in the count of missing devices because we want @@ -7082,9 +7017,6 @@ static u64 update_block_group_flags(struct btrfs_root *root, u64 flags) num_devices = root->fs_info->fs_devices->rw_devices + root->fs_info->fs_devices->missing_devices; - stripped = BTRFS_BLOCK_GROUP_RAID0 | - BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10; - if (num_devices == 1) { stripped |= BTRFS_BLOCK_GROUP_DUP; stripped = flags & ~stripped; @@ -7097,6 +7029,7 @@ static u64 update_block_group_flags(struct btrfs_root *root, u64 flags) if (flags & (BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10)) return stripped | BTRFS_BLOCK_GROUP_DUP; + return flags; } else { /* they already had raid on here, just return */ if (flags & stripped) @@ -7109,9 +7042,9 @@ static u64 update_block_group_flags(struct btrfs_root *root, u64 flags) if (flags & BTRFS_BLOCK_GROUP_DUP) return stripped | BTRFS_BLOCK_GROUP_RAID1; - /* this is drive concat, leave it alone */ + /* turn single device chunks into raid0 */ + return stripped | BTRFS_BLOCK_GROUP_RAID0; } - return flags; } @@ -7170,16 +7103,12 @@ int btrfs_set_block_group_ro(struct btrfs_root *root, BUG_ON(cache->ro); trans = btrfs_join_transaction(root); - if (IS_ERR(trans)) - return PTR_ERR(trans); + BUG_ON(IS_ERR(trans)); alloc_flags = update_block_group_flags(root, cache->flags); - if (alloc_flags != cache->flags) { - ret = do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags, - CHUNK_ALLOC_FORCE); - if (ret < 0) - goto out; - } + if (alloc_flags != cache->flags) + do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags, + CHUNK_ALLOC_FORCE); ret = set_block_group_ro(cache, 0); if (!ret) @@ -7259,7 +7188,7 @@ u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo) return free_bytes; } -void btrfs_set_block_group_rw(struct btrfs_root *root, +int btrfs_set_block_group_rw(struct btrfs_root *root, struct btrfs_block_group_cache *cache) { struct btrfs_space_info *sinfo = cache->space_info; @@ -7275,6 +7204,7 @@ void btrfs_set_block_group_rw(struct btrfs_root *root, cache->ro = 0; spin_unlock(&cache->lock); spin_unlock(&sinfo->lock); + return 0; } /* @@ -7292,7 +7222,6 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) u64 min_free; u64 dev_min = 1; u64 dev_nr = 0; - u64 target; int index; int full = 0; int ret = 0; @@ -7333,11 +7262,13 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) /* * ok we don't have enough space, but maybe we have free space on our * devices to allocate new chunks for relocation, so loop through our - * alloc devices and guess if we have enough space. if this block - * group is going to be restriped, run checks against the target - * profile instead of the current one. + * alloc devices and guess if we have enough space. However, if we + * were marked as full, then we know there aren't enough chunks, and we + * can just return. */ ret = -1; + if (full) + goto out; /* * index: @@ -7347,20 +7278,7 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) * 3: raid0 * 4: single */ - target = get_restripe_target(root->fs_info, block_group->flags); - if (target) { - index = __get_block_group_index(extended_to_chunk(target)); - } else { - /* - * this is just a balance, so if we were marked as full - * we know there is no space for a new chunk - */ - if (full) - goto out; - - index = get_block_group_index(block_group); - } - + index = get_block_group_index(block_group); if (index == 0) { dev_min = 4; /* Divide by 2 */ @@ -7654,7 +7572,7 @@ int btrfs_read_block_groups(struct btrfs_root *root) ret = update_space_info(info, cache->flags, found_key.offset, btrfs_block_group_used(&cache->item), &space_info); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); cache->space_info = space_info; spin_lock(&cache->space_info->lock); cache->space_info->bytes_readonly += cache->bytes_super; @@ -7663,7 +7581,7 @@ int btrfs_read_block_groups(struct btrfs_root *root) __link_block_group(space_info, cache); ret = btrfs_add_block_group_cache(root->fs_info, cache); - BUG_ON(ret); /* Logic error */ + BUG_ON(ret); set_avail_alloc_bits(root->fs_info, cache->flags); if (btrfs_chunk_readonly(root, cache->key.objectid)) @@ -7745,7 +7663,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, ret = update_space_info(root->fs_info, cache->flags, size, bytes_used, &cache->space_info); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); update_global_block_rsv(root->fs_info); spin_lock(&cache->space_info->lock); @@ -7755,14 +7673,11 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, __link_block_group(cache->space_info, cache); ret = btrfs_add_block_group_cache(root->fs_info, cache); - BUG_ON(ret); /* Logic error */ + BUG_ON(ret); ret = btrfs_insert_item(trans, extent_root, &cache->key, &cache->item, sizeof(cache->item)); - if (ret) { - btrfs_abort_transaction(trans, extent_root, ret); - return ret; - } + BUG_ON(ret); set_avail_alloc_bits(extent_root->fs_info, type); @@ -7771,8 +7686,11 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, static void clear_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags) { - u64 extra_flags = chunk_to_extended(flags) & - BTRFS_EXTENDED_PROFILE_MASK; + u64 extra_flags = flags & BTRFS_BLOCK_GROUP_PROFILE_MASK; + + /* chunk -> extended profile */ + if (extra_flags == 0) + extra_flags = BTRFS_AVAIL_ALLOC_BIT_SINGLE; if (flags & BTRFS_BLOCK_GROUP_DATA) fs_info->avail_data_alloc_bits &= ~extra_flags; @@ -7840,10 +7758,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, inode = lookup_free_space_inode(tree_root, block_group, path); if (!IS_ERR(inode)) { ret = btrfs_orphan_add(trans, inode); - if (ret) { - btrfs_add_delayed_iput(inode); - goto out; - } + BUG_ON(ret); clear_nlink(inode); /* One for the block groups ref */ spin_lock(&block_group->lock); diff --git a/trunk/fs/btrfs/extent_io.c b/trunk/fs/btrfs/extent_io.c index c9018a05036e..2862454bcdb3 100644 --- a/trunk/fs/btrfs/extent_io.c +++ b/trunk/fs/btrfs/extent_io.c @@ -19,7 +19,6 @@ #include "btrfs_inode.h" #include "volumes.h" #include "check-integrity.h" -#include "locking.h" static struct kmem_cache *extent_state_cache; static struct kmem_cache *extent_buffer_cache; @@ -54,13 +53,6 @@ struct extent_page_data { unsigned int sync_io:1; }; -static noinline void flush_write_bio(void *data); -static inline struct btrfs_fs_info * -tree_fs_info(struct extent_io_tree *tree) -{ - return btrfs_sb(tree->mapping->host->i_sb); -} - int __init extent_io_init(void) { extent_state_cache = kmem_cache_create("extent_state", @@ -144,7 +136,6 @@ static struct extent_state *alloc_extent_state(gfp_t mask) #endif atomic_set(&state->refs, 1); init_waitqueue_head(&state->wq); - trace_alloc_extent_state(state, mask, _RET_IP_); return state; } @@ -162,7 +153,6 @@ void free_extent_state(struct extent_state *state) list_del(&state->leak_list); spin_unlock_irqrestore(&leak_lock, flags); #endif - trace_free_extent_state(state, _RET_IP_); kmem_cache_free(extent_state_cache, state); } } @@ -402,28 +392,20 @@ static int split_state(struct extent_io_tree *tree, struct extent_state *orig, return 0; } -static struct extent_state *next_state(struct extent_state *state) -{ - struct rb_node *next = rb_next(&state->rb_node); - if (next) - return rb_entry(next, struct extent_state, rb_node); - else - return NULL; -} - /* * utility function to clear some bits in an extent state struct. - * it will optionally wake up any one waiting on this state (wake == 1) + * it will optionally wake up any one waiting on this state (wake == 1), or + * forcibly remove the state from the tree (delete == 1). * * If no bits are set on the state struct after clearing things, the * struct is freed and removed from the tree */ -static struct extent_state *clear_state_bit(struct extent_io_tree *tree, - struct extent_state *state, - int *bits, int wake) +static int clear_state_bit(struct extent_io_tree *tree, + struct extent_state *state, + int *bits, int wake) { - struct extent_state *next; int bits_to_clear = *bits & ~EXTENT_CTLBITS; + int ret = state->state & bits_to_clear; if ((bits_to_clear & EXTENT_DIRTY) && (state->state & EXTENT_DIRTY)) { u64 range = state->end - state->start + 1; @@ -435,7 +417,6 @@ static struct extent_state *clear_state_bit(struct extent_io_tree *tree, if (wake) wake_up(&state->wq); if (state->state == 0) { - next = next_state(state); if (state->tree) { rb_erase(&state->rb_node, &tree->state); state->tree = NULL; @@ -445,9 +426,8 @@ static struct extent_state *clear_state_bit(struct extent_io_tree *tree, } } else { merge_state(tree, state); - next = next_state(state); } - return next; + return ret; } static struct extent_state * @@ -459,13 +439,6 @@ alloc_extent_state_atomic(struct extent_state *prealloc) return prealloc; } -void extent_io_tree_panic(struct extent_io_tree *tree, int err) -{ - btrfs_panic(tree_fs_info(tree), err, "Locking error: " - "Extent tree was modified by another " - "thread while locked."); -} - /* * clear some bits on a range in the tree. This may require splitting * or inserting elements in the tree, so the gfp mask is used to @@ -476,7 +449,8 @@ void extent_io_tree_panic(struct extent_io_tree *tree, int err) * * the range [start, end] is inclusive. * - * This takes the tree lock, and returns 0 on success and < 0 on error. + * This takes the tree lock, and returns < 0 on error, > 0 if any of the + * bits were already set, or zero if none of the bits were already set. */ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int bits, int wake, int delete, @@ -486,9 +460,11 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, struct extent_state *state; struct extent_state *cached; struct extent_state *prealloc = NULL; + struct rb_node *next_node; struct rb_node *node; u64 last_end; int err; + int set = 0; int clear = 0; if (delete) @@ -537,11 +513,14 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, WARN_ON(state->end < start); last_end = state->end; + if (state->end < end && !need_resched()) + next_node = rb_next(&state->rb_node); + else + next_node = NULL; + /* the state doesn't have the wanted bits, go ahead */ - if (!(state->state & bits)) { - state = next_state(state); + if (!(state->state & bits)) goto next; - } /* * | ---- desired range ---- | @@ -563,14 +542,12 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, prealloc = alloc_extent_state_atomic(prealloc); BUG_ON(!prealloc); err = split_state(tree, state, prealloc, start); - if (err) - extent_io_tree_panic(tree, err); - + BUG_ON(err == -EEXIST); prealloc = NULL; if (err) goto out; if (state->end <= end) { - clear_state_bit(tree, state, &bits, wake); + set |= clear_state_bit(tree, state, &bits, wake); if (last_end == (u64)-1) goto out; start = last_end + 1; @@ -587,25 +564,26 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, prealloc = alloc_extent_state_atomic(prealloc); BUG_ON(!prealloc); err = split_state(tree, state, prealloc, end + 1); - if (err) - extent_io_tree_panic(tree, err); - + BUG_ON(err == -EEXIST); if (wake) wake_up(&state->wq); - clear_state_bit(tree, prealloc, &bits, wake); + set |= clear_state_bit(tree, prealloc, &bits, wake); prealloc = NULL; goto out; } - state = clear_state_bit(tree, state, &bits, wake); + set |= clear_state_bit(tree, state, &bits, wake); next: if (last_end == (u64)-1) goto out; start = last_end + 1; - if (start <= end && state && !need_resched()) + if (start <= end && next_node) { + state = rb_entry(next_node, struct extent_state, + rb_node); goto hit_next; + } goto search_again; out: @@ -613,7 +591,7 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, if (prealloc) free_extent_state(prealloc); - return 0; + return set; search_again: if (start > end) @@ -624,8 +602,8 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, goto again; } -static void wait_on_state(struct extent_io_tree *tree, - struct extent_state *state) +static int wait_on_state(struct extent_io_tree *tree, + struct extent_state *state) __releases(tree->lock) __acquires(tree->lock) { @@ -635,6 +613,7 @@ static void wait_on_state(struct extent_io_tree *tree, schedule(); spin_lock(&tree->lock); finish_wait(&state->wq, &wait); + return 0; } /* @@ -642,7 +621,7 @@ static void wait_on_state(struct extent_io_tree *tree, * The range [start, end] is inclusive. * The tree lock is taken by this function */ -void wait_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int bits) +int wait_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int bits) { struct extent_state *state; struct rb_node *node; @@ -679,6 +658,7 @@ void wait_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int bits) } out: spin_unlock(&tree->lock); + return 0; } static void set_state_bits(struct extent_io_tree *tree, @@ -726,10 +706,9 @@ static void uncache_state(struct extent_state **cached_ptr) * [start, end] is inclusive This takes the tree lock. */ -static int __must_check -__set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, - int bits, int exclusive_bits, u64 *failed_start, - struct extent_state **cached_state, gfp_t mask) +int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, + int bits, int exclusive_bits, u64 *failed_start, + struct extent_state **cached_state, gfp_t mask) { struct extent_state *state; struct extent_state *prealloc = NULL; @@ -763,10 +742,8 @@ __set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, prealloc = alloc_extent_state_atomic(prealloc); BUG_ON(!prealloc); err = insert_state(tree, prealloc, start, end, &bits); - if (err) - extent_io_tree_panic(tree, err); - prealloc = NULL; + BUG_ON(err == -EEXIST); goto out; } state = rb_entry(node, struct extent_state, rb_node); @@ -832,9 +809,7 @@ __set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, prealloc = alloc_extent_state_atomic(prealloc); BUG_ON(!prealloc); err = split_state(tree, state, prealloc, start); - if (err) - extent_io_tree_panic(tree, err); - + BUG_ON(err == -EEXIST); prealloc = NULL; if (err) goto out; @@ -871,9 +846,12 @@ __set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, */ err = insert_state(tree, prealloc, start, this_end, &bits); - if (err) - extent_io_tree_panic(tree, err); - + BUG_ON(err == -EEXIST); + if (err) { + free_extent_state(prealloc); + prealloc = NULL; + goto out; + } cache_state(prealloc, cached_state); prealloc = NULL; start = this_end + 1; @@ -895,8 +873,7 @@ __set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, prealloc = alloc_extent_state_atomic(prealloc); BUG_ON(!prealloc); err = split_state(tree, state, prealloc, end + 1); - if (err) - extent_io_tree_panic(tree, err); + BUG_ON(err == -EEXIST); set_state_bits(tree, prealloc, &bits); cache_state(prealloc, cached_state); @@ -923,15 +900,6 @@ __set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, goto again; } -int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int bits, - u64 *failed_start, struct extent_state **cached_state, - gfp_t mask) -{ - return __set_extent_bit(tree, start, end, bits, 0, failed_start, - cached_state, mask); -} - - /** * convert_extent - convert all bits in a given range from one bit to another * @tree: the io tree to search @@ -978,8 +946,7 @@ int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, } err = insert_state(tree, prealloc, start, end, &bits); prealloc = NULL; - if (err) - extent_io_tree_panic(tree, err); + BUG_ON(err == -EEXIST); goto out; } state = rb_entry(node, struct extent_state, rb_node); @@ -1035,8 +1002,7 @@ int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, goto out; } err = split_state(tree, state, prealloc, start); - if (err) - extent_io_tree_panic(tree, err); + BUG_ON(err == -EEXIST); prealloc = NULL; if (err) goto out; @@ -1075,8 +1041,12 @@ int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, */ err = insert_state(tree, prealloc, start, this_end, &bits); - if (err) - extent_io_tree_panic(tree, err); + BUG_ON(err == -EEXIST); + if (err) { + free_extent_state(prealloc); + prealloc = NULL; + goto out; + } prealloc = NULL; start = this_end + 1; goto search_again; @@ -1095,8 +1065,7 @@ int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, } err = split_state(tree, state, prealloc, end + 1); - if (err) - extent_io_tree_panic(tree, err); + BUG_ON(err == -EEXIST); set_state_bits(tree, prealloc, &bits); clear_state_bit(tree, prealloc, &clear_bits, 0); @@ -1126,14 +1095,14 @@ int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int set_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask) { - return set_extent_bit(tree, start, end, EXTENT_DIRTY, NULL, + return set_extent_bit(tree, start, end, EXTENT_DIRTY, 0, NULL, NULL, mask); } int set_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, int bits, gfp_t mask) { - return set_extent_bit(tree, start, end, bits, NULL, + return set_extent_bit(tree, start, end, bits, 0, NULL, NULL, mask); } @@ -1148,7 +1117,7 @@ int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end, { return set_extent_bit(tree, start, end, EXTENT_DELALLOC | EXTENT_UPTODATE, - NULL, cached_state, mask); + 0, NULL, cached_state, mask); } int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, @@ -1162,7 +1131,7 @@ int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, int set_extent_new(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask) { - return set_extent_bit(tree, start, end, EXTENT_NEW, NULL, + return set_extent_bit(tree, start, end, EXTENT_NEW, 0, NULL, NULL, mask); } @@ -1170,7 +1139,7 @@ int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, struct extent_state **cached_state, gfp_t mask) { return set_extent_bit(tree, start, end, EXTENT_UPTODATE, 0, - cached_state, mask); + NULL, cached_state, mask); } static int clear_extent_uptodate(struct extent_io_tree *tree, u64 start, @@ -1186,40 +1155,42 @@ static int clear_extent_uptodate(struct extent_io_tree *tree, u64 start, * us if waiting is desired. */ int lock_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, - int bits, struct extent_state **cached_state) + int bits, struct extent_state **cached_state, gfp_t mask) { int err; u64 failed_start; while (1) { - err = __set_extent_bit(tree, start, end, EXTENT_LOCKED | bits, - EXTENT_LOCKED, &failed_start, - cached_state, GFP_NOFS); - if (err == -EEXIST) { + err = set_extent_bit(tree, start, end, EXTENT_LOCKED | bits, + EXTENT_LOCKED, &failed_start, + cached_state, mask); + if (err == -EEXIST && (mask & __GFP_WAIT)) { wait_extent_bit(tree, failed_start, end, EXTENT_LOCKED); start = failed_start; - } else + } else { break; + } WARN_ON(start > end); } return err; } -int lock_extent(struct extent_io_tree *tree, u64 start, u64 end) +int lock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask) { - return lock_extent_bits(tree, start, end, 0, NULL); + return lock_extent_bits(tree, start, end, 0, NULL, mask); } -int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end) +int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end, + gfp_t mask) { int err; u64 failed_start; - err = __set_extent_bit(tree, start, end, EXTENT_LOCKED, EXTENT_LOCKED, - &failed_start, NULL, GFP_NOFS); + err = set_extent_bit(tree, start, end, EXTENT_LOCKED, EXTENT_LOCKED, + &failed_start, NULL, mask); if (err == -EEXIST) { if (failed_start > start) clear_extent_bit(tree, start, failed_start - 1, - EXTENT_LOCKED, 1, 0, NULL, GFP_NOFS); + EXTENT_LOCKED, 1, 0, NULL, mask); return 0; } return 1; @@ -1232,10 +1203,10 @@ int unlock_extent_cached(struct extent_io_tree *tree, u64 start, u64 end, mask); } -int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end) +int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask) { return clear_extent_bit(tree, start, end, EXTENT_LOCKED, 1, 0, NULL, - GFP_NOFS); + mask); } /* @@ -1249,7 +1220,7 @@ static int set_range_writeback(struct extent_io_tree *tree, u64 start, u64 end) while (index <= end_index) { page = find_get_page(tree->mapping, index); - BUG_ON(!page); /* Pages should be in the extent_io_tree */ + BUG_ON(!page); set_page_writeback(page); page_cache_release(page); index++; @@ -1372,9 +1343,9 @@ static noinline u64 find_delalloc_range(struct extent_io_tree *tree, return found; } -static noinline void __unlock_for_delalloc(struct inode *inode, - struct page *locked_page, - u64 start, u64 end) +static noinline int __unlock_for_delalloc(struct inode *inode, + struct page *locked_page, + u64 start, u64 end) { int ret; struct page *pages[16]; @@ -1384,7 +1355,7 @@ static noinline void __unlock_for_delalloc(struct inode *inode, int i; if (index == locked_page->index && end_index == index) - return; + return 0; while (nr_pages > 0) { ret = find_get_pages_contig(inode->i_mapping, index, @@ -1399,6 +1370,7 @@ static noinline void __unlock_for_delalloc(struct inode *inode, index += ret; cond_resched(); } + return 0; } static noinline int lock_delalloc_pages(struct inode *inode, @@ -1528,10 +1500,11 @@ static noinline u64 find_lock_delalloc_range(struct inode *inode, goto out_failed; } } - BUG_ON(ret); /* Only valid values are 0 and -EAGAIN */ + BUG_ON(ret); /* step three, lock the state bits for the whole range */ - lock_extent_bits(tree, delalloc_start, delalloc_end, 0, &cached_state); + lock_extent_bits(tree, delalloc_start, delalloc_end, + 0, &cached_state, GFP_NOFS); /* then test to make sure it is all still delalloc */ ret = test_range_bit(tree, delalloc_start, delalloc_end, @@ -1788,34 +1761,39 @@ int test_range_bit(struct extent_io_tree *tree, u64 start, u64 end, * helper function to set a given page up to date if all the * extents in the tree for that page are up to date */ -static void check_page_uptodate(struct extent_io_tree *tree, struct page *page) +static int check_page_uptodate(struct extent_io_tree *tree, + struct page *page) { u64 start = (u64)page->index << PAGE_CACHE_SHIFT; u64 end = start + PAGE_CACHE_SIZE - 1; if (test_range_bit(tree, start, end, EXTENT_UPTODATE, 1, NULL)) SetPageUptodate(page); + return 0; } /* * helper function to unlock a page if all the extents in the tree * for that page are unlocked */ -static void check_page_locked(struct extent_io_tree *tree, struct page *page) +static int check_page_locked(struct extent_io_tree *tree, + struct page *page) { u64 start = (u64)page->index << PAGE_CACHE_SHIFT; u64 end = start + PAGE_CACHE_SIZE - 1; if (!test_range_bit(tree, start, end, EXTENT_LOCKED, 0, NULL)) unlock_page(page); + return 0; } /* * helper function to end page writeback if all the extents * in the tree for that page are done with writeback */ -static void check_page_writeback(struct extent_io_tree *tree, - struct page *page) +static int check_page_writeback(struct extent_io_tree *tree, + struct page *page) { end_page_writeback(page); + return 0; } /* @@ -1934,26 +1912,6 @@ int repair_io_failure(struct btrfs_mapping_tree *map_tree, u64 start, return 0; } -int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb, - int mirror_num) -{ - struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree; - u64 start = eb->start; - unsigned long i, num_pages = num_extent_pages(eb->start, eb->len); - int ret = 0; - - for (i = 0; i < num_pages; i++) { - struct page *p = extent_buffer_page(eb, i); - ret = repair_io_failure(map_tree, start, PAGE_CACHE_SIZE, - start, p, mirror_num); - if (ret) - break; - start += PAGE_CACHE_SIZE; - } - - return ret; -} - /* * each time an IO finishes, we do a fast check in the IO failure tree * to see if we need to process or clean up an io_failure_record @@ -2183,10 +2141,6 @@ static int bio_readpage_error(struct bio *failed_bio, struct page *page, } bio = bio_alloc(GFP_NOFS, 1); - if (!bio) { - free_io_failure(inode, failrec, 0); - return -EIO; - } bio->bi_private = state; bio->bi_end_io = failed_bio->bi_end_io; bio->bi_sector = failrec->logical >> 9; @@ -2304,7 +2258,6 @@ static void end_bio_extent_readpage(struct bio *bio, int err) u64 start; u64 end; int whole_page; - int mirror; int ret; if (err) @@ -2343,22 +2296,17 @@ static void end_bio_extent_readpage(struct bio *bio, int err) } spin_unlock(&tree->lock); - mirror = (int)(unsigned long)bio->bi_bdev; if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) { ret = tree->ops->readpage_end_io_hook(page, start, end, - state, mirror); + state); if (ret) uptodate = 0; else clean_io_failure(start, page); } - - if (!uptodate && tree->ops && tree->ops->readpage_io_failed_hook) { - ret = tree->ops->readpage_io_failed_hook(page, mirror); - if (!ret && !err && - test_bit(BIO_UPTODATE, &bio->bi_flags)) - uptodate = 1; - } else if (!uptodate) { + if (!uptodate) { + int failed_mirror; + failed_mirror = (int)(unsigned long)bio->bi_bdev; /* * The generic bio_readpage_error handles errors the * following way: If possible, new read requests are @@ -2369,8 +2317,10 @@ static void end_bio_extent_readpage(struct bio *bio, int err) * can't handle the error it will return -EIO and we * remain responsible for that page. */ - ret = bio_readpage_error(bio, page, start, end, mirror, NULL); + ret = bio_readpage_error(bio, page, start, end, + failed_mirror, NULL); if (ret == 0) { +error_handled: uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); if (err) @@ -2378,9 +2328,16 @@ static void end_bio_extent_readpage(struct bio *bio, int err) uncache_state(&cached); continue; } + if (tree->ops && tree->ops->readpage_io_failed_hook) { + ret = tree->ops->readpage_io_failed_hook( + bio, page, start, end, + failed_mirror, state); + if (ret == 0) + goto error_handled; + } } - if (uptodate && tree->track_uptodate) { + if (uptodate) { set_extent_uptodate(tree, start, end, &cached, GFP_ATOMIC); } @@ -2429,12 +2386,8 @@ btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, return bio; } -/* - * Since writes are async, they will only return -ENOMEM. - * Reads can return the full range of I/O error conditions. - */ -static int __must_check submit_one_bio(int rw, struct bio *bio, - int mirror_num, unsigned long bio_flags) +static int submit_one_bio(int rw, struct bio *bio, int mirror_num, + unsigned long bio_flags) { int ret = 0; struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; @@ -2460,19 +2413,6 @@ static int __must_check submit_one_bio(int rw, struct bio *bio, return ret; } -static int merge_bio(struct extent_io_tree *tree, struct page *page, - unsigned long offset, size_t size, struct bio *bio, - unsigned long bio_flags) -{ - int ret = 0; - if (tree->ops && tree->ops->merge_bio_hook) - ret = tree->ops->merge_bio_hook(page, offset, size, bio, - bio_flags); - BUG_ON(ret < 0); - return ret; - -} - static int submit_extent_page(int rw, struct extent_io_tree *tree, struct page *page, sector_t sector, size_t size, unsigned long offset, @@ -2501,12 +2441,12 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree, sector; if (prev_bio_flags != bio_flags || !contig || - merge_bio(tree, page, offset, page_size, bio, bio_flags) || + (tree->ops && tree->ops->merge_bio_hook && + tree->ops->merge_bio_hook(page, offset, page_size, bio, + bio_flags)) || bio_add_page(bio, page, page_size, offset) < page_size) { ret = submit_one_bio(rw, bio, mirror_num, prev_bio_flags); - if (ret < 0) - return ret; bio = NULL; } else { return 0; @@ -2533,31 +2473,25 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree, return ret; } -void attach_extent_buffer_page(struct extent_buffer *eb, struct page *page) +void set_page_extent_mapped(struct page *page) { if (!PagePrivate(page)) { SetPagePrivate(page); page_cache_get(page); - set_page_private(page, (unsigned long)eb); - } else { - WARN_ON(page->private != (unsigned long)eb); + set_page_private(page, EXTENT_PAGE_PRIVATE); } } -void set_page_extent_mapped(struct page *page) +static void set_page_extent_head(struct page *page, unsigned long len) { - if (!PagePrivate(page)) { - SetPagePrivate(page); - page_cache_get(page); - set_page_private(page, EXTENT_PAGE_PRIVATE); - } + WARN_ON(!PagePrivate(page)); + set_page_private(page, EXTENT_PAGE_PRIVATE_FIRST_PAGE | len << 2); } /* * basic readpage implementation. Locked extent state structs are inserted * into the tree that are removed when the IO is done (by the end_io * handlers) - * XXX JDM: This needs looking at to ensure proper page locking */ static int __extent_read_full_page(struct extent_io_tree *tree, struct page *page, @@ -2597,11 +2531,11 @@ static int __extent_read_full_page(struct extent_io_tree *tree, end = page_end; while (1) { - lock_extent(tree, start, end); + lock_extent(tree, start, end, GFP_NOFS); ordered = btrfs_lookup_ordered_extent(inode, start); if (!ordered) break; - unlock_extent(tree, start, end); + unlock_extent(tree, start, end, GFP_NOFS); btrfs_start_ordered_extent(inode, ordered, 1); btrfs_put_ordered_extent(ordered); } @@ -2638,7 +2572,7 @@ static int __extent_read_full_page(struct extent_io_tree *tree, end - cur + 1, 0); if (IS_ERR_OR_NULL(em)) { SetPageError(page); - unlock_extent(tree, cur, end); + unlock_extent(tree, cur, end, GFP_NOFS); break; } extent_offset = cur - em->start; @@ -2690,7 +2624,7 @@ static int __extent_read_full_page(struct extent_io_tree *tree, if (test_range_bit(tree, cur, cur_end, EXTENT_UPTODATE, 1, NULL)) { check_page_uptodate(tree, page); - unlock_extent(tree, cur, cur + iosize - 1); + unlock_extent(tree, cur, cur + iosize - 1, GFP_NOFS); cur = cur + iosize; pg_offset += iosize; continue; @@ -2700,7 +2634,7 @@ static int __extent_read_full_page(struct extent_io_tree *tree, */ if (block_start == EXTENT_MAP_INLINE) { SetPageError(page); - unlock_extent(tree, cur, cur + iosize - 1); + unlock_extent(tree, cur, cur + iosize - 1, GFP_NOFS); cur = cur + iosize; pg_offset += iosize; continue; @@ -2720,7 +2654,6 @@ static int __extent_read_full_page(struct extent_io_tree *tree, end_bio_extent_readpage, mirror_num, *bio_flags, this_bio_flag); - BUG_ON(ret == -ENOMEM); nr++; *bio_flags = this_bio_flag; } @@ -2862,11 +2795,7 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, delalloc_end, &page_started, &nr_written); - /* File system has been set read-only */ - if (ret) { - SetPageError(page); - goto done; - } + BUG_ON(ret); /* * delalloc_end is already one less than the total * length, so we don't subtract one from @@ -3039,275 +2968,6 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, return 0; } -static int eb_wait(void *word) -{ - io_schedule(); - return 0; -} - -static void wait_on_extent_buffer_writeback(struct extent_buffer *eb) -{ - wait_on_bit(&eb->bflags, EXTENT_BUFFER_WRITEBACK, eb_wait, - TASK_UNINTERRUPTIBLE); -} - -static int lock_extent_buffer_for_io(struct extent_buffer *eb, - struct btrfs_fs_info *fs_info, - struct extent_page_data *epd) -{ - unsigned long i, num_pages; - int flush = 0; - int ret = 0; - - if (!btrfs_try_tree_write_lock(eb)) { - flush = 1; - flush_write_bio(epd); - btrfs_tree_lock(eb); - } - - if (test_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags)) { - btrfs_tree_unlock(eb); - if (!epd->sync_io) - return 0; - if (!flush) { - flush_write_bio(epd); - flush = 1; - } - while (1) { - wait_on_extent_buffer_writeback(eb); - btrfs_tree_lock(eb); - if (!test_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags)) - break; - btrfs_tree_unlock(eb); - } - } - - if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) { - set_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags); - btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN); - spin_lock(&fs_info->delalloc_lock); - if (fs_info->dirty_metadata_bytes >= eb->len) - fs_info->dirty_metadata_bytes -= eb->len; - else - WARN_ON(1); - spin_unlock(&fs_info->delalloc_lock); - ret = 1; - } - - btrfs_tree_unlock(eb); - - if (!ret) - return ret; - - num_pages = num_extent_pages(eb->start, eb->len); - for (i = 0; i < num_pages; i++) { - struct page *p = extent_buffer_page(eb, i); - - if (!trylock_page(p)) { - if (!flush) { - flush_write_bio(epd); - flush = 1; - } - lock_page(p); - } - } - - return ret; -} - -static void end_extent_buffer_writeback(struct extent_buffer *eb) -{ - clear_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags); - smp_mb__after_clear_bit(); - wake_up_bit(&eb->bflags, EXTENT_BUFFER_WRITEBACK); -} - -static void end_bio_extent_buffer_writepage(struct bio *bio, int err) -{ - int uptodate = err == 0; - struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; - struct extent_buffer *eb; - int done; - - do { - struct page *page = bvec->bv_page; - - bvec--; - eb = (struct extent_buffer *)page->private; - BUG_ON(!eb); - done = atomic_dec_and_test(&eb->io_pages); - - if (!uptodate || test_bit(EXTENT_BUFFER_IOERR, &eb->bflags)) { - set_bit(EXTENT_BUFFER_IOERR, &eb->bflags); - ClearPageUptodate(page); - SetPageError(page); - } - - end_page_writeback(page); - - if (!done) - continue; - - end_extent_buffer_writeback(eb); - } while (bvec >= bio->bi_io_vec); - - bio_put(bio); - -} - -static int write_one_eb(struct extent_buffer *eb, - struct btrfs_fs_info *fs_info, - struct writeback_control *wbc, - struct extent_page_data *epd) -{ - struct block_device *bdev = fs_info->fs_devices->latest_bdev; - u64 offset = eb->start; - unsigned long i, num_pages; - int rw = (epd->sync_io ? WRITE_SYNC : WRITE); - int ret; - - clear_bit(EXTENT_BUFFER_IOERR, &eb->bflags); - num_pages = num_extent_pages(eb->start, eb->len); - atomic_set(&eb->io_pages, num_pages); - for (i = 0; i < num_pages; i++) { - struct page *p = extent_buffer_page(eb, i); - - clear_page_dirty_for_io(p); - set_page_writeback(p); - ret = submit_extent_page(rw, eb->tree, p, offset >> 9, - PAGE_CACHE_SIZE, 0, bdev, &epd->bio, - -1, end_bio_extent_buffer_writepage, - 0, 0, 0); - if (ret) { - set_bit(EXTENT_BUFFER_IOERR, &eb->bflags); - SetPageError(p); - if (atomic_sub_and_test(num_pages - i, &eb->io_pages)) - end_extent_buffer_writeback(eb); - ret = -EIO; - break; - } - offset += PAGE_CACHE_SIZE; - update_nr_written(p, wbc, 1); - unlock_page(p); - } - - if (unlikely(ret)) { - for (; i < num_pages; i++) { - struct page *p = extent_buffer_page(eb, i); - unlock_page(p); - } - } - - return ret; -} - -int btree_write_cache_pages(struct address_space *mapping, - struct writeback_control *wbc) -{ - struct extent_io_tree *tree = &BTRFS_I(mapping->host)->io_tree; - struct btrfs_fs_info *fs_info = BTRFS_I(mapping->host)->root->fs_info; - struct extent_buffer *eb, *prev_eb = NULL; - struct extent_page_data epd = { - .bio = NULL, - .tree = tree, - .extent_locked = 0, - .sync_io = wbc->sync_mode == WB_SYNC_ALL, - }; - int ret = 0; - int done = 0; - int nr_to_write_done = 0; - struct pagevec pvec; - int nr_pages; - pgoff_t index; - pgoff_t end; /* Inclusive */ - int scanned = 0; - int tag; - - pagevec_init(&pvec, 0); - if (wbc->range_cyclic) { - index = mapping->writeback_index; /* Start from prev offset */ - end = -1; - } else { - index = wbc->range_start >> PAGE_CACHE_SHIFT; - end = wbc->range_end >> PAGE_CACHE_SHIFT; - scanned = 1; - } - if (wbc->sync_mode == WB_SYNC_ALL) - tag = PAGECACHE_TAG_TOWRITE; - else - tag = PAGECACHE_TAG_DIRTY; -retry: - if (wbc->sync_mode == WB_SYNC_ALL) - tag_pages_for_writeback(mapping, index, end); - while (!done && !nr_to_write_done && (index <= end) && - (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag, - min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) { - unsigned i; - - scanned = 1; - for (i = 0; i < nr_pages; i++) { - struct page *page = pvec.pages[i]; - - if (!PagePrivate(page)) - continue; - - if (!wbc->range_cyclic && page->index > end) { - done = 1; - break; - } - - eb = (struct extent_buffer *)page->private; - if (!eb) { - WARN_ON(1); - continue; - } - - if (eb == prev_eb) - continue; - - if (!atomic_inc_not_zero(&eb->refs)) { - WARN_ON(1); - continue; - } - - prev_eb = eb; - ret = lock_extent_buffer_for_io(eb, fs_info, &epd); - if (!ret) { - free_extent_buffer(eb); - continue; - } - - ret = write_one_eb(eb, fs_info, wbc, &epd); - if (ret) { - done = 1; - free_extent_buffer(eb); - break; - } - free_extent_buffer(eb); - - /* - * the filesystem may choose to bump up nr_to_write. - * We have to make sure to honor the new nr_to_write - * at any time - */ - nr_to_write_done = wbc->nr_to_write <= 0; - } - pagevec_release(&pvec); - cond_resched(); - } - if (!scanned && !done) { - /* - * We hit the last page and there is more work to be done: wrap - * back to the start of the file - */ - scanned = 1; - index = 0; - goto retry; - } - flush_write_bio(&epd); - return ret; -} - /** * write_cache_pages - walk the list of dirty pages of the given address space and write all of them. * @mapping: address space structure to write @@ -3439,14 +3099,10 @@ static int extent_write_cache_pages(struct extent_io_tree *tree, static void flush_epd_write_bio(struct extent_page_data *epd) { if (epd->bio) { - int rw = WRITE; - int ret; - if (epd->sync_io) - rw = WRITE_SYNC; - - ret = submit_one_bio(rw, epd->bio, 0, 0); - BUG_ON(ret < 0); /* -ENOMEM */ + submit_one_bio(WRITE_SYNC, epd->bio, 0, 0); + else + submit_one_bio(WRITE, epd->bio, 0, 0); epd->bio = NULL; } } @@ -3563,7 +3219,7 @@ int extent_readpages(struct extent_io_tree *tree, } BUG_ON(!list_empty(pages)); if (bio) - return submit_one_bio(READ, bio, 0, bio_flags); + submit_one_bio(READ, bio, 0, bio_flags); return 0; } @@ -3584,7 +3240,7 @@ int extent_invalidatepage(struct extent_io_tree *tree, if (start > end) return 0; - lock_extent_bits(tree, start, end, 0, &cached_state); + lock_extent_bits(tree, start, end, 0, &cached_state, GFP_NOFS); wait_on_page_writeback(page); clear_extent_bit(tree, start, end, EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC | @@ -3798,7 +3454,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, } lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0, - &cached_state); + &cached_state, GFP_NOFS); em = get_extent_skip_holes(inode, start, last_for_get_extent, get_extent); @@ -3892,7 +3548,26 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, inline struct page *extent_buffer_page(struct extent_buffer *eb, unsigned long i) { - return eb->pages[i]; + struct page *p; + struct address_space *mapping; + + if (i == 0) + return eb->first_page; + i += eb->start >> PAGE_CACHE_SHIFT; + mapping = eb->first_page->mapping; + if (!mapping) + return NULL; + + /* + * extent_buffer_page is only called after pinning the page + * by increasing the reference count. So we know the page must + * be in the radix tree. + */ + rcu_read_lock(); + p = radix_tree_lookup(&mapping->page_tree, i); + rcu_read_unlock(); + + return p; } inline unsigned long num_extent_pages(u64 start, u64 len) @@ -3901,19 +3576,6 @@ inline unsigned long num_extent_pages(u64 start, u64 len) (start >> PAGE_CACHE_SHIFT); } -static void __free_extent_buffer(struct extent_buffer *eb) -{ -#if LEAK_DEBUG - unsigned long flags; - spin_lock_irqsave(&leak_lock, flags); - list_del(&eb->leak_list); - spin_unlock_irqrestore(&leak_lock, flags); -#endif - if (eb->pages && eb->pages != eb->inline_pages) - kfree(eb->pages); - kmem_cache_free(extent_buffer_cache, eb); -} - static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree, u64 start, unsigned long len, @@ -3929,7 +3591,6 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree, return NULL; eb->start = start; eb->len = len; - eb->tree = tree; rwlock_init(&eb->lock); atomic_set(&eb->write_locks, 0); atomic_set(&eb->read_locks, 0); @@ -3946,32 +3607,20 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree, list_add(&eb->leak_list, &buffers); spin_unlock_irqrestore(&leak_lock, flags); #endif - spin_lock_init(&eb->refs_lock); atomic_set(&eb->refs, 1); - atomic_set(&eb->io_pages, 0); - - if (len > MAX_INLINE_EXTENT_BUFFER_SIZE) { - struct page **pages; - int num_pages = (len + PAGE_CACHE_SIZE - 1) >> - PAGE_CACHE_SHIFT; - pages = kzalloc(num_pages, mask); - if (!pages) { - __free_extent_buffer(eb); - return NULL; - } - eb->pages = pages; - } else { - eb->pages = eb->inline_pages; - } return eb; } -static int extent_buffer_under_io(struct extent_buffer *eb) +static void __free_extent_buffer(struct extent_buffer *eb) { - return (atomic_read(&eb->io_pages) || - test_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags) || - test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)); +#if LEAK_DEBUG + unsigned long flags; + spin_lock_irqsave(&leak_lock, flags); + list_del(&eb->leak_list); + spin_unlock_irqrestore(&leak_lock, flags); +#endif + kmem_cache_free(extent_buffer_cache, eb); } /* @@ -3983,7 +3632,8 @@ static void btrfs_release_extent_buffer_page(struct extent_buffer *eb, unsigned long index; struct page *page; - BUG_ON(extent_buffer_under_io(eb)); + if (!eb->first_page) + return; index = num_extent_pages(eb->start, eb->len); if (start_idx >= index) @@ -3992,34 +3642,8 @@ static void btrfs_release_extent_buffer_page(struct extent_buffer *eb, do { index--; page = extent_buffer_page(eb, index); - if (page) { - spin_lock(&page->mapping->private_lock); - /* - * We do this since we'll remove the pages after we've - * removed the eb from the radix tree, so we could race - * and have this page now attached to the new eb. So - * only clear page_private if it's still connected to - * this eb. - */ - if (PagePrivate(page) && - page->private == (unsigned long)eb) { - BUG_ON(test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)); - BUG_ON(PageDirty(page)); - BUG_ON(PageWriteback(page)); - /* - * We need to make sure we haven't be attached - * to a new eb. - */ - ClearPagePrivate(page); - set_page_private(page, 0); - /* One for the page private */ - page_cache_release(page); - } - spin_unlock(&page->mapping->private_lock); - - /* One for when we alloced the page */ + if (page) page_cache_release(page); - } } while (index != start_idx); } @@ -4032,50 +3656,9 @@ static inline void btrfs_release_extent_buffer(struct extent_buffer *eb) __free_extent_buffer(eb); } -static void check_buffer_tree_ref(struct extent_buffer *eb) -{ - /* the ref bit is tricky. We have to make sure it is set - * if we have the buffer dirty. Otherwise the - * code to free a buffer can end up dropping a dirty - * page - * - * Once the ref bit is set, it won't go away while the - * buffer is dirty or in writeback, and it also won't - * go away while we have the reference count on the - * eb bumped. - * - * We can't just set the ref bit without bumping the - * ref on the eb because free_extent_buffer might - * see the ref bit and try to clear it. If this happens - * free_extent_buffer might end up dropping our original - * ref by mistake and freeing the page before we are able - * to add one more ref. - * - * So bump the ref count first, then set the bit. If someone - * beat us to it, drop the ref we added. - */ - if (!test_bit(EXTENT_BUFFER_TREE_REF, &eb->bflags)) { - atomic_inc(&eb->refs); - if (test_and_set_bit(EXTENT_BUFFER_TREE_REF, &eb->bflags)) - atomic_dec(&eb->refs); - } -} - -static void mark_extent_buffer_accessed(struct extent_buffer *eb) -{ - unsigned long num_pages, i; - - check_buffer_tree_ref(eb); - - num_pages = num_extent_pages(eb->start, eb->len); - for (i = 0; i < num_pages; i++) { - struct page *p = extent_buffer_page(eb, i); - mark_page_accessed(p); - } -} - struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, - u64 start, unsigned long len) + u64 start, unsigned long len, + struct page *page0) { unsigned long num_pages = num_extent_pages(start, len); unsigned long i; @@ -4091,7 +3674,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT); if (eb && atomic_inc_not_zero(&eb->refs)) { rcu_read_unlock(); - mark_extent_buffer_accessed(eb); + mark_page_accessed(eb->first_page); return eb; } rcu_read_unlock(); @@ -4100,44 +3683,32 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, if (!eb) return NULL; - for (i = 0; i < num_pages; i++, index++) { + if (page0) { + eb->first_page = page0; + i = 1; + index++; + page_cache_get(page0); + mark_page_accessed(page0); + set_page_extent_mapped(page0); + set_page_extent_head(page0, len); + uptodate = PageUptodate(page0); + } else { + i = 0; + } + for (; i < num_pages; i++, index++) { p = find_or_create_page(mapping, index, GFP_NOFS); if (!p) { WARN_ON(1); goto free_eb; } - - spin_lock(&mapping->private_lock); - if (PagePrivate(p)) { - /* - * We could have already allocated an eb for this page - * and attached one so lets see if we can get a ref on - * the existing eb, and if we can we know it's good and - * we can just return that one, else we know we can just - * overwrite page->private. - */ - exists = (struct extent_buffer *)p->private; - if (atomic_inc_not_zero(&exists->refs)) { - spin_unlock(&mapping->private_lock); - unlock_page(p); - page_cache_release(p); - mark_extent_buffer_accessed(exists); - goto free_eb; - } - - /* - * Do this so attach doesn't complain and we need to - * drop the ref the old guy had. - */ - ClearPagePrivate(p); - WARN_ON(PageDirty(p)); - page_cache_release(p); - } - attach_extent_buffer_page(eb, p); - spin_unlock(&mapping->private_lock); - WARN_ON(PageDirty(p)); + set_page_extent_mapped(p); mark_page_accessed(p); - eb->pages[i] = p; + if (i == 0) { + eb->first_page = p; + set_page_extent_head(p, len); + } else { + set_page_private(p, EXTENT_PAGE_PRIVATE); + } if (!PageUptodate(p)) uptodate = 0; @@ -4145,10 +3716,12 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, * see below about how we avoid a nasty race with release page * and why we unlock later */ + if (i != 0) + unlock_page(p); } if (uptodate) set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); -again: + ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM); if (ret) goto free_eb; @@ -4158,21 +3731,14 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, if (ret == -EEXIST) { exists = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT); - if (!atomic_inc_not_zero(&exists->refs)) { - spin_unlock(&tree->buffer_lock); - radix_tree_preload_end(); - exists = NULL; - goto again; - } + /* add one reference for the caller */ + atomic_inc(&exists->refs); spin_unlock(&tree->buffer_lock); radix_tree_preload_end(); - mark_extent_buffer_accessed(exists); goto free_eb; } /* add one reference for the tree */ - spin_lock(&eb->refs_lock); - check_buffer_tree_ref(eb); - spin_unlock(&eb->refs_lock); + atomic_inc(&eb->refs); spin_unlock(&tree->buffer_lock); radix_tree_preload_end(); @@ -4185,22 +3751,18 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, * after the extent buffer is in the radix tree so * it doesn't get lost */ - SetPageChecked(eb->pages[0]); - for (i = 1; i < num_pages; i++) { - p = extent_buffer_page(eb, i); - ClearPageChecked(p); - unlock_page(p); - } - unlock_page(eb->pages[0]); + set_page_extent_mapped(eb->first_page); + set_page_extent_head(eb->first_page, eb->len); + if (!page0) + unlock_page(eb->first_page); return eb; free_eb: - for (i = 0; i < num_pages; i++) { - if (eb->pages[i]) - unlock_page(eb->pages[i]); - } + if (eb->first_page && !page0) + unlock_page(eb->first_page); - WARN_ON(!atomic_dec_and_test(&eb->refs)); + if (!atomic_dec_and_test(&eb->refs)) + return exists; btrfs_release_extent_buffer(eb); return exists; } @@ -4214,7 +3776,7 @@ struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree, eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT); if (eb && atomic_inc_not_zero(&eb->refs)) { rcu_read_unlock(); - mark_extent_buffer_accessed(eb); + mark_page_accessed(eb->first_page); return eb; } rcu_read_unlock(); @@ -4222,71 +3784,19 @@ struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree, return NULL; } -static inline void btrfs_release_extent_buffer_rcu(struct rcu_head *head) -{ - struct extent_buffer *eb = - container_of(head, struct extent_buffer, rcu_head); - - __free_extent_buffer(eb); -} - -/* Expects to have eb->eb_lock already held */ -static void release_extent_buffer(struct extent_buffer *eb, gfp_t mask) -{ - WARN_ON(atomic_read(&eb->refs) == 0); - if (atomic_dec_and_test(&eb->refs)) { - struct extent_io_tree *tree = eb->tree; - - spin_unlock(&eb->refs_lock); - - spin_lock(&tree->buffer_lock); - radix_tree_delete(&tree->buffer, - eb->start >> PAGE_CACHE_SHIFT); - spin_unlock(&tree->buffer_lock); - - /* Should be safe to release our pages at this point */ - btrfs_release_extent_buffer_page(eb, 0); - - call_rcu(&eb->rcu_head, btrfs_release_extent_buffer_rcu); - return; - } - spin_unlock(&eb->refs_lock); -} - void free_extent_buffer(struct extent_buffer *eb) { if (!eb) return; - spin_lock(&eb->refs_lock); - if (atomic_read(&eb->refs) == 2 && - test_bit(EXTENT_BUFFER_STALE, &eb->bflags) && - !extent_buffer_under_io(eb) && - test_and_clear_bit(EXTENT_BUFFER_TREE_REF, &eb->bflags)) - atomic_dec(&eb->refs); - - /* - * I know this is terrible, but it's temporary until we stop tracking - * the uptodate bits and such for the extent buffers. - */ - release_extent_buffer(eb, GFP_ATOMIC); -} - -void free_extent_buffer_stale(struct extent_buffer *eb) -{ - if (!eb) + if (!atomic_dec_and_test(&eb->refs)) return; - spin_lock(&eb->refs_lock); - set_bit(EXTENT_BUFFER_STALE, &eb->bflags); - - if (atomic_read(&eb->refs) == 2 && !extent_buffer_under_io(eb) && - test_and_clear_bit(EXTENT_BUFFER_TREE_REF, &eb->bflags)) - atomic_dec(&eb->refs); - release_extent_buffer(eb, GFP_NOFS); + WARN_ON(1); } -void clear_extent_buffer_dirty(struct extent_buffer *eb) +int clear_extent_buffer_dirty(struct extent_io_tree *tree, + struct extent_buffer *eb) { unsigned long i; unsigned long num_pages; @@ -4302,6 +3812,10 @@ void clear_extent_buffer_dirty(struct extent_buffer *eb) lock_page(page); WARN_ON(!PagePrivate(page)); + set_page_extent_mapped(page); + if (i == 0) + set_page_extent_head(page, eb->len); + clear_page_dirty_for_io(page); spin_lock_irq(&page->mapping->tree_lock); if (!PageDirty(page)) { @@ -4313,29 +3827,24 @@ void clear_extent_buffer_dirty(struct extent_buffer *eb) ClearPageError(page); unlock_page(page); } - WARN_ON(atomic_read(&eb->refs) == 0); + return 0; } -int set_extent_buffer_dirty(struct extent_buffer *eb) +int set_extent_buffer_dirty(struct extent_io_tree *tree, + struct extent_buffer *eb) { unsigned long i; unsigned long num_pages; int was_dirty = 0; - check_buffer_tree_ref(eb); - was_dirty = test_and_set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags); - num_pages = num_extent_pages(eb->start, eb->len); - WARN_ON(atomic_read(&eb->refs) == 0); - WARN_ON(!test_bit(EXTENT_BUFFER_TREE_REF, &eb->bflags)); - for (i = 0; i < num_pages; i++) - set_page_dirty(extent_buffer_page(eb, i)); + __set_page_dirty_nobuffers(extent_buffer_page(eb, i)); return was_dirty; } -static int range_straddles_pages(u64 start, u64 len) +static int __eb_straddles_pages(u64 start, u64 len) { if (len < PAGE_CACHE_SIZE) return 1; @@ -4346,14 +3855,25 @@ static int range_straddles_pages(u64 start, u64 len) return 0; } -int clear_extent_buffer_uptodate(struct extent_buffer *eb) +static int eb_straddles_pages(struct extent_buffer *eb) +{ + return __eb_straddles_pages(eb->start, eb->len); +} + +int clear_extent_buffer_uptodate(struct extent_io_tree *tree, + struct extent_buffer *eb, + struct extent_state **cached_state) { unsigned long i; struct page *page; unsigned long num_pages; - clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); num_pages = num_extent_pages(eb->start, eb->len); + clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); + + clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, + cached_state, GFP_NOFS); + for (i = 0; i < num_pages; i++) { page = extent_buffer_page(eb, i); if (page) @@ -4362,16 +3882,27 @@ int clear_extent_buffer_uptodate(struct extent_buffer *eb) return 0; } -int set_extent_buffer_uptodate(struct extent_buffer *eb) +int set_extent_buffer_uptodate(struct extent_io_tree *tree, + struct extent_buffer *eb) { unsigned long i; struct page *page; unsigned long num_pages; - set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); num_pages = num_extent_pages(eb->start, eb->len); + + if (eb_straddles_pages(eb)) { + set_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, + NULL, GFP_NOFS); + } for (i = 0; i < num_pages; i++) { page = extent_buffer_page(eb, i); + if ((i == 0 && (eb->start & (PAGE_CACHE_SIZE - 1))) || + ((i == num_pages - 1) && + ((eb->start + eb->len) & (PAGE_CACHE_SIZE - 1)))) { + check_page_uptodate(tree, page); + continue; + } SetPageUptodate(page); } return 0; @@ -4386,7 +3917,7 @@ int extent_range_uptodate(struct extent_io_tree *tree, int uptodate; unsigned long index; - if (range_straddles_pages(start, end - start + 1)) { + if (__eb_straddles_pages(start, end - start + 1)) { ret = test_range_bit(tree, start, end, EXTENT_UPTODATE, 1, NULL); if (ret) @@ -4408,9 +3939,35 @@ int extent_range_uptodate(struct extent_io_tree *tree, return pg_uptodate; } -int extent_buffer_uptodate(struct extent_buffer *eb) +int extent_buffer_uptodate(struct extent_io_tree *tree, + struct extent_buffer *eb, + struct extent_state *cached_state) { - return test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); + int ret = 0; + unsigned long num_pages; + unsigned long i; + struct page *page; + int pg_uptodate = 1; + + if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags)) + return 1; + + if (eb_straddles_pages(eb)) { + ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1, + EXTENT_UPTODATE, 1, cached_state); + if (ret) + return ret; + } + + num_pages = num_extent_pages(eb->start, eb->len); + for (i = 0; i < num_pages; i++) { + page = extent_buffer_page(eb, i); + if (!PageUptodate(page)) { + pg_uptodate = 0; + break; + } + } + return pg_uptodate; } int read_extent_buffer_pages(struct extent_io_tree *tree, @@ -4424,14 +3981,21 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, int ret = 0; int locked_pages = 0; int all_uptodate = 1; + int inc_all_pages = 0; unsigned long num_pages; - unsigned long num_reads = 0; struct bio *bio = NULL; unsigned long bio_flags = 0; if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags)) return 0; + if (eb_straddles_pages(eb)) { + if (test_range_bit(tree, eb->start, eb->start + eb->len - 1, + EXTENT_UPTODATE, 1, NULL)) { + return 0; + } + } + if (start) { WARN_ON(start < eb->start); start_i = (start >> PAGE_CACHE_SHIFT) - @@ -4450,10 +4014,8 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, lock_page(page); } locked_pages++; - if (!PageUptodate(page)) { - num_reads++; + if (!PageUptodate(page)) all_uptodate = 0; - } } if (all_uptodate) { if (start_i == 0) @@ -4461,12 +4023,20 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, goto unlock_exit; } - clear_bit(EXTENT_BUFFER_IOERR, &eb->bflags); - eb->read_mirror = 0; - atomic_set(&eb->io_pages, num_reads); for (i = start_i; i < num_pages; i++) { page = extent_buffer_page(eb, i); + + WARN_ON(!PagePrivate(page)); + + set_page_extent_mapped(page); + if (i == 0) + set_page_extent_head(page, eb->len); + + if (inc_all_pages) + page_cache_get(page); if (!PageUptodate(page)) { + if (start_i == 0) + inc_all_pages = 1; ClearPageError(page); err = __extent_read_full_page(tree, page, get_extent, &bio, @@ -4478,11 +4048,8 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, } } - if (bio) { - err = submit_one_bio(READ, bio, mirror_num, bio_flags); - if (err) - return err; - } + if (bio) + submit_one_bio(READ, bio, mirror_num, bio_flags); if (ret || wait != WAIT_COMPLETE) return ret; @@ -4494,6 +4061,8 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, ret = -EIO; } + if (!ret) + set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); return ret; unlock_exit: @@ -4735,20 +4304,15 @@ static void copy_pages(struct page *dst_page, struct page *src_page, { char *dst_kaddr = page_address(dst_page); char *src_kaddr; - int must_memmove = 0; if (dst_page != src_page) { src_kaddr = page_address(src_page); } else { src_kaddr = dst_kaddr; - if (areas_overlap(src_off, dst_off, len)) - must_memmove = 1; + BUG_ON(areas_overlap(src_off, dst_off, len)); } - if (must_memmove) - memmove(dst_kaddr + dst_off, src_kaddr + src_off, len); - else - memcpy(dst_kaddr + dst_off, src_kaddr + src_off, len); + memcpy(dst_kaddr + dst_off, src_kaddr + src_off, len); } void memcpy_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset, @@ -4818,7 +4382,7 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset, "len %lu len %lu\n", dst_offset, len, dst->len); BUG_ON(1); } - if (dst_offset < src_offset) { + if (!areas_overlap(src_offset, dst_offset, len)) { memcpy_extent_buffer(dst, dst_offset, src_offset, len); return; } @@ -4844,48 +4408,47 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset, } } -int try_release_extent_buffer(struct page *page, gfp_t mask) +static inline void btrfs_release_extent_buffer_rcu(struct rcu_head *head) { - struct extent_buffer *eb; + struct extent_buffer *eb = + container_of(head, struct extent_buffer, rcu_head); - /* - * We need to make sure noboody is attaching this page to an eb right - * now. - */ - spin_lock(&page->mapping->private_lock); - if (!PagePrivate(page)) { - spin_unlock(&page->mapping->private_lock); - return 1; - } + btrfs_release_extent_buffer(eb); +} - eb = (struct extent_buffer *)page->private; - BUG_ON(!eb); +int try_release_extent_buffer(struct extent_io_tree *tree, struct page *page) +{ + u64 start = page_offset(page); + struct extent_buffer *eb; + int ret = 1; - /* - * This is a little awful but should be ok, we need to make sure that - * the eb doesn't disappear out from under us while we're looking at - * this page. - */ - spin_lock(&eb->refs_lock); - if (atomic_read(&eb->refs) != 1 || extent_buffer_under_io(eb)) { - spin_unlock(&eb->refs_lock); - spin_unlock(&page->mapping->private_lock); - return 0; + spin_lock(&tree->buffer_lock); + eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT); + if (!eb) { + spin_unlock(&tree->buffer_lock); + return ret; } - spin_unlock(&page->mapping->private_lock); - if ((mask & GFP_NOFS) == GFP_NOFS) - mask = GFP_NOFS; + if (test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) { + ret = 0; + goto out; + } /* - * If tree ref isn't set then we know the ref on this eb is a real ref, - * so just return, this page will likely be freed soon anyway. + * set @eb->refs to 0 if it is already 1, and then release the @eb. + * Or go back. */ - if (!test_and_clear_bit(EXTENT_BUFFER_TREE_REF, &eb->bflags)) { - spin_unlock(&eb->refs_lock); - return 0; + if (atomic_cmpxchg(&eb->refs, 1, 0) != 1) { + ret = 0; + goto out; } - release_extent_buffer(eb, mask); - return 1; + radix_tree_delete(&tree->buffer, start >> PAGE_CACHE_SHIFT); +out: + spin_unlock(&tree->buffer_lock); + + /* at this point we can safely release the extent buffer */ + if (atomic_read(&eb->refs) == 0) + call_rcu(&eb->rcu_head, btrfs_release_extent_buffer_rcu); + return ret; } diff --git a/trunk/fs/btrfs/extent_io.h b/trunk/fs/btrfs/extent_io.h index b516c3b8dec6..cecc3518c121 100644 --- a/trunk/fs/btrfs/extent_io.h +++ b/trunk/fs/btrfs/extent_io.h @@ -35,10 +35,6 @@ #define EXTENT_BUFFER_DIRTY 2 #define EXTENT_BUFFER_CORRUPT 3 #define EXTENT_BUFFER_READAHEAD 4 /* this got triggered by readahead */ -#define EXTENT_BUFFER_TREE_REF 5 -#define EXTENT_BUFFER_STALE 6 -#define EXTENT_BUFFER_WRITEBACK 7 -#define EXTENT_BUFFER_IOERR 8 /* these are flags for extent_clear_unlock_delalloc */ #define EXTENT_CLEAR_UNLOCK_PAGE 0x1 @@ -58,7 +54,6 @@ #define EXTENT_PAGE_PRIVATE_FIRST_PAGE 3 struct extent_state; -struct btrfs_root; typedef int (extent_submit_bio_hook_t)(struct inode *inode, int rw, struct bio *bio, int mirror_num, @@ -74,12 +69,14 @@ struct extent_io_ops { size_t size, struct bio *bio, unsigned long bio_flags); int (*readpage_io_hook)(struct page *page, u64 start, u64 end); - int (*readpage_io_failed_hook)(struct page *page, int failed_mirror); + int (*readpage_io_failed_hook)(struct bio *bio, struct page *page, + u64 start, u64 end, int failed_mirror, + struct extent_state *state); int (*writepage_io_failed_hook)(struct bio *bio, struct page *page, u64 start, u64 end, struct extent_state *state); int (*readpage_end_io_hook)(struct page *page, u64 start, u64 end, - struct extent_state *state, int mirror); + struct extent_state *state); int (*writepage_end_io_hook)(struct page *page, u64 start, u64 end, struct extent_state *state, int uptodate); void (*set_bit_hook)(struct inode *inode, struct extent_state *state, @@ -100,7 +97,6 @@ struct extent_io_tree { struct radix_tree_root buffer; struct address_space *mapping; u64 dirty_bytes; - int track_uptodate; spinlock_t lock; spinlock_t buffer_lock; struct extent_io_ops *ops; @@ -123,21 +119,16 @@ struct extent_state { struct list_head leak_list; }; -#define INLINE_EXTENT_BUFFER_PAGES 16 -#define MAX_INLINE_EXTENT_BUFFER_SIZE (INLINE_EXTENT_BUFFER_PAGES * PAGE_CACHE_SIZE) struct extent_buffer { u64 start; unsigned long len; unsigned long map_start; unsigned long map_len; + struct page *first_page; unsigned long bflags; - struct extent_io_tree *tree; - spinlock_t refs_lock; - atomic_t refs; - atomic_t io_pages; - int read_mirror; struct list_head leak_list; struct rcu_head rcu_head; + atomic_t refs; pid_t lock_owner; /* count of read lock holders on the extent buffer */ @@ -161,9 +152,6 @@ struct extent_buffer { * to unlock */ wait_queue_head_t read_lock_wq; - wait_queue_head_t lock_wq; - struct page *inline_pages[INLINE_EXTENT_BUFFER_PAGES]; - struct page **pages; }; static inline void extent_set_compress_type(unsigned long *bio_flags, @@ -190,17 +178,18 @@ void extent_io_tree_init(struct extent_io_tree *tree, int try_release_extent_mapping(struct extent_map_tree *map, struct extent_io_tree *tree, struct page *page, gfp_t mask); -int try_release_extent_buffer(struct page *page, gfp_t mask); +int try_release_extent_buffer(struct extent_io_tree *tree, struct page *page); int try_release_extent_state(struct extent_map_tree *map, struct extent_io_tree *tree, struct page *page, gfp_t mask); -int lock_extent(struct extent_io_tree *tree, u64 start, u64 end); +int lock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask); int lock_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, - int bits, struct extent_state **cached); -int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end); + int bits, struct extent_state **cached, gfp_t mask); +int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask); int unlock_extent_cached(struct extent_io_tree *tree, u64 start, u64 end, struct extent_state **cached, gfp_t mask); -int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end); +int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end, + gfp_t mask); int extent_read_full_page(struct extent_io_tree *tree, struct page *page, get_extent_t *get_extent, int mirror_num); int __init extent_io_init(void); @@ -221,7 +210,7 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int set_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, int bits, gfp_t mask); int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, - int bits, u64 *failed_start, + int bits, int exclusive_bits, u64 *failed_start, struct extent_state **cached_state, gfp_t mask); int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, struct extent_state **cached_state, gfp_t mask); @@ -251,8 +240,6 @@ int extent_writepages(struct extent_io_tree *tree, struct address_space *mapping, get_extent_t *get_extent, struct writeback_control *wbc); -int btree_write_cache_pages(struct address_space *mapping, - struct writeback_control *wbc); int extent_readpages(struct extent_io_tree *tree, struct address_space *mapping, struct list_head *pages, unsigned nr_pages, @@ -264,11 +251,11 @@ int get_state_private(struct extent_io_tree *tree, u64 start, u64 *private); void set_page_extent_mapped(struct page *page); struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, - u64 start, unsigned long len); + u64 start, unsigned long len, + struct page *page0); struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree, u64 start, unsigned long len); void free_extent_buffer(struct extent_buffer *eb); -void free_extent_buffer_stale(struct extent_buffer *eb); #define WAIT_NONE 0 #define WAIT_COMPLETE 1 #define WAIT_PAGE_LOCK 2 @@ -300,12 +287,19 @@ void memmove_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset, unsigned long src_offset, unsigned long len); void memset_extent_buffer(struct extent_buffer *eb, char c, unsigned long start, unsigned long len); -void wait_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int bits); -void clear_extent_buffer_dirty(struct extent_buffer *eb); -int set_extent_buffer_dirty(struct extent_buffer *eb); -int set_extent_buffer_uptodate(struct extent_buffer *eb); -int clear_extent_buffer_uptodate(struct extent_buffer *eb); -int extent_buffer_uptodate(struct extent_buffer *eb); +int wait_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int bits); +int clear_extent_buffer_dirty(struct extent_io_tree *tree, + struct extent_buffer *eb); +int set_extent_buffer_dirty(struct extent_io_tree *tree, + struct extent_buffer *eb); +int set_extent_buffer_uptodate(struct extent_io_tree *tree, + struct extent_buffer *eb); +int clear_extent_buffer_uptodate(struct extent_io_tree *tree, + struct extent_buffer *eb, + struct extent_state **cached_state); +int extent_buffer_uptodate(struct extent_io_tree *tree, + struct extent_buffer *eb, + struct extent_state *cached_state); int map_private_extent_buffer(struct extent_buffer *eb, unsigned long offset, unsigned long min_len, char **map, unsigned long *map_start, @@ -326,6 +320,4 @@ int repair_io_failure(struct btrfs_mapping_tree *map_tree, u64 start, u64 length, u64 logical, struct page *page, int mirror_num); int end_extent_writepage(struct page *page, int err, u64 start, u64 end); -int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb, - int mirror_num); #endif diff --git a/trunk/fs/btrfs/file-item.c b/trunk/fs/btrfs/file-item.c index 5d158d320233..078b4fd54500 100644 --- a/trunk/fs/btrfs/file-item.c +++ b/trunk/fs/btrfs/file-item.c @@ -25,12 +25,10 @@ #include "transaction.h" #include "print-tree.h" -#define __MAX_CSUM_ITEMS(r, size) ((((BTRFS_LEAF_DATA_SIZE(r) - \ +#define MAX_CSUM_ITEMS(r, size) ((((BTRFS_LEAF_DATA_SIZE(r) - \ sizeof(struct btrfs_item) * 2) / \ size) - 1)) -#define MAX_CSUM_ITEMS(r, size) (min(__MAX_CSUM_ITEMS(r, size), PAGE_CACHE_SIZE)) - #define MAX_ORDERED_SUM_BYTES(r) ((PAGE_SIZE - \ sizeof(struct btrfs_ordered_sum)) / \ sizeof(struct btrfs_sector_sum) * \ @@ -61,7 +59,7 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans, sizeof(*item)); if (ret < 0) goto out; - BUG_ON(ret); /* Can't happen */ + BUG_ON(ret); leaf = path->nodes[0]; item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item); @@ -286,7 +284,6 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, struct btrfs_ordered_sum *sums; struct btrfs_sector_sum *sector_sum; struct btrfs_csum_item *item; - LIST_HEAD(tmplist); unsigned long offset; int ret; size_t size; @@ -361,10 +358,7 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, MAX_ORDERED_SUM_BYTES(root)); sums = kzalloc(btrfs_ordered_sum_size(root, size), GFP_NOFS); - if (!sums) { - ret = -ENOMEM; - goto fail; - } + BUG_ON(!sums); sector_sum = sums->sums; sums->bytenr = start; @@ -386,19 +380,12 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, offset += csum_size; sector_sum++; } - list_add_tail(&sums->list, &tmplist); + list_add_tail(&sums->list, list); } path->slots[0]++; } ret = 0; fail: - while (ret < 0 && !list_empty(&tmplist)) { - sums = list_entry(&tmplist, struct btrfs_ordered_sum, list); - list_del(&sums->list); - kfree(sums); - } - list_splice_tail(&tmplist, list); - btrfs_free_path(path); return ret; } @@ -433,7 +420,7 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode, offset = page_offset(bvec->bv_page) + bvec->bv_offset; ordered = btrfs_lookup_ordered_extent(inode, offset); - BUG_ON(!ordered); /* Logic error */ + BUG_ON(!ordered); sums->bytenr = ordered->start; while (bio_index < bio->bi_vcnt) { @@ -452,11 +439,11 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode, sums = kzalloc(btrfs_ordered_sum_size(root, bytes_left), GFP_NOFS); - BUG_ON(!sums); /* -ENOMEM */ + BUG_ON(!sums); sector_sum = sums->sums; sums->len = bytes_left; ordered = btrfs_lookup_ordered_extent(inode, offset); - BUG_ON(!ordered); /* Logic error */ + BUG_ON(!ordered); sums->bytenr = ordered->start; } @@ -496,17 +483,18 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode, * This calls btrfs_truncate_item with the correct args based on the * overlap, and fixes up the key as required. */ -static noinline void truncate_one_csum(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, - struct btrfs_key *key, - u64 bytenr, u64 len) +static noinline int truncate_one_csum(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + struct btrfs_key *key, + u64 bytenr, u64 len) { struct extent_buffer *leaf; u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy); u64 csum_end; u64 end_byte = bytenr + len; u32 blocksize_bits = root->fs_info->sb->s_blocksize_bits; + int ret; leaf = path->nodes[0]; csum_end = btrfs_item_size_nr(leaf, path->slots[0]) / csum_size; @@ -522,7 +510,7 @@ static noinline void truncate_one_csum(struct btrfs_trans_handle *trans, */ u32 new_size = (bytenr - key->offset) >> blocksize_bits; new_size *= csum_size; - btrfs_truncate_item(trans, root, path, new_size, 1); + ret = btrfs_truncate_item(trans, root, path, new_size, 1); } else if (key->offset >= bytenr && csum_end > end_byte && end_byte > key->offset) { /* @@ -534,13 +522,15 @@ static noinline void truncate_one_csum(struct btrfs_trans_handle *trans, u32 new_size = (csum_end - end_byte) >> blocksize_bits; new_size *= csum_size; - btrfs_truncate_item(trans, root, path, new_size, 0); + ret = btrfs_truncate_item(trans, root, path, new_size, 0); key->offset = end_byte; - btrfs_set_item_key_safe(trans, root, path, key); + ret = btrfs_set_item_key_safe(trans, root, path, key); + BUG_ON(ret); } else { BUG(); } + return 0; } /* @@ -645,14 +635,13 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, * item changed size or key */ ret = btrfs_split_item(trans, root, path, &key, offset); - if (ret && ret != -EAGAIN) { - btrfs_abort_transaction(trans, root, ret); - goto out; - } + BUG_ON(ret && ret != -EAGAIN); key.offset = end_byte - 1; } else { - truncate_one_csum(trans, root, path, &key, bytenr, len); + ret = truncate_one_csum(trans, root, path, + &key, bytenr, len); + BUG_ON(ret); if (key.offset < bytenr) break; } @@ -783,7 +772,7 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, if (diff != csum_size) goto insert; - btrfs_extend_item(trans, root, path, diff); + ret = btrfs_extend_item(trans, root, path, diff); goto csum; } diff --git a/trunk/fs/btrfs/file.c b/trunk/fs/btrfs/file.c index 53bf2d764bbc..e8d06b6b9194 100644 --- a/trunk/fs/btrfs/file.c +++ b/trunk/fs/btrfs/file.c @@ -452,7 +452,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, split = alloc_extent_map(); if (!split2) split2 = alloc_extent_map(); - BUG_ON(!split || !split2); /* -ENOMEM */ + BUG_ON(!split || !split2); write_lock(&em_tree->lock); em = lookup_extent_mapping(em_tree, start, len); @@ -494,7 +494,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, split->flags = flags; split->compress_type = em->compress_type; ret = add_extent_mapping(em_tree, split); - BUG_ON(ret); /* Logic error */ + BUG_ON(ret); free_extent_map(split); split = split2; split2 = NULL; @@ -520,7 +520,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, } ret = add_extent_mapping(em_tree, split); - BUG_ON(ret); /* Logic error */ + BUG_ON(ret); free_extent_map(split); split = NULL; } @@ -567,7 +567,6 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, int extent_type; int recow; int ret; - int modify_tree = -1; if (drop_cache) btrfs_drop_extent_cache(inode, start, end - 1, 0); @@ -576,13 +575,10 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, if (!path) return -ENOMEM; - if (start >= BTRFS_I(inode)->disk_i_size) - modify_tree = 0; - while (1) { recow = 0; ret = btrfs_lookup_file_extent(trans, root, path, ino, - search_start, modify_tree); + search_start, -1); if (ret < 0) break; if (ret > 0 && path->slots[0] > 0 && search_start == start) { @@ -638,8 +634,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, } search_start = max(key.offset, start); - if (recow || !modify_tree) { - modify_tree = -1; + if (recow) { btrfs_release_path(path); continue; } @@ -684,7 +679,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, root->root_key.objectid, new_key.objectid, start - extent_offset, 0); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); *hint_byte = disk_bytenr; } key.offset = start; @@ -759,7 +754,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, root->root_key.objectid, key.objectid, key.offset - extent_offset, 0); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); inode_sub_bytes(inode, extent_end - key.offset); *hint_byte = disk_bytenr; @@ -775,10 +770,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, ret = btrfs_del_items(trans, root, path, del_slot, del_nr); - if (ret) { - btrfs_abort_transaction(trans, root, ret); - goto out; - } + BUG_ON(ret); del_nr = 0; del_slot = 0; @@ -790,13 +782,11 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, BUG_ON(1); } - if (!ret && del_nr > 0) { + if (del_nr > 0) { ret = btrfs_del_items(trans, root, path, del_slot, del_nr); - if (ret) - btrfs_abort_transaction(trans, root, ret); + BUG_ON(ret); } -out: btrfs_free_path(path); return ret; } @@ -954,10 +944,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, btrfs_release_path(path); goto again; } - if (ret < 0) { - btrfs_abort_transaction(trans, root, ret); - goto out; - } + BUG_ON(ret < 0); leaf = path->nodes[0]; fi = btrfs_item_ptr(leaf, path->slots[0] - 1, @@ -976,7 +963,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, 0, root->root_key.objectid, ino, orig_offset, 0); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); if (split == start) { key.offset = start; @@ -1003,7 +990,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, ret = btrfs_free_extent(trans, root, bytenr, num_bytes, 0, root->root_key.objectid, ino, orig_offset, 0); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } other_start = 0; other_end = start; @@ -1020,7 +1007,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, ret = btrfs_free_extent(trans, root, bytenr, num_bytes, 0, root->root_key.objectid, ino, orig_offset, 0); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } if (del_nr == 0) { fi = btrfs_item_ptr(leaf, path->slots[0], @@ -1038,10 +1025,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, btrfs_mark_buffer_dirty(leaf); ret = btrfs_del_items(trans, root, path, del_slot, del_nr); - if (ret < 0) { - btrfs_abort_transaction(trans, root, ret); - goto out; - } + BUG_ON(ret); } out: btrfs_free_path(path); @@ -1121,7 +1105,8 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file, if (start_pos < inode->i_size) { struct btrfs_ordered_extent *ordered; lock_extent_bits(&BTRFS_I(inode)->io_tree, - start_pos, last_pos - 1, 0, &cached_state); + start_pos, last_pos - 1, 0, &cached_state, + GFP_NOFS); ordered = btrfs_lookup_first_ordered_extent(inode, last_pos - 1); if (ordered && @@ -1653,7 +1638,7 @@ static long btrfs_fallocate(struct file *file, int mode, * transaction */ lock_extent_bits(&BTRFS_I(inode)->io_tree, alloc_start, - locked_end, 0, &cached_state); + locked_end, 0, &cached_state, GFP_NOFS); ordered = btrfs_lookup_first_ordered_extent(inode, alloc_end - 1); if (ordered && @@ -1682,13 +1667,7 @@ static long btrfs_fallocate(struct file *file, int mode, em = btrfs_get_extent(inode, NULL, 0, cur_offset, alloc_end - cur_offset, 0); - if (IS_ERR_OR_NULL(em)) { - if (!em) - ret = -ENOMEM; - else - ret = PTR_ERR(em); - break; - } + BUG_ON(IS_ERR_OR_NULL(em)); last_byte = min(extent_map_end(em), alloc_end); actual_end = min_t(u64, extent_map_end(em), offset + len); last_byte = (last_byte + mask) & ~mask; @@ -1758,7 +1737,7 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin) return -ENXIO; lock_extent_bits(&BTRFS_I(inode)->io_tree, lockstart, lockend, 0, - &cached_state); + &cached_state, GFP_NOFS); /* * Delalloc is such a pain. If we have a hole and we have pending diff --git a/trunk/fs/btrfs/free-space-cache.c b/trunk/fs/btrfs/free-space-cache.c index 202008ec367d..b02e379b14c7 100644 --- a/trunk/fs/btrfs/free-space-cache.c +++ b/trunk/fs/btrfs/free-space-cache.c @@ -230,13 +230,11 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root, if (ret) { trans->block_rsv = rsv; - btrfs_abort_transaction(trans, root, ret); + WARN_ON(1); return ret; } ret = btrfs_update_inode(trans, root, inode); - if (ret) - btrfs_abort_transaction(trans, root, ret); trans->block_rsv = rsv; return ret; @@ -747,6 +745,13 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, bool matched; u64 used = btrfs_block_group_used(&block_group->item); + /* + * If we're unmounting then just return, since this does a search on the + * normal root and not the commit root and we could deadlock. + */ + if (btrfs_fs_closing(fs_info)) + return 0; + /* * If this block group has been marked to be cleared for one reason or * another then we can't trust the on disk cache, so just return. @@ -761,8 +766,6 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, path = btrfs_alloc_path(); if (!path) return 0; - path->search_commit_root = 1; - path->skip_locking = 1; inode = lookup_free_space_inode(root, block_group, path); if (IS_ERR(inode)) { @@ -866,7 +869,7 @@ int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, io_ctl_prepare_pages(&io_ctl, inode, 0); lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1, - 0, &cached_state); + 0, &cached_state, GFP_NOFS); node = rb_first(&ctl->free_space_offset); if (!node && cluster) { @@ -1945,14 +1948,14 @@ int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group, */ ret = btrfs_add_free_space(block_group, old_start, offset - old_start); - WARN_ON(ret); /* -ENOMEM */ + WARN_ON(ret); goto out; } ret = remove_from_bitmap(ctl, info, &offset, &bytes); if (ret == -EAGAIN) goto again; - BUG_ON(ret); /* logic error */ + BUG_ON(ret); out_lock: spin_unlock(&ctl->tree_lock); out: @@ -2343,7 +2346,7 @@ static int btrfs_bitmap_cluster(struct btrfs_block_group_cache *block_group, rb_erase(&entry->offset_index, &ctl->free_space_offset); ret = tree_insert_offset(&cluster->root, entry->offset, &entry->offset_index, 1); - BUG_ON(ret); /* -EEXIST; Logic error */ + BUG_ON(ret); trace_btrfs_setup_cluster(block_group, cluster, total_found * block_group->sectorsize, 1); @@ -2436,7 +2439,7 @@ setup_cluster_no_bitmap(struct btrfs_block_group_cache *block_group, ret = tree_insert_offset(&cluster->root, entry->offset, &entry->offset_index, 0); total_size += entry->bytes; - BUG_ON(ret); /* -EEXIST; Logic error */ + BUG_ON(ret); } while (node && entry != last); cluster->max_size = max_extent; @@ -2827,7 +2830,6 @@ u64 btrfs_find_ino_for_alloc(struct btrfs_root *fs_root) int ret; ret = search_bitmap(ctl, entry, &offset, &count); - /* Logic error; Should be empty if it can't find anything */ BUG_ON(ret); ino = offset; diff --git a/trunk/fs/btrfs/inode-item.c b/trunk/fs/btrfs/inode-item.c index a13cf1a96c73..baa74f3db691 100644 --- a/trunk/fs/btrfs/inode-item.c +++ b/trunk/fs/btrfs/inode-item.c @@ -19,7 +19,6 @@ #include "ctree.h" #include "disk-io.h" #include "transaction.h" -#include "print-tree.h" static int find_name_in_backref(struct btrfs_path *path, const char *name, int name_len, struct btrfs_inode_ref **ref_ret) @@ -129,14 +128,13 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans, item_start = btrfs_item_ptr_offset(leaf, path->slots[0]); memmove_extent_buffer(leaf, ptr, ptr + sub_item_len, item_size - (ptr + sub_item_len - item_start)); - btrfs_truncate_item(trans, root, path, + ret = btrfs_truncate_item(trans, root, path, item_size - sub_item_len, 1); out: btrfs_free_path(path); return ret; } -/* Will return 0, -ENOMEM, -EMLINK, or -EEXIST or anything from the CoW path */ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, const char *name, int name_len, @@ -167,7 +165,7 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, goto out; old_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]); - btrfs_extend_item(trans, root, path, ins_len); + ret = btrfs_extend_item(trans, root, path, ins_len); ref = btrfs_item_ptr(path->nodes[0], path->slots[0], struct btrfs_inode_ref); ref = (struct btrfs_inode_ref *)((unsigned long)ref + old_size); diff --git a/trunk/fs/btrfs/inode-map.c b/trunk/fs/btrfs/inode-map.c index b1a1c929ba80..ee15d88b33d2 100644 --- a/trunk/fs/btrfs/inode-map.c +++ b/trunk/fs/btrfs/inode-map.c @@ -178,7 +178,7 @@ static void start_caching(struct btrfs_root *root) tsk = kthread_run(caching_kthread, root, "btrfs-ino-cache-%llu\n", root->root_key.objectid); - BUG_ON(IS_ERR(tsk)); /* -ENOMEM */ + BUG_ON(IS_ERR(tsk)); } int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid) @@ -271,7 +271,7 @@ void btrfs_unpin_free_ino(struct btrfs_root *root) break; info = rb_entry(n, struct btrfs_free_space, offset_index); - BUG_ON(info->bitmap); /* Logic error */ + BUG_ON(info->bitmap); if (info->offset > root->cache_progress) goto free; @@ -439,16 +439,17 @@ int btrfs_save_ino_cache(struct btrfs_root *root, if (ret) goto out; trace_btrfs_space_reservation(root->fs_info, "ino_cache", - trans->transid, trans->bytes_reserved, 1); + (u64)(unsigned long)trans, + trans->bytes_reserved, 1); again: inode = lookup_free_ino_inode(root, path); - if (IS_ERR(inode) && (PTR_ERR(inode) != -ENOENT || retry)) { + if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) { ret = PTR_ERR(inode); goto out_release; } if (IS_ERR(inode)) { - BUG_ON(retry); /* Logic error */ + BUG_ON(retry); retry = true; ret = create_free_ino_inode(root, trans, path); @@ -459,17 +460,12 @@ int btrfs_save_ino_cache(struct btrfs_root *root, BTRFS_I(inode)->generation = 0; ret = btrfs_update_inode(trans, root, inode); - if (ret) { - btrfs_abort_transaction(trans, root, ret); - goto out_put; - } + WARN_ON(ret); if (i_size_read(inode) > 0) { ret = btrfs_truncate_free_space_cache(root, trans, path, inode); - if (ret) { - btrfs_abort_transaction(trans, root, ret); + if (ret) goto out_put; - } } spin_lock(&root->cache_lock); @@ -506,7 +502,8 @@ int btrfs_save_ino_cache(struct btrfs_root *root, iput(inode); out_release: trace_btrfs_space_reservation(root->fs_info, "ino_cache", - trans->transid, trans->bytes_reserved, 0); + (u64)(unsigned long)trans, + trans->bytes_reserved, 0); btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved); out: trans->block_rsv = rsv; @@ -535,7 +532,7 @@ static int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid) ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); if (ret < 0) goto error; - BUG_ON(ret == 0); /* Corruption */ + BUG_ON(ret == 0); if (path->slots[0] > 0) { slot = path->slots[0] - 1; l = path->nodes[0]; diff --git a/trunk/fs/btrfs/inode.c b/trunk/fs/btrfs/inode.c index 61b16c641ce0..3a0b5c1f9d31 100644 --- a/trunk/fs/btrfs/inode.c +++ b/trunk/fs/btrfs/inode.c @@ -150,6 +150,7 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans, inode_add_bytes(inode, size); ret = btrfs_insert_empty_item(trans, root, path, &key, datasize); + BUG_ON(ret); if (ret) { err = ret; goto fail; @@ -205,9 +206,9 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans, * could end up racing with unlink. */ BTRFS_I(inode)->disk_i_size = inode->i_size; - ret = btrfs_update_inode(trans, root, inode); + btrfs_update_inode(trans, root, inode); - return ret; + return 0; fail: btrfs_free_path(path); return err; @@ -249,18 +250,14 @@ static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans, ret = btrfs_drop_extents(trans, inode, start, aligned_end, &hint_byte, 1); - if (ret) - return ret; + BUG_ON(ret); if (isize > actual_end) inline_len = min_t(u64, isize, actual_end); ret = insert_inline_extent(trans, root, inode, start, inline_len, compressed_size, compress_type, compressed_pages); - if (ret) { - btrfs_abort_transaction(trans, root, ret); - return ret; - } + BUG_ON(ret); btrfs_delalloc_release_metadata(inode, end + 1 - start); btrfs_drop_extent_cache(inode, start, aligned_end - 1, 0); return 0; @@ -296,7 +293,7 @@ static noinline int add_async_extent(struct async_cow *cow, struct async_extent *async_extent; async_extent = kmalloc(sizeof(*async_extent), GFP_NOFS); - BUG_ON(!async_extent); /* -ENOMEM */ + BUG_ON(!async_extent); async_extent->start = start; async_extent->ram_size = ram_size; async_extent->compressed_size = compressed_size; @@ -347,9 +344,8 @@ static noinline int compress_file_range(struct inode *inode, int will_compress; int compress_type = root->fs_info->compress_type; - /* if this is a small write inside eof, kick off a defrag */ - if ((end - start + 1) < 16 * 1024 && - (start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size)) + /* if this is a small write inside eof, kick off a defragbot */ + if (end <= BTRFS_I(inode)->disk_i_size && (end - start + 1) < 16 * 1024) btrfs_add_inode_defrag(NULL, inode); actual_end = min_t(u64, isize, end + 1); @@ -437,11 +433,7 @@ static noinline int compress_file_range(struct inode *inode, cont: if (start == 0) { trans = btrfs_join_transaction(root); - if (IS_ERR(trans)) { - ret = PTR_ERR(trans); - trans = NULL; - goto cleanup_and_out; - } + BUG_ON(IS_ERR(trans)); trans->block_rsv = &root->fs_info->delalloc_block_rsv; /* lets try to make an inline extent */ @@ -458,11 +450,11 @@ static noinline int compress_file_range(struct inode *inode, total_compressed, compress_type, pages); } - if (ret <= 0) { + if (ret == 0) { /* - * inline extent creation worked or returned error, - * we don't need to create any more async work items. - * Unlock and free up our temp pages. + * inline extent creation worked, we don't need + * to create any more async work items. Unlock + * and free up our temp pages. */ extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, @@ -555,7 +547,7 @@ static noinline int compress_file_range(struct inode *inode, } out: - return ret; + return 0; free_pages_out: for (i = 0; i < nr_pages_ret; i++) { @@ -565,20 +557,6 @@ static noinline int compress_file_range(struct inode *inode, kfree(pages); goto out; - -cleanup_and_out: - extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, - start, end, NULL, - EXTENT_CLEAR_UNLOCK_PAGE | - EXTENT_CLEAR_DIRTY | - EXTENT_CLEAR_DELALLOC | - EXTENT_SET_WRITEBACK | - EXTENT_END_WRITEBACK); - if (!trans || IS_ERR(trans)) - btrfs_error(root->fs_info, ret, "Failed to join transaction"); - else - btrfs_abort_transaction(trans, root, ret); - goto free_pages_out; } /* @@ -619,7 +597,7 @@ static noinline int submit_compressed_extents(struct inode *inode, lock_extent(io_tree, async_extent->start, async_extent->start + - async_extent->ram_size - 1); + async_extent->ram_size - 1, GFP_NOFS); /* allocate blocks */ ret = cow_file_range(inode, async_cow->locked_page, @@ -628,8 +606,6 @@ static noinline int submit_compressed_extents(struct inode *inode, async_extent->ram_size - 1, &page_started, &nr_written, 0); - /* JDM XXX */ - /* * if page_started, cow_file_range inserted an * inline extent and took care of all the unlocking @@ -649,21 +625,18 @@ static noinline int submit_compressed_extents(struct inode *inode, } lock_extent(io_tree, async_extent->start, - async_extent->start + async_extent->ram_size - 1); + async_extent->start + async_extent->ram_size - 1, + GFP_NOFS); trans = btrfs_join_transaction(root); - if (IS_ERR(trans)) { - ret = PTR_ERR(trans); - } else { - trans->block_rsv = &root->fs_info->delalloc_block_rsv; - ret = btrfs_reserve_extent(trans, root, + BUG_ON(IS_ERR(trans)); + trans->block_rsv = &root->fs_info->delalloc_block_rsv; + ret = btrfs_reserve_extent(trans, root, async_extent->compressed_size, async_extent->compressed_size, - 0, alloc_hint, &ins, 1); - if (ret) - btrfs_abort_transaction(trans, root, ret); - btrfs_end_transaction(trans, root); - } + 0, alloc_hint, + (u64)-1, &ins, 1); + btrfs_end_transaction(trans, root); if (ret) { int i; @@ -676,10 +649,8 @@ static noinline int submit_compressed_extents(struct inode *inode, async_extent->pages = NULL; unlock_extent(io_tree, async_extent->start, async_extent->start + - async_extent->ram_size - 1); - if (ret == -ENOSPC) - goto retry; - goto out_free; /* JDM: Requeue? */ + async_extent->ram_size - 1, GFP_NOFS); + goto retry; } /* @@ -691,7 +662,7 @@ static noinline int submit_compressed_extents(struct inode *inode, async_extent->ram_size - 1, 0); em = alloc_extent_map(); - BUG_ON(!em); /* -ENOMEM */ + BUG_ON(!em); em->start = async_extent->start; em->len = async_extent->ram_size; em->orig_start = em->start; @@ -723,7 +694,7 @@ static noinline int submit_compressed_extents(struct inode *inode, ins.offset, BTRFS_ORDERED_COMPRESSED, async_extent->compress_type); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); /* * clear dirty, set writeback and unlock the pages. @@ -745,17 +716,13 @@ static noinline int submit_compressed_extents(struct inode *inode, ins.offset, async_extent->pages, async_extent->nr_pages); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); alloc_hint = ins.objectid + ins.offset; kfree(async_extent); cond_resched(); } - ret = 0; -out: - return ret; -out_free: - kfree(async_extent); - goto out; + + return 0; } static u64 get_extent_allocation_hint(struct inode *inode, u64 start, @@ -824,18 +791,7 @@ static noinline int cow_file_range(struct inode *inode, BUG_ON(btrfs_is_free_space_inode(root, inode)); trans = btrfs_join_transaction(root); - if (IS_ERR(trans)) { - extent_clear_unlock_delalloc(inode, - &BTRFS_I(inode)->io_tree, - start, end, NULL, - EXTENT_CLEAR_UNLOCK_PAGE | - EXTENT_CLEAR_UNLOCK | - EXTENT_CLEAR_DELALLOC | - EXTENT_CLEAR_DIRTY | - EXTENT_SET_WRITEBACK | - EXTENT_END_WRITEBACK); - return PTR_ERR(trans); - } + BUG_ON(IS_ERR(trans)); trans->block_rsv = &root->fs_info->delalloc_block_rsv; num_bytes = (end - start + blocksize) & ~(blocksize - 1); @@ -844,8 +800,7 @@ static noinline int cow_file_range(struct inode *inode, ret = 0; /* if this is a small write inside eof, kick off defrag */ - if (num_bytes < 64 * 1024 && - (start > 0 || end + 1 < BTRFS_I(inode)->disk_i_size)) + if (end <= BTRFS_I(inode)->disk_i_size && num_bytes < 64 * 1024) btrfs_add_inode_defrag(trans, inode); if (start == 0) { @@ -866,10 +821,8 @@ static noinline int cow_file_range(struct inode *inode, *nr_written = *nr_written + (end - start + PAGE_CACHE_SIZE) / PAGE_CACHE_SIZE; *page_started = 1; + ret = 0; goto out; - } else if (ret < 0) { - btrfs_abort_transaction(trans, root, ret); - goto out_unlock; } } @@ -885,14 +838,11 @@ static noinline int cow_file_range(struct inode *inode, cur_alloc_size = disk_num_bytes; ret = btrfs_reserve_extent(trans, root, cur_alloc_size, root->sectorsize, 0, alloc_hint, - &ins, 1); - if (ret < 0) { - btrfs_abort_transaction(trans, root, ret); - goto out_unlock; - } + (u64)-1, &ins, 1); + BUG_ON(ret); em = alloc_extent_map(); - BUG_ON(!em); /* -ENOMEM */ + BUG_ON(!em); em->start = start; em->orig_start = em->start; ram_size = ins.offset; @@ -918,16 +868,13 @@ static noinline int cow_file_range(struct inode *inode, cur_alloc_size = ins.offset; ret = btrfs_add_ordered_extent(inode, start, ins.objectid, ram_size, cur_alloc_size, 0); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID) { ret = btrfs_reloc_clone_csums(inode, start, cur_alloc_size); - if (ret) { - btrfs_abort_transaction(trans, root, ret); - goto out_unlock; - } + BUG_ON(ret); } if (disk_num_bytes < cur_alloc_size) @@ -952,23 +899,11 @@ static noinline int cow_file_range(struct inode *inode, alloc_hint = ins.objectid + ins.offset; start += cur_alloc_size; } - ret = 0; out: + ret = 0; btrfs_end_transaction(trans, root); return ret; -out_unlock: - extent_clear_unlock_delalloc(inode, - &BTRFS_I(inode)->io_tree, - start, end, NULL, - EXTENT_CLEAR_UNLOCK_PAGE | - EXTENT_CLEAR_UNLOCK | - EXTENT_CLEAR_DELALLOC | - EXTENT_CLEAR_DIRTY | - EXTENT_SET_WRITEBACK | - EXTENT_END_WRITEBACK); - - goto out; } /* @@ -1034,7 +969,7 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page, 1, 0, NULL, GFP_NOFS); while (start < end) { async_cow = kmalloc(sizeof(*async_cow), GFP_NOFS); - BUG_ON(!async_cow); /* -ENOMEM */ + BUG_ON(!async_cow); async_cow->inode = inode; async_cow->root = root; async_cow->locked_page = locked_page; @@ -1125,7 +1060,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, u64 disk_bytenr; u64 num_bytes; int extent_type; - int ret, err; + int ret; int type; int nocow; int check_prev = 1; @@ -1143,11 +1078,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, else trans = btrfs_join_transaction(root); - if (IS_ERR(trans)) { - btrfs_free_path(path); - return PTR_ERR(trans); - } - + BUG_ON(IS_ERR(trans)); trans->block_rsv = &root->fs_info->delalloc_block_rsv; cow_start = (u64)-1; @@ -1155,10 +1086,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, while (1) { ret = btrfs_lookup_file_extent(trans, root, path, ino, cur_offset, 0); - if (ret < 0) { - btrfs_abort_transaction(trans, root, ret); - goto error; - } + BUG_ON(ret < 0); if (ret > 0 && path->slots[0] > 0 && check_prev) { leaf = path->nodes[0]; btrfs_item_key_to_cpu(leaf, &found_key, @@ -1172,10 +1100,8 @@ static noinline int run_delalloc_nocow(struct inode *inode, leaf = path->nodes[0]; if (path->slots[0] >= btrfs_header_nritems(leaf)) { ret = btrfs_next_leaf(root, path); - if (ret < 0) { - btrfs_abort_transaction(trans, root, ret); - goto error; - } + if (ret < 0) + BUG_ON(1); if (ret > 0) break; leaf = path->nodes[0]; @@ -1263,10 +1189,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, ret = cow_file_range(inode, locked_page, cow_start, found_key.offset - 1, page_started, nr_written, 1); - if (ret) { - btrfs_abort_transaction(trans, root, ret); - goto error; - } + BUG_ON(ret); cow_start = (u64)-1; } @@ -1275,7 +1198,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, struct extent_map_tree *em_tree; em_tree = &BTRFS_I(inode)->extent_tree; em = alloc_extent_map(); - BUG_ON(!em); /* -ENOMEM */ + BUG_ON(!em); em->start = cur_offset; em->orig_start = em->start; em->len = num_bytes; @@ -1301,16 +1224,13 @@ static noinline int run_delalloc_nocow(struct inode *inode, ret = btrfs_add_ordered_extent(inode, cur_offset, disk_bytenr, num_bytes, num_bytes, type); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID) { ret = btrfs_reloc_clone_csums(inode, cur_offset, num_bytes); - if (ret) { - btrfs_abort_transaction(trans, root, ret); - goto error; - } + BUG_ON(ret); } extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, @@ -1329,23 +1249,18 @@ static noinline int run_delalloc_nocow(struct inode *inode, if (cow_start != (u64)-1) { ret = cow_file_range(inode, locked_page, cow_start, end, page_started, nr_written, 1); - if (ret) { - btrfs_abort_transaction(trans, root, ret); - goto error; - } + BUG_ON(ret); } -error: if (nolock) { - err = btrfs_end_transaction_nolock(trans, root); + ret = btrfs_end_transaction_nolock(trans, root); + BUG_ON(ret); } else { - err = btrfs_end_transaction(trans, root); + ret = btrfs_end_transaction(trans, root); + BUG_ON(ret); } - if (!ret) - ret = err; - btrfs_free_path(path); - return ret; + return 0; } /* @@ -1510,11 +1425,10 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset, map_length = length; ret = btrfs_map_block(map_tree, READ, logical, &map_length, NULL, 0); - /* Will always return 0 or 1 with map_multi == NULL */ - BUG_ON(ret < 0); + if (map_length < length + size) return 1; - return 0; + return ret; } /* @@ -1534,7 +1448,7 @@ static int __btrfs_submit_bio_start(struct inode *inode, int rw, int ret = 0; ret = btrfs_csum_one_bio(root, inode, bio, 0, 0); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); return 0; } @@ -1565,16 +1479,14 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, struct btrfs_root *root = BTRFS_I(inode)->root; int ret = 0; int skip_sum; - int metadata = 0; skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; if (btrfs_is_free_space_inode(root, inode)) - metadata = 2; - - ret = btrfs_bio_wq_end_io(root->fs_info, bio, metadata); - if (ret) - return ret; + ret = btrfs_bio_wq_end_io(root->fs_info, bio, 2); + else + ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); + BUG_ON(ret); if (!(rw & REQ_WRITE)) { if (bio_flags & EXTENT_BIO_COMPRESSED) { @@ -1659,7 +1571,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) page_end = page_offset(page) + PAGE_CACHE_SIZE - 1; lock_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end, 0, - &cached_state); + &cached_state, GFP_NOFS); /* already ordered? We're done */ if (PagePrivate2(page)) @@ -1763,15 +1675,13 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, */ ret = btrfs_drop_extents(trans, inode, file_pos, file_pos + num_bytes, &hint, 0); - if (ret) - goto out; + BUG_ON(ret); ins.objectid = btrfs_ino(inode); ins.offset = file_pos; ins.type = BTRFS_EXTENT_DATA_KEY; ret = btrfs_insert_empty_item(trans, root, path, &ins, sizeof(*fi)); - if (ret) - goto out; + BUG_ON(ret); leaf = path->nodes[0]; fi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item); @@ -1799,10 +1709,10 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, ret = btrfs_alloc_reserved_file_extent(trans, root, root->root_key.objectid, btrfs_ino(inode), file_pos, &ins); -out: + BUG_ON(ret); btrfs_free_path(path); - return ret; + return 0; } /* @@ -1830,41 +1740,35 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) end - start + 1); if (!ret) return 0; - BUG_ON(!ordered_extent); /* Logic error */ + BUG_ON(!ordered_extent); nolock = btrfs_is_free_space_inode(root, inode); if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) { - BUG_ON(!list_empty(&ordered_extent->list)); /* Logic error */ + BUG_ON(!list_empty(&ordered_extent->list)); ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); if (!ret) { if (nolock) trans = btrfs_join_transaction_nolock(root); else trans = btrfs_join_transaction(root); - if (IS_ERR(trans)) - return PTR_ERR(trans); + BUG_ON(IS_ERR(trans)); trans->block_rsv = &root->fs_info->delalloc_block_rsv; ret = btrfs_update_inode_fallback(trans, root, inode); - if (ret) /* -ENOMEM or corruption */ - btrfs_abort_transaction(trans, root, ret); + BUG_ON(ret); } goto out; } lock_extent_bits(io_tree, ordered_extent->file_offset, ordered_extent->file_offset + ordered_extent->len - 1, - 0, &cached_state); + 0, &cached_state, GFP_NOFS); if (nolock) trans = btrfs_join_transaction_nolock(root); else trans = btrfs_join_transaction(root); - if (IS_ERR(trans)) { - ret = PTR_ERR(trans); - trans = NULL; - goto out_unlock; - } + BUG_ON(IS_ERR(trans)); trans->block_rsv = &root->fs_info->delalloc_block_rsv; if (test_bit(BTRFS_ORDERED_COMPRESSED, &ordered_extent->flags)) @@ -1875,6 +1779,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) ordered_extent->file_offset, ordered_extent->file_offset + ordered_extent->len); + BUG_ON(ret); } else { BUG_ON(root == root->fs_info->tree_root); ret = insert_reserved_file_extent(trans, inode, @@ -1888,14 +1793,11 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) unpin_extent_cache(&BTRFS_I(inode)->extent_tree, ordered_extent->file_offset, ordered_extent->len); + BUG_ON(ret); } unlock_extent_cached(io_tree, ordered_extent->file_offset, ordered_extent->file_offset + ordered_extent->len - 1, &cached_state, GFP_NOFS); - if (ret < 0) { - btrfs_abort_transaction(trans, root, ret); - goto out; - } add_pending_csums(trans, inode, ordered_extent->file_offset, &ordered_extent->list); @@ -1903,10 +1805,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) { ret = btrfs_update_inode_fallback(trans, root, inode); - if (ret) { /* -ENOMEM or corruption */ - btrfs_abort_transaction(trans, root, ret); - goto out; - } + BUG_ON(ret); } ret = 0; out: @@ -1925,11 +1824,6 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) btrfs_put_ordered_extent(ordered_extent); return 0; -out_unlock: - unlock_extent_cached(io_tree, ordered_extent->file_offset, - ordered_extent->file_offset + - ordered_extent->len - 1, &cached_state, GFP_NOFS); - goto out; } static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end, @@ -1947,7 +1841,7 @@ static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end, * extent_io.c will try to find good copies for us. */ static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end, - struct extent_state *state, int mirror) + struct extent_state *state) { size_t offset = start - ((u64)page->index << PAGE_CACHE_SHIFT); struct inode *inode = page->mapping->host; @@ -2011,8 +1905,6 @@ struct delayed_iput { struct inode *inode; }; -/* JDM: If this is fs-wide, why can't we add a pointer to - * btrfs_inode instead and avoid the allocation? */ void btrfs_add_delayed_iput(struct inode *inode) { struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info; @@ -2159,27 +2051,20 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode) /* grab metadata reservation from transaction handle */ if (reserve) { ret = btrfs_orphan_reserve_metadata(trans, inode); - BUG_ON(ret); /* -ENOSPC in reservation; Logic error? JDM */ + BUG_ON(ret); } /* insert an orphan item to track this unlinked/truncated file */ if (insert >= 1) { ret = btrfs_insert_orphan_item(trans, root, btrfs_ino(inode)); - if (ret && ret != -EEXIST) { - btrfs_abort_transaction(trans, root, ret); - return ret; - } - ret = 0; + BUG_ON(ret && ret != -EEXIST); } /* insert an orphan item to track subvolume contains orphan files */ if (insert >= 2) { ret = btrfs_insert_orphan_item(trans, root->fs_info->tree_root, root->root_key.objectid); - if (ret && ret != -EEXIST) { - btrfs_abort_transaction(trans, root, ret); - return ret; - } + BUG_ON(ret); } return 0; } @@ -2209,7 +2094,7 @@ int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode) if (trans && delete_item) { ret = btrfs_del_orphan_item(trans, root, btrfs_ino(inode)); - BUG_ON(ret); /* -ENOMEM or corruption (JDM: Recheck) */ + BUG_ON(ret); } if (release_rsv) @@ -2343,7 +2228,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) } ret = btrfs_del_orphan_item(trans, root, found_key.objectid); - BUG_ON(ret); /* -ENOMEM or corruption (JDM: Recheck) */ + BUG_ON(ret); btrfs_end_transaction(trans, root); continue; } @@ -2725,22 +2610,16 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans, printk(KERN_INFO "btrfs failed to delete reference to %.*s, " "inode %llu parent %llu\n", name_len, name, (unsigned long long)ino, (unsigned long long)dir_ino); - btrfs_abort_transaction(trans, root, ret); goto err; } ret = btrfs_delete_delayed_dir_index(trans, root, dir, index); - if (ret) { - btrfs_abort_transaction(trans, root, ret); + if (ret) goto err; - } ret = btrfs_del_inode_ref_in_log(trans, root, name, name_len, inode, dir_ino); - if (ret != 0 && ret != -ENOENT) { - btrfs_abort_transaction(trans, root, ret); - goto err; - } + BUG_ON(ret != 0 && ret != -ENOENT); ret = btrfs_del_dir_entries_in_log(trans, root, name, name_len, dir, index); @@ -2898,7 +2777,7 @@ static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir, err = ret; goto out; } - BUG_ON(ret == 0); /* Corruption */ + BUG_ON(ret == 0); if (check_path_shared(root, path)) goto out; btrfs_release_path(path); @@ -2931,7 +2810,7 @@ static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir, err = PTR_ERR(ref); goto out; } - BUG_ON(!ref); /* Logic error */ + BUG_ON(!ref); if (check_path_shared(root, path)) goto out; index = btrfs_inode_ref_index(path->nodes[0], ref); @@ -3038,42 +2917,23 @@ int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, di = btrfs_lookup_dir_item(trans, root, path, dir_ino, name, name_len, -1); - if (IS_ERR_OR_NULL(di)) { - if (!di) - ret = -ENOENT; - else - ret = PTR_ERR(di); - goto out; - } + BUG_ON(IS_ERR_OR_NULL(di)); leaf = path->nodes[0]; btrfs_dir_item_key_to_cpu(leaf, di, &key); WARN_ON(key.type != BTRFS_ROOT_ITEM_KEY || key.objectid != objectid); ret = btrfs_delete_one_dir_name(trans, root, path, di); - if (ret) { - btrfs_abort_transaction(trans, root, ret); - goto out; - } + BUG_ON(ret); btrfs_release_path(path); ret = btrfs_del_root_ref(trans, root->fs_info->tree_root, objectid, root->root_key.objectid, dir_ino, &index, name, name_len); if (ret < 0) { - if (ret != -ENOENT) { - btrfs_abort_transaction(trans, root, ret); - goto out; - } + BUG_ON(ret != -ENOENT); di = btrfs_search_dir_index_item(root, path, dir_ino, name, name_len); - if (IS_ERR_OR_NULL(di)) { - if (!di) - ret = -ENOENT; - else - ret = PTR_ERR(di); - btrfs_abort_transaction(trans, root, ret); - goto out; - } + BUG_ON(IS_ERR_OR_NULL(di)); leaf = path->nodes[0]; btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); @@ -3083,19 +2943,15 @@ int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, btrfs_release_path(path); ret = btrfs_delete_delayed_dir_index(trans, root, dir, index); - if (ret) { - btrfs_abort_transaction(trans, root, ret); - goto out; - } + BUG_ON(ret); btrfs_i_size_write(dir, dir->i_size - name_len * 2); dir->i_mtime = dir->i_ctime = CURRENT_TIME; ret = btrfs_update_inode(trans, root, dir); - if (ret) - btrfs_abort_transaction(trans, root, ret); -out: + BUG_ON(ret); + btrfs_free_path(path); - return ret; + return 0; } static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) @@ -3305,8 +3161,8 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, } size = btrfs_file_extent_calc_inline_size(size); - btrfs_truncate_item(trans, root, path, - size, 1); + ret = btrfs_truncate_item(trans, root, path, + size, 1); } else if (root->ref_cows) { inode_sub_bytes(inode, item_end + 1 - found_key.offset); @@ -3354,11 +3210,7 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, ret = btrfs_del_items(trans, root, path, pending_del_slot, pending_del_nr); - if (ret) { - btrfs_abort_transaction(trans, - root, ret); - goto error; - } + BUG_ON(ret); pending_del_nr = 0; } btrfs_release_path(path); @@ -3371,10 +3223,8 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, if (pending_del_nr) { ret = btrfs_del_items(trans, root, path, pending_del_slot, pending_del_nr); - if (ret) - btrfs_abort_transaction(trans, root, ret); + BUG_ON(ret); } -error: btrfs_free_path(path); return err; } @@ -3432,7 +3282,8 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from) } wait_on_page_writeback(page); - lock_extent_bits(io_tree, page_start, page_end, 0, &cached_state); + lock_extent_bits(io_tree, page_start, page_end, 0, &cached_state, + GFP_NOFS); set_page_extent_mapped(page); ordered = btrfs_lookup_ordered_extent(inode, page_start); @@ -3508,7 +3359,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) btrfs_wait_ordered_range(inode, hole_start, block_end - hole_start); lock_extent_bits(io_tree, hole_start, block_end - 1, 0, - &cached_state); + &cached_state, GFP_NOFS); ordered = btrfs_lookup_ordered_extent(inode, hole_start); if (!ordered) break; @@ -3521,10 +3372,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) while (1) { em = btrfs_get_extent(inode, NULL, 0, cur_offset, block_end - cur_offset, 0); - if (IS_ERR(em)) { - err = PTR_ERR(em); - break; - } + BUG_ON(IS_ERR_OR_NULL(em)); last_byte = min(extent_map_end(em), block_end); last_byte = (last_byte + mask) & ~mask; if (!test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) { @@ -3541,7 +3389,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) cur_offset + hole_size, &hint_byte, 1); if (err) { - btrfs_abort_transaction(trans, root, err); + btrfs_update_inode(trans, root, inode); btrfs_end_transaction(trans, root); break; } @@ -3551,7 +3399,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) 0, hole_size, 0, hole_size, 0, 0, 0); if (err) { - btrfs_abort_transaction(trans, root, err); + btrfs_update_inode(trans, root, inode); btrfs_end_transaction(trans, root); break; } @@ -3931,7 +3779,7 @@ static void inode_tree_del(struct inode *inode) } } -void btrfs_invalidate_inodes(struct btrfs_root *root) +int btrfs_invalidate_inodes(struct btrfs_root *root) { struct rb_node *node; struct rb_node *prev; @@ -3991,6 +3839,7 @@ void btrfs_invalidate_inodes(struct btrfs_root *root) node = rb_next(node); } spin_unlock(&root->inode_lock); + return 0; } static int btrfs_init_locked_inode(struct inode *inode, void *p) @@ -4069,7 +3918,7 @@ static struct inode *new_simple_dir(struct super_block *s, BTRFS_I(inode)->dummy_inode = 1; inode->i_ino = BTRFS_EMPTY_SUBVOL_DIR_OBJECTID; - inode->i_op = &btrfs_dir_ro_inode_operations; + inode->i_op = &simple_dir_inode_operations; inode->i_fop = &simple_dir_operations; inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; @@ -4140,18 +3989,14 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) static int btrfs_dentry_delete(const struct dentry *dentry) { struct btrfs_root *root; - struct inode *inode = dentry->d_inode; - if (!inode && !IS_ROOT(dentry)) - inode = dentry->d_parent->d_inode; + if (!dentry->d_inode && !IS_ROOT(dentry)) + dentry = dentry->d_parent; - if (inode) { - root = BTRFS_I(inode)->root; + if (dentry->d_inode) { + root = BTRFS_I(dentry->d_inode)->root; if (btrfs_root_refs(&root->root_item) == 0) return 1; - - if (btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) - return 1; } return 0; } @@ -4192,6 +4037,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, struct btrfs_path *path; struct list_head ins_list; struct list_head del_list; + struct qstr q; int ret; struct extent_buffer *leaf; int slot; @@ -4282,6 +4128,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, while (di_cur < di_total) { struct btrfs_key location; + struct dentry *tmp; if (verify_dir_item(root, leaf, di)) break; @@ -4302,15 +4149,35 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, d_type = btrfs_filetype_table[btrfs_dir_type(leaf, di)]; btrfs_dir_item_key_to_cpu(leaf, di, &location); - + q.name = name_ptr; + q.len = name_len; + q.hash = full_name_hash(q.name, q.len); + tmp = d_lookup(filp->f_dentry, &q); + if (!tmp) { + struct btrfs_key *newkey; + + newkey = kzalloc(sizeof(struct btrfs_key), + GFP_NOFS); + if (!newkey) + goto no_dentry; + tmp = d_alloc(filp->f_dentry, &q); + if (!tmp) { + kfree(newkey); + dput(tmp); + goto no_dentry; + } + memcpy(newkey, &location, + sizeof(struct btrfs_key)); + tmp->d_fsdata = newkey; + tmp->d_flags |= DCACHE_NEED_LOOKUP; + d_rehash(tmp); + dput(tmp); + } else { + dput(tmp); + } +no_dentry: /* is this a reference to our own snapshot? If so - * skip it. - * - * In contrast to old kernels, we insert the snapshot's - * dir item and dir index after it has been created, so - * we won't find a reference to our own snapshot. We - * still keep the following code for backward - * compatibility. + * skip it */ if (location.type == BTRFS_ROOT_ITEM_KEY && location.objectid == root->root_key.objectid) { @@ -4714,26 +4581,18 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, parent_ino, index); } - /* Nothing to clean up yet */ - if (ret) - return ret; + if (ret == 0) { + ret = btrfs_insert_dir_item(trans, root, name, name_len, + parent_inode, &key, + btrfs_inode_type(inode), index); + if (ret) + goto fail_dir_item; - ret = btrfs_insert_dir_item(trans, root, name, name_len, - parent_inode, &key, - btrfs_inode_type(inode), index); - if (ret == -EEXIST) - goto fail_dir_item; - else if (ret) { - btrfs_abort_transaction(trans, root, ret); - return ret; + btrfs_i_size_write(parent_inode, parent_inode->i_size + + name_len * 2); + parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME; + ret = btrfs_update_inode(trans, root, parent_inode); } - - btrfs_i_size_write(parent_inode, parent_inode->i_size + - name_len * 2); - parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME; - ret = btrfs_update_inode(trans, root, parent_inode); - if (ret) - btrfs_abort_transaction(trans, root, ret); return ret; fail_dir_item: @@ -4947,8 +4806,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, } else { struct dentry *parent = dentry->d_parent; err = btrfs_update_inode(trans, root, inode); - if (err) - goto fail; + BUG_ON(err); d_instantiate(dentry, inode); btrfs_log_new_name(trans, inode, NULL, parent); } @@ -5279,7 +5137,7 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, ret = uncompress_inline(path, inode, page, pg_offset, extent_offset, item); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } else { map = kmap(page); read_extent_buffer(leaf, map + pg_offset, ptr, @@ -5394,7 +5252,6 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, free_extent_map(em); return ERR_PTR(err); } - BUG_ON(!em); /* Error is always set */ return em; } @@ -5557,7 +5414,7 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode, alloc_hint = get_extent_allocation_hint(inode, start, len); ret = btrfs_reserve_extent(trans, root, len, root->sectorsize, 0, - alloc_hint, &ins, 1); + alloc_hint, (u64)-1, &ins, 1); if (ret) { em = ERR_PTR(ret); goto out; @@ -5745,7 +5602,7 @@ static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock, free_extent_map(em); /* DIO will do one hole at a time, so just unlock a sector */ unlock_extent(&BTRFS_I(inode)->io_tree, start, - start + root->sectorsize - 1); + start + root->sectorsize - 1, GFP_NOFS); return 0; } @@ -5886,7 +5743,7 @@ static void btrfs_endio_direct_read(struct bio *bio, int err) } while (bvec <= bvec_end); unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset, - dip->logical_offset + dip->bytes - 1); + dip->logical_offset + dip->bytes - 1, GFP_NOFS); bio->bi_private = dip->private; kfree(dip->csums); @@ -5937,7 +5794,7 @@ static void btrfs_endio_direct_write(struct bio *bio, int err) lock_extent_bits(&BTRFS_I(inode)->io_tree, ordered->file_offset, ordered->file_offset + ordered->len - 1, 0, - &cached_state); + &cached_state, GFP_NOFS); if (test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags)) { ret = btrfs_mark_extent_written(trans, inode, @@ -6011,7 +5868,7 @@ static int __btrfs_submit_bio_start_direct_io(struct inode *inode, int rw, int ret; struct btrfs_root *root = BTRFS_I(inode)->root; ret = btrfs_csum_one_bio(root, inode, bio, offset, 1); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); return 0; } @@ -6352,7 +6209,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, while (1) { lock_extent_bits(&BTRFS_I(inode)->io_tree, lockstart, lockend, - 0, &cached_state); + 0, &cached_state, GFP_NOFS); /* * We're concerned with the entire range that we're going to be * doing DIO to, so we need to make sure theres no ordered @@ -6376,7 +6233,7 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, if (writing) { write_bits = EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING; ret = set_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, lockend, - EXTENT_DELALLOC, NULL, &cached_state, + EXTENT_DELALLOC, 0, NULL, &cached_state, GFP_NOFS); if (ret) { clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart, @@ -6506,7 +6363,8 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) btrfs_releasepage(page, GFP_NOFS); return; } - lock_extent_bits(tree, page_start, page_end, 0, &cached_state); + lock_extent_bits(tree, page_start, page_end, 0, &cached_state, + GFP_NOFS); ordered = btrfs_lookup_ordered_extent(page->mapping->host, page_offset(page)); if (ordered) { @@ -6528,7 +6386,8 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) } btrfs_put_ordered_extent(ordered); cached_state = NULL; - lock_extent_bits(tree, page_start, page_end, 0, &cached_state); + lock_extent_bits(tree, page_start, page_end, 0, &cached_state, + GFP_NOFS); } clear_extent_bit(tree, page_start, page_end, EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC | @@ -6603,7 +6462,8 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) } wait_on_page_writeback(page); - lock_extent_bits(io_tree, page_start, page_end, 0, &cached_state); + lock_extent_bits(io_tree, page_start, page_end, 0, &cached_state, + GFP_NOFS); set_page_extent_mapped(page); /* @@ -6877,9 +6737,10 @@ int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, btrfs_i_size_write(inode, 0); err = btrfs_update_inode(trans, new_root, inode); + BUG_ON(err); iput(inode); - return err; + return 0; } struct inode *btrfs_alloc_inode(struct super_block *sb) @@ -6922,8 +6783,6 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) extent_map_tree_init(&ei->extent_tree); extent_io_tree_init(&ei->io_tree, &inode->i_data); extent_io_tree_init(&ei->io_failure_tree, &inode->i_data); - ei->io_tree.track_uptodate = 1; - ei->io_failure_tree.track_uptodate = 1; mutex_init(&ei->log_mutex); mutex_init(&ei->delalloc_mutex); btrfs_ordered_inode_tree_init(&ei->ordered_tree); @@ -7213,10 +7072,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (!ret) ret = btrfs_update_inode(trans, root, old_inode); } - if (ret) { - btrfs_abort_transaction(trans, root, ret); - goto out_fail; - } + BUG_ON(ret); if (new_inode) { new_inode->i_ctime = CURRENT_TIME; @@ -7234,14 +7090,11 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, new_dentry->d_name.name, new_dentry->d_name.len); } - if (!ret && new_inode->i_nlink == 0) { + BUG_ON(ret); + if (new_inode->i_nlink == 0) { ret = btrfs_orphan_add(trans, new_dentry->d_inode); BUG_ON(ret); } - if (ret) { - btrfs_abort_transaction(trans, root, ret); - goto out_fail; - } } fixup_inode_flags(new_dir, old_inode); @@ -7249,10 +7102,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, ret = btrfs_add_link(trans, new_dir, old_inode, new_dentry->d_name.name, new_dentry->d_name.len, 0, index); - if (ret) { - btrfs_abort_transaction(trans, root, ret); - goto out_fail; - } + BUG_ON(ret); if (old_ino != BTRFS_FIRST_FREE_OBJECTID) { struct dentry *parent = new_dentry->d_parent; @@ -7465,7 +7315,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, } ret = btrfs_reserve_extent(trans, root, num_bytes, min_size, - 0, *alloc_hint, &ins, 1); + 0, *alloc_hint, (u64)-1, &ins, 1); if (ret) { if (own_trans) btrfs_end_transaction(trans, root); @@ -7477,12 +7327,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, ins.offset, ins.offset, ins.offset, 0, 0, 0, BTRFS_FILE_EXTENT_PREALLOC); - if (ret) { - btrfs_abort_transaction(trans, root, ret); - if (own_trans) - btrfs_end_transaction(trans, root); - break; - } + BUG_ON(ret); btrfs_drop_extent_cache(inode, cur_offset, cur_offset + ins.offset -1, 0); @@ -7504,13 +7349,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, } ret = btrfs_update_inode(trans, root, inode); - - if (ret) { - btrfs_abort_transaction(trans, root, ret); - if (own_trans) - btrfs_end_transaction(trans, root); - break; - } + BUG_ON(ret); if (own_trans) btrfs_end_transaction(trans, root); diff --git a/trunk/fs/btrfs/ioctl.c b/trunk/fs/btrfs/ioctl.c index 14f8e1faa46e..d8b54715c2de 100644 --- a/trunk/fs/btrfs/ioctl.c +++ b/trunk/fs/btrfs/ioctl.c @@ -425,37 +425,22 @@ static noinline int create_subvol(struct btrfs_root *root, key.offset = (u64)-1; new_root = btrfs_read_fs_root_no_name(root->fs_info, &key); - if (IS_ERR(new_root)) { - btrfs_abort_transaction(trans, root, PTR_ERR(new_root)); - ret = PTR_ERR(new_root); - goto fail; - } + BUG_ON(IS_ERR(new_root)); btrfs_record_root_in_trans(trans, new_root); ret = btrfs_create_subvol_root(trans, new_root, new_dirid); - if (ret) { - /* We potentially lose an unused inode item here */ - btrfs_abort_transaction(trans, root, ret); - goto fail; - } - /* * insert the directory item */ ret = btrfs_set_inode_index(dir, &index); - if (ret) { - btrfs_abort_transaction(trans, root, ret); - goto fail; - } + BUG_ON(ret); ret = btrfs_insert_dir_item(trans, root, name, namelen, dir, &key, BTRFS_FT_DIR, index); - if (ret) { - btrfs_abort_transaction(trans, root, ret); + if (ret) goto fail; - } btrfs_i_size_write(dir, dir->i_size + namelen * 2); ret = btrfs_update_inode(trans, root, dir); @@ -784,31 +769,6 @@ static int find_new_extents(struct btrfs_root *root, return -ENOENT; } -/* - * Validaty check of prev em and next em: - * 1) no prev/next em - * 2) prev/next em is an hole/inline extent - */ -static int check_adjacent_extents(struct inode *inode, struct extent_map *em) -{ - struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; - struct extent_map *prev = NULL, *next = NULL; - int ret = 0; - - read_lock(&em_tree->lock); - prev = lookup_extent_mapping(em_tree, em->start - 1, (u64)-1); - next = lookup_extent_mapping(em_tree, em->start + em->len, (u64)-1); - read_unlock(&em_tree->lock); - - if ((!prev || prev->block_start >= EXTENT_MAP_LAST_BYTE) && - (!next || next->block_start >= EXTENT_MAP_LAST_BYTE)) - ret = 1; - free_extent_map(prev); - free_extent_map(next); - - return ret; -} - static int should_defrag_range(struct inode *inode, u64 start, u64 len, int thresh, u64 *last_len, u64 *skip, u64 *defrag_end) @@ -837,25 +797,17 @@ static int should_defrag_range(struct inode *inode, u64 start, u64 len, if (!em) { /* get the big lock and read metadata off disk */ - lock_extent(io_tree, start, start + len - 1); + lock_extent(io_tree, start, start + len - 1, GFP_NOFS); em = btrfs_get_extent(inode, NULL, 0, start, len, 0); - unlock_extent(io_tree, start, start + len - 1); + unlock_extent(io_tree, start, start + len - 1, GFP_NOFS); if (IS_ERR(em)) return 0; } /* this will cover holes, and inline extents */ - if (em->block_start >= EXTENT_MAP_LAST_BYTE) { + if (em->block_start >= EXTENT_MAP_LAST_BYTE) ret = 0; - goto out; - } - - /* If we have nothing to merge with us, just skip. */ - if (check_adjacent_extents(inode, em)) { - ret = 0; - goto out; - } /* * we hit a real extent, if it is big don't bother defragging it again @@ -863,7 +815,6 @@ static int should_defrag_range(struct inode *inode, u64 start, u64 len, if ((*last_len == 0 || *last_len >= thresh) && em->len >= thresh) ret = 0; -out: /* * last_len ends up being a counter of how many bytes we've defragged. * every time we choose not to defrag an extent, we reset *last_len @@ -905,7 +856,6 @@ static int cluster_pages_for_defrag(struct inode *inode, u64 isize = i_size_read(inode); u64 page_start; u64 page_end; - u64 page_cnt; int ret; int i; int i_done; @@ -914,21 +864,19 @@ static int cluster_pages_for_defrag(struct inode *inode, struct extent_io_tree *tree; gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping); - file_end = (isize - 1) >> PAGE_CACHE_SHIFT; - if (!isize || start_index > file_end) + if (isize == 0) return 0; - - page_cnt = min_t(u64, (u64)num_pages, (u64)file_end - start_index + 1); + file_end = (isize - 1) >> PAGE_CACHE_SHIFT; ret = btrfs_delalloc_reserve_space(inode, - page_cnt << PAGE_CACHE_SHIFT); + num_pages << PAGE_CACHE_SHIFT); if (ret) return ret; i_done = 0; tree = &BTRFS_I(inode)->io_tree; /* step one, lock all the pages */ - for (i = 0; i < page_cnt; i++) { + for (i = 0; i < num_pages; i++) { struct page *page; again: page = find_or_create_page(inode->i_mapping, @@ -939,10 +887,10 @@ static int cluster_pages_for_defrag(struct inode *inode, page_start = page_offset(page); page_end = page_start + PAGE_CACHE_SIZE - 1; while (1) { - lock_extent(tree, page_start, page_end); + lock_extent(tree, page_start, page_end, GFP_NOFS); ordered = btrfs_lookup_ordered_extent(inode, page_start); - unlock_extent(tree, page_start, page_end); + unlock_extent(tree, page_start, page_end, GFP_NOFS); if (!ordered) break; @@ -950,15 +898,6 @@ static int cluster_pages_for_defrag(struct inode *inode, btrfs_start_ordered_extent(inode, ordered, 1); btrfs_put_ordered_extent(ordered); lock_page(page); - /* - * we unlocked the page above, so we need check if - * it was released or not. - */ - if (page->mapping != inode->i_mapping) { - unlock_page(page); - page_cache_release(page); - goto again; - } } if (!PageUptodate(page)) { @@ -972,6 +911,15 @@ static int cluster_pages_for_defrag(struct inode *inode, } } + isize = i_size_read(inode); + file_end = (isize - 1) >> PAGE_CACHE_SHIFT; + if (!isize || page->index > file_end) { + /* whoops, we blew past eof, skip this page */ + unlock_page(page); + page_cache_release(page); + break; + } + if (page->mapping != inode->i_mapping) { unlock_page(page); page_cache_release(page); @@ -998,18 +946,19 @@ static int cluster_pages_for_defrag(struct inode *inode, page_end = page_offset(pages[i_done - 1]) + PAGE_CACHE_SIZE; lock_extent_bits(&BTRFS_I(inode)->io_tree, - page_start, page_end - 1, 0, &cached_state); + page_start, page_end - 1, 0, &cached_state, + GFP_NOFS); clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end - 1, EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING, 0, 0, &cached_state, GFP_NOFS); - if (i_done != page_cnt) { + if (i_done != num_pages) { spin_lock(&BTRFS_I(inode)->lock); BTRFS_I(inode)->outstanding_extents++; spin_unlock(&BTRFS_I(inode)->lock); btrfs_delalloc_release_space(inode, - (page_cnt - i_done) << PAGE_CACHE_SHIFT); + (num_pages - i_done) << PAGE_CACHE_SHIFT); } @@ -1034,7 +983,7 @@ static int cluster_pages_for_defrag(struct inode *inode, unlock_page(pages[i]); page_cache_release(pages[i]); } - btrfs_delalloc_release_space(inode, page_cnt << PAGE_CACHE_SHIFT); + btrfs_delalloc_release_space(inode, num_pages << PAGE_CACHE_SHIFT); return ret; } @@ -1140,9 +1089,12 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, if (!(inode->i_sb->s_flags & MS_ACTIVE)) break; - if (!should_defrag_range(inode, (u64)i << PAGE_CACHE_SHIFT, - PAGE_CACHE_SIZE, extent_thresh, - &last_len, &skip, &defrag_end)) { + if (!newer_than && + !should_defrag_range(inode, (u64)i << PAGE_CACHE_SHIFT, + PAGE_CACHE_SIZE, + extent_thresh, + &last_len, &skip, + &defrag_end)) { unsigned long next; /* * the should_defrag function tells us how much to skip @@ -1171,24 +1123,17 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, ra_index += max_cluster; } - mutex_lock(&inode->i_mutex); ret = cluster_pages_for_defrag(inode, pages, i, cluster); - if (ret < 0) { - mutex_unlock(&inode->i_mutex); + if (ret < 0) goto out_ra; - } defrag_count += ret; balance_dirty_pages_ratelimited_nr(inode->i_mapping, ret); - mutex_unlock(&inode->i_mutex); if (newer_than) { if (newer_off == (u64)-1) break; - if (ret > 0) - i += ret; - newer_off = max(newer_off + 1, (u64)i << PAGE_CACHE_SHIFT); @@ -2021,11 +1966,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, dest->root_key.objectid, dentry->d_name.name, dentry->d_name.len); - if (ret) { - err = ret; - btrfs_abort_transaction(trans, root, ret); - goto out_end_trans; - } + BUG_ON(ret); btrfs_record_root_in_trans(trans, dest); @@ -2038,16 +1979,11 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, ret = btrfs_insert_orphan_item(trans, root->fs_info->tree_root, dest->root_key.objectid); - if (ret) { - btrfs_abort_transaction(trans, root, ret); - err = ret; - goto out_end_trans; - } + BUG_ON(ret); } -out_end_trans: + ret = btrfs_end_transaction(trans, root); - if (ret && !err) - err = ret; + BUG_ON(ret); inode->i_flags |= S_DEAD; out_up_write: up_write(&root->fs_info->subvol_sem); @@ -2262,10 +2198,7 @@ static long btrfs_ioctl_dev_info(struct btrfs_root *root, void __user *arg) di_args->bytes_used = dev->bytes_used; di_args->total_bytes = dev->total_bytes; memcpy(di_args->uuid, dev->uuid, sizeof(di_args->uuid)); - if (dev->name) - strncpy(di_args->path, dev->name, sizeof(di_args->path)); - else - di_args->path[0] = '\0'; + strncpy(di_args->path, dev->name, sizeof(di_args->path)); out: if (ret == 0 && copy_to_user(arg, di_args, sizeof(*di_args))) @@ -2393,13 +2326,13 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, another, and lock file content */ while (1) { struct btrfs_ordered_extent *ordered; - lock_extent(&BTRFS_I(src)->io_tree, off, off+len); + lock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS); ordered = btrfs_lookup_first_ordered_extent(src, off+len); if (!ordered && !test_range_bit(&BTRFS_I(src)->io_tree, off, off+len, EXTENT_DELALLOC, 0, NULL)) break; - unlock_extent(&BTRFS_I(src)->io_tree, off, off+len); + unlock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS); if (ordered) btrfs_put_ordered_extent(ordered); btrfs_wait_ordered_range(src, off, len); @@ -2514,21 +2447,11 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, new_key.offset, new_key.offset + datal, &hint_byte, 1); - if (ret) { - btrfs_abort_transaction(trans, root, - ret); - btrfs_end_transaction(trans, root); - goto out; - } + BUG_ON(ret); ret = btrfs_insert_empty_item(trans, root, path, &new_key, size); - if (ret) { - btrfs_abort_transaction(trans, root, - ret); - btrfs_end_transaction(trans, root); - goto out; - } + BUG_ON(ret); leaf = path->nodes[0]; slot = path->slots[0]; @@ -2555,15 +2478,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, btrfs_ino(inode), new_key.offset - datao, 0); - if (ret) { - btrfs_abort_transaction(trans, - root, - ret); - btrfs_end_transaction(trans, - root); - goto out; - - } + BUG_ON(ret); } } else if (type == BTRFS_FILE_EXTENT_INLINE) { u64 skip = 0; @@ -2588,21 +2503,11 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, new_key.offset, new_key.offset + datal, &hint_byte, 1); - if (ret) { - btrfs_abort_transaction(trans, root, - ret); - btrfs_end_transaction(trans, root); - goto out; - } + BUG_ON(ret); ret = btrfs_insert_empty_item(trans, root, path, &new_key, size); - if (ret) { - btrfs_abort_transaction(trans, root, - ret); - btrfs_end_transaction(trans, root); - goto out; - } + BUG_ON(ret); if (skip) { u32 start = @@ -2636,12 +2541,8 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, btrfs_i_size_write(inode, endoff); ret = btrfs_update_inode(trans, root, inode); - if (ret) { - btrfs_abort_transaction(trans, root, ret); - btrfs_end_transaction(trans, root); - goto out; - } - ret = btrfs_end_transaction(trans, root); + BUG_ON(ret); + btrfs_end_transaction(trans, root); } next: btrfs_release_path(path); @@ -2650,7 +2551,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, ret = 0; out: btrfs_release_path(path); - unlock_extent(&BTRFS_I(src)->io_tree, off, off+len); + unlock_extent(&BTRFS_I(src)->io_tree, off, off+len, GFP_NOFS); out_unlock: mutex_unlock(&src->i_mutex); mutex_unlock(&inode->i_mutex); @@ -3165,8 +3066,8 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root, goto out; extent_item_pos = loi->logical - key.objectid; - ret = iterate_extent_inodes(root->fs_info, key.objectid, - extent_item_pos, 0, build_ino_list, + ret = iterate_extent_inodes(root->fs_info, path, key.objectid, + extent_item_pos, build_ino_list, inodes); if (ret < 0) diff --git a/trunk/fs/btrfs/ioctl.h b/trunk/fs/btrfs/ioctl.h index 086e6bdae1c4..4f69028a68c4 100644 --- a/trunk/fs/btrfs/ioctl.h +++ b/trunk/fs/btrfs/ioctl.h @@ -252,7 +252,7 @@ struct btrfs_data_container { struct btrfs_ioctl_ino_path_args { __u64 inum; /* in */ - __u64 size; /* in */ + __u32 size; /* in */ __u64 reserved[4]; /* struct btrfs_data_container *fspath; out */ __u64 fspath; /* out */ @@ -260,7 +260,7 @@ struct btrfs_ioctl_ino_path_args { struct btrfs_ioctl_logical_ino_args { __u64 logical; /* in */ - __u64 size; /* in */ + __u32 size; /* in */ __u64 reserved[4]; /* struct btrfs_data_container *inodes; out */ __u64 inodes; diff --git a/trunk/fs/btrfs/locking.c b/trunk/fs/btrfs/locking.c index 272f911203ff..5e178d8f7167 100644 --- a/trunk/fs/btrfs/locking.c +++ b/trunk/fs/btrfs/locking.c @@ -208,7 +208,7 @@ void btrfs_tree_read_unlock_blocking(struct extent_buffer *eb) * take a spinning write lock. This will wait for both * blocking readers or writers */ -void btrfs_tree_lock(struct extent_buffer *eb) +int btrfs_tree_lock(struct extent_buffer *eb) { again: wait_event(eb->read_lock_wq, atomic_read(&eb->blocking_readers) == 0); @@ -230,12 +230,13 @@ void btrfs_tree_lock(struct extent_buffer *eb) atomic_inc(&eb->spinning_writers); atomic_inc(&eb->write_locks); eb->lock_owner = current->pid; + return 0; } /* * drop a spinning or a blocking write lock. */ -void btrfs_tree_unlock(struct extent_buffer *eb) +int btrfs_tree_unlock(struct extent_buffer *eb) { int blockers = atomic_read(&eb->blocking_writers); @@ -254,6 +255,7 @@ void btrfs_tree_unlock(struct extent_buffer *eb) atomic_dec(&eb->spinning_writers); write_unlock(&eb->lock); } + return 0; } void btrfs_assert_tree_locked(struct extent_buffer *eb) diff --git a/trunk/fs/btrfs/locking.h b/trunk/fs/btrfs/locking.h index ca52681e5f40..17247ddb81a0 100644 --- a/trunk/fs/btrfs/locking.h +++ b/trunk/fs/btrfs/locking.h @@ -24,8 +24,8 @@ #define BTRFS_WRITE_LOCK_BLOCKING 3 #define BTRFS_READ_LOCK_BLOCKING 4 -void btrfs_tree_lock(struct extent_buffer *eb); -void btrfs_tree_unlock(struct extent_buffer *eb); +int btrfs_tree_lock(struct extent_buffer *eb); +int 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); diff --git a/trunk/fs/btrfs/ordered-data.c b/trunk/fs/btrfs/ordered-data.c index bbf6d0d9aebe..a1c940425307 100644 --- a/trunk/fs/btrfs/ordered-data.c +++ b/trunk/fs/btrfs/ordered-data.c @@ -59,14 +59,6 @@ static struct rb_node *tree_insert(struct rb_root *root, u64 file_offset, return NULL; } -static void ordered_data_tree_panic(struct inode *inode, int errno, - u64 offset) -{ - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); - btrfs_panic(fs_info, errno, "Inconsistency in ordered tree at offset " - "%llu\n", (unsigned long long)offset); -} - /* * look for a given offset in the tree, and if it can't be found return the * first lesser offset @@ -215,8 +207,7 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, spin_lock(&tree->lock); node = tree_insert(&tree->tree, file_offset, &entry->rb_node); - if (node) - ordered_data_tree_panic(inode, -EEXIST, file_offset); + BUG_ON(node); spin_unlock(&tree->lock); spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); @@ -224,6 +215,7 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, &BTRFS_I(inode)->root->fs_info->ordered_extents); spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); + BUG_ON(node); return 0; } @@ -257,9 +249,9 @@ int btrfs_add_ordered_extent_compress(struct inode *inode, u64 file_offset, * when an ordered extent is finished. If the list covers more than one * ordered extent, it is split across multiples. */ -void btrfs_add_ordered_sum(struct inode *inode, - struct btrfs_ordered_extent *entry, - struct btrfs_ordered_sum *sum) +int btrfs_add_ordered_sum(struct inode *inode, + struct btrfs_ordered_extent *entry, + struct btrfs_ordered_sum *sum) { struct btrfs_ordered_inode_tree *tree; @@ -267,6 +259,7 @@ void btrfs_add_ordered_sum(struct inode *inode, spin_lock(&tree->lock); list_add_tail(&sum->list, &entry->list); spin_unlock(&tree->lock); + return 0; } /* @@ -391,7 +384,7 @@ int btrfs_dec_test_ordered_pending(struct inode *inode, * used to drop a reference on an ordered extent. This will free * the extent if the last reference is dropped */ -void btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry) +int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry) { struct list_head *cur; struct btrfs_ordered_sum *sum; @@ -407,6 +400,7 @@ void btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry) } kfree(entry); } + return 0; } /* @@ -414,8 +408,8 @@ void btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry) * and you must wake_up entry->wait. You must hold the tree lock * while you call this function. */ -static void __btrfs_remove_ordered_extent(struct inode *inode, - struct btrfs_ordered_extent *entry) +static int __btrfs_remove_ordered_extent(struct inode *inode, + struct btrfs_ordered_extent *entry) { struct btrfs_ordered_inode_tree *tree; struct btrfs_root *root = BTRFS_I(inode)->root; @@ -442,30 +436,35 @@ static void __btrfs_remove_ordered_extent(struct inode *inode, list_del_init(&BTRFS_I(inode)->ordered_operations); } spin_unlock(&root->fs_info->ordered_extent_lock); + + return 0; } /* * remove an ordered extent from the tree. No references are dropped * but any waiters are woken. */ -void btrfs_remove_ordered_extent(struct inode *inode, - struct btrfs_ordered_extent *entry) +int btrfs_remove_ordered_extent(struct inode *inode, + struct btrfs_ordered_extent *entry) { struct btrfs_ordered_inode_tree *tree; + int ret; tree = &BTRFS_I(inode)->ordered_tree; spin_lock(&tree->lock); - __btrfs_remove_ordered_extent(inode, entry); + ret = __btrfs_remove_ordered_extent(inode, entry); spin_unlock(&tree->lock); wake_up(&entry->wait); + + return ret; } /* * wait for all the ordered extents in a root. This is done when balancing * space between drives. */ -void btrfs_wait_ordered_extents(struct btrfs_root *root, - int nocow_only, int delay_iput) +int btrfs_wait_ordered_extents(struct btrfs_root *root, + int nocow_only, int delay_iput) { struct list_head splice; struct list_head *cur; @@ -513,6 +512,7 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root, spin_lock(&root->fs_info->ordered_extent_lock); } spin_unlock(&root->fs_info->ordered_extent_lock); + return 0; } /* @@ -525,7 +525,7 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root, * extra check to make sure the ordered operation list really is empty * before we return */ -void btrfs_run_ordered_operations(struct btrfs_root *root, int wait) +int btrfs_run_ordered_operations(struct btrfs_root *root, int wait) { struct btrfs_inode *btrfs_inode; struct inode *inode; @@ -573,6 +573,8 @@ void btrfs_run_ordered_operations(struct btrfs_root *root, int wait) spin_unlock(&root->fs_info->ordered_extent_lock); mutex_unlock(&root->fs_info->ordered_operations_mutex); + + return 0; } /* @@ -607,7 +609,7 @@ void btrfs_start_ordered_extent(struct inode *inode, /* * Used to wait on ordered extents across a large range of bytes. */ -void btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) +int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) { u64 end; u64 orig_end; @@ -662,6 +664,7 @@ void btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) schedule_timeout(1); goto again; } + return 0; } /* @@ -945,8 +948,9 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, * If trans is not null, we'll do a friendly check for a transaction that * is already flushing things and force the IO down ourselves. */ -void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans, - struct btrfs_root *root, struct inode *inode) +int btrfs_add_ordered_operation(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct inode *inode) { u64 last_mod; @@ -957,7 +961,7 @@ void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans, * commit, we can safely return without doing anything */ if (last_mod < root->fs_info->last_trans_committed) - return; + return 0; /* * the transaction is already committing. Just start the IO and @@ -965,7 +969,7 @@ void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans, */ if (trans && root->fs_info->running_transaction->blocked) { btrfs_wait_ordered_range(inode, 0, (u64)-1); - return; + return 0; } spin_lock(&root->fs_info->ordered_extent_lock); @@ -974,4 +978,6 @@ void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans, &root->fs_info->ordered_operations); } spin_unlock(&root->fs_info->ordered_extent_lock); + + return 0; } diff --git a/trunk/fs/btrfs/ordered-data.h b/trunk/fs/btrfs/ordered-data.h index c355ad4dc1a6..ff1f69aa1883 100644 --- a/trunk/fs/btrfs/ordered-data.h +++ b/trunk/fs/btrfs/ordered-data.h @@ -138,8 +138,8 @@ btrfs_ordered_inode_tree_init(struct btrfs_ordered_inode_tree *t) t->last = NULL; } -void btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry); -void btrfs_remove_ordered_extent(struct inode *inode, +int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry); +int btrfs_remove_ordered_extent(struct inode *inode, struct btrfs_ordered_extent *entry); int btrfs_dec_test_ordered_pending(struct inode *inode, struct btrfs_ordered_extent **cached, @@ -154,14 +154,14 @@ int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset, int btrfs_add_ordered_extent_compress(struct inode *inode, u64 file_offset, u64 start, u64 len, u64 disk_len, int type, int compress_type); -void btrfs_add_ordered_sum(struct inode *inode, - struct btrfs_ordered_extent *entry, - struct btrfs_ordered_sum *sum); +int btrfs_add_ordered_sum(struct inode *inode, + struct btrfs_ordered_extent *entry, + struct btrfs_ordered_sum *sum); struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode, u64 file_offset); void btrfs_start_ordered_extent(struct inode *inode, struct btrfs_ordered_extent *entry, int wait); -void btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len); +int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len); struct btrfs_ordered_extent * btrfs_lookup_first_ordered_extent(struct inode * inode, u64 file_offset); struct btrfs_ordered_extent *btrfs_lookup_ordered_range(struct inode *inode, @@ -170,10 +170,10 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_range(struct inode *inode, int btrfs_ordered_update_i_size(struct inode *inode, u64 offset, struct btrfs_ordered_extent *ordered); int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, u32 *sum); -void btrfs_run_ordered_operations(struct btrfs_root *root, int wait); -void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct inode *inode); -void btrfs_wait_ordered_extents(struct btrfs_root *root, - int nocow_only, int delay_iput); +int btrfs_run_ordered_operations(struct btrfs_root *root, int wait); +int btrfs_add_ordered_operation(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct inode *inode); +int btrfs_wait_ordered_extents(struct btrfs_root *root, + int nocow_only, int delay_iput); #endif diff --git a/trunk/fs/btrfs/orphan.c b/trunk/fs/btrfs/orphan.c index 24cad1695af7..f8be250963a0 100644 --- a/trunk/fs/btrfs/orphan.c +++ b/trunk/fs/btrfs/orphan.c @@ -58,7 +58,7 @@ int btrfs_del_orphan_item(struct btrfs_trans_handle *trans, ret = btrfs_search_slot(trans, root, &key, path, -1, 1); if (ret < 0) goto out; - if (ret) { /* JDM: Really? */ + if (ret) { ret = -ENOENT; goto out; } diff --git a/trunk/fs/btrfs/reada.c b/trunk/fs/btrfs/reada.c index ac5d01085884..22db04550f6a 100644 --- a/trunk/fs/btrfs/reada.c +++ b/trunk/fs/btrfs/reada.c @@ -54,6 +54,7 @@ * than the 2 started one after another. */ +#define MAX_MIRRORS 2 #define MAX_IN_FLIGHT 6 struct reada_extctl { @@ -70,7 +71,7 @@ struct reada_extent { struct list_head extctl; struct kref refcnt; spinlock_t lock; - struct reada_zone *zones[BTRFS_MAX_MIRRORS]; + struct reada_zone *zones[MAX_MIRRORS]; int nzones; struct btrfs_device *scheduled_for; }; @@ -83,8 +84,7 @@ struct reada_zone { spinlock_t lock; int locked; struct btrfs_device *device; - struct btrfs_device *devs[BTRFS_MAX_MIRRORS]; /* full list, incl - * self */ + struct btrfs_device *devs[MAX_MIRRORS]; /* full list, incl self */ int ndevs; struct kref refcnt; }; @@ -250,12 +250,14 @@ static struct reada_zone *reada_find_zone(struct btrfs_fs_info *fs_info, struct btrfs_bio *bbio) { int ret; + int looped = 0; struct reada_zone *zone; struct btrfs_block_group_cache *cache = NULL; u64 start; u64 end; int i; +again: zone = NULL; spin_lock(&fs_info->reada_lock); ret = radix_tree_gang_lookup(&dev->reada_zones, (void **)&zone, @@ -272,6 +274,9 @@ static struct reada_zone *reada_find_zone(struct btrfs_fs_info *fs_info, spin_unlock(&fs_info->reada_lock); } + if (looped) + return NULL; + cache = btrfs_lookup_block_group(fs_info, logical); if (!cache) return NULL; @@ -302,15 +307,13 @@ static struct reada_zone *reada_find_zone(struct btrfs_fs_info *fs_info, ret = radix_tree_insert(&dev->reada_zones, (unsigned long)(zone->end >> PAGE_CACHE_SHIFT), zone); + spin_unlock(&fs_info->reada_lock); - if (ret == -EEXIST) { + if (ret) { kfree(zone); - ret = radix_tree_gang_lookup(&dev->reada_zones, (void **)&zone, - logical >> PAGE_CACHE_SHIFT, 1); - if (ret == 1) - kref_get(&zone->refcnt); + looped = 1; + goto again; } - spin_unlock(&fs_info->reada_lock); return zone; } @@ -320,26 +323,26 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root, struct btrfs_key *top, int level) { int ret; + int looped = 0; struct reada_extent *re = NULL; - struct reada_extent *re_exist = NULL; struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree; struct btrfs_bio *bbio = NULL; struct btrfs_device *dev; - struct btrfs_device *prev_dev; u32 blocksize; u64 length; int nzones = 0; int i; unsigned long index = logical >> PAGE_CACHE_SHIFT; +again: spin_lock(&fs_info->reada_lock); re = radix_tree_lookup(&fs_info->reada_tree, index); if (re) kref_get(&re->refcnt); spin_unlock(&fs_info->reada_lock); - if (re) + if (re || looped) return re; re = kzalloc(sizeof(*re), GFP_NOFS); @@ -362,9 +365,9 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root, if (ret || !bbio || length < blocksize) goto error; - if (bbio->num_stripes > BTRFS_MAX_MIRRORS) { + if (bbio->num_stripes > MAX_MIRRORS) { printk(KERN_ERR "btrfs readahead: more than %d copies not " - "supported", BTRFS_MAX_MIRRORS); + "supported", MAX_MIRRORS); goto error; } @@ -395,31 +398,16 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root, /* insert extent in reada_tree + all per-device trees, all or nothing */ spin_lock(&fs_info->reada_lock); ret = radix_tree_insert(&fs_info->reada_tree, index, re); - if (ret == -EEXIST) { - re_exist = radix_tree_lookup(&fs_info->reada_tree, index); - BUG_ON(!re_exist); - kref_get(&re_exist->refcnt); - spin_unlock(&fs_info->reada_lock); - goto error; - } if (ret) { spin_unlock(&fs_info->reada_lock); + if (ret != -ENOMEM) { + /* someone inserted the extent in the meantime */ + looped = 1; + } goto error; } - prev_dev = NULL; for (i = 0; i < nzones; ++i) { dev = bbio->stripes[i].dev; - if (dev == prev_dev) { - /* - * in case of DUP, just add the first zone. As both - * are on the same device, there's nothing to gain - * from adding both. - * Also, it wouldn't work, as the tree is per device - * and adding would fail with EEXIST - */ - continue; - } - prev_dev = dev; ret = radix_tree_insert(&dev->reada_extents, index, re); if (ret) { while (--i >= 0) { @@ -462,7 +450,9 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root, } kfree(bbio); kfree(re); - return re_exist; + if (looped) + goto again; + return NULL; } static void reada_kref_dummy(struct kref *kr) diff --git a/trunk/fs/btrfs/relocation.c b/trunk/fs/btrfs/relocation.c index 646ee21bb035..8c1aae2c845d 100644 --- a/trunk/fs/btrfs/relocation.c +++ b/trunk/fs/btrfs/relocation.c @@ -326,19 +326,6 @@ static struct rb_node *tree_search(struct rb_root *root, u64 bytenr) return NULL; } -void backref_tree_panic(struct rb_node *rb_node, int errno, - u64 bytenr) -{ - - struct btrfs_fs_info *fs_info = NULL; - struct backref_node *bnode = rb_entry(rb_node, struct backref_node, - rb_node); - if (bnode->root) - fs_info = bnode->root->fs_info; - btrfs_panic(fs_info, errno, "Inconsistency in backref cache " - "found at offset %llu\n", (unsigned long long)bytenr); -} - /* * walk up backref nodes until reach node presents tree root */ @@ -465,8 +452,7 @@ static void update_backref_node(struct backref_cache *cache, rb_erase(&node->rb_node, &cache->rb_root); node->bytenr = bytenr; rb_node = tree_insert(&cache->rb_root, node->bytenr, &node->rb_node); - if (rb_node) - backref_tree_panic(rb_node, -EEXIST, bytenr); + BUG_ON(rb_node); } /* @@ -1013,8 +999,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc, if (!cowonly) { rb_node = tree_insert(&cache->rb_root, node->bytenr, &node->rb_node); - if (rb_node) - backref_tree_panic(rb_node, -EEXIST, node->bytenr); + BUG_ON(rb_node); list_add_tail(&node->lower, &cache->leaves); } @@ -1049,9 +1034,7 @@ struct backref_node *build_backref_tree(struct reloc_control *rc, if (!cowonly) { rb_node = tree_insert(&cache->rb_root, upper->bytenr, &upper->rb_node); - if (rb_node) - backref_tree_panic(rb_node, -EEXIST, - upper->bytenr); + BUG_ON(rb_node); } list_add_tail(&edge->list[UPPER], &upper->lower); @@ -1197,8 +1180,7 @@ static int clone_backref_node(struct btrfs_trans_handle *trans, rb_node = tree_insert(&cache->rb_root, new_node->bytenr, &new_node->rb_node); - if (rb_node) - backref_tree_panic(rb_node, -EEXIST, new_node->bytenr); + BUG_ON(rb_node); if (!new_node->lowest) { list_for_each_entry(new_edge, &new_node->lower, list[UPPER]) { @@ -1221,15 +1203,14 @@ static int clone_backref_node(struct btrfs_trans_handle *trans, /* * helper to add 'address of tree root -> reloc tree' mapping */ -static int __must_check __add_reloc_root(struct btrfs_root *root) +static int __add_reloc_root(struct btrfs_root *root) { struct rb_node *rb_node; struct mapping_node *node; struct reloc_control *rc = root->fs_info->reloc_ctl; node = kmalloc(sizeof(*node), GFP_NOFS); - if (!node) - return -ENOMEM; + BUG_ON(!node); node->bytenr = root->node->start; node->data = root; @@ -1238,12 +1219,7 @@ static int __must_check __add_reloc_root(struct btrfs_root *root) rb_node = tree_insert(&rc->reloc_root_tree.rb_root, node->bytenr, &node->rb_node); spin_unlock(&rc->reloc_root_tree.lock); - if (rb_node) { - kfree(node); - btrfs_panic(root->fs_info, -EEXIST, "Duplicate root found " - "for start=%llu while inserting into relocation " - "tree\n"); - } + BUG_ON(rb_node); list_add_tail(&root->root_list, &rc->reloc_roots); return 0; @@ -1276,12 +1252,9 @@ static int __update_reloc_root(struct btrfs_root *root, int del) rb_node = tree_insert(&rc->reloc_root_tree.rb_root, node->bytenr, &node->rb_node); spin_unlock(&rc->reloc_root_tree.lock); - if (rb_node) - backref_tree_panic(rb_node, -EEXIST, node->bytenr); + BUG_ON(rb_node); } else { - spin_lock(&root->fs_info->trans_lock); list_del_init(&root->root_list); - spin_unlock(&root->fs_info->trans_lock); kfree(node); } return 0; @@ -1361,7 +1334,6 @@ int btrfs_init_reloc_root(struct btrfs_trans_handle *trans, struct btrfs_root *reloc_root; struct reloc_control *rc = root->fs_info->reloc_ctl; int clear_rsv = 0; - int ret; if (root->reloc_root) { reloc_root = root->reloc_root; @@ -1381,8 +1353,7 @@ int btrfs_init_reloc_root(struct btrfs_trans_handle *trans, if (clear_rsv) trans->block_rsv = NULL; - ret = __add_reloc_root(reloc_root); - BUG_ON(ret < 0); + __add_reloc_root(reloc_root); root->reloc_root = reloc_root; return 0; } @@ -1606,14 +1577,15 @@ int replace_file_extents(struct btrfs_trans_handle *trans, WARN_ON(!IS_ALIGNED(end, root->sectorsize)); end--; ret = try_lock_extent(&BTRFS_I(inode)->io_tree, - key.offset, end); + key.offset, end, + GFP_NOFS); if (!ret) continue; btrfs_drop_extent_cache(inode, key.offset, end, 1); unlock_extent(&BTRFS_I(inode)->io_tree, - key.offset, end); + key.offset, end, GFP_NOFS); } } @@ -1984,9 +1956,9 @@ static int invalidate_extent_cache(struct btrfs_root *root, } /* the lock_extent waits for readpage to complete */ - lock_extent(&BTRFS_I(inode)->io_tree, start, end); + lock_extent(&BTRFS_I(inode)->io_tree, start, end, GFP_NOFS); btrfs_drop_extent_cache(inode, start, end, 1); - unlock_extent(&BTRFS_I(inode)->io_tree, start, end); + unlock_extent(&BTRFS_I(inode)->io_tree, start, end, GFP_NOFS); } return 0; } @@ -2274,8 +2246,7 @@ int merge_reloc_roots(struct reloc_control *rc) } else { list_del_init(&reloc_root->root_list); } - ret = btrfs_drop_snapshot(reloc_root, rc->block_rsv, 0, 1); - BUG_ON(ret < 0); + btrfs_drop_snapshot(reloc_root, rc->block_rsv, 0, 1); } if (found) { @@ -2891,12 +2862,12 @@ int prealloc_file_extent_cluster(struct inode *inode, else end = cluster->end - offset; - lock_extent(&BTRFS_I(inode)->io_tree, start, end); + lock_extent(&BTRFS_I(inode)->io_tree, start, end, GFP_NOFS); num_bytes = end + 1 - start; ret = btrfs_prealloc_file_range(inode, 0, start, num_bytes, num_bytes, end + 1, &alloc_hint); - unlock_extent(&BTRFS_I(inode)->io_tree, start, end); + unlock_extent(&BTRFS_I(inode)->io_tree, start, end, GFP_NOFS); if (ret) break; nr++; @@ -2928,7 +2899,7 @@ int setup_extent_mapping(struct inode *inode, u64 start, u64 end, em->bdev = root->fs_info->fs_devices->latest_bdev; set_bit(EXTENT_FLAG_PINNED, &em->flags); - lock_extent(&BTRFS_I(inode)->io_tree, start, end); + lock_extent(&BTRFS_I(inode)->io_tree, start, end, GFP_NOFS); while (1) { write_lock(&em_tree->lock); ret = add_extent_mapping(em_tree, em); @@ -2939,7 +2910,7 @@ int setup_extent_mapping(struct inode *inode, u64 start, u64 end, } btrfs_drop_extent_cache(inode, start, end, 0); } - unlock_extent(&BTRFS_I(inode)->io_tree, start, end); + unlock_extent(&BTRFS_I(inode)->io_tree, start, end, GFP_NOFS); return ret; } @@ -3019,7 +2990,8 @@ static int relocate_file_extent_cluster(struct inode *inode, page_start = (u64)page->index << PAGE_CACHE_SHIFT; page_end = page_start + PAGE_CACHE_SIZE - 1; - lock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end); + lock_extent(&BTRFS_I(inode)->io_tree, + page_start, page_end, GFP_NOFS); set_page_extent_mapped(page); @@ -3035,7 +3007,7 @@ static int relocate_file_extent_cluster(struct inode *inode, set_page_dirty(page); unlock_extent(&BTRFS_I(inode)->io_tree, - page_start, page_end); + page_start, page_end, GFP_NOFS); unlock_page(page); page_cache_release(page); @@ -3182,8 +3154,7 @@ static int add_tree_block(struct reloc_control *rc, block->key_ready = 0; rb_node = tree_insert(blocks, block->bytenr, &block->rb_node); - if (rb_node) - backref_tree_panic(rb_node, -EEXIST, block->bytenr); + BUG_ON(rb_node); return 0; } @@ -3455,9 +3426,7 @@ static int find_data_references(struct reloc_control *rc, block->key_ready = 1; rb_node = tree_insert(blocks, block->bytenr, &block->rb_node); - if (rb_node) - backref_tree_panic(rb_node, -EEXIST, - block->bytenr); + BUG_ON(rb_node); } if (counted) added = 1; @@ -3813,7 +3782,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) ret = btrfs_block_rsv_check(rc->extent_root, rc->block_rsv, 5); if (ret < 0) { - if (ret != -ENOSPC) { + if (ret != -EAGAIN) { err = ret; WARN_ON(1); break; @@ -4104,11 +4073,10 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start) static noinline_for_stack int mark_garbage_root(struct btrfs_root *root) { struct btrfs_trans_handle *trans; - int ret, err; + int ret; trans = btrfs_start_transaction(root->fs_info->tree_root, 0); - if (IS_ERR(trans)) - return PTR_ERR(trans); + BUG_ON(IS_ERR(trans)); memset(&root->root_item.drop_progress, 0, sizeof(root->root_item.drop_progress)); @@ -4116,11 +4084,11 @@ static noinline_for_stack int mark_garbage_root(struct btrfs_root *root) btrfs_set_root_refs(&root->root_item, 0); ret = btrfs_update_root(trans, root->fs_info->tree_root, &root->root_key, &root->root_item); + BUG_ON(ret); - err = btrfs_end_transaction(trans, root->fs_info->tree_root); - if (err) - return err; - return ret; + ret = btrfs_end_transaction(trans, root->fs_info->tree_root); + BUG_ON(ret); + return 0; } /* @@ -4188,11 +4156,7 @@ int btrfs_recover_relocation(struct btrfs_root *root) err = ret; goto out; } - ret = mark_garbage_root(reloc_root); - if (ret < 0) { - err = ret; - goto out; - } + mark_garbage_root(reloc_root); } } @@ -4238,19 +4202,13 @@ int btrfs_recover_relocation(struct btrfs_root *root) fs_root = read_fs_root(root->fs_info, reloc_root->root_key.offset); - if (IS_ERR(fs_root)) { - err = PTR_ERR(fs_root); - goto out_free; - } + BUG_ON(IS_ERR(fs_root)); - err = __add_reloc_root(reloc_root); - BUG_ON(err < 0); /* -ENOMEM or logic error */ + __add_reloc_root(reloc_root); fs_root->reloc_root = reloc_root; } - err = btrfs_commit_transaction(trans, rc->extent_root); - if (err) - goto out_free; + btrfs_commit_transaction(trans, rc->extent_root); merge_reloc_roots(rc); @@ -4260,7 +4218,7 @@ int btrfs_recover_relocation(struct btrfs_root *root) if (IS_ERR(trans)) err = PTR_ERR(trans); else - err = btrfs_commit_transaction(trans, rc->extent_root); + btrfs_commit_transaction(trans, rc->extent_root); out_free: kfree(rc); out: @@ -4309,8 +4267,6 @@ int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len) disk_bytenr = file_pos + BTRFS_I(inode)->index_cnt; ret = btrfs_lookup_csums_range(root->fs_info->csum_root, disk_bytenr, disk_bytenr + len - 1, &list, 0); - if (ret) - goto out; while (!list_empty(&list)) { sums = list_entry(list.next, struct btrfs_ordered_sum, list); @@ -4328,7 +4284,6 @@ int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len) btrfs_add_ordered_sum(inode, ordered, sums); } -out: btrfs_put_ordered_extent(ordered); return ret; } @@ -4425,7 +4380,7 @@ void btrfs_reloc_pre_snapshot(struct btrfs_trans_handle *trans, * called after snapshot is created. migrate block reservation * and create reloc root for the newly created snapshot */ -int btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans, +void btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans, struct btrfs_pending_snapshot *pending) { struct btrfs_root *root = pending->root; @@ -4435,7 +4390,7 @@ int btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans, int ret; if (!root->reloc_root) - return 0; + return; rc = root->fs_info->reloc_ctl; rc->merging_rsv_size += rc->nodes_relocated; @@ -4444,21 +4399,18 @@ int btrfs_reloc_post_snapshot(struct btrfs_trans_handle *trans, ret = btrfs_block_rsv_migrate(&pending->block_rsv, rc->block_rsv, rc->nodes_relocated); - if (ret) - return ret; + BUG_ON(ret); } new_root = pending->snap; reloc_root = create_reloc_root(trans, root->reloc_root, new_root->root_key.objectid); - if (IS_ERR(reloc_root)) - return PTR_ERR(reloc_root); - ret = __add_reloc_root(reloc_root); - BUG_ON(ret < 0); + __add_reloc_root(reloc_root); new_root->reloc_root = reloc_root; - if (rc->create_reloc_tree) + if (rc->create_reloc_tree) { ret = clone_backref_node(trans, rc, root, reloc_root); - return ret; + BUG_ON(ret); + } } diff --git a/trunk/fs/btrfs/root-tree.c b/trunk/fs/btrfs/root-tree.c index 24fb8ce4e071..f4099904565a 100644 --- a/trunk/fs/btrfs/root-tree.c +++ b/trunk/fs/btrfs/root-tree.c @@ -93,14 +93,10 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root unsigned long ptr; path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; - + BUG_ON(!path); ret = btrfs_search_slot(trans, root, key, path, 0, 1); - if (ret < 0) { - btrfs_abort_transaction(trans, root, ret); + if (ret < 0) goto out; - } if (ret != 0) { btrfs_print_leaf(root, path->nodes[0]); @@ -120,10 +116,13 @@ int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root return ret; } -int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, - struct btrfs_key *key, struct btrfs_root_item *item) +int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root + *root, struct btrfs_key *key, struct btrfs_root_item + *item) { - return btrfs_insert_item(trans, root, key, item, sizeof(*item)); + int ret; + ret = btrfs_insert_item(trans, root, key, item, sizeof(*item)); + return ret; } /* @@ -385,8 +384,6 @@ int btrfs_find_root_ref(struct btrfs_root *tree_root, * * For a back ref the root_id is the id of the subvol or snapshot and * ref_id is the id of the tree referencing it. - * - * Will return 0, -ENOMEM, or anything from the CoW path */ int btrfs_add_root_ref(struct btrfs_trans_handle *trans, struct btrfs_root *tree_root, @@ -410,11 +407,7 @@ int btrfs_add_root_ref(struct btrfs_trans_handle *trans, again: ret = btrfs_insert_empty_item(trans, tree_root, path, &key, sizeof(*ref) + name_len); - if (ret) { - btrfs_abort_transaction(trans, tree_root, ret); - btrfs_free_path(path); - return ret; - } + BUG_ON(ret); leaf = path->nodes[0]; ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref); diff --git a/trunk/fs/btrfs/scrub.c b/trunk/fs/btrfs/scrub.c index 2f3d6f917fb3..390e7102b0ff 100644 --- a/trunk/fs/btrfs/scrub.c +++ b/trunk/fs/btrfs/scrub.c @@ -36,30 +36,37 @@ * Future enhancements: * - In case an unrepairable extent is encountered, track which files are * affected and report them + * - In case of a read error on files with nodatasum, map the file and read + * the extent to trigger a writeback of the good copy * - track and record media errors, throw out bad devices * - add a mode to also read unallocated space */ -struct scrub_block; +struct scrub_bio; +struct scrub_page; struct scrub_dev; +static void scrub_bio_end_io(struct bio *bio, int err); +static void scrub_checksum(struct btrfs_work *work); +static int scrub_checksum_data(struct scrub_dev *sdev, + struct scrub_page *spag, void *buffer); +static int scrub_checksum_tree_block(struct scrub_dev *sdev, + struct scrub_page *spag, u64 logical, + void *buffer); +static int scrub_checksum_super(struct scrub_bio *sbio, void *buffer); +static int scrub_fixup_check(struct scrub_bio *sbio, int ix); +static void scrub_fixup_end_io(struct bio *bio, int err); +static int scrub_fixup_io(int rw, struct block_device *bdev, sector_t sector, + struct page *page); +static void scrub_fixup(struct scrub_bio *sbio, int ix); #define SCRUB_PAGES_PER_BIO 16 /* 64k per bio */ #define SCRUB_BIOS_PER_DEV 16 /* 1 MB per device in flight */ -#define SCRUB_MAX_PAGES_PER_BLOCK 16 /* 64k per node/leaf/sector */ struct scrub_page { - struct scrub_block *sblock; - struct page *page; - struct block_device *bdev; u64 flags; /* extent flags */ u64 generation; - u64 logical; - u64 physical; - struct { - unsigned int mirror_num:8; - unsigned int have_csum:1; - unsigned int io_error:1; - }; + int mirror_num; + int have_csum; u8 csum[BTRFS_CSUM_SIZE]; }; @@ -70,25 +77,12 @@ struct scrub_bio { int err; u64 logical; u64 physical; - struct scrub_page *pagev[SCRUB_PAGES_PER_BIO]; - int page_count; + struct scrub_page spag[SCRUB_PAGES_PER_BIO]; + u64 count; int next_free; struct btrfs_work work; }; -struct scrub_block { - struct scrub_page pagev[SCRUB_MAX_PAGES_PER_BLOCK]; - int page_count; - atomic_t outstanding_pages; - atomic_t ref_count; /* free mem on transition to zero */ - struct scrub_dev *sdev; - struct { - unsigned int header_error:1; - unsigned int checksum_error:1; - unsigned int no_io_error_seen:1; - }; -}; - struct scrub_dev { struct scrub_bio *bios[SCRUB_BIOS_PER_DEV]; struct btrfs_device *dev; @@ -102,10 +96,6 @@ struct scrub_dev { struct list_head csum_list; atomic_t cancel_req; int readonly; - int pages_per_bio; /* <= SCRUB_PAGES_PER_BIO */ - u32 sectorsize; - u32 nodesize; - u32 leafsize; /* * statistics */ @@ -134,43 +124,6 @@ struct scrub_warning { int scratch_bufsize; }; - -static int scrub_handle_errored_block(struct scrub_block *sblock_to_check); -static int scrub_setup_recheck_block(struct scrub_dev *sdev, - struct btrfs_mapping_tree *map_tree, - u64 length, u64 logical, - struct scrub_block *sblock); -static int scrub_recheck_block(struct btrfs_fs_info *fs_info, - struct scrub_block *sblock, int is_metadata, - int have_csum, u8 *csum, u64 generation, - u16 csum_size); -static void scrub_recheck_block_checksum(struct btrfs_fs_info *fs_info, - struct scrub_block *sblock, - int is_metadata, int have_csum, - const u8 *csum, u64 generation, - u16 csum_size); -static void scrub_complete_bio_end_io(struct bio *bio, int err); -static int scrub_repair_block_from_good_copy(struct scrub_block *sblock_bad, - struct scrub_block *sblock_good, - int force_write); -static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad, - struct scrub_block *sblock_good, - int page_num, int force_write); -static int scrub_checksum_data(struct scrub_block *sblock); -static int scrub_checksum_tree_block(struct scrub_block *sblock); -static int scrub_checksum_super(struct scrub_block *sblock); -static void scrub_block_get(struct scrub_block *sblock); -static void scrub_block_put(struct scrub_block *sblock); -static int scrub_add_page_to_bio(struct scrub_dev *sdev, - struct scrub_page *spage); -static int scrub_pages(struct scrub_dev *sdev, u64 logical, u64 len, - u64 physical, u64 flags, u64 gen, int mirror_num, - u8 *csum, int force); -static void scrub_bio_end_io(struct bio *bio, int err); -static void scrub_bio_end_io_worker(struct btrfs_work *work); -static void scrub_block_complete(struct scrub_block *sblock); - - static void scrub_free_csums(struct scrub_dev *sdev) { while (!list_empty(&sdev->csum_list)) { @@ -182,30 +135,37 @@ static void scrub_free_csums(struct scrub_dev *sdev) } } -static noinline_for_stack void scrub_free_dev(struct scrub_dev *sdev) +static void scrub_free_bio(struct bio *bio) { int i; + struct page *last_page = NULL; - if (!sdev) + if (!bio) return; - /* this can happen when scrub is cancelled */ - if (sdev->curr != -1) { - struct scrub_bio *sbio = sdev->bios[sdev->curr]; - - for (i = 0; i < sbio->page_count; i++) { - BUG_ON(!sbio->pagev[i]); - BUG_ON(!sbio->pagev[i]->page); - scrub_block_put(sbio->pagev[i]->sblock); - } - bio_put(sbio->bio); + for (i = 0; i < bio->bi_vcnt; ++i) { + if (bio->bi_io_vec[i].bv_page == last_page) + continue; + last_page = bio->bi_io_vec[i].bv_page; + __free_page(last_page); } + bio_put(bio); +} + +static noinline_for_stack void scrub_free_dev(struct scrub_dev *sdev) +{ + int i; + + if (!sdev) + return; for (i = 0; i < SCRUB_BIOS_PER_DEV; ++i) { struct scrub_bio *sbio = sdev->bios[i]; if (!sbio) break; + + scrub_free_bio(sbio->bio); kfree(sbio); } @@ -219,16 +179,11 @@ struct scrub_dev *scrub_setup_dev(struct btrfs_device *dev) struct scrub_dev *sdev; int i; struct btrfs_fs_info *fs_info = dev->dev_root->fs_info; - int pages_per_bio; - pages_per_bio = min_t(int, SCRUB_PAGES_PER_BIO, - bio_get_nr_vecs(dev->bdev)); sdev = kzalloc(sizeof(*sdev), GFP_NOFS); if (!sdev) goto nomem; sdev->dev = dev; - sdev->pages_per_bio = pages_per_bio; - sdev->curr = -1; for (i = 0; i < SCRUB_BIOS_PER_DEV; ++i) { struct scrub_bio *sbio; @@ -239,8 +194,8 @@ struct scrub_dev *scrub_setup_dev(struct btrfs_device *dev) sbio->index = i; sbio->sdev = sdev; - sbio->page_count = 0; - sbio->work.func = scrub_bio_end_io_worker; + sbio->count = 0; + sbio->work.func = scrub_checksum; if (i != SCRUB_BIOS_PER_DEV-1) sdev->bios[i]->next_free = i + 1; @@ -248,9 +203,7 @@ struct scrub_dev *scrub_setup_dev(struct btrfs_device *dev) sdev->bios[i]->next_free = -1; } sdev->first_free = 0; - sdev->nodesize = dev->dev_root->nodesize; - sdev->leafsize = dev->dev_root->leafsize; - sdev->sectorsize = dev->dev_root->sectorsize; + sdev->curr = -1; atomic_set(&sdev->in_flight, 0); atomic_set(&sdev->fixup_cnt, 0); atomic_set(&sdev->cancel_req, 0); @@ -341,9 +294,10 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root, void *ctx) return 0; } -static void scrub_print_warning(const char *errstr, struct scrub_block *sblock) +static void scrub_print_warning(const char *errstr, struct scrub_bio *sbio, + int ix) { - struct btrfs_device *dev = sblock->sdev->dev; + struct btrfs_device *dev = sbio->sdev->dev; struct btrfs_fs_info *fs_info = dev->dev_root->fs_info; struct btrfs_path *path; struct btrfs_key found_key; @@ -362,9 +316,8 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock) swarn.scratch_buf = kmalloc(bufsize, GFP_NOFS); swarn.msg_buf = kmalloc(bufsize, GFP_NOFS); - BUG_ON(sblock->page_count < 1); - swarn.sector = (sblock->pagev[0].physical) >> 9; - swarn.logical = sblock->pagev[0].logical; + swarn.sector = (sbio->physical + ix * PAGE_SIZE) >> 9; + swarn.logical = sbio->logical + ix * PAGE_SIZE; swarn.errstr = errstr; swarn.dev = dev; swarn.msg_bufsize = bufsize; @@ -389,8 +342,7 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock) do { ret = tree_backref_for_extent(&ptr, eb, ei, item_size, &ref_root, &ref_level); - printk(KERN_WARNING - "btrfs: %s at logical %llu on dev %s, " + printk(KERN_WARNING "%s at logical %llu on dev %s, " "sector %llu: metadata %s (level %d) in tree " "%llu\n", errstr, swarn.logical, dev->name, (unsigned long long)swarn.sector, @@ -400,8 +352,8 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock) } while (ret != 1); } else { swarn.path = path; - iterate_extent_inodes(fs_info, found_key.objectid, - extent_item_pos, 1, + iterate_extent_inodes(fs_info, path, found_key.objectid, + extent_item_pos, scrub_print_warning_inode, &swarn); } @@ -579,9 +531,9 @@ static void scrub_fixup_nodatasum(struct btrfs_work *work) spin_lock(&sdev->stat_lock); ++sdev->stat.uncorrectable_errors; spin_unlock(&sdev->stat_lock); - printk_ratelimited(KERN_ERR - "btrfs: unable to fixup (nodatasum) error at logical %llu on dev %s\n", - (unsigned long long)fixup->logical, sdev->dev->name); + printk_ratelimited(KERN_ERR "btrfs: unable to fixup " + "(nodatasum) error at logical %llu\n", + fixup->logical); } btrfs_free_path(path); @@ -598,168 +550,91 @@ static void scrub_fixup_nodatasum(struct btrfs_work *work) } /* - * scrub_handle_errored_block gets called when either verification of the - * pages failed or the bio failed to read, e.g. with EIO. In the latter - * case, this function handles all pages in the bio, even though only one - * may be bad. - * The goal of this function is to repair the errored block by using the - * contents of one of the mirrors. + * scrub_recheck_error gets called when either verification of the page + * failed or the bio failed to read, e.g. with EIO. In the latter case, + * recheck_error gets called for every page in the bio, even though only + * one may be bad */ -static int scrub_handle_errored_block(struct scrub_block *sblock_to_check) +static int scrub_recheck_error(struct scrub_bio *sbio, int ix) { - struct scrub_dev *sdev = sblock_to_check->sdev; - struct btrfs_fs_info *fs_info; - u64 length; - u64 logical; - u64 generation; - unsigned int failed_mirror_index; - unsigned int is_metadata; - unsigned int have_csum; - u8 *csum; - struct scrub_block *sblocks_for_recheck; /* holds one for each mirror */ - struct scrub_block *sblock_bad; - int ret; - int mirror_index; - int page_num; - int success; + struct scrub_dev *sdev = sbio->sdev; + u64 sector = (sbio->physical + ix * PAGE_SIZE) >> 9; static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL, - DEFAULT_RATELIMIT_BURST); - - BUG_ON(sblock_to_check->page_count < 1); - fs_info = sdev->dev->dev_root->fs_info; - length = sblock_to_check->page_count * PAGE_SIZE; - logical = sblock_to_check->pagev[0].logical; - generation = sblock_to_check->pagev[0].generation; - BUG_ON(sblock_to_check->pagev[0].mirror_num < 1); - failed_mirror_index = sblock_to_check->pagev[0].mirror_num - 1; - is_metadata = !(sblock_to_check->pagev[0].flags & - BTRFS_EXTENT_FLAG_DATA); - have_csum = sblock_to_check->pagev[0].have_csum; - csum = sblock_to_check->pagev[0].csum; - - /* - * read all mirrors one after the other. This includes to - * re-read the extent or metadata block that failed (that was - * the cause that this fixup code is called) another time, - * page by page this time in order to know which pages - * caused I/O errors and which ones are good (for all mirrors). - * It is the goal to handle the situation when more than one - * mirror contains I/O errors, but the errors do not - * overlap, i.e. the data can be repaired by selecting the - * pages from those mirrors without I/O error on the - * particular pages. One example (with blocks >= 2 * PAGE_SIZE) - * would be that mirror #1 has an I/O error on the first page, - * the second page is good, and mirror #2 has an I/O error on - * the second page, but the first page is good. - * Then the first page of the first mirror can be repaired by - * taking the first page of the second mirror, and the - * second page of the second mirror can be repaired by - * copying the contents of the 2nd page of the 1st mirror. - * One more note: if the pages of one mirror contain I/O - * errors, the checksum cannot be verified. In order to get - * the best data for repairing, the first attempt is to find - * a mirror without I/O errors and with a validated checksum. - * Only if this is not possible, the pages are picked from - * mirrors with I/O errors without considering the checksum. - * If the latter is the case, at the end, the checksum of the - * repaired area is verified in order to correctly maintain - * the statistics. - */ - - sblocks_for_recheck = kzalloc(BTRFS_MAX_MIRRORS * - sizeof(*sblocks_for_recheck), - GFP_NOFS); - if (!sblocks_for_recheck) { - spin_lock(&sdev->stat_lock); - sdev->stat.malloc_errors++; - sdev->stat.read_errors++; - sdev->stat.uncorrectable_errors++; - spin_unlock(&sdev->stat_lock); - goto out; - } + DEFAULT_RATELIMIT_BURST); - /* setup the context, map the logical blocks and alloc the pages */ - ret = scrub_setup_recheck_block(sdev, &fs_info->mapping_tree, length, - logical, sblocks_for_recheck); - if (ret) { - spin_lock(&sdev->stat_lock); - sdev->stat.read_errors++; - sdev->stat.uncorrectable_errors++; - spin_unlock(&sdev->stat_lock); - goto out; + if (sbio->err) { + if (scrub_fixup_io(READ, sbio->sdev->dev->bdev, sector, + sbio->bio->bi_io_vec[ix].bv_page) == 0) { + if (scrub_fixup_check(sbio, ix) == 0) + return 0; + } + if (__ratelimit(&_rs)) + scrub_print_warning("i/o error", sbio, ix); + } else { + if (__ratelimit(&_rs)) + scrub_print_warning("checksum error", sbio, ix); } - BUG_ON(failed_mirror_index >= BTRFS_MAX_MIRRORS); - sblock_bad = sblocks_for_recheck + failed_mirror_index; - /* build and submit the bios for the failed mirror, check checksums */ - ret = scrub_recheck_block(fs_info, sblock_bad, is_metadata, have_csum, - csum, generation, sdev->csum_size); - if (ret) { - spin_lock(&sdev->stat_lock); - sdev->stat.read_errors++; - sdev->stat.uncorrectable_errors++; - spin_unlock(&sdev->stat_lock); - goto out; - } + spin_lock(&sdev->stat_lock); + ++sdev->stat.read_errors; + spin_unlock(&sdev->stat_lock); - if (!sblock_bad->header_error && !sblock_bad->checksum_error && - sblock_bad->no_io_error_seen) { - /* - * the error disappeared after reading page by page, or - * the area was part of a huge bio and other parts of the - * bio caused I/O errors, or the block layer merged several - * read requests into one and the error is caused by a - * different bio (usually one of the two latter cases is - * the cause) - */ - spin_lock(&sdev->stat_lock); - sdev->stat.unverified_errors++; - spin_unlock(&sdev->stat_lock); + scrub_fixup(sbio, ix); + return 1; +} - goto out; - } +static int scrub_fixup_check(struct scrub_bio *sbio, int ix) +{ + int ret = 1; + struct page *page; + void *buffer; + u64 flags = sbio->spag[ix].flags; - if (!sblock_bad->no_io_error_seen) { - spin_lock(&sdev->stat_lock); - sdev->stat.read_errors++; - spin_unlock(&sdev->stat_lock); - if (__ratelimit(&_rs)) - scrub_print_warning("i/o error", sblock_to_check); - } else if (sblock_bad->checksum_error) { - spin_lock(&sdev->stat_lock); - sdev->stat.csum_errors++; - spin_unlock(&sdev->stat_lock); - if (__ratelimit(&_rs)) - scrub_print_warning("checksum error", sblock_to_check); - } else if (sblock_bad->header_error) { - spin_lock(&sdev->stat_lock); - sdev->stat.verify_errors++; - spin_unlock(&sdev->stat_lock); - if (__ratelimit(&_rs)) - scrub_print_warning("checksum/header error", - sblock_to_check); + page = sbio->bio->bi_io_vec[ix].bv_page; + buffer = kmap_atomic(page); + if (flags & BTRFS_EXTENT_FLAG_DATA) { + ret = scrub_checksum_data(sbio->sdev, + sbio->spag + ix, buffer); + } else if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) { + ret = scrub_checksum_tree_block(sbio->sdev, + sbio->spag + ix, + sbio->logical + ix * PAGE_SIZE, + buffer); + } else { + WARN_ON(1); } + kunmap_atomic(buffer); - if (sdev->readonly) - goto did_not_correct_error; + return ret; +} - if (!is_metadata && !have_csum) { - struct scrub_fixup_nodatasum *fixup_nodatasum; +static void scrub_fixup_end_io(struct bio *bio, int err) +{ + complete((struct completion *)bio->bi_private); +} - /* - * !is_metadata and !have_csum, this means that the data - * might not be COW'ed, that it might be modified - * concurrently. The general strategy to work on the - * commit root does not help in the case when COW is not - * used. - */ - fixup_nodatasum = kzalloc(sizeof(*fixup_nodatasum), GFP_NOFS); - if (!fixup_nodatasum) - goto did_not_correct_error; - fixup_nodatasum->sdev = sdev; - fixup_nodatasum->logical = logical; - fixup_nodatasum->root = fs_info->extent_root; - fixup_nodatasum->mirror_num = failed_mirror_index + 1; +static void scrub_fixup(struct scrub_bio *sbio, int ix) +{ + struct scrub_dev *sdev = sbio->sdev; + struct btrfs_fs_info *fs_info = sdev->dev->dev_root->fs_info; + struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree; + struct btrfs_bio *bbio = NULL; + struct scrub_fixup_nodatasum *fixup; + u64 logical = sbio->logical + ix * PAGE_SIZE; + u64 length; + int i; + int ret; + DECLARE_COMPLETION_ONSTACK(complete); + + if ((sbio->spag[ix].flags & BTRFS_EXTENT_FLAG_DATA) && + (sbio->spag[ix].have_csum == 0)) { + fixup = kzalloc(sizeof(*fixup), GFP_NOFS); + if (!fixup) + goto uncorrectable; + fixup->sdev = sdev; + fixup->logical = logical; + fixup->root = fs_info->extent_root; + fixup->mirror_num = sbio->spag[ix].mirror_num; /* * increment scrubs_running to prevent cancel requests from * completing as long as a fixup worker is running. we must also @@ -774,533 +649,235 @@ static int scrub_handle_errored_block(struct scrub_block *sblock_to_check) atomic_inc(&fs_info->scrubs_paused); mutex_unlock(&fs_info->scrub_lock); atomic_inc(&sdev->fixup_cnt); - fixup_nodatasum->work.func = scrub_fixup_nodatasum; - btrfs_queue_worker(&fs_info->scrub_workers, - &fixup_nodatasum->work); - goto out; + fixup->work.func = scrub_fixup_nodatasum; + btrfs_queue_worker(&fs_info->scrub_workers, &fixup->work); + return; } - /* - * now build and submit the bios for the other mirrors, check - * checksums - */ - for (mirror_index = 0; - mirror_index < BTRFS_MAX_MIRRORS && - sblocks_for_recheck[mirror_index].page_count > 0; - mirror_index++) { - if (mirror_index == failed_mirror_index) - continue; - - /* build and submit the bios, check checksums */ - ret = scrub_recheck_block(fs_info, - sblocks_for_recheck + mirror_index, - is_metadata, have_csum, csum, - generation, sdev->csum_size); - if (ret) - goto did_not_correct_error; + length = PAGE_SIZE; + ret = btrfs_map_block(map_tree, REQ_WRITE, logical, &length, + &bbio, 0); + if (ret || !bbio || length < PAGE_SIZE) { + printk(KERN_ERR + "scrub_fixup: btrfs_map_block failed us for %llu\n", + (unsigned long long)logical); + WARN_ON(1); + kfree(bbio); + return; } - /* - * first try to pick the mirror which is completely without I/O - * errors and also does not have a checksum error. - * If one is found, and if a checksum is present, the full block - * that is known to contain an error is rewritten. Afterwards - * the block is known to be corrected. - * If a mirror is found which is completely correct, and no - * checksum is present, only those pages are rewritten that had - * an I/O error in the block to be repaired, since it cannot be - * determined, which copy of the other pages is better (and it - * could happen otherwise that a correct page would be - * overwritten by a bad one). - */ - for (mirror_index = 0; - mirror_index < BTRFS_MAX_MIRRORS && - sblocks_for_recheck[mirror_index].page_count > 0; - mirror_index++) { - struct scrub_block *sblock_other = sblocks_for_recheck + - mirror_index; - - if (!sblock_other->header_error && - !sblock_other->checksum_error && - sblock_other->no_io_error_seen) { - int force_write = is_metadata || have_csum; - - ret = scrub_repair_block_from_good_copy(sblock_bad, - sblock_other, - force_write); - if (0 == ret) - goto corrected_error; - } - } + if (bbio->num_stripes == 1) + /* there aren't any replicas */ + goto uncorrectable; /* - * in case of I/O errors in the area that is supposed to be - * repaired, continue by picking good copies of those pages. - * Select the good pages from mirrors to rewrite bad pages from - * the area to fix. Afterwards verify the checksum of the block - * that is supposed to be repaired. This verification step is - * only done for the purpose of statistic counting and for the - * final scrub report, whether errors remain. - * A perfect algorithm could make use of the checksum and try - * all possible combinations of pages from the different mirrors - * until the checksum verification succeeds. For example, when - * the 2nd page of mirror #1 faces I/O errors, and the 2nd page - * of mirror #2 is readable but the final checksum test fails, - * then the 2nd page of mirror #3 could be tried, whether now - * the final checksum succeedes. But this would be a rare - * exception and is therefore not implemented. At least it is - * avoided that the good copy is overwritten. - * A more useful improvement would be to pick the sectors - * without I/O error based on sector sizes (512 bytes on legacy - * disks) instead of on PAGE_SIZE. Then maybe 512 byte of one - * mirror could be repaired by taking 512 byte of a different - * mirror, even if other 512 byte sectors in the same PAGE_SIZE - * area are unreadable. + * first find a good copy */ - - /* can only fix I/O errors from here on */ - if (sblock_bad->no_io_error_seen) - goto did_not_correct_error; - - success = 1; - for (page_num = 0; page_num < sblock_bad->page_count; page_num++) { - struct scrub_page *page_bad = sblock_bad->pagev + page_num; - - if (!page_bad->io_error) + for (i = 0; i < bbio->num_stripes; ++i) { + if (i + 1 == sbio->spag[ix].mirror_num) continue; - for (mirror_index = 0; - mirror_index < BTRFS_MAX_MIRRORS && - sblocks_for_recheck[mirror_index].page_count > 0; - mirror_index++) { - struct scrub_block *sblock_other = sblocks_for_recheck + - mirror_index; - struct scrub_page *page_other = sblock_other->pagev + - page_num; - - if (!page_other->io_error) { - ret = scrub_repair_page_from_good_copy( - sblock_bad, sblock_other, page_num, 0); - if (0 == ret) { - page_bad->io_error = 0; - break; /* succeeded for this page */ - } - } - } - - if (page_bad->io_error) { - /* did not find a mirror to copy the page from */ - success = 0; - } - } - - if (success) { - if (is_metadata || have_csum) { - /* - * need to verify the checksum now that all - * sectors on disk are repaired (the write - * request for data to be repaired is on its way). - * Just be lazy and use scrub_recheck_block() - * which re-reads the data before the checksum - * is verified, but most likely the data comes out - * of the page cache. - */ - ret = scrub_recheck_block(fs_info, sblock_bad, - is_metadata, have_csum, csum, - generation, sdev->csum_size); - if (!ret && !sblock_bad->header_error && - !sblock_bad->checksum_error && - sblock_bad->no_io_error_seen) - goto corrected_error; - else - goto did_not_correct_error; - } else { -corrected_error: - spin_lock(&sdev->stat_lock); - sdev->stat.corrected_errors++; - spin_unlock(&sdev->stat_lock); - printk_ratelimited(KERN_ERR - "btrfs: fixed up error at logical %llu on dev %s\n", - (unsigned long long)logical, sdev->dev->name); + if (scrub_fixup_io(READ, bbio->stripes[i].dev->bdev, + bbio->stripes[i].physical >> 9, + sbio->bio->bi_io_vec[ix].bv_page)) { + /* I/O-error, this is not a good copy */ + continue; } - } else { -did_not_correct_error: - spin_lock(&sdev->stat_lock); - sdev->stat.uncorrectable_errors++; - spin_unlock(&sdev->stat_lock); - printk_ratelimited(KERN_ERR - "btrfs: unable to fixup (regular) error at logical %llu on dev %s\n", - (unsigned long long)logical, sdev->dev->name); - } -out: - if (sblocks_for_recheck) { - for (mirror_index = 0; mirror_index < BTRFS_MAX_MIRRORS; - mirror_index++) { - struct scrub_block *sblock = sblocks_for_recheck + - mirror_index; - int page_index; - - for (page_index = 0; page_index < SCRUB_PAGES_PER_BIO; - page_index++) - if (sblock->pagev[page_index].page) - __free_page( - sblock->pagev[page_index].page); - } - kfree(sblocks_for_recheck); + if (scrub_fixup_check(sbio, ix) == 0) + break; } + if (i == bbio->num_stripes) + goto uncorrectable; - return 0; -} - -static int scrub_setup_recheck_block(struct scrub_dev *sdev, - struct btrfs_mapping_tree *map_tree, - u64 length, u64 logical, - struct scrub_block *sblocks_for_recheck) -{ - int page_index; - int mirror_index; - int ret; - - /* - * note: the three members sdev, ref_count and outstanding_pages - * are not used (and not set) in the blocks that are used for - * the recheck procedure - */ - - page_index = 0; - while (length > 0) { - u64 sublen = min_t(u64, length, PAGE_SIZE); - u64 mapped_length = sublen; - struct btrfs_bio *bbio = NULL; - + if (!sdev->readonly) { /* - * with a length of PAGE_SIZE, each returned stripe - * represents one mirror + * bi_io_vec[ix].bv_page now contains good data, write it back */ - ret = btrfs_map_block(map_tree, WRITE, logical, &mapped_length, - &bbio, 0); - if (ret || !bbio || mapped_length < sublen) { - kfree(bbio); - return -EIO; + if (scrub_fixup_io(WRITE, sdev->dev->bdev, + (sbio->physical + ix * PAGE_SIZE) >> 9, + sbio->bio->bi_io_vec[ix].bv_page)) { + /* I/O-error, writeback failed, give up */ + goto uncorrectable; } - - BUG_ON(page_index >= SCRUB_PAGES_PER_BIO); - for (mirror_index = 0; mirror_index < (int)bbio->num_stripes; - mirror_index++) { - struct scrub_block *sblock; - struct scrub_page *page; - - if (mirror_index >= BTRFS_MAX_MIRRORS) - continue; - - sblock = sblocks_for_recheck + mirror_index; - page = sblock->pagev + page_index; - page->logical = logical; - page->physical = bbio->stripes[mirror_index].physical; - /* for missing devices, bdev is NULL */ - page->bdev = bbio->stripes[mirror_index].dev->bdev; - page->mirror_num = mirror_index + 1; - page->page = alloc_page(GFP_NOFS); - if (!page->page) { - spin_lock(&sdev->stat_lock); - sdev->stat.malloc_errors++; - spin_unlock(&sdev->stat_lock); - return -ENOMEM; - } - sblock->page_count++; - } - kfree(bbio); - length -= sublen; - logical += sublen; - page_index++; } - return 0; -} - -/* - * this function will check the on disk data for checksum errors, header - * errors and read I/O errors. If any I/O errors happen, the exact pages - * which are errored are marked as being bad. The goal is to enable scrub - * to take those pages that are not errored from all the mirrors so that - * the pages that are errored in the just handled mirror can be repaired. - */ -static int scrub_recheck_block(struct btrfs_fs_info *fs_info, - struct scrub_block *sblock, int is_metadata, - int have_csum, u8 *csum, u64 generation, - u16 csum_size) -{ - int page_num; - - sblock->no_io_error_seen = 1; - sblock->header_error = 0; - sblock->checksum_error = 0; - - for (page_num = 0; page_num < sblock->page_count; page_num++) { - struct bio *bio; - int ret; - struct scrub_page *page = sblock->pagev + page_num; - DECLARE_COMPLETION_ONSTACK(complete); - - if (page->bdev == NULL) { - page->io_error = 1; - sblock->no_io_error_seen = 0; - continue; - } - - BUG_ON(!page->page); - bio = bio_alloc(GFP_NOFS, 1); - if (!bio) - return -EIO; - bio->bi_bdev = page->bdev; - bio->bi_sector = page->physical >> 9; - bio->bi_end_io = scrub_complete_bio_end_io; - bio->bi_private = &complete; - - ret = bio_add_page(bio, page->page, PAGE_SIZE, 0); - if (PAGE_SIZE != ret) { - bio_put(bio); - return -EIO; - } - btrfsic_submit_bio(READ, bio); - - /* this will also unplug the queue */ - wait_for_completion(&complete); + kfree(bbio); + spin_lock(&sdev->stat_lock); + ++sdev->stat.corrected_errors; + spin_unlock(&sdev->stat_lock); - page->io_error = !test_bit(BIO_UPTODATE, &bio->bi_flags); - if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) - sblock->no_io_error_seen = 0; - bio_put(bio); - } + printk_ratelimited(KERN_ERR "btrfs: fixed up error at logical %llu\n", + (unsigned long long)logical); + return; - if (sblock->no_io_error_seen) - scrub_recheck_block_checksum(fs_info, sblock, is_metadata, - have_csum, csum, generation, - csum_size); +uncorrectable: + kfree(bbio); + spin_lock(&sdev->stat_lock); + ++sdev->stat.uncorrectable_errors; + spin_unlock(&sdev->stat_lock); - return 0; + printk_ratelimited(KERN_ERR "btrfs: unable to fixup (regular) error at " + "logical %llu\n", (unsigned long long)logical); } -static void scrub_recheck_block_checksum(struct btrfs_fs_info *fs_info, - struct scrub_block *sblock, - int is_metadata, int have_csum, - const u8 *csum, u64 generation, - u16 csum_size) +static int scrub_fixup_io(int rw, struct block_device *bdev, sector_t sector, + struct page *page) { - int page_num; - u8 calculated_csum[BTRFS_CSUM_SIZE]; - u32 crc = ~(u32)0; - struct btrfs_root *root = fs_info->extent_root; - void *mapped_buffer; - - BUG_ON(!sblock->pagev[0].page); - if (is_metadata) { - struct btrfs_header *h; - - mapped_buffer = kmap_atomic(sblock->pagev[0].page); - h = (struct btrfs_header *)mapped_buffer; - - if (sblock->pagev[0].logical != le64_to_cpu(h->bytenr) || - generation != le64_to_cpu(h->generation) || - memcmp(h->fsid, fs_info->fsid, BTRFS_UUID_SIZE) || - memcmp(h->chunk_tree_uuid, fs_info->chunk_tree_uuid, - BTRFS_UUID_SIZE)) - sblock->header_error = 1; - csum = h->csum; - } else { - if (!have_csum) - return; - - mapped_buffer = kmap_atomic(sblock->pagev[0].page); - } - - for (page_num = 0;;) { - if (page_num == 0 && is_metadata) - crc = btrfs_csum_data(root, - ((u8 *)mapped_buffer) + BTRFS_CSUM_SIZE, - crc, PAGE_SIZE - BTRFS_CSUM_SIZE); - else - crc = btrfs_csum_data(root, mapped_buffer, crc, - PAGE_SIZE); + struct bio *bio = NULL; + int ret; + DECLARE_COMPLETION_ONSTACK(complete); - kunmap_atomic(mapped_buffer); - page_num++; - if (page_num >= sblock->page_count) - break; - BUG_ON(!sblock->pagev[page_num].page); + bio = bio_alloc(GFP_NOFS, 1); + bio->bi_bdev = bdev; + bio->bi_sector = sector; + bio_add_page(bio, page, PAGE_SIZE, 0); + bio->bi_end_io = scrub_fixup_end_io; + bio->bi_private = &complete; + btrfsic_submit_bio(rw, bio); - mapped_buffer = kmap_atomic(sblock->pagev[page_num].page); - } + /* this will also unplug the queue */ + wait_for_completion(&complete); - btrfs_csum_final(crc, calculated_csum); - if (memcmp(calculated_csum, csum, csum_size)) - sblock->checksum_error = 1; -} - -static void scrub_complete_bio_end_io(struct bio *bio, int err) -{ - complete((struct completion *)bio->bi_private); + ret = !test_bit(BIO_UPTODATE, &bio->bi_flags); + bio_put(bio); + return ret; } -static int scrub_repair_block_from_good_copy(struct scrub_block *sblock_bad, - struct scrub_block *sblock_good, - int force_write) +static void scrub_bio_end_io(struct bio *bio, int err) { - int page_num; - int ret = 0; - - for (page_num = 0; page_num < sblock_bad->page_count; page_num++) { - int ret_sub; + struct scrub_bio *sbio = bio->bi_private; + struct scrub_dev *sdev = sbio->sdev; + struct btrfs_fs_info *fs_info = sdev->dev->dev_root->fs_info; - ret_sub = scrub_repair_page_from_good_copy(sblock_bad, - sblock_good, - page_num, - force_write); - if (ret_sub) - ret = ret_sub; - } + sbio->err = err; + sbio->bio = bio; - return ret; + btrfs_queue_worker(&fs_info->scrub_workers, &sbio->work); } -static int scrub_repair_page_from_good_copy(struct scrub_block *sblock_bad, - struct scrub_block *sblock_good, - int page_num, int force_write) +static void scrub_checksum(struct btrfs_work *work) { - struct scrub_page *page_bad = sblock_bad->pagev + page_num; - struct scrub_page *page_good = sblock_good->pagev + page_num; - - BUG_ON(sblock_bad->pagev[page_num].page == NULL); - BUG_ON(sblock_good->pagev[page_num].page == NULL); - if (force_write || sblock_bad->header_error || - sblock_bad->checksum_error || page_bad->io_error) { - struct bio *bio; - int ret; - DECLARE_COMPLETION_ONSTACK(complete); + struct scrub_bio *sbio = container_of(work, struct scrub_bio, work); + struct scrub_dev *sdev = sbio->sdev; + struct page *page; + void *buffer; + int i; + u64 flags; + u64 logical; + int ret; - bio = bio_alloc(GFP_NOFS, 1); - if (!bio) - return -EIO; - bio->bi_bdev = page_bad->bdev; - bio->bi_sector = page_bad->physical >> 9; - bio->bi_end_io = scrub_complete_bio_end_io; - bio->bi_private = &complete; - - ret = bio_add_page(bio, page_good->page, PAGE_SIZE, 0); - if (PAGE_SIZE != ret) { - bio_put(bio); - return -EIO; + if (sbio->err) { + ret = 0; + for (i = 0; i < sbio->count; ++i) + ret |= scrub_recheck_error(sbio, i); + if (!ret) { + spin_lock(&sdev->stat_lock); + ++sdev->stat.unverified_errors; + spin_unlock(&sdev->stat_lock); } - btrfsic_submit_bio(WRITE, bio); - - /* this will also unplug the queue */ - wait_for_completion(&complete); - bio_put(bio); - } - return 0; -} + sbio->bio->bi_flags &= ~(BIO_POOL_MASK - 1); + sbio->bio->bi_flags |= 1 << BIO_UPTODATE; + sbio->bio->bi_phys_segments = 0; + sbio->bio->bi_idx = 0; -static void scrub_checksum(struct scrub_block *sblock) -{ - u64 flags; - int ret; + for (i = 0; i < sbio->count; i++) { + struct bio_vec *bi; + bi = &sbio->bio->bi_io_vec[i]; + bi->bv_offset = 0; + bi->bv_len = PAGE_SIZE; + } + goto out; + } + for (i = 0; i < sbio->count; ++i) { + page = sbio->bio->bi_io_vec[i].bv_page; + buffer = kmap_atomic(page); + flags = sbio->spag[i].flags; + logical = sbio->logical + i * PAGE_SIZE; + ret = 0; + if (flags & BTRFS_EXTENT_FLAG_DATA) { + ret = scrub_checksum_data(sdev, sbio->spag + i, buffer); + } else if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) { + ret = scrub_checksum_tree_block(sdev, sbio->spag + i, + logical, buffer); + } else if (flags & BTRFS_EXTENT_FLAG_SUPER) { + BUG_ON(i); + (void)scrub_checksum_super(sbio, buffer); + } else { + WARN_ON(1); + } + kunmap_atomic(buffer); + if (ret) { + ret = scrub_recheck_error(sbio, i); + if (!ret) { + spin_lock(&sdev->stat_lock); + ++sdev->stat.unverified_errors; + spin_unlock(&sdev->stat_lock); + } + } + } - BUG_ON(sblock->page_count < 1); - flags = sblock->pagev[0].flags; - ret = 0; - if (flags & BTRFS_EXTENT_FLAG_DATA) - ret = scrub_checksum_data(sblock); - else if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) - ret = scrub_checksum_tree_block(sblock); - else if (flags & BTRFS_EXTENT_FLAG_SUPER) - (void)scrub_checksum_super(sblock); - else - WARN_ON(1); - if (ret) - scrub_handle_errored_block(sblock); +out: + scrub_free_bio(sbio->bio); + sbio->bio = NULL; + spin_lock(&sdev->list_lock); + sbio->next_free = sdev->first_free; + sdev->first_free = sbio->index; + spin_unlock(&sdev->list_lock); + atomic_dec(&sdev->in_flight); + wake_up(&sdev->list_wait); } -static int scrub_checksum_data(struct scrub_block *sblock) +static int scrub_checksum_data(struct scrub_dev *sdev, + struct scrub_page *spag, void *buffer) { - struct scrub_dev *sdev = sblock->sdev; u8 csum[BTRFS_CSUM_SIZE]; - u8 *on_disk_csum; - struct page *page; - void *buffer; u32 crc = ~(u32)0; int fail = 0; struct btrfs_root *root = sdev->dev->dev_root; - u64 len; - int index; - BUG_ON(sblock->page_count < 1); - if (!sblock->pagev[0].have_csum) + if (!spag->have_csum) return 0; - on_disk_csum = sblock->pagev[0].csum; - page = sblock->pagev[0].page; - buffer = kmap_atomic(page); - - len = sdev->sectorsize; - index = 0; - for (;;) { - u64 l = min_t(u64, len, PAGE_SIZE); - - crc = btrfs_csum_data(root, buffer, crc, l); - kunmap_atomic(buffer); - len -= l; - if (len == 0) - break; - index++; - BUG_ON(index >= sblock->page_count); - BUG_ON(!sblock->pagev[index].page); - page = sblock->pagev[index].page; - buffer = kmap_atomic(page); - } - + crc = btrfs_csum_data(root, buffer, crc, PAGE_SIZE); btrfs_csum_final(crc, csum); - if (memcmp(csum, on_disk_csum, sdev->csum_size)) + if (memcmp(csum, spag->csum, sdev->csum_size)) fail = 1; + spin_lock(&sdev->stat_lock); + ++sdev->stat.data_extents_scrubbed; + sdev->stat.data_bytes_scrubbed += PAGE_SIZE; + if (fail) + ++sdev->stat.csum_errors; + spin_unlock(&sdev->stat_lock); + return fail; } -static int scrub_checksum_tree_block(struct scrub_block *sblock) +static int scrub_checksum_tree_block(struct scrub_dev *sdev, + struct scrub_page *spag, u64 logical, + void *buffer) { - struct scrub_dev *sdev = sblock->sdev; struct btrfs_header *h; struct btrfs_root *root = sdev->dev->dev_root; struct btrfs_fs_info *fs_info = root->fs_info; - u8 calculated_csum[BTRFS_CSUM_SIZE]; - u8 on_disk_csum[BTRFS_CSUM_SIZE]; - struct page *page; - void *mapped_buffer; - u64 mapped_size; - void *p; + u8 csum[BTRFS_CSUM_SIZE]; u32 crc = ~(u32)0; int fail = 0; int crc_fail = 0; - u64 len; - int index; - - BUG_ON(sblock->page_count < 1); - page = sblock->pagev[0].page; - mapped_buffer = kmap_atomic(page); - h = (struct btrfs_header *)mapped_buffer; - memcpy(on_disk_csum, h->csum, sdev->csum_size); /* * we don't use the getter functions here, as we * a) don't have an extent buffer and * b) the page is already kmapped */ + h = (struct btrfs_header *)buffer; - if (sblock->pagev[0].logical != le64_to_cpu(h->bytenr)) + if (logical != le64_to_cpu(h->bytenr)) ++fail; - if (sblock->pagev[0].generation != le64_to_cpu(h->generation)) + if (spag->generation != le64_to_cpu(h->generation)) ++fail; if (memcmp(h->fsid, fs_info->fsid, BTRFS_UUID_SIZE)) @@ -1310,90 +887,51 @@ static int scrub_checksum_tree_block(struct scrub_block *sblock) BTRFS_UUID_SIZE)) ++fail; - BUG_ON(sdev->nodesize != sdev->leafsize); - len = sdev->nodesize - BTRFS_CSUM_SIZE; - mapped_size = PAGE_SIZE - BTRFS_CSUM_SIZE; - p = ((u8 *)mapped_buffer) + BTRFS_CSUM_SIZE; - index = 0; - for (;;) { - u64 l = min_t(u64, len, mapped_size); - - crc = btrfs_csum_data(root, p, crc, l); - kunmap_atomic(mapped_buffer); - len -= l; - if (len == 0) - break; - index++; - BUG_ON(index >= sblock->page_count); - BUG_ON(!sblock->pagev[index].page); - page = sblock->pagev[index].page; - mapped_buffer = kmap_atomic(page); - mapped_size = PAGE_SIZE; - p = mapped_buffer; - } - - btrfs_csum_final(crc, calculated_csum); - if (memcmp(calculated_csum, on_disk_csum, sdev->csum_size)) + crc = btrfs_csum_data(root, buffer + BTRFS_CSUM_SIZE, crc, + PAGE_SIZE - BTRFS_CSUM_SIZE); + btrfs_csum_final(crc, csum); + if (memcmp(csum, h->csum, sdev->csum_size)) ++crc_fail; + spin_lock(&sdev->stat_lock); + ++sdev->stat.tree_extents_scrubbed; + sdev->stat.tree_bytes_scrubbed += PAGE_SIZE; + if (crc_fail) + ++sdev->stat.csum_errors; + if (fail) + ++sdev->stat.verify_errors; + spin_unlock(&sdev->stat_lock); + return fail || crc_fail; } -static int scrub_checksum_super(struct scrub_block *sblock) +static int scrub_checksum_super(struct scrub_bio *sbio, void *buffer) { struct btrfs_super_block *s; - struct scrub_dev *sdev = sblock->sdev; + u64 logical; + struct scrub_dev *sdev = sbio->sdev; struct btrfs_root *root = sdev->dev->dev_root; struct btrfs_fs_info *fs_info = root->fs_info; - u8 calculated_csum[BTRFS_CSUM_SIZE]; - u8 on_disk_csum[BTRFS_CSUM_SIZE]; - struct page *page; - void *mapped_buffer; - u64 mapped_size; - void *p; + u8 csum[BTRFS_CSUM_SIZE]; u32 crc = ~(u32)0; int fail = 0; - u64 len; - int index; - BUG_ON(sblock->page_count < 1); - page = sblock->pagev[0].page; - mapped_buffer = kmap_atomic(page); - s = (struct btrfs_super_block *)mapped_buffer; - memcpy(on_disk_csum, s->csum, sdev->csum_size); + s = (struct btrfs_super_block *)buffer; + logical = sbio->logical; - if (sblock->pagev[0].logical != le64_to_cpu(s->bytenr)) + if (logical != le64_to_cpu(s->bytenr)) ++fail; - if (sblock->pagev[0].generation != le64_to_cpu(s->generation)) + if (sbio->spag[0].generation != le64_to_cpu(s->generation)) ++fail; if (memcmp(s->fsid, fs_info->fsid, BTRFS_UUID_SIZE)) ++fail; - len = BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE; - mapped_size = PAGE_SIZE - BTRFS_CSUM_SIZE; - p = ((u8 *)mapped_buffer) + BTRFS_CSUM_SIZE; - index = 0; - for (;;) { - u64 l = min_t(u64, len, mapped_size); - - crc = btrfs_csum_data(root, p, crc, l); - kunmap_atomic(mapped_buffer); - len -= l; - if (len == 0) - break; - index++; - BUG_ON(index >= sblock->page_count); - BUG_ON(!sblock->pagev[index].page); - page = sblock->pagev[index].page; - mapped_buffer = kmap_atomic(page); - mapped_size = PAGE_SIZE; - p = mapped_buffer; - } - - btrfs_csum_final(crc, calculated_csum); - if (memcmp(calculated_csum, on_disk_csum, sdev->csum_size)) + crc = btrfs_csum_data(root, buffer + BTRFS_CSUM_SIZE, crc, + PAGE_SIZE - BTRFS_CSUM_SIZE); + btrfs_csum_final(crc, csum); + if (memcmp(csum, s->csum, sbio->sdev->csum_size)) ++fail; if (fail) { @@ -1410,42 +948,29 @@ static int scrub_checksum_super(struct scrub_block *sblock) return fail; } -static void scrub_block_get(struct scrub_block *sblock) -{ - atomic_inc(&sblock->ref_count); -} - -static void scrub_block_put(struct scrub_block *sblock) -{ - if (atomic_dec_and_test(&sblock->ref_count)) { - int i; - - for (i = 0; i < sblock->page_count; i++) - if (sblock->pagev[i].page) - __free_page(sblock->pagev[i].page); - kfree(sblock); - } -} - -static void scrub_submit(struct scrub_dev *sdev) +static int scrub_submit(struct scrub_dev *sdev) { struct scrub_bio *sbio; if (sdev->curr == -1) - return; + return 0; sbio = sdev->bios[sdev->curr]; + sbio->err = 0; sdev->curr = -1; atomic_inc(&sdev->in_flight); btrfsic_submit_bio(READ, sbio->bio); + + return 0; } -static int scrub_add_page_to_bio(struct scrub_dev *sdev, - struct scrub_page *spage) +static int scrub_page(struct scrub_dev *sdev, u64 logical, u64 len, + u64 physical, u64 flags, u64 gen, int mirror_num, + u8 *csum, int force) { - struct scrub_block *sblock = spage->sblock; struct scrub_bio *sbio; + struct page *page; int ret; again: @@ -1458,7 +983,7 @@ static int scrub_add_page_to_bio(struct scrub_dev *sdev, if (sdev->curr != -1) { sdev->first_free = sdev->bios[sdev->curr]->next_free; sdev->bios[sdev->curr]->next_free = -1; - sdev->bios[sdev->curr]->page_count = 0; + sdev->bios[sdev->curr]->count = 0; spin_unlock(&sdev->list_lock); } else { spin_unlock(&sdev->list_lock); @@ -1466,200 +991,62 @@ static int scrub_add_page_to_bio(struct scrub_dev *sdev, } } sbio = sdev->bios[sdev->curr]; - if (sbio->page_count == 0) { + if (sbio->count == 0) { struct bio *bio; - sbio->physical = spage->physical; - sbio->logical = spage->logical; - bio = sbio->bio; - if (!bio) { - bio = bio_alloc(GFP_NOFS, sdev->pages_per_bio); - if (!bio) - return -ENOMEM; - sbio->bio = bio; - } + sbio->physical = physical; + sbio->logical = logical; + bio = bio_alloc(GFP_NOFS, SCRUB_PAGES_PER_BIO); + if (!bio) + return -ENOMEM; bio->bi_private = sbio; bio->bi_end_io = scrub_bio_end_io; bio->bi_bdev = sdev->dev->bdev; - bio->bi_sector = spage->physical >> 9; + bio->bi_sector = sbio->physical >> 9; sbio->err = 0; - } else if (sbio->physical + sbio->page_count * PAGE_SIZE != - spage->physical || - sbio->logical + sbio->page_count * PAGE_SIZE != - spage->logical) { - scrub_submit(sdev); - goto again; - } - - sbio->pagev[sbio->page_count] = spage; - ret = bio_add_page(sbio->bio, spage->page, PAGE_SIZE, 0); - if (ret != PAGE_SIZE) { - if (sbio->page_count < 1) { - bio_put(sbio->bio); - sbio->bio = NULL; - return -EIO; - } - scrub_submit(sdev); + sbio->bio = bio; + } else if (sbio->physical + sbio->count * PAGE_SIZE != physical || + sbio->logical + sbio->count * PAGE_SIZE != logical) { + ret = scrub_submit(sdev); + if (ret) + return ret; goto again; } + sbio->spag[sbio->count].flags = flags; + sbio->spag[sbio->count].generation = gen; + sbio->spag[sbio->count].have_csum = 0; + sbio->spag[sbio->count].mirror_num = mirror_num; - scrub_block_get(sblock); /* one for the added page */ - atomic_inc(&sblock->outstanding_pages); - sbio->page_count++; - if (sbio->page_count == sdev->pages_per_bio) - scrub_submit(sdev); - - return 0; -} - -static int scrub_pages(struct scrub_dev *sdev, u64 logical, u64 len, - u64 physical, u64 flags, u64 gen, int mirror_num, - u8 *csum, int force) -{ - struct scrub_block *sblock; - int index; - - sblock = kzalloc(sizeof(*sblock), GFP_NOFS); - if (!sblock) { - spin_lock(&sdev->stat_lock); - sdev->stat.malloc_errors++; - spin_unlock(&sdev->stat_lock); + page = alloc_page(GFP_NOFS); + if (!page) return -ENOMEM; - } - /* one ref inside this function, plus one for each page later on */ - atomic_set(&sblock->ref_count, 1); - sblock->sdev = sdev; - sblock->no_io_error_seen = 1; - - for (index = 0; len > 0; index++) { - struct scrub_page *spage = sblock->pagev + index; - u64 l = min_t(u64, len, PAGE_SIZE); - - BUG_ON(index >= SCRUB_MAX_PAGES_PER_BLOCK); - spage->page = alloc_page(GFP_NOFS); - if (!spage->page) { - spin_lock(&sdev->stat_lock); - sdev->stat.malloc_errors++; - spin_unlock(&sdev->stat_lock); - while (index > 0) { - index--; - __free_page(sblock->pagev[index].page); - } - kfree(sblock); - return -ENOMEM; - } - spage->sblock = sblock; - spage->bdev = sdev->dev->bdev; - spage->flags = flags; - spage->generation = gen; - spage->logical = logical; - spage->physical = physical; - spage->mirror_num = mirror_num; - if (csum) { - spage->have_csum = 1; - memcpy(spage->csum, csum, sdev->csum_size); - } else { - spage->have_csum = 0; - } - sblock->page_count++; - len -= l; - logical += l; - physical += l; + ret = bio_add_page(sbio->bio, page, PAGE_SIZE, 0); + if (!ret) { + __free_page(page); + ret = scrub_submit(sdev); + if (ret) + return ret; + goto again; } - BUG_ON(sblock->page_count == 0); - for (index = 0; index < sblock->page_count; index++) { - struct scrub_page *spage = sblock->pagev + index; + if (csum) { + sbio->spag[sbio->count].have_csum = 1; + memcpy(sbio->spag[sbio->count].csum, csum, sdev->csum_size); + } + ++sbio->count; + if (sbio->count == SCRUB_PAGES_PER_BIO || force) { int ret; - ret = scrub_add_page_to_bio(sdev, spage); - if (ret) { - scrub_block_put(sblock); + ret = scrub_submit(sdev); + if (ret) return ret; - } } - if (force) - scrub_submit(sdev); - - /* last one frees, either here or in bio completion for last page */ - scrub_block_put(sblock); return 0; } -static void scrub_bio_end_io(struct bio *bio, int err) -{ - struct scrub_bio *sbio = bio->bi_private; - struct scrub_dev *sdev = sbio->sdev; - struct btrfs_fs_info *fs_info = sdev->dev->dev_root->fs_info; - - sbio->err = err; - sbio->bio = bio; - - btrfs_queue_worker(&fs_info->scrub_workers, &sbio->work); -} - -static void scrub_bio_end_io_worker(struct btrfs_work *work) -{ - struct scrub_bio *sbio = container_of(work, struct scrub_bio, work); - struct scrub_dev *sdev = sbio->sdev; - int i; - - BUG_ON(sbio->page_count > SCRUB_PAGES_PER_BIO); - if (sbio->err) { - for (i = 0; i < sbio->page_count; i++) { - struct scrub_page *spage = sbio->pagev[i]; - - spage->io_error = 1; - spage->sblock->no_io_error_seen = 0; - } - } - - /* now complete the scrub_block items that have all pages completed */ - for (i = 0; i < sbio->page_count; i++) { - struct scrub_page *spage = sbio->pagev[i]; - struct scrub_block *sblock = spage->sblock; - - if (atomic_dec_and_test(&sblock->outstanding_pages)) - scrub_block_complete(sblock); - scrub_block_put(sblock); - } - - if (sbio->err) { - /* what is this good for??? */ - sbio->bio->bi_flags &= ~(BIO_POOL_MASK - 1); - sbio->bio->bi_flags |= 1 << BIO_UPTODATE; - sbio->bio->bi_phys_segments = 0; - sbio->bio->bi_idx = 0; - - for (i = 0; i < sbio->page_count; i++) { - struct bio_vec *bi; - bi = &sbio->bio->bi_io_vec[i]; - bi->bv_offset = 0; - bi->bv_len = PAGE_SIZE; - } - } - - bio_put(sbio->bio); - sbio->bio = NULL; - spin_lock(&sdev->list_lock); - sbio->next_free = sdev->first_free; - sdev->first_free = sbio->index; - spin_unlock(&sdev->list_lock); - atomic_dec(&sdev->in_flight); - wake_up(&sdev->list_wait); -} - -static void scrub_block_complete(struct scrub_block *sblock) -{ - if (!sblock->no_io_error_seen) - scrub_handle_errored_block(sblock); - else - scrub_checksum(sblock); -} - static int scrub_find_csum(struct scrub_dev *sdev, u64 logical, u64 len, u8 *csum) { @@ -1667,6 +1054,7 @@ static int scrub_find_csum(struct scrub_dev *sdev, u64 logical, u64 len, int ret = 0; unsigned long i; unsigned long num_sectors; + u32 sectorsize = sdev->dev->dev_root->sectorsize; while (!list_empty(&sdev->csum_list)) { sum = list_first_entry(&sdev->csum_list, @@ -1684,7 +1072,7 @@ static int scrub_find_csum(struct scrub_dev *sdev, u64 logical, u64 len, if (!sum) return 0; - num_sectors = sum->len / sdev->sectorsize; + num_sectors = sum->len / sectorsize; for (i = 0; i < num_sectors; ++i) { if (sum->sums[i].bytenr == logical) { memcpy(csum, &sum->sums[i].sum, sdev->csum_size); @@ -1705,28 +1093,9 @@ static int scrub_extent(struct scrub_dev *sdev, u64 logical, u64 len, { int ret; u8 csum[BTRFS_CSUM_SIZE]; - u32 blocksize; - - if (flags & BTRFS_EXTENT_FLAG_DATA) { - blocksize = sdev->sectorsize; - spin_lock(&sdev->stat_lock); - sdev->stat.data_extents_scrubbed++; - sdev->stat.data_bytes_scrubbed += len; - spin_unlock(&sdev->stat_lock); - } else if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) { - BUG_ON(sdev->nodesize != sdev->leafsize); - blocksize = sdev->nodesize; - spin_lock(&sdev->stat_lock); - sdev->stat.tree_extents_scrubbed++; - sdev->stat.tree_bytes_scrubbed += len; - spin_unlock(&sdev->stat_lock); - } else { - blocksize = sdev->sectorsize; - BUG_ON(1); - } while (len) { - u64 l = min_t(u64, len, blocksize); + u64 l = min_t(u64, len, PAGE_SIZE); int have_csum = 0; if (flags & BTRFS_EXTENT_FLAG_DATA) { @@ -1735,8 +1104,8 @@ static int scrub_extent(struct scrub_dev *sdev, u64 logical, u64 len, if (have_csum == 0) ++sdev->stat.no_csum; } - ret = scrub_pages(sdev, logical, l, physical, flags, gen, - mirror_num, have_csum ? csum : NULL, 0); + ret = scrub_page(sdev, logical, l, physical, flags, gen, + mirror_num, have_csum ? csum : NULL, 0); if (ret) return ret; len -= l; @@ -1801,11 +1170,6 @@ static noinline_for_stack int scrub_stripe(struct scrub_dev *sdev, if (!path) return -ENOMEM; - /* - * work on commit root. The related disk blocks are static as - * long as COW is applied. This means, it is save to rewrite - * them to repair disk errors without any race conditions - */ path->search_commit_root = 1; path->skip_locking = 1; @@ -2152,18 +1516,15 @@ static noinline_for_stack int scrub_supers(struct scrub_dev *sdev) struct btrfs_device *device = sdev->dev; struct btrfs_root *root = device->dev_root; - if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) - return -EIO; - gen = root->fs_info->last_trans_committed; for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { bytenr = btrfs_sb_offset(i); - if (bytenr + BTRFS_SUPER_INFO_SIZE > device->total_bytes) + if (bytenr + BTRFS_SUPER_INFO_SIZE >= device->total_bytes) break; - ret = scrub_pages(sdev, bytenr, BTRFS_SUPER_INFO_SIZE, bytenr, - BTRFS_EXTENT_FLAG_SUPER, gen, i, NULL, 1); + ret = scrub_page(sdev, bytenr, PAGE_SIZE, bytenr, + BTRFS_EXTENT_FLAG_SUPER, gen, i, NULL, 1); if (ret) return ret; } @@ -2222,30 +1583,10 @@ int btrfs_scrub_dev(struct btrfs_root *root, u64 devid, u64 start, u64 end, /* * check some assumptions */ - if (root->nodesize != root->leafsize) { - printk(KERN_ERR - "btrfs_scrub: size assumption nodesize == leafsize (%d == %d) fails\n", - root->nodesize, root->leafsize); - return -EINVAL; - } - - if (root->nodesize > BTRFS_STRIPE_LEN) { - /* - * in this case scrub is unable to calculate the checksum - * the way scrub is implemented. Do not handle this - * situation at all because it won't ever happen. - */ - printk(KERN_ERR - "btrfs_scrub: size assumption nodesize <= BTRFS_STRIPE_LEN (%d <= %d) fails\n", - root->nodesize, BTRFS_STRIPE_LEN); - return -EINVAL; - } - - if (root->sectorsize != PAGE_SIZE) { - /* not supported for data w/o checksums */ - printk(KERN_ERR - "btrfs_scrub: size assumption sectorsize != PAGE_SIZE (%d != %lld) fails\n", - root->sectorsize, (unsigned long long)PAGE_SIZE); + if (root->sectorsize != PAGE_SIZE || + root->sectorsize != root->leafsize || + root->sectorsize != root->nodesize) { + printk(KERN_ERR "btrfs_scrub: size assumptions fail\n"); return -EINVAL; } @@ -2315,7 +1656,7 @@ int btrfs_scrub_dev(struct btrfs_root *root, u64 devid, u64 start, u64 end, return ret; } -void btrfs_scrub_pause(struct btrfs_root *root) +int btrfs_scrub_pause(struct btrfs_root *root) { struct btrfs_fs_info *fs_info = root->fs_info; @@ -2330,28 +1671,34 @@ void btrfs_scrub_pause(struct btrfs_root *root) mutex_lock(&fs_info->scrub_lock); } mutex_unlock(&fs_info->scrub_lock); + + return 0; } -void btrfs_scrub_continue(struct btrfs_root *root) +int btrfs_scrub_continue(struct btrfs_root *root) { struct btrfs_fs_info *fs_info = root->fs_info; atomic_dec(&fs_info->scrub_pause_req); wake_up(&fs_info->scrub_pause_wait); + return 0; } -void btrfs_scrub_pause_super(struct btrfs_root *root) +int btrfs_scrub_pause_super(struct btrfs_root *root) { down_write(&root->fs_info->scrub_super_lock); + return 0; } -void btrfs_scrub_continue_super(struct btrfs_root *root) +int btrfs_scrub_continue_super(struct btrfs_root *root) { up_write(&root->fs_info->scrub_super_lock); + return 0; } -int __btrfs_scrub_cancel(struct btrfs_fs_info *fs_info) +int btrfs_scrub_cancel(struct btrfs_root *root) { + struct btrfs_fs_info *fs_info = root->fs_info; mutex_lock(&fs_info->scrub_lock); if (!atomic_read(&fs_info->scrubs_running)) { @@ -2372,11 +1719,6 @@ int __btrfs_scrub_cancel(struct btrfs_fs_info *fs_info) return 0; } -int btrfs_scrub_cancel(struct btrfs_root *root) -{ - return __btrfs_scrub_cancel(root->fs_info); -} - int btrfs_scrub_cancel_dev(struct btrfs_root *root, struct btrfs_device *dev) { struct btrfs_fs_info *fs_info = root->fs_info; @@ -2399,7 +1741,6 @@ int btrfs_scrub_cancel_dev(struct btrfs_root *root, struct btrfs_device *dev) return 0; } - int btrfs_scrub_cancel_devid(struct btrfs_root *root, u64 devid) { struct btrfs_fs_info *fs_info = root->fs_info; diff --git a/trunk/fs/btrfs/struct-funcs.c b/trunk/fs/btrfs/struct-funcs.c index c6ffa5812419..bc1f6ad18442 100644 --- a/trunk/fs/btrfs/struct-funcs.c +++ b/trunk/fs/btrfs/struct-funcs.c @@ -44,9 +44,8 @@ #define BTRFS_SETGET_FUNCS(name, type, member, bits) \ u##bits btrfs_##name(struct extent_buffer *eb, type *s); \ void btrfs_set_##name(struct extent_buffer *eb, type *s, u##bits val); \ -void btrfs_set_token_##name(struct extent_buffer *eb, type *s, u##bits val, struct btrfs_map_token *token); \ -u##bits btrfs_token_##name(struct extent_buffer *eb, \ - type *s, struct btrfs_map_token *token) \ +u##bits btrfs_##name(struct extent_buffer *eb, \ + type *s) \ { \ unsigned long part_offset = (unsigned long)s; \ unsigned long offset = part_offset + offsetof(type, member); \ @@ -55,18 +54,9 @@ u##bits btrfs_token_##name(struct extent_buffer *eb, \ char *kaddr; \ unsigned long map_start; \ unsigned long map_len; \ - unsigned long mem_len = sizeof(((type *)0)->member); \ u##bits res; \ - if (token && token->kaddr && token->offset <= offset && \ - token->eb == eb && \ - (token->offset + PAGE_CACHE_SIZE >= offset + mem_len)) { \ - kaddr = token->kaddr; \ - p = (type *)(kaddr + part_offset - token->offset); \ - res = le##bits##_to_cpu(p->member); \ - return res; \ - } \ err = map_private_extent_buffer(eb, offset, \ - mem_len, \ + sizeof(((type *)0)->member), \ &kaddr, &map_start, &map_len); \ if (err) { \ __le##bits leres; \ @@ -75,15 +65,10 @@ u##bits btrfs_token_##name(struct extent_buffer *eb, \ } \ p = (type *)(kaddr + part_offset - map_start); \ res = le##bits##_to_cpu(p->member); \ - if (token) { \ - token->kaddr = kaddr; \ - token->offset = map_start; \ - token->eb = eb; \ - } \ return res; \ } \ -void btrfs_set_token_##name(struct extent_buffer *eb, \ - type *s, u##bits val, struct btrfs_map_token *token) \ +void btrfs_set_##name(struct extent_buffer *eb, \ + type *s, u##bits val) \ { \ unsigned long part_offset = (unsigned long)s; \ unsigned long offset = part_offset + offsetof(type, member); \ @@ -92,17 +77,8 @@ void btrfs_set_token_##name(struct extent_buffer *eb, \ char *kaddr; \ unsigned long map_start; \ unsigned long map_len; \ - unsigned long mem_len = sizeof(((type *)0)->member); \ - if (token && token->kaddr && token->offset <= offset && \ - token->eb == eb && \ - (token->offset + PAGE_CACHE_SIZE >= offset + mem_len)) { \ - kaddr = token->kaddr; \ - p = (type *)(kaddr + part_offset - token->offset); \ - p->member = cpu_to_le##bits(val); \ - return; \ - } \ err = map_private_extent_buffer(eb, offset, \ - mem_len, \ + sizeof(((type *)0)->member), \ &kaddr, &map_start, &map_len); \ if (err) { \ __le##bits val2; \ @@ -112,22 +88,7 @@ void btrfs_set_token_##name(struct extent_buffer *eb, \ } \ p = (type *)(kaddr + part_offset - map_start); \ p->member = cpu_to_le##bits(val); \ - if (token) { \ - token->kaddr = kaddr; \ - token->offset = map_start; \ - token->eb = eb; \ - } \ -} \ -void btrfs_set_##name(struct extent_buffer *eb, \ - type *s, u##bits val) \ -{ \ - btrfs_set_token_##name(eb, s, val, NULL); \ -} \ -u##bits btrfs_##name(struct extent_buffer *eb, \ - type *s) \ -{ \ - return btrfs_token_##name(eb, s, NULL); \ -} \ +} #include "ctree.h" diff --git a/trunk/fs/btrfs/super.c b/trunk/fs/btrfs/super.c index c5f8fca4195f..81df3fec6a6d 100644 --- a/trunk/fs/btrfs/super.c +++ b/trunk/fs/btrfs/super.c @@ -76,9 +76,6 @@ static const char *btrfs_decode_error(struct btrfs_fs_info *fs_info, int errno, case -EROFS: errstr = "Readonly filesystem"; break; - case -EEXIST: - errstr = "Object already exists"; - break; default: if (nbuf) { if (snprintf(nbuf, 16, "error %d", -errno) >= 0) @@ -119,8 +116,6 @@ static void btrfs_handle_error(struct btrfs_fs_info *fs_info) if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { sb->s_flags |= MS_RDONLY; printk(KERN_INFO "btrfs is forced readonly\n"); - __btrfs_scrub_cancel(fs_info); -// WARN_ON(1); } } @@ -129,132 +124,25 @@ static void btrfs_handle_error(struct btrfs_fs_info *fs_info) * invokes the approciate error response. */ void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, - unsigned int line, int errno, const char *fmt, ...) + unsigned int line, int errno) { struct super_block *sb = fs_info->sb; char nbuf[16]; const char *errstr; - va_list args; - va_start(args, fmt); /* * Special case: if the error is EROFS, and we're already * under MS_RDONLY, then it is safe here. */ if (errno == -EROFS && (sb->s_flags & MS_RDONLY)) - return; - - errstr = btrfs_decode_error(fs_info, errno, nbuf); - if (fmt) { - struct va_format vaf = { - .fmt = fmt, - .va = &args, - }; - - printk(KERN_CRIT "BTRFS error (device %s) in %s:%d: %s (%pV)\n", - sb->s_id, function, line, errstr, &vaf); - } else { - printk(KERN_CRIT "BTRFS error (device %s) in %s:%d: %s\n", - sb->s_id, function, line, errstr); - } - - /* Don't go through full error handling during mount */ - if (sb->s_flags & MS_BORN) { - save_error_info(fs_info); - btrfs_handle_error(fs_info); - } - va_end(args); -} - -const char *logtypes[] = { - "emergency", - "alert", - "critical", - "error", - "warning", - "notice", - "info", - "debug", -}; - -void btrfs_printk(struct btrfs_fs_info *fs_info, const char *fmt, ...) -{ - struct super_block *sb = fs_info->sb; - char lvl[4]; - struct va_format vaf; - va_list args; - const char *type = logtypes[4]; - - va_start(args, fmt); - - if (fmt[0] == '<' && isdigit(fmt[1]) && fmt[2] == '>') { - strncpy(lvl, fmt, 3); - fmt += 3; - type = logtypes[fmt[1] - '0']; - } else - *lvl = '\0'; - - vaf.fmt = fmt; - vaf.va = &args; - printk("%sBTRFS %s (device %s): %pV", lvl, type, sb->s_id, &vaf); -} - -/* - * We only mark the transaction aborted and then set the file system read-only. - * This will prevent new transactions from starting or trying to join this - * one. - * - * This means that error recovery at the call site is limited to freeing - * any local memory allocations and passing the error code up without - * further cleanup. The transaction should complete as it normally would - * in the call path but will return -EIO. - * - * We'll complete the cleanup in btrfs_end_transaction and - * btrfs_commit_transaction. - */ -void __btrfs_abort_transaction(struct btrfs_trans_handle *trans, - struct btrfs_root *root, const char *function, - unsigned int line, int errno) -{ - WARN_ONCE(1, KERN_DEBUG "btrfs: Transaction aborted"); - trans->aborted = errno; - /* Nothing used. The other threads that have joined this - * transaction may be able to continue. */ - if (!trans->blocks_used) { - btrfs_printk(root->fs_info, "Aborting unused transaction.\n"); return; - } - trans->transaction->aborted = errno; - __btrfs_std_error(root->fs_info, function, line, errno, NULL); -} -/* - * __btrfs_panic decodes unexpected, fatal errors from the caller, - * issues an alert, and either panics or BUGs, depending on mount options. - */ -void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function, - unsigned int line, int errno, const char *fmt, ...) -{ - char nbuf[16]; - char *s_id = ""; - const char *errstr; - struct va_format vaf = { .fmt = fmt }; - va_list args; - - if (fs_info) - s_id = fs_info->sb->s_id; - - va_start(args, fmt); - vaf.va = &args; errstr = btrfs_decode_error(fs_info, errno, nbuf); - if (fs_info->mount_opt & BTRFS_MOUNT_PANIC_ON_FATAL_ERROR) - panic(KERN_CRIT "BTRFS panic (device %s) in %s:%d: %pV (%s)\n", - s_id, function, line, &vaf, errstr); - - printk(KERN_CRIT "BTRFS panic (device %s) in %s:%d: %pV (%s)\n", - s_id, function, line, &vaf, errstr); - va_end(args); - /* Caller calls BUG() */ + printk(KERN_CRIT "BTRFS error (device %s) in %s:%d: %s\n", + sb->s_id, function, line, errstr); + save_error_info(fs_info); + + btrfs_handle_error(fs_info); } static void btrfs_put_super(struct super_block *sb) @@ -278,7 +166,7 @@ enum { Opt_enospc_debug, Opt_subvolrootid, Opt_defrag, Opt_inode_cache, Opt_no_space_cache, Opt_recovery, Opt_skip_balance, Opt_check_integrity, Opt_check_integrity_including_extent_data, - Opt_check_integrity_print_mask, Opt_fatal_errors, + Opt_check_integrity_print_mask, Opt_err, }; @@ -318,14 +206,12 @@ static match_table_t tokens = { {Opt_check_integrity, "check_int"}, {Opt_check_integrity_including_extent_data, "check_int_data"}, {Opt_check_integrity_print_mask, "check_int_print_mask=%d"}, - {Opt_fatal_errors, "fatal_errors=%s"}, {Opt_err, NULL}, }; /* * Regular mount options parser. Everything that is needed only when * reading in a new superblock is parsed here. - * XXX JDM: This needs to be cleaned up for remount. */ int btrfs_parse_options(struct btrfs_root *root, char *options) { @@ -552,18 +438,6 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) ret = -EINVAL; goto out; #endif - case Opt_fatal_errors: - if (strcmp(args[0].from, "panic") == 0) - btrfs_set_opt(info->mount_opt, - PANIC_ON_FATAL_ERROR); - else if (strcmp(args[0].from, "bug") == 0) - btrfs_clear_opt(info->mount_opt, - PANIC_ON_FATAL_ERROR); - else { - ret = -EINVAL; - goto out; - } - break; case Opt_err: printk(KERN_INFO "btrfs: unrecognized mount option " "'%s'\n", p); @@ -815,6 +689,7 @@ int btrfs_sync_fs(struct super_block *sb, int wait) return 0; } + btrfs_start_delalloc_inodes(root, 0); btrfs_wait_ordered_extents(root, 0, 0); trans = btrfs_start_transaction(root, 0); @@ -887,8 +762,6 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry) seq_puts(seq, ",inode_cache"); if (btrfs_test_opt(root, SKIP_BALANCE)) seq_puts(seq, ",skip_balance"); - if (btrfs_test_opt(root, PANIC_ON_FATAL_ERROR)) - seq_puts(seq, ",fatal_errors=panic"); return 0; } @@ -1122,20 +995,11 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) { struct btrfs_fs_info *fs_info = btrfs_sb(sb); struct btrfs_root *root = fs_info->tree_root; - unsigned old_flags = sb->s_flags; - unsigned long old_opts = fs_info->mount_opt; - unsigned long old_compress_type = fs_info->compress_type; - u64 old_max_inline = fs_info->max_inline; - u64 old_alloc_start = fs_info->alloc_start; - int old_thread_pool_size = fs_info->thread_pool_size; - unsigned int old_metadata_ratio = fs_info->metadata_ratio; int ret; ret = btrfs_parse_options(root, data); - if (ret) { - ret = -EINVAL; - goto restore; - } + if (ret) + return -EINVAL; if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) return 0; @@ -1143,46 +1007,26 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) if (*flags & MS_RDONLY) { sb->s_flags |= MS_RDONLY; - ret = btrfs_commit_super(root); - if (ret) - goto restore; + ret = btrfs_commit_super(root); + WARN_ON(ret); } else { - if (fs_info->fs_devices->rw_devices == 0) { - ret = -EACCES; - goto restore; - } + if (fs_info->fs_devices->rw_devices == 0) + return -EACCES; - if (btrfs_super_log_root(fs_info->super_copy) != 0) { - ret = -EINVAL; - goto restore; - } + if (btrfs_super_log_root(fs_info->super_copy) != 0) + return -EINVAL; ret = btrfs_cleanup_fs_roots(fs_info); - if (ret) - goto restore; + WARN_ON(ret); /* recover relocation */ ret = btrfs_recover_relocation(root); - if (ret) - goto restore; + WARN_ON(ret); sb->s_flags &= ~MS_RDONLY; } return 0; - -restore: - /* We've hit an error - don't reset MS_RDONLY */ - if (sb->s_flags & MS_RDONLY) - old_flags |= MS_RDONLY; - sb->s_flags = old_flags; - fs_info->mount_opt = old_opts; - fs_info->compress_type = old_compress_type; - fs_info->max_inline = old_max_inline; - fs_info->alloc_start = old_alloc_start; - fs_info->thread_pool_size = old_thread_pool_size; - fs_info->metadata_ratio = old_metadata_ratio; - return ret; } /* Used to sort the devices by max_avail(descending sort) */ @@ -1512,7 +1356,9 @@ static int __init init_btrfs_fs(void) if (err) return err; - btrfs_init_compress(); + err = btrfs_init_compress(); + if (err) + goto free_sysfs; err = btrfs_init_cachep(); if (err) @@ -1538,8 +1384,6 @@ static int __init init_btrfs_fs(void) if (err) goto unregister_ioctl; - btrfs_init_lockdep(); - printk(KERN_INFO "%s loaded\n", BTRFS_BUILD_VERSION); return 0; @@ -1555,6 +1399,7 @@ static int __init init_btrfs_fs(void) btrfs_destroy_cachep(); free_compress: btrfs_exit_compress(); +free_sysfs: btrfs_exit_sysfs(); return err; } diff --git a/trunk/fs/btrfs/transaction.c b/trunk/fs/btrfs/transaction.c index 36422254ef67..04b77e3ceb7a 100644 --- a/trunk/fs/btrfs/transaction.c +++ b/trunk/fs/btrfs/transaction.c @@ -31,7 +31,7 @@ #define BTRFS_ROOT_TRANS_TAG 0 -void put_transaction(struct btrfs_transaction *transaction) +static noinline void put_transaction(struct btrfs_transaction *transaction) { WARN_ON(atomic_read(&transaction->use_count) == 0); if (atomic_dec_and_test(&transaction->use_count)) { @@ -58,12 +58,6 @@ static noinline int join_transaction(struct btrfs_root *root, int nofail) spin_lock(&root->fs_info->trans_lock); loop: - /* The file system has been taken offline. No new transactions. */ - if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { - spin_unlock(&root->fs_info->trans_lock); - return -EROFS; - } - if (root->fs_info->trans_no_join) { if (!nofail) { spin_unlock(&root->fs_info->trans_lock); @@ -73,10 +67,6 @@ static noinline int join_transaction(struct btrfs_root *root, int nofail) cur_trans = root->fs_info->running_transaction; if (cur_trans) { - if (cur_trans->aborted) { - spin_unlock(&root->fs_info->trans_lock); - return cur_trans->aborted; - } atomic_inc(&cur_trans->use_count); atomic_inc(&cur_trans->num_writers); cur_trans->num_joined++; @@ -133,7 +123,6 @@ static noinline int join_transaction(struct btrfs_root *root, int nofail) root->fs_info->generation++; cur_trans->transid = root->fs_info->generation; root->fs_info->running_transaction = cur_trans; - cur_trans->aborted = 0; spin_unlock(&root->fs_info->trans_lock); return 0; @@ -329,7 +318,6 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, h->use_count = 1; h->block_rsv = NULL; h->orig_rsv = NULL; - h->aborted = 0; smp_mb(); if (cur_trans->blocked && may_wait_transaction(root, type)) { @@ -339,7 +327,8 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, if (num_bytes) { trace_btrfs_space_reservation(root->fs_info, "transaction", - h->transid, num_bytes, 1); + (u64)(unsigned long)h, + num_bytes, 1); h->block_rsv = &root->fs_info->trans_block_rsv; h->bytes_reserved = num_bytes; } @@ -451,7 +440,6 @@ int btrfs_should_end_transaction(struct btrfs_trans_handle *trans, struct btrfs_transaction *cur_trans = trans->transaction; struct btrfs_block_rsv *rsv = trans->block_rsv; int updates; - int err; smp_mb(); if (cur_trans->blocked || cur_trans->delayed_refs.flushing) @@ -465,11 +453,8 @@ int btrfs_should_end_transaction(struct btrfs_trans_handle *trans, updates = trans->delayed_ref_updates; trans->delayed_ref_updates = 0; - if (updates) { - err = btrfs_run_delayed_refs(trans, root, updates); - if (err) /* Error code will also eval true */ - return err; - } + if (updates) + btrfs_run_delayed_refs(trans, root, updates); trans->block_rsv = rsv; @@ -482,7 +467,6 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, struct btrfs_transaction *cur_trans = trans->transaction; struct btrfs_fs_info *info = root->fs_info; int count = 0; - int err = 0; if (--trans->use_count) { trans->block_rsv = trans->orig_rsv; @@ -535,18 +519,13 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, if (current->journal_info == trans) current->journal_info = NULL; + memset(trans, 0, sizeof(*trans)); + kmem_cache_free(btrfs_trans_handle_cachep, trans); if (throttle) btrfs_run_delayed_iputs(root); - if (trans->aborted || - root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { - err = -EIO; - } - - memset(trans, 0, sizeof(*trans)); - kmem_cache_free(btrfs_trans_handle_cachep, trans); - return err; + return 0; } int btrfs_end_transaction(struct btrfs_trans_handle *trans, @@ -711,13 +690,11 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, ret = btrfs_update_root(trans, tree_root, &root->root_key, &root->root_item); - if (ret) - return ret; + BUG_ON(ret); old_root_used = btrfs_root_used(&root->root_item); ret = btrfs_write_dirty_block_groups(trans, root); - if (ret) - return ret; + BUG_ON(ret); } if (root != root->fs_info->extent_root) @@ -728,10 +705,6 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, /* * update all the cowonly tree roots on disk - * - * The error handling in this function may not be obvious. Any of the - * failures will cause the file system to go offline. We still need - * to clean up the delayed refs. */ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, struct btrfs_root *root) @@ -742,30 +715,22 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, int ret; ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); - if (ret) - return ret; + BUG_ON(ret); eb = btrfs_lock_root_node(fs_info->tree_root); - ret = btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, - 0, &eb); + btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, 0, &eb); btrfs_tree_unlock(eb); free_extent_buffer(eb); - if (ret) - return ret; - ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); - if (ret) - return ret; + BUG_ON(ret); while (!list_empty(&fs_info->dirty_cowonly_roots)) { next = fs_info->dirty_cowonly_roots.next; list_del_init(next); root = list_entry(next, struct btrfs_root, dirty_list); - ret = update_cowonly_root(trans, root); - if (ret) - return ret; + update_cowonly_root(trans, root); } down_write(&fs_info->extent_commit_sem); @@ -909,7 +874,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); if (!new_root_item) { - ret = pending->error = -ENOMEM; + pending->error = -ENOMEM; goto fail; } @@ -946,24 +911,21 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, * insert the directory item */ ret = btrfs_set_inode_index(parent_inode, &index); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); ret = btrfs_insert_dir_item(trans, parent_root, dentry->d_name.name, dentry->d_name.len, parent_inode, &key, BTRFS_FT_DIR, index); - if (ret == -EEXIST) { + if (ret) { pending->error = -EEXIST; dput(parent); goto fail; - } else if (ret) { - goto abort_trans_dput; } btrfs_i_size_write(parent_inode, parent_inode->i_size + dentry->d_name.len * 2); ret = btrfs_update_inode(trans, parent_root, parent_inode); - if (ret) - goto abort_trans_dput; + BUG_ON(ret); /* * pull in the delayed directory update @@ -972,10 +934,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, * snapshot */ ret = btrfs_run_delayed_items(trans, root); - if (ret) { /* Transaction aborted */ - dput(parent); - goto fail; - } + BUG_ON(ret); record_root_in_trans(trans, root); btrfs_set_root_last_snapshot(&root->root_item, trans->transid); @@ -990,21 +949,12 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, btrfs_set_root_flags(new_root_item, root_flags); old = btrfs_lock_root_node(root); - ret = btrfs_cow_block(trans, root, old, NULL, 0, &old); - if (ret) { - btrfs_tree_unlock(old); - free_extent_buffer(old); - goto abort_trans_dput; - } - + btrfs_cow_block(trans, root, old, NULL, 0, &old); btrfs_set_lock_blocking(old); - ret = btrfs_copy_root(trans, root, old, &tmp, objectid); - /* clean up in any case */ + btrfs_copy_root(trans, root, old, &tmp, objectid); btrfs_tree_unlock(old); free_extent_buffer(old); - if (ret) - goto abort_trans_dput; /* see comments in should_cow_block() */ root->force_cow = 1; @@ -1016,8 +966,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, ret = btrfs_insert_root(trans, tree_root, &key, new_root_item); btrfs_tree_unlock(tmp); free_extent_buffer(tmp); - if (ret) - goto abort_trans_dput; + BUG_ON(ret); /* * insert root back/forward references @@ -1026,32 +975,19 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, parent_root->root_key.objectid, btrfs_ino(parent_inode), index, dentry->d_name.name, dentry->d_name.len); + BUG_ON(ret); dput(parent); - if (ret) - goto fail; key.offset = (u64)-1; pending->snap = btrfs_read_fs_root_no_name(root->fs_info, &key); - if (IS_ERR(pending->snap)) { - ret = PTR_ERR(pending->snap); - goto abort_trans; - } + BUG_ON(IS_ERR(pending->snap)); - ret = btrfs_reloc_post_snapshot(trans, pending); - if (ret) - goto abort_trans; - ret = 0; + btrfs_reloc_post_snapshot(trans, pending); fail: kfree(new_root_item); trans->block_rsv = rsv; btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1); - return ret; - -abort_trans_dput: - dput(parent); -abort_trans: - btrfs_abort_transaction(trans, root, ret); - goto fail; + return 0; } /* @@ -1188,33 +1124,6 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans, return 0; } - -static void cleanup_transaction(struct btrfs_trans_handle *trans, - struct btrfs_root *root) -{ - struct btrfs_transaction *cur_trans = trans->transaction; - - WARN_ON(trans->use_count > 1); - - spin_lock(&root->fs_info->trans_lock); - list_del_init(&cur_trans->list); - spin_unlock(&root->fs_info->trans_lock); - - btrfs_cleanup_one_transaction(trans->transaction, root); - - put_transaction(cur_trans); - put_transaction(cur_trans); - - trace_btrfs_transaction_commit(root); - - btrfs_scrub_continue(root); - - if (current->journal_info == trans) - current->journal_info = NULL; - - kmem_cache_free(btrfs_trans_handle_cachep, trans); -} - /* * btrfs_transaction state sequence: * in_commit = 0, blocked = 0 (initial) @@ -1226,10 +1135,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, struct btrfs_root *root) { unsigned long joined = 0; - struct btrfs_transaction *cur_trans = trans->transaction; + struct btrfs_transaction *cur_trans; struct btrfs_transaction *prev_trans = NULL; DEFINE_WAIT(wait); - int ret = -EIO; + int ret; int should_grow = 0; unsigned long now = get_seconds(); int flush_on_commit = btrfs_test_opt(root, FLUSHONCOMMIT); @@ -1239,18 +1148,13 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, btrfs_trans_release_metadata(trans, root); trans->block_rsv = NULL; - if (cur_trans->aborted) - goto cleanup_transaction; - /* make a pass through all the delayed refs we have so far * any runnings procs may add more while we are here */ ret = btrfs_run_delayed_refs(trans, root, 0); - if (ret) - goto cleanup_transaction; + BUG_ON(ret); cur_trans = trans->transaction; - /* * set the flushing flag so procs in this transaction have to * start sending their work down. @@ -1258,20 +1162,19 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, cur_trans->delayed_refs.flushing = 1; ret = btrfs_run_delayed_refs(trans, root, 0); - if (ret) - goto cleanup_transaction; + BUG_ON(ret); spin_lock(&cur_trans->commit_lock); if (cur_trans->in_commit) { spin_unlock(&cur_trans->commit_lock); atomic_inc(&cur_trans->use_count); - ret = btrfs_end_transaction(trans, root); + btrfs_end_transaction(trans, root); wait_for_commit(root, cur_trans); put_transaction(cur_trans); - return ret; + return 0; } trans->transaction->in_commit = 1; @@ -1311,12 +1214,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, if (flush_on_commit || snap_pending) { btrfs_start_delalloc_inodes(root, 1); - btrfs_wait_ordered_extents(root, 0, 1); + ret = btrfs_wait_ordered_extents(root, 0, 1); + BUG_ON(ret); } ret = btrfs_run_delayed_items(trans, root); - if (ret) - goto cleanup_transaction; + BUG_ON(ret); /* * rename don't use btrfs_join_transaction, so, once we @@ -1358,22 +1261,13 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, mutex_lock(&root->fs_info->reloc_mutex); ret = btrfs_run_delayed_items(trans, root); - if (ret) { - mutex_unlock(&root->fs_info->reloc_mutex); - goto cleanup_transaction; - } + BUG_ON(ret); ret = create_pending_snapshots(trans, root->fs_info); - if (ret) { - mutex_unlock(&root->fs_info->reloc_mutex); - goto cleanup_transaction; - } + BUG_ON(ret); ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); - if (ret) { - mutex_unlock(&root->fs_info->reloc_mutex); - goto cleanup_transaction; - } + BUG_ON(ret); /* * make sure none of the code above managed to slip in a @@ -1400,11 +1294,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, mutex_lock(&root->fs_info->tree_log_mutex); ret = commit_fs_roots(trans, root); - if (ret) { - mutex_unlock(&root->fs_info->tree_log_mutex); - mutex_unlock(&root->fs_info->reloc_mutex); - goto cleanup_transaction; - } + BUG_ON(ret); /* commit_fs_roots gets rid of all the tree log roots, it is now * safe to free the root of tree log roots @@ -1412,11 +1302,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, btrfs_free_log_root_tree(trans, root->fs_info); ret = commit_cowonly_roots(trans, root); - if (ret) { - mutex_unlock(&root->fs_info->tree_log_mutex); - mutex_unlock(&root->fs_info->reloc_mutex); - goto cleanup_transaction; - } + BUG_ON(ret); btrfs_prepare_extent_commit(trans, root); @@ -1450,18 +1336,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, wake_up(&root->fs_info->transaction_wait); ret = btrfs_write_and_wait_transaction(trans, root); - if (ret) { - btrfs_error(root->fs_info, ret, - "Error while writing out transaction."); - mutex_unlock(&root->fs_info->tree_log_mutex); - goto cleanup_transaction; - } - - ret = write_ctree_super(trans, root, 0); - if (ret) { - mutex_unlock(&root->fs_info->tree_log_mutex); - goto cleanup_transaction; - } + BUG_ON(ret); + write_ctree_super(trans, root, 0); /* * the super is written, we can safely allow the tree-loggers @@ -1497,15 +1373,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, btrfs_run_delayed_iputs(root); return ret; - -cleanup_transaction: - btrfs_printk(root->fs_info, "Skipping commit of aborted transaction.\n"); -// WARN_ON(1); - if (current->journal_info == trans) - current->journal_info = NULL; - cleanup_transaction(trans, root); - - return ret; } /* @@ -1521,8 +1388,6 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root) spin_unlock(&fs_info->trans_lock); while (!list_empty(&list)) { - int ret; - root = list_entry(list.next, struct btrfs_root, root_list); list_del(&root->root_list); @@ -1530,10 +1395,9 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root) if (btrfs_header_backref_rev(root->node) < BTRFS_MIXED_BACKREF_REV) - ret = btrfs_drop_snapshot(root, NULL, 0, 0); + btrfs_drop_snapshot(root, NULL, 0, 0); else - ret =btrfs_drop_snapshot(root, NULL, 1, 0); - BUG_ON(ret < 0); + btrfs_drop_snapshot(root, NULL, 1, 0); } return 0; } diff --git a/trunk/fs/btrfs/transaction.h b/trunk/fs/btrfs/transaction.h index fe27379e368b..02564e6230ac 100644 --- a/trunk/fs/btrfs/transaction.h +++ b/trunk/fs/btrfs/transaction.h @@ -43,7 +43,6 @@ struct btrfs_transaction { wait_queue_head_t commit_wait; struct list_head pending_snapshots; struct btrfs_delayed_ref_root delayed_refs; - int aborted; }; struct btrfs_trans_handle { @@ -56,7 +55,6 @@ struct btrfs_trans_handle { struct btrfs_transaction *transaction; struct btrfs_block_rsv *block_rsv; struct btrfs_block_rsv *orig_rsv; - int aborted; }; struct btrfs_pending_snapshot { @@ -116,5 +114,4 @@ int btrfs_wait_marked_extents(struct btrfs_root *root, struct extent_io_tree *dirty_pages, int mark); int btrfs_transaction_blocked(struct btrfs_fs_info *info); int btrfs_transaction_in_commit(struct btrfs_fs_info *info); -void put_transaction(struct btrfs_transaction *transaction); #endif diff --git a/trunk/fs/btrfs/tree-log.c b/trunk/fs/btrfs/tree-log.c index eb1ae908582c..966cc74f5d6c 100644 --- a/trunk/fs/btrfs/tree-log.c +++ b/trunk/fs/btrfs/tree-log.c @@ -212,13 +212,14 @@ int btrfs_pin_log_trans(struct btrfs_root *root) * indicate we're done making changes to the log tree * and wake up anyone waiting to do a sync */ -void btrfs_end_log_trans(struct btrfs_root *root) +int btrfs_end_log_trans(struct btrfs_root *root) { if (atomic_dec_and_test(&root->log_writers)) { smp_mb(); if (waitqueue_active(&root->log_writer_wait)) wake_up(&root->log_writer_wait); } + return 0; } @@ -279,7 +280,7 @@ static int process_one_buffer(struct btrfs_root *log, log->fs_info->extent_root, eb->start, eb->len); - if (btrfs_buffer_uptodate(eb, gen, 0)) { + if (btrfs_buffer_uptodate(eb, gen)) { if (wc->write) btrfs_write_tree_block(eb); if (wc->wait) @@ -377,11 +378,12 @@ static noinline int overwrite_item(struct btrfs_trans_handle *trans, u32 found_size; found_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]); - if (found_size > item_size) + if (found_size > item_size) { btrfs_truncate_item(trans, root, path, item_size, 1); - else if (found_size < item_size) - btrfs_extend_item(trans, root, path, - item_size - found_size); + } else if (found_size < item_size) { + ret = btrfs_extend_item(trans, root, path, + item_size - found_size); + } } else if (ret) { return ret; } @@ -1761,7 +1763,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, BTRFS_TREE_LOG_OBJECTID); ret = btrfs_free_and_pin_reserved_extent(root, bytenr, blocksize); - BUG_ON(ret); /* -ENOMEM or logic errors */ + BUG_ON(ret); } free_extent_buffer(next); continue; @@ -1869,26 +1871,20 @@ static int walk_log_tree(struct btrfs_trans_handle *trans, wret = walk_down_log_tree(trans, log, path, &level, wc); if (wret > 0) break; - if (wret < 0) { + if (wret < 0) ret = wret; - goto out; - } wret = walk_up_log_tree(trans, log, path, &level, wc); if (wret > 0) break; - if (wret < 0) { + if (wret < 0) ret = wret; - goto out; - } } /* was the root node processed? if not, catch it here */ if (path->nodes[orig_level]) { - ret = wc->process_func(log, path->nodes[orig_level], wc, + wc->process_func(log, path->nodes[orig_level], wc, btrfs_header_generation(path->nodes[orig_level])); - if (ret) - goto out; if (wc->free) { struct extent_buffer *next; @@ -1904,11 +1900,10 @@ static int walk_log_tree(struct btrfs_trans_handle *trans, BTRFS_TREE_LOG_OBJECTID); ret = btrfs_free_and_pin_reserved_extent(log, next->start, next->len); - BUG_ON(ret); /* -ENOMEM or logic errors */ + BUG_ON(ret); } } -out: for (i = 0; i <= orig_level; i++) { if (path->nodes[i]) { free_extent_buffer(path->nodes[i]); @@ -1968,8 +1963,8 @@ static int wait_log_commit(struct btrfs_trans_handle *trans, return 0; } -static void wait_for_writer(struct btrfs_trans_handle *trans, - struct btrfs_root *root) +static int wait_for_writer(struct btrfs_trans_handle *trans, + struct btrfs_root *root) { DEFINE_WAIT(wait); while (root->fs_info->last_trans_log_full_commit != @@ -1983,6 +1978,7 @@ static void wait_for_writer(struct btrfs_trans_handle *trans, mutex_lock(&root->log_mutex); finish_wait(&root->log_writer_wait, &wait); } + return 0; } /* @@ -2050,11 +2046,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, * wait for them until later. */ ret = btrfs_write_marked_extents(log, &log->dirty_log_pages, mark); - if (ret) { - btrfs_abort_transaction(trans, root, ret); - mutex_unlock(&root->log_mutex); - goto out; - } + BUG_ON(ret); btrfs_set_root_node(&log->root_item, log->node); @@ -2085,11 +2077,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, } if (ret) { - if (ret != -ENOSPC) { - btrfs_abort_transaction(trans, root, ret); - mutex_unlock(&log_root_tree->log_mutex); - goto out; - } + BUG_ON(ret != -ENOSPC); root->fs_info->last_trans_log_full_commit = trans->transid; btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); mutex_unlock(&log_root_tree->log_mutex); @@ -2129,11 +2117,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, ret = btrfs_write_and_wait_marked_extents(log_root_tree, &log_root_tree->dirty_log_pages, EXTENT_DIRTY | EXTENT_NEW); - if (ret) { - btrfs_abort_transaction(trans, root, ret); - mutex_unlock(&log_root_tree->log_mutex); - goto out_wake_log_root; - } + BUG_ON(ret); btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); btrfs_set_super_log_root(root->fs_info->super_for_commit, @@ -2342,9 +2326,7 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, if (ret == -ENOSPC) { root->fs_info->last_trans_log_full_commit = trans->transid; ret = 0; - } else if (ret < 0) - btrfs_abort_transaction(trans, root, ret); - + } btrfs_end_log_trans(root); return err; @@ -2375,8 +2357,7 @@ int btrfs_del_inode_ref_in_log(struct btrfs_trans_handle *trans, if (ret == -ENOSPC) { root->fs_info->last_trans_log_full_commit = trans->transid; ret = 0; - } else if (ret < 0 && ret != -ENOENT) - btrfs_abort_transaction(trans, root, ret); + } btrfs_end_log_trans(root); return ret; @@ -3188,20 +3169,13 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree) fs_info->log_root_recovering = 1; trans = btrfs_start_transaction(fs_info->tree_root, 0); - if (IS_ERR(trans)) { - ret = PTR_ERR(trans); - goto error; - } + BUG_ON(IS_ERR(trans)); wc.trans = trans; wc.pin = 1; ret = walk_log_tree(trans, log_root_tree, &wc); - if (ret) { - btrfs_error(fs_info, ret, "Failed to pin buffers while " - "recovering log root tree."); - goto error; - } + BUG_ON(ret); again: key.objectid = BTRFS_TREE_LOG_OBJECTID; @@ -3210,12 +3184,8 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree) while (1) { ret = btrfs_search_slot(NULL, log_root_tree, &key, path, 0, 0); - - if (ret < 0) { - btrfs_error(fs_info, ret, - "Couldn't find tree log root."); - goto error; - } + if (ret < 0) + break; if (ret > 0) { if (path->slots[0] == 0) break; @@ -3229,24 +3199,14 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree) log = btrfs_read_fs_root_no_radix(log_root_tree, &found_key); - if (IS_ERR(log)) { - ret = PTR_ERR(log); - btrfs_error(fs_info, ret, - "Couldn't read tree log root."); - goto error; - } + BUG_ON(IS_ERR(log)); tmp_key.objectid = found_key.offset; tmp_key.type = BTRFS_ROOT_ITEM_KEY; tmp_key.offset = (u64)-1; wc.replay_dest = btrfs_read_fs_root_no_name(fs_info, &tmp_key); - if (IS_ERR(wc.replay_dest)) { - ret = PTR_ERR(wc.replay_dest); - btrfs_error(fs_info, ret, "Couldn't read target root " - "for tree log recovery."); - goto error; - } + BUG_ON(IS_ERR_OR_NULL(wc.replay_dest)); wc.replay_dest->log_root = log; btrfs_record_root_in_trans(trans, wc.replay_dest); @@ -3294,10 +3254,6 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree) kfree(log_root_tree); return 0; - -error: - btrfs_free_path(path); - return ret; } /* diff --git a/trunk/fs/btrfs/tree-log.h b/trunk/fs/btrfs/tree-log.h index 862ac813f6b8..2270ac58d746 100644 --- a/trunk/fs/btrfs/tree-log.h +++ b/trunk/fs/btrfs/tree-log.h @@ -38,7 +38,7 @@ int btrfs_del_inode_ref_in_log(struct btrfs_trans_handle *trans, struct btrfs_root *root, const char *name, int name_len, struct inode *inode, u64 dirid); -void btrfs_end_log_trans(struct btrfs_root *root); +int btrfs_end_log_trans(struct btrfs_root *root); int btrfs_pin_log_trans(struct btrfs_root *root); int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct inode *inode, diff --git a/trunk/fs/btrfs/volumes.c b/trunk/fs/btrfs/volumes.c index 1411b99555a4..ef41f285a475 100644 --- a/trunk/fs/btrfs/volumes.c +++ b/trunk/fs/btrfs/volumes.c @@ -67,7 +67,7 @@ static void free_fs_devices(struct btrfs_fs_devices *fs_devices) kfree(fs_devices); } -void btrfs_cleanup_fs_uuids(void) +int btrfs_cleanup_fs_uuids(void) { struct btrfs_fs_devices *fs_devices; @@ -77,6 +77,7 @@ void btrfs_cleanup_fs_uuids(void) list_del(&fs_devices->list); free_fs_devices(fs_devices); } + return 0; } static noinline struct btrfs_device *__find_device(struct list_head *head, @@ -129,7 +130,7 @@ static void requeue_list(struct btrfs_pending_bios *pending_bios, * the list if the block device is congested. This way, multiple devices * can make progress from a single worker thread. */ -static noinline void run_scheduled_bios(struct btrfs_device *device) +static noinline int run_scheduled_bios(struct btrfs_device *device) { struct bio *pending; struct backing_dev_info *bdi; @@ -315,6 +316,7 @@ static noinline void run_scheduled_bios(struct btrfs_device *device) done: blk_finish_plug(&plug); + return 0; } static void pending_bios_fn(struct btrfs_work *work) @@ -453,7 +455,7 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig) return ERR_PTR(-ENOMEM); } -void btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) +int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) { struct btrfs_device *device, *next; @@ -501,6 +503,7 @@ void btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) fs_devices->latest_trans = latest_transid; mutex_unlock(&uuid_mutex); + return 0; } static void __free_device(struct work_struct *work) @@ -549,10 +552,10 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) fs_devices->num_can_discard--; new_device = kmalloc(sizeof(*new_device), GFP_NOFS); - BUG_ON(!new_device); /* -ENOMEM */ + BUG_ON(!new_device); memcpy(new_device, device, sizeof(*new_device)); new_device->name = kstrdup(device->name, GFP_NOFS); - BUG_ON(device->name && !new_device->name); /* -ENOMEM */ + BUG_ON(device->name && !new_device->name); new_device->bdev = NULL; new_device->writeable = 0; new_device->in_fs_metadata = 0; @@ -622,8 +625,6 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, printk(KERN_INFO "open %s failed\n", device->name); goto error; } - filemap_write_and_wait(bdev->bd_inode->i_mapping); - invalidate_bdev(bdev); set_blocksize(bdev, 4096); bh = btrfs_read_dev_super(bdev); @@ -1038,10 +1039,8 @@ static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans, leaf = path->nodes[0]; extent = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dev_extent); - } else { - btrfs_error(root->fs_info, ret, "Slot search failed"); - goto out; } + BUG_ON(ret); if (device->bytes_used > 0) { u64 len = btrfs_dev_extent_length(leaf, extent); @@ -1051,10 +1050,7 @@ static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans, spin_unlock(&root->fs_info->free_chunk_lock); } ret = btrfs_del_item(trans, root, path); - if (ret) { - btrfs_error(root->fs_info, ret, - "Failed to remove dev extent item"); - } + out: btrfs_free_path(path); return ret; @@ -1082,8 +1078,7 @@ int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans, key.type = BTRFS_DEV_EXTENT_KEY; ret = btrfs_insert_empty_item(trans, root, path, &key, sizeof(*extent)); - if (ret) - goto out; + BUG_ON(ret); leaf = path->nodes[0]; extent = btrfs_item_ptr(leaf, path->slots[0], @@ -1098,7 +1093,6 @@ int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans, btrfs_set_dev_extent_length(leaf, extent, num_bytes); btrfs_mark_buffer_dirty(leaf); -out: btrfs_free_path(path); return ret; } @@ -1124,7 +1118,7 @@ static noinline int find_next_chunk(struct btrfs_root *root, if (ret < 0) goto error; - BUG_ON(ret == 0); /* Corruption */ + BUG_ON(ret == 0); ret = btrfs_previous_item(root, path, 0, BTRFS_CHUNK_ITEM_KEY); if (ret) { @@ -1168,7 +1162,7 @@ static noinline int find_next_devid(struct btrfs_root *root, u64 *objectid) if (ret < 0) goto error; - BUG_ON(ret == 0); /* Corruption */ + BUG_ON(ret == 0); ret = btrfs_previous_item(root, path, BTRFS_DEV_ITEMS_OBJECTID, BTRFS_DEV_ITEM_KEY); @@ -1356,7 +1350,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) } set_blocksize(bdev, 4096); - invalidate_bdev(bdev); bh = btrfs_read_dev_super(bdev); if (!bh) { ret = -EINVAL; @@ -1603,7 +1596,7 @@ static int btrfs_finish_sprout(struct btrfs_trans_handle *trans, (unsigned long)btrfs_device_fsid(dev_item), BTRFS_UUID_SIZE); device = btrfs_find_device(root, devid, dev_uuid, fs_uuid); - BUG_ON(!device); /* Logic error */ + BUG_ON(!device); if (device->fs_devices->seeding) { btrfs_set_device_generation(leaf, dev_item, @@ -1713,7 +1706,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) if (seeding_dev) { sb->s_flags &= ~MS_RDONLY; ret = btrfs_prepare_sprout(root); - BUG_ON(ret); /* -ENOMEM */ + BUG_ON(ret); } device->fs_devices = root->fs_info->fs_devices; @@ -1751,15 +1744,11 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) if (seeding_dev) { ret = init_first_rw_device(trans, root, device); - if (ret) - goto error_trans; + BUG_ON(ret); ret = btrfs_finish_sprout(trans, root); - if (ret) - goto error_trans; + BUG_ON(ret); } else { ret = btrfs_add_device(trans, root, device); - if (ret) - goto error_trans; } /* @@ -1769,31 +1758,17 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) btrfs_clear_space_info_full(root->fs_info); unlock_chunks(root); - ret = btrfs_commit_transaction(trans, root); + btrfs_commit_transaction(trans, root); if (seeding_dev) { mutex_unlock(&uuid_mutex); up_write(&sb->s_umount); - if (ret) /* transaction commit */ - return ret; - ret = btrfs_relocate_sys_chunks(root); - if (ret < 0) - btrfs_error(root->fs_info, ret, - "Failed to relocate sys chunks after " - "device initialization. This can be fixed " - "using the \"btrfs balance\" command."); + BUG_ON(ret); } return ret; - -error_trans: - unlock_chunks(root); - btrfs_abort_transaction(trans, root, ret); - btrfs_end_transaction(trans, root); - kfree(device->name); - kfree(device); error: blkdev_put(bdev, FMODE_EXCL); if (seeding_dev) { @@ -1901,20 +1876,10 @@ static int btrfs_free_chunk(struct btrfs_trans_handle *trans, key.type = BTRFS_CHUNK_ITEM_KEY; ret = btrfs_search_slot(trans, root, &key, path, -1, 1); - if (ret < 0) - goto out; - else if (ret > 0) { /* Logic error or corruption */ - btrfs_error(root->fs_info, -ENOENT, - "Failed lookup while freeing chunk."); - ret = -ENOENT; - goto out; - } + BUG_ON(ret); ret = btrfs_del_item(trans, root, path); - if (ret < 0) - btrfs_error(root->fs_info, ret, - "Failed to delete chunk item."); -out: + btrfs_free_path(path); return ret; } @@ -2076,7 +2041,7 @@ static int btrfs_relocate_sys_chunks(struct btrfs_root *root) ret = btrfs_search_slot(NULL, chunk_root, &key, path, 0, 0); if (ret < 0) goto error; - BUG_ON(ret == 0); /* Corruption */ + BUG_ON(ret == 0); ret = btrfs_previous_item(chunk_root, path, key.objectid, key.type); @@ -2285,13 +2250,15 @@ static void unset_balance_control(struct btrfs_fs_info *fs_info) * Balance filters. Return 1 if chunk should be filtered out * (should not be balanced). */ -static int chunk_profiles_filter(u64 chunk_type, +static int chunk_profiles_filter(u64 chunk_profile, struct btrfs_balance_args *bargs) { - chunk_type = chunk_to_extended(chunk_type) & - BTRFS_EXTENDED_PROFILE_MASK; + chunk_profile &= BTRFS_BLOCK_GROUP_PROFILE_MASK; - if (bargs->profiles & chunk_type) + if (chunk_profile == 0) + chunk_profile = BTRFS_AVAIL_ALLOC_BIT_SINGLE; + + if (bargs->profiles & chunk_profile) return 0; return 1; @@ -2398,16 +2365,18 @@ static int chunk_vrange_filter(struct extent_buffer *leaf, return 1; } -static int chunk_soft_convert_filter(u64 chunk_type, +static int chunk_soft_convert_filter(u64 chunk_profile, struct btrfs_balance_args *bargs) { if (!(bargs->flags & BTRFS_BALANCE_ARGS_CONVERT)) return 0; - chunk_type = chunk_to_extended(chunk_type) & - BTRFS_EXTENDED_PROFILE_MASK; + chunk_profile &= BTRFS_BLOCK_GROUP_PROFILE_MASK; + + if (chunk_profile == 0) + chunk_profile = BTRFS_AVAIL_ALLOC_BIT_SINGLE; - if (bargs->target == chunk_type) + if (bargs->target & chunk_profile) return 1; return 0; @@ -2633,30 +2602,6 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info) return ret; } -/** - * alloc_profile_is_valid - see if a given profile is valid and reduced - * @flags: profile to validate - * @extended: if true @flags is treated as an extended profile - */ -static int alloc_profile_is_valid(u64 flags, int extended) -{ - u64 mask = (extended ? BTRFS_EXTENDED_PROFILE_MASK : - BTRFS_BLOCK_GROUP_PROFILE_MASK); - - flags &= ~BTRFS_BLOCK_GROUP_TYPE_MASK; - - /* 1) check that all other bits are zeroed */ - if (flags & ~mask) - return 0; - - /* 2) see if profile is reduced */ - if (flags == 0) - return !extended; /* "0" is valid for usual profiles */ - - /* true if exactly one bit set */ - return (flags & (flags - 1)) == 0; -} - static inline int balance_need_close(struct btrfs_fs_info *fs_info) { /* cancel requested || normal exit path */ @@ -2685,7 +2630,6 @@ int btrfs_balance(struct btrfs_balance_control *bctl, { struct btrfs_fs_info *fs_info = bctl->fs_info; u64 allowed; - int mixed = 0; int ret; if (btrfs_fs_closing(fs_info) || @@ -2695,16 +2639,13 @@ int btrfs_balance(struct btrfs_balance_control *bctl, goto out; } - allowed = btrfs_super_incompat_flags(fs_info->super_copy); - if (allowed & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) - mixed = 1; - /* * In case of mixed groups both data and meta should be picked, * and identical options should be given for both of them. */ - allowed = BTRFS_BALANCE_DATA | BTRFS_BALANCE_METADATA; - if (mixed && (bctl->flags & allowed)) { + allowed = btrfs_super_incompat_flags(fs_info->super_copy); + if ((allowed & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) && + (bctl->flags & (BTRFS_BALANCE_DATA | BTRFS_BALANCE_METADATA))) { if (!(bctl->flags & BTRFS_BALANCE_DATA) || !(bctl->flags & BTRFS_BALANCE_METADATA) || memcmp(&bctl->data, &bctl->meta, sizeof(bctl->data))) { @@ -2715,6 +2656,14 @@ int btrfs_balance(struct btrfs_balance_control *bctl, } } + /* + * Profile changing sanity checks. Skip them if a simple + * balance is requested. + */ + if (!((bctl->data.flags | bctl->sys.flags | bctl->meta.flags) & + BTRFS_BALANCE_ARGS_CONVERT)) + goto do_balance; + allowed = BTRFS_AVAIL_ALLOC_BIT_SINGLE; if (fs_info->fs_devices->num_devices == 1) allowed |= BTRFS_BLOCK_GROUP_DUP; @@ -2724,27 +2673,24 @@ int btrfs_balance(struct btrfs_balance_control *bctl, allowed |= (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10); - if ((bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT) && - (!alloc_profile_is_valid(bctl->data.target, 1) || - (bctl->data.target & ~allowed))) { + if (!profile_is_valid(bctl->data.target, 1) || + bctl->data.target & ~allowed) { printk(KERN_ERR "btrfs: unable to start balance with target " "data profile %llu\n", (unsigned long long)bctl->data.target); ret = -EINVAL; goto out; } - if ((bctl->meta.flags & BTRFS_BALANCE_ARGS_CONVERT) && - (!alloc_profile_is_valid(bctl->meta.target, 1) || - (bctl->meta.target & ~allowed))) { + if (!profile_is_valid(bctl->meta.target, 1) || + bctl->meta.target & ~allowed) { printk(KERN_ERR "btrfs: unable to start balance with target " "metadata profile %llu\n", (unsigned long long)bctl->meta.target); ret = -EINVAL; goto out; } - if ((bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) && - (!alloc_profile_is_valid(bctl->sys.target, 1) || - (bctl->sys.target & ~allowed))) { + if (!profile_is_valid(bctl->sys.target, 1) || + bctl->sys.target & ~allowed) { printk(KERN_ERR "btrfs: unable to start balance with target " "system profile %llu\n", (unsigned long long)bctl->sys.target); @@ -2752,9 +2698,7 @@ int btrfs_balance(struct btrfs_balance_control *bctl, goto out; } - /* allow dup'ed data chunks only in mixed mode */ - if (!mixed && (bctl->data.flags & BTRFS_BALANCE_ARGS_CONVERT) && - (bctl->data.target & BTRFS_BLOCK_GROUP_DUP)) { + if (bctl->data.target & BTRFS_BLOCK_GROUP_DUP) { printk(KERN_ERR "btrfs: dup for data is not allowed\n"); ret = -EINVAL; goto out; @@ -2780,6 +2724,7 @@ int btrfs_balance(struct btrfs_balance_control *bctl, } } +do_balance: ret = insert_balance_item(fs_info->tree_root, bctl); if (ret && ret != -EEXIST) goto out; @@ -3022,7 +2967,7 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size) key.offset = (u64)-1; key.type = BTRFS_DEV_EXTENT_KEY; - do { + while (1) { ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); if (ret < 0) goto done; @@ -3064,7 +3009,8 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size) goto done; if (ret == -ENOSPC) failed++; - } while (key.offset-- > 0); + key.offset -= 1; + } if (failed && !retried) { failed = 0; @@ -3182,7 +3128,11 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, int i; int j; - BUG_ON(!alloc_profile_is_valid(type, 0)); + if ((type & BTRFS_BLOCK_GROUP_RAID1) && + (type & BTRFS_BLOCK_GROUP_DUP)) { + WARN_ON(1); + type &= ~BTRFS_BLOCK_GROUP_DUP; + } if (list_empty(&fs_devices->alloc_list)) return -ENOSPC; @@ -3324,14 +3274,12 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, stripe_size = devices_info[ndevs-1].max_avail; num_stripes = ndevs * dev_stripes; - if (stripe_size * ndevs > max_chunk_size * ncopies) { + if (stripe_size * num_stripes > max_chunk_size * ncopies) { stripe_size = max_chunk_size * ncopies; - do_div(stripe_size, ndevs); + do_div(stripe_size, num_stripes); } do_div(stripe_size, dev_stripes); - - /* align to BTRFS_STRIPE_LEN */ do_div(stripe_size, BTRFS_STRIPE_LEN); stripe_size *= BTRFS_STRIPE_LEN; @@ -3380,15 +3328,13 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, write_lock(&em_tree->lock); ret = add_extent_mapping(em_tree, em); write_unlock(&em_tree->lock); + BUG_ON(ret); free_extent_map(em); - if (ret) - goto error; ret = btrfs_make_block_group(trans, extent_root, 0, type, BTRFS_FIRST_CHUNK_TREE_OBJECTID, start, num_bytes); - if (ret) - goto error; + BUG_ON(ret); for (i = 0; i < map->num_stripes; ++i) { struct btrfs_device *device; @@ -3401,10 +3347,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, info->chunk_root->root_key.objectid, BTRFS_FIRST_CHUNK_TREE_OBJECTID, start, dev_offset, stripe_size); - if (ret) { - btrfs_abort_transaction(trans, extent_root, ret); - goto error; - } + BUG_ON(ret); } kfree(devices_info); @@ -3440,8 +3383,7 @@ static int __finish_chunk_alloc(struct btrfs_trans_handle *trans, device = map->stripes[index].dev; device->bytes_used += stripe_size; ret = btrfs_update_device(trans, device); - if (ret) - goto out_free; + BUG_ON(ret); index++; } @@ -3478,19 +3420,16 @@ static int __finish_chunk_alloc(struct btrfs_trans_handle *trans, key.offset = chunk_offset; ret = btrfs_insert_item(trans, chunk_root, &key, chunk, item_size); + BUG_ON(ret); - if (ret == 0 && map->type & BTRFS_BLOCK_GROUP_SYSTEM) { - /* - * TODO: Cleanup of inserted chunk root in case of - * failure. - */ + if (map->type & BTRFS_BLOCK_GROUP_SYSTEM) { ret = btrfs_add_system_chunk(chunk_root, &key, chunk, item_size); + BUG_ON(ret); } -out_free: kfree(chunk); - return ret; + return 0; } /* @@ -3522,8 +3461,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, ret = __finish_chunk_alloc(trans, extent_root, map, chunk_offset, chunk_size, stripe_size); - if (ret) - return ret; + BUG_ON(ret); return 0; } @@ -3555,8 +3493,7 @@ static noinline int init_first_rw_device(struct btrfs_trans_handle *trans, ret = __btrfs_alloc_chunk(trans, extent_root, &map, &chunk_size, &stripe_size, chunk_offset, alloc_profile); - if (ret) - return ret; + BUG_ON(ret); sys_chunk_offset = chunk_offset + chunk_size; @@ -3567,12 +3504,10 @@ static noinline int init_first_rw_device(struct btrfs_trans_handle *trans, ret = __btrfs_alloc_chunk(trans, extent_root, &sys_map, &sys_chunk_size, &sys_stripe_size, sys_chunk_offset, alloc_profile); - if (ret) - goto abort; + BUG_ON(ret); ret = btrfs_add_device(trans, fs_info->chunk_root, device); - if (ret) - goto abort; + BUG_ON(ret); /* * Modifying chunk tree needs allocating new blocks from both @@ -3582,20 +3517,13 @@ static noinline int init_first_rw_device(struct btrfs_trans_handle *trans, */ ret = __finish_chunk_alloc(trans, extent_root, map, chunk_offset, chunk_size, stripe_size); - if (ret) - goto abort; + BUG_ON(ret); ret = __finish_chunk_alloc(trans, extent_root, sys_map, sys_chunk_offset, sys_chunk_size, sys_stripe_size); - if (ret) - goto abort; - + BUG_ON(ret); return 0; - -abort: - btrfs_abort_transaction(trans, root, ret); - return ret; } int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset) @@ -3807,11 +3735,10 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, else if (mirror_num) stripe_index += mirror_num - 1; else { - int old_stripe_index = stripe_index; stripe_index = find_live_mirror(map, stripe_index, map->sub_stripes, stripe_index + current->pid % map->sub_stripes); - mirror_num = stripe_index - old_stripe_index + 1; + mirror_num = stripe_index + 1; } } else { /* @@ -3836,7 +3763,6 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, int sub_stripes = 0; u64 stripes_per_dev = 0; u32 remaining_stripes = 0; - u32 last_stripe = 0; if (map->type & (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID10)) { @@ -3850,8 +3776,6 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, stripe_nr_orig, factor, &remaining_stripes); - div_u64_rem(stripe_nr_end - 1, factor, &last_stripe); - last_stripe *= sub_stripes; } for (i = 0; i < num_stripes; i++) { @@ -3864,29 +3788,16 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, BTRFS_BLOCK_GROUP_RAID10)) { bbio->stripes[i].length = stripes_per_dev * map->stripe_len; - if (i / sub_stripes < remaining_stripes) bbio->stripes[i].length += map->stripe_len; - - /* - * Special for the first stripe and - * the last stripe: - * - * |-------|...|-------| - * |----------| - * off end_off - */ if (i < sub_stripes) bbio->stripes[i].length -= stripe_offset; - - if (stripe_index >= last_stripe && - stripe_index <= (last_stripe + - sub_stripes - 1)) + if ((i / sub_stripes + 1) % + sub_stripes == remaining_stripes) bbio->stripes[i].length -= stripe_end_offset; - if (i == sub_stripes - 1) stripe_offset = 0; } else @@ -3963,7 +3874,7 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, do_div(length, map->num_stripes); buf = kzalloc(sizeof(u64) * map->num_stripes, GFP_NOFS); - BUG_ON(!buf); /* -ENOMEM */ + BUG_ON(!buf); for (i = 0; i < map->num_stripes; i++) { if (devid && map->stripes[i].dev->devid != devid) @@ -4056,7 +3967,7 @@ struct async_sched { * This will add one bio to the pending list for a device and make sure * the work struct is scheduled. */ -static noinline void schedule_bio(struct btrfs_root *root, +static noinline int schedule_bio(struct btrfs_root *root, struct btrfs_device *device, int rw, struct bio *bio) { @@ -4068,7 +3979,7 @@ static noinline void schedule_bio(struct btrfs_root *root, bio_get(bio); btrfsic_submit_bio(rw, bio); bio_put(bio); - return; + return 0; } /* @@ -4102,6 +4013,7 @@ static noinline void schedule_bio(struct btrfs_root *root, if (should_queue) btrfs_queue_worker(&root->fs_info->submit_workers, &device->work); + return 0; } int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, @@ -4124,8 +4036,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, ret = btrfs_map_block(map_tree, rw, logical, &map_length, &bbio, mirror_num); - if (ret) /* -ENOMEM */ - return ret; + BUG_ON(ret); total_devs = bbio->num_stripes; if (map_length < length) { @@ -4144,7 +4055,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, while (dev_nr < total_devs) { if (dev_nr < total_devs - 1) { bio = bio_clone(first_bio, GFP_NOFS); - BUG_ON(!bio); /* -ENOMEM */ + BUG_ON(!bio); } else { bio = first_bio; } @@ -4298,13 +4209,13 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, write_lock(&map_tree->map_tree.lock); ret = add_extent_mapping(&map_tree->map_tree, em); write_unlock(&map_tree->map_tree.lock); - BUG_ON(ret); /* Tree corruption */ + BUG_ON(ret); free_extent_map(em); return 0; } -static void fill_device_from_item(struct extent_buffer *leaf, +static int fill_device_from_item(struct extent_buffer *leaf, struct btrfs_dev_item *dev_item, struct btrfs_device *device) { @@ -4321,6 +4232,8 @@ static void fill_device_from_item(struct extent_buffer *leaf, ptr = (unsigned long)btrfs_device_uuid(dev_item); read_extent_buffer(leaf, device->uuid, ptr, BTRFS_UUID_SIZE); + + return 0; } static int open_seed_devices(struct btrfs_root *root, u8 *fsid) @@ -4353,10 +4266,8 @@ static int open_seed_devices(struct btrfs_root *root, u8 *fsid) ret = __btrfs_open_devices(fs_devices, FMODE_READ, root->fs_info->bdev_holder); - if (ret) { - free_fs_devices(fs_devices); + if (ret) goto out; - } if (!fs_devices->seeding) { __btrfs_close_devices(fs_devices); @@ -4473,7 +4384,7 @@ int btrfs_read_sys_array(struct btrfs_root *root) * to silence the warning eg. on PowerPC 64. */ if (PAGE_CACHE_SIZE > BTRFS_SUPER_INFO_SIZE) - SetPageUptodate(sb->pages[0]); + SetPageUptodate(sb->first_page); write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE); array_size = btrfs_super_sys_array_size(super_copy); diff --git a/trunk/fs/btrfs/volumes.h b/trunk/fs/btrfs/volumes.h index bb6b03f97aaa..19ac95048b88 100644 --- a/trunk/fs/btrfs/volumes.h +++ b/trunk/fs/btrfs/volumes.h @@ -260,12 +260,12 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices, int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, struct btrfs_fs_devices **fs_devices_ret); int btrfs_close_devices(struct btrfs_fs_devices *fs_devices); -void btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices); +int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices); int btrfs_add_device(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_device *device); int btrfs_rm_device(struct btrfs_root *root, char *device_path); -void btrfs_cleanup_fs_uuids(void); +int btrfs_cleanup_fs_uuids(void); int btrfs_num_copies(struct btrfs_mapping_tree *map_tree, u64 logical, u64 len); int btrfs_grow_device(struct btrfs_trans_handle *trans, struct btrfs_device *device, u64 new_size); diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index 351e18ea2e53..36d66653b931 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -985,6 +985,7 @@ grow_dev_page(struct block_device *bdev, sector_t block, return page; failed: + BUG(); unlock_page(page); page_cache_release(page); return NULL; diff --git a/trunk/fs/cifs/cifs_debug.c b/trunk/fs/cifs/cifs_debug.c index 270464629416..573b899b5a5d 100644 --- a/trunk/fs/cifs/cifs_debug.c +++ b/trunk/fs/cifs/cifs_debug.c @@ -58,16 +58,15 @@ cifs_dump_mem(char *label, void *data, int length) } #ifdef CONFIG_CIFS_DEBUG2 -void cifs_dump_detail(void *buf) +void cifs_dump_detail(struct smb_hdr *smb) { - struct smb_hdr *smb = (struct smb_hdr *)buf; - cERROR(1, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d", smb->Command, smb->Status.CifsError, smb->Flags, smb->Flags2, smb->Mid, smb->Pid); cERROR(1, "smb buf %p len %d", smb, smbCalcSize(smb)); } + void cifs_dump_mids(struct TCP_Server_Info *server) { struct list_head *tmp; @@ -80,15 +79,15 @@ void cifs_dump_mids(struct TCP_Server_Info *server) spin_lock(&GlobalMid_Lock); list_for_each(tmp, &server->pending_mid_q) { mid_entry = list_entry(tmp, struct mid_q_entry, qhead); - cERROR(1, "State: %d Cmd: %d Pid: %d Cbdata: %p Mid %llu", - mid_entry->mid_state, - le16_to_cpu(mid_entry->command), + cERROR(1, "State: %d Cmd: %d Pid: %d Cbdata: %p Mid %d", + mid_entry->midState, + (int)mid_entry->command, mid_entry->pid, mid_entry->callback_data, mid_entry->mid); #ifdef CONFIG_CIFS_STATS2 cERROR(1, "IsLarge: %d buf: %p time rcv: %ld now: %ld", - mid_entry->large_buf, + mid_entry->largeBuf, mid_entry->resp_buf, mid_entry->when_received, jiffies); @@ -218,12 +217,12 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) mid_entry = list_entry(tmp3, struct mid_q_entry, qhead); seq_printf(m, "\tState: %d com: %d pid:" - " %d cbdata: %p mid %llu\n", - mid_entry->mid_state, - le16_to_cpu(mid_entry->command), - mid_entry->pid, - mid_entry->callback_data, - mid_entry->mid); + " %d cbdata: %p mid %d\n", + mid_entry->midState, + (int)mid_entry->command, + mid_entry->pid, + mid_entry->callback_data, + mid_entry->mid); } spin_unlock(&GlobalMid_Lock); } @@ -418,6 +417,7 @@ static const struct file_operations cifs_stats_proc_fops = { static struct proc_dir_entry *proc_fs_cifs; static const struct file_operations cifsFYI_proc_fops; +static const struct file_operations cifs_oplock_proc_fops; static const struct file_operations cifs_lookup_cache_proc_fops; static const struct file_operations traceSMB_proc_fops; static const struct file_operations cifs_multiuser_mount_proc_fops; @@ -438,6 +438,7 @@ cifs_proc_init(void) #endif /* STATS */ proc_create("cifsFYI", 0, proc_fs_cifs, &cifsFYI_proc_fops); proc_create("traceSMB", 0, proc_fs_cifs, &traceSMB_proc_fops); + proc_create("OplockEnabled", 0, proc_fs_cifs, &cifs_oplock_proc_fops); proc_create("LinuxExtensionsEnabled", 0, proc_fs_cifs, &cifs_linux_ext_proc_fops); proc_create("MultiuserMount", 0, proc_fs_cifs, @@ -461,6 +462,7 @@ cifs_proc_clean(void) remove_proc_entry("Stats", proc_fs_cifs); #endif remove_proc_entry("MultiuserMount", proc_fs_cifs); + remove_proc_entry("OplockEnabled", proc_fs_cifs); remove_proc_entry("SecurityFlags", proc_fs_cifs); remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs); remove_proc_entry("LookupCacheEnabled", proc_fs_cifs); @@ -506,6 +508,46 @@ static const struct file_operations cifsFYI_proc_fops = { .write = cifsFYI_proc_write, }; +static int cifs_oplock_proc_show(struct seq_file *m, void *v) +{ + seq_printf(m, "%d\n", enable_oplocks); + return 0; +} + +static int cifs_oplock_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, cifs_oplock_proc_show, NULL); +} + +static ssize_t cifs_oplock_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *ppos) +{ + char c; + int rc; + + printk(KERN_WARNING "CIFS: The /proc/fs/cifs/OplockEnabled interface " + "will be removed in kernel version 3.4. Please migrate to " + "using the 'enable_oplocks' module parameter in cifs.ko.\n"); + rc = get_user(c, buffer); + if (rc) + return rc; + if (c == '0' || c == 'n' || c == 'N') + enable_oplocks = false; + else if (c == '1' || c == 'y' || c == 'Y') + enable_oplocks = true; + + return count; +} + +static const struct file_operations cifs_oplock_proc_fops = { + .owner = THIS_MODULE, + .open = cifs_oplock_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = cifs_oplock_proc_write, +}; + static int cifs_linux_ext_proc_show(struct seq_file *m, void *v) { seq_printf(m, "%d\n", linuxExtEnabled); diff --git a/trunk/fs/cifs/cifs_debug.h b/trunk/fs/cifs/cifs_debug.h index 566e0ae8dc2c..8942b28cf807 100644 --- a/trunk/fs/cifs/cifs_debug.h +++ b/trunk/fs/cifs/cifs_debug.h @@ -26,13 +26,13 @@ void cifs_dump_mem(char *label, void *data, int length); #ifdef CONFIG_CIFS_DEBUG2 #define DBG2 2 -void cifs_dump_detail(void *); +void cifs_dump_detail(struct smb_hdr *); void cifs_dump_mids(struct TCP_Server_Info *); #else #define DBG2 0 #endif extern int traceSMB; /* flag which enables the function below */ -void dump_smb(void *, int); +void dump_smb(struct smb_hdr *, int); #define CIFS_INFO 0x01 #define CIFS_RC 0x02 #define CIFS_TIMER 0x04 diff --git a/trunk/fs/cifs/cifsfs.c b/trunk/fs/cifs/cifsfs.c index ca6a3796a33b..eee522c56ef0 100644 --- a/trunk/fs/cifs/cifsfs.c +++ b/trunk/fs/cifs/cifsfs.c @@ -85,8 +85,6 @@ extern mempool_t *cifs_sm_req_poolp; extern mempool_t *cifs_req_poolp; extern mempool_t *cifs_mid_poolp; -struct workqueue_struct *cifsiod_wq; - static int cifs_read_super(struct super_block *sb) { @@ -370,13 +368,13 @@ cifs_show_options(struct seq_file *s, struct dentry *root) (int)(srcaddr->sa_family)); } - seq_printf(s, ",uid=%u", cifs_sb->mnt_uid); + seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) seq_printf(s, ",forceuid"); else seq_printf(s, ",noforceuid"); - seq_printf(s, ",gid=%u", cifs_sb->mnt_gid); + seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) seq_printf(s, ",forcegid"); else @@ -434,15 +432,11 @@ cifs_show_options(struct seq_file *s, struct dentry *root) seq_printf(s, ",noperm"); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) seq_printf(s, ",strictcache"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) - seq_printf(s, ",backupuid=%u", cifs_sb->mnt_backupuid); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) - seq_printf(s, ",backupgid=%u", cifs_sb->mnt_backupgid); - seq_printf(s, ",rsize=%u", cifs_sb->rsize); - seq_printf(s, ",wsize=%u", cifs_sb->wsize); + seq_printf(s, ",rsize=%d", cifs_sb->rsize); + seq_printf(s, ",wsize=%d", cifs_sb->wsize); /* convert actimeo and display it in seconds */ - seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); + seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); return 0; } @@ -1117,15 +1111,9 @@ init_cifs(void) cFYI(1, "cifs_max_pending set to max of %u", CIFS_MAX_REQ); } - cifsiod_wq = alloc_workqueue("cifsiod", WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); - if (!cifsiod_wq) { - rc = -ENOMEM; - goto out_clean_proc; - } - rc = cifs_fscache_register(); if (rc) - goto out_destroy_wq; + goto out_clean_proc; rc = cifs_init_inodecache(); if (rc) @@ -1173,8 +1161,6 @@ init_cifs(void) cifs_destroy_inodecache(); out_unreg_fscache: cifs_fscache_unregister(); -out_destroy_wq: - destroy_workqueue(cifsiod_wq); out_clean_proc: cifs_proc_clean(); return rc; @@ -1197,7 +1183,6 @@ exit_cifs(void) cifs_destroy_mids(); cifs_destroy_inodecache(); cifs_fscache_unregister(); - destroy_workqueue(cifsiod_wq); cifs_proc_clean(); } diff --git a/trunk/fs/cifs/cifsfs.h b/trunk/fs/cifs/cifsfs.h index 65365358c976..fe5ecf1b422a 100644 --- a/trunk/fs/cifs/cifsfs.h +++ b/trunk/fs/cifs/cifsfs.h @@ -125,5 +125,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); extern const struct export_operations cifs_export_ops; #endif /* CONFIG_CIFS_NFSD_EXPORT */ -#define CIFS_VERSION "1.78" +#define CIFS_VERSION "1.76" #endif /* _CIFSFS_H */ diff --git a/trunk/fs/cifs/cifsglob.h b/trunk/fs/cifs/cifsglob.h index 4ff6313f0a91..339ebe3ebc0d 100644 --- a/trunk/fs/cifs/cifsglob.h +++ b/trunk/fs/cifs/cifsglob.h @@ -230,12 +230,6 @@ struct cifs_mnt_data { int flags; }; -static inline unsigned int -get_rfc1002_length(void *buf) -{ - return be32_to_cpu(*((__be32 *)buf)); -} - struct TCP_Server_Info { struct list_head tcp_ses_list; struct list_head smb_ses_list; @@ -282,7 +276,7 @@ struct TCP_Server_Info { vcnumbers */ int capabilities; /* allow selective disabling of caps by smb sess */ int timeAdj; /* Adjust for difference in server time zone in sec */ - __u64 CurrentMid; /* multiplex id - rotating counter */ + __u16 CurrentMid; /* multiplex id - rotating counter */ char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlm, ntlmv2 etc */ /* 16th byte of RFC1001 workstation name is always null */ char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; @@ -341,18 +335,6 @@ has_credits(struct TCP_Server_Info *server, int *credits) return num > 0; } -static inline size_t -header_size(void) -{ - return sizeof(struct smb_hdr); -} - -static inline size_t -max_header_size(void) -{ - return MAX_CIFS_HDR_SIZE; -} - /* * Macros to allow the TCP_Server_Info->net field and related code to drop out * when CONFIG_NET_NS isn't set. @@ -601,11 +583,9 @@ struct cifs_io_parms { * Take a reference on the file private data. Must be called with * cifs_file_list_lock held. */ -static inline -struct cifsFileInfo *cifsFileInfo_get(struct cifsFileInfo *cifs_file) +static inline void cifsFileInfo_get(struct cifsFileInfo *cifs_file) { ++cifs_file->count; - return cifs_file; } void cifsFileInfo_put(struct cifsFileInfo *cifs_file); @@ -626,7 +606,7 @@ struct cifsInodeInfo { bool delete_pending; /* DELETE_ON_CLOSE is set */ bool invalid_mapping; /* pagecache is invalid */ unsigned long time; /* jiffies of last update of inode */ - u64 server_eof; /* current file size on server -- protected by i_lock */ + u64 server_eof; /* current file size on server */ u64 uniqueid; /* server inode number */ u64 createtime; /* creation time on server */ #ifdef CONFIG_CIFS_FSCACHE @@ -733,8 +713,8 @@ typedef void (mid_callback_t)(struct mid_q_entry *mid); /* one of these for every pending CIFS request to the server */ struct mid_q_entry { struct list_head qhead; /* mids waiting on reply from this server */ - __u64 mid; /* multiplex id */ - __u32 pid; /* process id */ + __u16 mid; /* multiplex id */ + __u16 pid; /* process id */ __u32 sequence_number; /* for CIFS signing */ unsigned long when_alloc; /* when mid was created */ #ifdef CONFIG_CIFS_STATS2 @@ -744,10 +724,10 @@ struct mid_q_entry { mid_receive_t *receive; /* call receive callback */ mid_callback_t *callback; /* call completion callback */ void *callback_data; /* general purpose pointer for callback */ - void *resp_buf; /* pointer to received SMB header */ - int mid_state; /* wish this were enum but can not pass to wait_event */ - __le16 command; /* smb command code */ - bool large_buf:1; /* if valid response, is pointer to large buf */ + struct smb_hdr *resp_buf; /* pointer to received SMB header */ + int midState; /* wish this were enum but can not pass to wait_event */ + __u8 command; /* smb command code */ + bool largeBuf:1; /* if valid response, is pointer to large buf */ bool multiRsp:1; /* multiple trans2 responses for one request */ bool multiEnd:1; /* both received */ }; @@ -1072,6 +1052,5 @@ GLOBAL_EXTERN spinlock_t gidsidlock; void cifs_oplock_break(struct work_struct *work); extern const struct slow_work_ops cifs_oplock_break_ops; -extern struct workqueue_struct *cifsiod_wq; #endif /* _CIFS_GLOB_H */ diff --git a/trunk/fs/cifs/cifsproto.h b/trunk/fs/cifs/cifsproto.h index 96192c1e380a..503e73d8bdb7 100644 --- a/trunk/fs/cifs/cifsproto.h +++ b/trunk/fs/cifs/cifsproto.h @@ -77,7 +77,7 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *, struct smb_hdr * /* out */ , int * /* bytes returned */ , const int long_op); extern int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses, - char *in_buf, int flags); + struct smb_hdr *in_buf, int flags); extern int cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server, bool log_error); extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *, @@ -91,8 +91,9 @@ extern int SendReceiveBlockingLock(const unsigned int xid, extern void cifs_add_credits(struct TCP_Server_Info *server, const unsigned int add); extern void cifs_set_credits(struct TCP_Server_Info *server, const int val); -extern int checkSMB(char *buf, unsigned int length); -extern bool is_valid_oplock_break(char *, struct TCP_Server_Info *); +extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length); +extern bool is_valid_oplock_break(struct smb_hdr *smb, + struct TCP_Server_Info *); extern bool backup_cred(struct cifs_sb_info *); extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, @@ -106,7 +107,7 @@ extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len); extern int cifs_set_port(struct sockaddr *addr, const unsigned short int port); extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len, const unsigned short int port); -extern int map_smb_to_linux_error(char *buf, bool logErr); +extern int map_smb_to_linux_error(struct smb_hdr *smb, bool logErr); extern void header_assemble(struct smb_hdr *, char /* command */ , const struct cifs_tcon *, int /* length of fixed section (word count) in two byte units */); @@ -115,7 +116,7 @@ extern int small_smb_init_no_tc(const int smb_cmd, const int wct, void **request_buf); extern int CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses, const struct nls_table *nls_cp); -extern __u64 GetNextMid(struct TCP_Server_Info *server); +extern __u16 GetNextMid(struct TCP_Server_Info *server); extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); extern u64 cifs_UnixTimeToNT(struct timespec); extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, @@ -483,25 +484,18 @@ int cifs_async_readv(struct cifs_readdata *rdata); /* asynchronous write support */ struct cifs_writedata { struct kref refcount; - struct list_head list; - struct completion done; enum writeback_sync_modes sync_mode; struct work_struct work; struct cifsFileInfo *cfile; __u64 offset; - pid_t pid; unsigned int bytes; int result; - void (*marshal_iov) (struct kvec *iov, - struct cifs_writedata *wdata); unsigned int nr_pages; struct page *pages[1]; }; int cifs_async_writev(struct cifs_writedata *wdata); -void cifs_writev_complete(struct work_struct *work); -struct cifs_writedata *cifs_writedata_alloc(unsigned int nr_pages, - work_func_t complete); +struct cifs_writedata *cifs_writedata_alloc(unsigned int nr_pages); void cifs_writedata_release(struct kref *refcount); #endif /* _CIFSPROTO_H */ diff --git a/trunk/fs/cifs/cifssmb.c b/trunk/fs/cifs/cifssmb.c index da2f5446fa7a..70aac35c398f 100644 --- a/trunk/fs/cifs/cifssmb.c +++ b/trunk/fs/cifs/cifssmb.c @@ -696,7 +696,7 @@ CIFSSMBTDis(const int xid, struct cifs_tcon *tcon) if (rc) return rc; - rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0); + rc = SendReceiveNoRsp(xid, tcon->ses, smb_buffer, 0); if (rc) cFYI(1, "Tree disconnect failed %d", rc); @@ -792,7 +792,7 @@ CIFSSMBLogoff(const int xid, struct cifs_ses *ses) pSMB->hdr.Uid = ses->Suid; pSMB->AndXCommand = 0xFF; - rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0); + rc = SendReceiveNoRsp(xid, ses, (struct smb_hdr *) pSMB, 0); session_already_dead: mutex_unlock(&ses->session_mutex); @@ -1414,7 +1414,8 @@ cifs_readdata_free(struct cifs_readdata *rdata) static int cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) { - unsigned int rfclen = get_rfc1002_length(server->smallbuf); + READ_RSP *rsp = (READ_RSP *)server->smallbuf; + unsigned int rfclen = be32_to_cpu(rsp->hdr.smb_buf_length); int remaining = rfclen + 4 - server->total_read; struct cifs_readdata *rdata = mid->callback_data; @@ -1423,7 +1424,7 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) length = cifs_read_from_socket(server, server->bigbuf, min_t(unsigned int, remaining, - CIFSMaxBufSize + max_header_size())); + CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)); if (length < 0) return length; server->total_read += length; @@ -1434,40 +1435,19 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) return 0; } -static inline size_t -read_rsp_size(void) -{ - return sizeof(READ_RSP); -} - -static inline unsigned int -read_data_offset(char *buf) -{ - READ_RSP *rsp = (READ_RSP *)buf; - return le16_to_cpu(rsp->DataOffset); -} - -static inline unsigned int -read_data_length(char *buf) -{ - READ_RSP *rsp = (READ_RSP *)buf; - return (le16_to_cpu(rsp->DataLengthHigh) << 16) + - le16_to_cpu(rsp->DataLength); -} - static int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) { int length, len; unsigned int data_offset, remaining, data_len; struct cifs_readdata *rdata = mid->callback_data; - char *buf = server->smallbuf; - unsigned int buflen = get_rfc1002_length(buf) + 4; + READ_RSP *rsp = (READ_RSP *)server->smallbuf; + unsigned int rfclen = be32_to_cpu(rsp->hdr.smb_buf_length) + 4; u64 eof; pgoff_t eof_index; struct page *page, *tpage; - cFYI(1, "%s: mid=%llu offset=%llu bytes=%u", __func__, + cFYI(1, "%s: mid=%u offset=%llu bytes=%u", __func__, mid->mid, rdata->offset, rdata->bytes); /* @@ -1475,9 +1455,10 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) * can if there's not enough data. At this point, we've read down to * the Mid. */ - len = min_t(unsigned int, buflen, read_rsp_size()) - header_size() + 1; + len = min_t(unsigned int, rfclen, sizeof(*rsp)) - + sizeof(struct smb_hdr) + 1; - rdata->iov[0].iov_base = buf + header_size() - 1; + rdata->iov[0].iov_base = server->smallbuf + sizeof(struct smb_hdr) - 1; rdata->iov[0].iov_len = len; length = cifs_readv_from_socket(server, rdata->iov, 1, len); @@ -1486,7 +1467,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) server->total_read += length; /* Was the SMB read successful? */ - rdata->result = map_smb_to_linux_error(buf, false); + rdata->result = map_smb_to_linux_error(&rsp->hdr, false); if (rdata->result != 0) { cFYI(1, "%s: server returned error %d", __func__, rdata->result); @@ -1494,14 +1475,14 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) } /* Is there enough to get to the rest of the READ_RSP header? */ - if (server->total_read < read_rsp_size()) { + if (server->total_read < sizeof(READ_RSP)) { cFYI(1, "%s: server returned short header. got=%u expected=%zu", - __func__, server->total_read, read_rsp_size()); + __func__, server->total_read, sizeof(READ_RSP)); rdata->result = -EIO; return cifs_readv_discard(server, mid); } - data_offset = read_data_offset(buf) + 4; + data_offset = le16_to_cpu(rsp->DataOffset) + 4; if (data_offset < server->total_read) { /* * win2k8 sometimes sends an offset of 0 when the read @@ -1525,7 +1506,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) len = data_offset - server->total_read; if (len > 0) { /* read any junk before data into the rest of smallbuf */ - rdata->iov[0].iov_base = buf + server->total_read; + rdata->iov[0].iov_base = server->smallbuf + server->total_read; rdata->iov[0].iov_len = len; length = cifs_readv_from_socket(server, rdata->iov, 1, len); if (length < 0) @@ -1534,14 +1515,15 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) } /* set up first iov for signature check */ - rdata->iov[0].iov_base = buf; + rdata->iov[0].iov_base = server->smallbuf; rdata->iov[0].iov_len = server->total_read; cFYI(1, "0: iov_base=%p iov_len=%zu", rdata->iov[0].iov_base, rdata->iov[0].iov_len); /* how much data is in the response? */ - data_len = read_data_length(buf); - if (data_offset + data_len > buflen) { + data_len = le16_to_cpu(rsp->DataLengthHigh) << 16; + data_len += le16_to_cpu(rsp->DataLength); + if (data_offset + data_len > rfclen) { /* data_len is corrupt -- discard frame */ rdata->result = -EIO; return cifs_readv_discard(server, mid); @@ -1620,11 +1602,11 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) rdata->bytes = length; - cFYI(1, "total_read=%u buflen=%u remaining=%u", server->total_read, - buflen, remaining); + cFYI(1, "total_read=%u rfclen=%u remaining=%u", server->total_read, + rfclen, remaining); /* discard anything left over */ - if (server->total_read < buflen) + if (server->total_read < rfclen) return cifs_readv_discard(server, mid); dequeue_mid(mid, false); @@ -1665,10 +1647,10 @@ cifs_readv_callback(struct mid_q_entry *mid) struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink); struct TCP_Server_Info *server = tcon->ses->server; - cFYI(1, "%s: mid=%llu state=%d result=%d bytes=%u", __func__, - mid->mid, mid->mid_state, rdata->result, rdata->bytes); + cFYI(1, "%s: mid=%u state=%d result=%d bytes=%u", __func__, + mid->mid, mid->midState, rdata->result, rdata->bytes); - switch (mid->mid_state) { + switch (mid->midState) { case MID_RESPONSE_RECEIVED: /* result already set, check signature */ if (server->sec_mode & @@ -1689,7 +1671,7 @@ cifs_readv_callback(struct mid_q_entry *mid) rdata->result = -EIO; } - queue_work(cifsiod_wq, &rdata->work); + queue_work(system_nrt_wq, &rdata->work); DeleteMidQEntry(mid); cifs_add_credits(server, 1); } @@ -2035,7 +2017,7 @@ cifs_writev_requeue(struct cifs_writedata *wdata) kref_put(&wdata->refcount, cifs_writedata_release); } -void +static void cifs_writev_complete(struct work_struct *work) { struct cifs_writedata *wdata = container_of(work, @@ -2044,9 +2026,7 @@ cifs_writev_complete(struct work_struct *work) int i = 0; if (wdata->result == 0) { - spin_lock(&inode->i_lock); cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes); - spin_unlock(&inode->i_lock); cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink), wdata->bytes); } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN) @@ -2067,7 +2047,7 @@ cifs_writev_complete(struct work_struct *work) } struct cifs_writedata * -cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete) +cifs_writedata_alloc(unsigned int nr_pages) { struct cifs_writedata *wdata; @@ -2081,16 +2061,14 @@ cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete) wdata = kzalloc(sizeof(*wdata) + sizeof(struct page *) * (nr_pages - 1), GFP_NOFS); if (wdata != NULL) { + INIT_WORK(&wdata->work, cifs_writev_complete); kref_init(&wdata->refcount); - INIT_LIST_HEAD(&wdata->list); - init_completion(&wdata->done); - INIT_WORK(&wdata->work, complete); } return wdata; } /* - * Check the mid_state and signature on received buffer (if any), and queue the + * Check the midState and signature on received buffer (if any), and queue the * workqueue completion task. */ static void @@ -2101,7 +2079,7 @@ cifs_writev_callback(struct mid_q_entry *mid) unsigned int written; WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf; - switch (mid->mid_state) { + switch (mid->midState) { case MID_RESPONSE_RECEIVED: wdata->result = cifs_check_receive(mid, tcon->ses->server, 0); if (wdata->result != 0) @@ -2133,7 +2111,7 @@ cifs_writev_callback(struct mid_q_entry *mid) break; } - queue_work(cifsiod_wq, &wdata->work); + queue_work(system_nrt_wq, &wdata->work); DeleteMidQEntry(mid); cifs_add_credits(tcon->ses->server, 1); } @@ -2146,6 +2124,7 @@ cifs_async_writev(struct cifs_writedata *wdata) WRITE_REQ *smb = NULL; int wct; struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); + struct inode *inode = wdata->cfile->dentry->d_inode; struct kvec *iov = NULL; if (tcon->ses->capabilities & CAP_LARGE_FILES) { @@ -2169,8 +2148,8 @@ cifs_async_writev(struct cifs_writedata *wdata) goto async_writev_out; } - smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid); - smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16)); + smb->hdr.Pid = cpu_to_le16((__u16)wdata->cfile->pid); + smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->cfile->pid >> 16)); smb->AndXCommand = 0xFF; /* none */ smb->Fid = wdata->cfile->netfid; @@ -2188,13 +2167,15 @@ cifs_async_writev(struct cifs_writedata *wdata) iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1; iov[0].iov_base = smb; - /* - * This function should marshal up the page array into the kvec - * array, reserving [0] for the header. It should kmap the pages - * and set the iov_len properly for each one. It may also set - * wdata->bytes too. - */ - wdata->marshal_iov(iov, wdata); + /* marshal up the pages into iov array */ + wdata->bytes = 0; + for (i = 0; i < wdata->nr_pages; i++) { + iov[i + 1].iov_len = min(inode->i_size - + page_offset(wdata->pages[i]), + (loff_t)PAGE_CACHE_SIZE); + iov[i + 1].iov_base = kmap(wdata->pages[i]); + wdata->bytes += iov[i + 1].iov_len; + } cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes); @@ -2439,7 +2420,8 @@ CIFSSMBLock(const int xid, struct cifs_tcon *tcon, (struct smb_hdr *) pSMB, &bytes_returned); cifs_small_buf_release(pSMB); } else { - rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, timeout); + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB, + timeout); /* SMB buffer freed by function above */ } cifs_stats_inc(&tcon->num_locks); @@ -2606,7 +2588,7 @@ CIFSSMBClose(const int xid, struct cifs_tcon *tcon, int smb_file_id) pSMB->FileID = (__u16) smb_file_id; pSMB->LastWriteTime = 0xFFFFFFFF; pSMB->ByteCount = 0; - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); cifs_stats_inc(&tcon->num_closes); if (rc) { if (rc != -EINTR) { @@ -2635,7 +2617,7 @@ CIFSSMBFlush(const int xid, struct cifs_tcon *tcon, int smb_file_id) pSMB->FileID = (__u16) smb_file_id; pSMB->ByteCount = 0; - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); cifs_stats_inc(&tcon->num_flushes); if (rc) cERROR(1, "Send error in Flush = %d", rc); @@ -3892,12 +3874,13 @@ CIFSSMBSetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid, int rc = 0; int bytes_returned = 0; SET_SEC_DESC_REQ *pSMB = NULL; - void *pSMBr; + NTRANSACT_RSP *pSMBr = NULL; setCifsAclRetry: - rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr); + rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, + (void **) &pSMBr); if (rc) - return rc; + return (rc); pSMB->MaxSetupCount = 0; pSMB->Reserved = 0; @@ -3925,8 +3908,9 @@ CIFSSMBSetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid, pSMB->AclFlags = cpu_to_le32(aclflag); if (pntsd && acllen) { - memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) + - data_offset, pntsd, acllen); + memcpy((char *) &pSMBr->hdr.Protocol + data_offset, + (char *) pntsd, + acllen); inc_rfc1001_len(pSMB, byte_count + data_count); } else inc_rfc1001_len(pSMB, byte_count); @@ -4641,7 +4625,7 @@ CIFSFindClose(const int xid, struct cifs_tcon *tcon, pSMB->FileID = searchHandle; pSMB->ByteCount = 0; - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); if (rc) cERROR(1, "Send error in FindClose = %d", rc); @@ -4844,12 +4828,8 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr, max_len = data_end - temp; node->node_name = cifs_strndup_from_utf16(temp, max_len, is_unicode, nls_codepage); - if (!node->node_name) { + if (!node->node_name) rc = -ENOMEM; - goto parse_DFS_referrals_exit; - } - - ref++; } parse_DFS_referrals_exit: @@ -5666,7 +5646,7 @@ CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon, __u64 size, pSMB->Reserved4 = 0; inc_rfc1001_len(pSMB, byte_count); pSMB->ByteCount = cpu_to_le16(byte_count); - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); if (rc) { cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc); } @@ -5710,8 +5690,7 @@ CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon, param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; offset = param_offset + params; - data_offset = (char *)pSMB + - offsetof(struct smb_hdr, Protocol) + offset; + data_offset = (char *) (&pSMB->hdr.Protocol) + offset; count = sizeof(FILE_BASIC_INFO); pSMB->MaxParameterCount = cpu_to_le16(2); @@ -5736,7 +5715,7 @@ CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon, inc_rfc1001_len(pSMB, byte_count); pSMB->ByteCount = cpu_to_le16(byte_count); memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); if (rc) cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc); @@ -5795,7 +5774,7 @@ CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon, inc_rfc1001_len(pSMB, byte_count); pSMB->ByteCount = cpu_to_le16(byte_count); *data_offset = delete_file ? 1 : 0; - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); if (rc) cFYI(1, "Send error in SetFileDisposition = %d", rc); @@ -5980,7 +5959,7 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon, u16 fid, u32 pid_of_opener) { struct smb_com_transaction2_sfi_req *pSMB = NULL; - char *data_offset; + FILE_UNIX_BASIC_INFO *data_offset; int rc = 0; u16 params, param_offset, offset, byte_count, count; @@ -6002,9 +5981,8 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon, param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; offset = param_offset + params; - data_offset = (char *)pSMB + - offsetof(struct smb_hdr, Protocol) + offset; - + data_offset = (FILE_UNIX_BASIC_INFO *) + ((char *)(&pSMB->hdr.Protocol) + offset); count = sizeof(FILE_UNIX_BASIC_INFO); pSMB->MaxParameterCount = cpu_to_le16(2); @@ -6026,9 +6004,9 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon, inc_rfc1001_len(pSMB, byte_count); pSMB->ByteCount = cpu_to_le16(byte_count); - cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args); + cifs_fill_unix_set_info(data_offset, args); - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0); + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); if (rc) cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc); diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index 5dcc55197fb3..5560e1d5e54b 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -40,8 +40,6 @@ #include #include #include -#include - #include "cifspdu.h" #include "cifsglob.h" #include "cifsproto.h" @@ -65,201 +63,6 @@ extern mempool_t *cifs_req_poolp; #define TLINK_ERROR_EXPIRE (1 * HZ) #define TLINK_IDLE_EXPIRE (600 * HZ) -enum { - - /* Mount options that take no arguments */ - Opt_user_xattr, Opt_nouser_xattr, - Opt_forceuid, Opt_noforceuid, - Opt_noblocksend, Opt_noautotune, - Opt_hard, Opt_soft, Opt_perm, Opt_noperm, - Opt_mapchars, Opt_nomapchars, Opt_sfu, - Opt_nosfu, Opt_nodfs, Opt_posixpaths, - Opt_noposixpaths, Opt_nounix, - Opt_nocase, - Opt_brl, Opt_nobrl, - Opt_forcemandatorylock, Opt_setuids, - Opt_nosetuids, Opt_dynperm, Opt_nodynperm, - Opt_nohard, Opt_nosoft, - Opt_nointr, Opt_intr, - Opt_nostrictsync, Opt_strictsync, - Opt_serverino, Opt_noserverino, - Opt_rwpidforward, Opt_cifsacl, Opt_nocifsacl, - Opt_acl, Opt_noacl, Opt_locallease, - Opt_sign, Opt_seal, Opt_direct, - Opt_strictcache, Opt_noac, - Opt_fsc, Opt_mfsymlinks, - Opt_multiuser, Opt_sloppy, - - /* Mount options which take numeric value */ - Opt_backupuid, Opt_backupgid, Opt_uid, - Opt_cruid, Opt_gid, Opt_file_mode, - Opt_dirmode, Opt_port, - Opt_rsize, Opt_wsize, Opt_actimeo, - - /* Mount options which take string value */ - Opt_user, Opt_pass, Opt_ip, - Opt_unc, Opt_domain, - Opt_srcaddr, Opt_prefixpath, - Opt_iocharset, Opt_sockopt, - Opt_netbiosname, Opt_servern, - Opt_ver, Opt_sec, - - /* Mount options to be ignored */ - Opt_ignore, - - /* Options which could be blank */ - Opt_blank_pass, - Opt_blank_user, - Opt_blank_ip, - - Opt_err -}; - -static const match_table_t cifs_mount_option_tokens = { - - { Opt_user_xattr, "user_xattr" }, - { Opt_nouser_xattr, "nouser_xattr" }, - { Opt_forceuid, "forceuid" }, - { Opt_noforceuid, "noforceuid" }, - { Opt_noblocksend, "noblocksend" }, - { Opt_noautotune, "noautotune" }, - { Opt_hard, "hard" }, - { Opt_soft, "soft" }, - { Opt_perm, "perm" }, - { Opt_noperm, "noperm" }, - { Opt_mapchars, "mapchars" }, - { Opt_nomapchars, "nomapchars" }, - { Opt_sfu, "sfu" }, - { Opt_nosfu, "nosfu" }, - { Opt_nodfs, "nodfs" }, - { Opt_posixpaths, "posixpaths" }, - { Opt_noposixpaths, "noposixpaths" }, - { Opt_nounix, "nounix" }, - { Opt_nounix, "nolinux" }, - { Opt_nocase, "nocase" }, - { Opt_nocase, "ignorecase" }, - { Opt_brl, "brl" }, - { Opt_nobrl, "nobrl" }, - { Opt_nobrl, "nolock" }, - { Opt_forcemandatorylock, "forcemandatorylock" }, - { Opt_forcemandatorylock, "forcemand" }, - { Opt_setuids, "setuids" }, - { Opt_nosetuids, "nosetuids" }, - { Opt_dynperm, "dynperm" }, - { Opt_nodynperm, "nodynperm" }, - { Opt_nohard, "nohard" }, - { Opt_nosoft, "nosoft" }, - { Opt_nointr, "nointr" }, - { Opt_intr, "intr" }, - { Opt_nostrictsync, "nostrictsync" }, - { Opt_strictsync, "strictsync" }, - { Opt_serverino, "serverino" }, - { Opt_noserverino, "noserverino" }, - { Opt_rwpidforward, "rwpidforward" }, - { Opt_cifsacl, "cifsacl" }, - { Opt_nocifsacl, "nocifsacl" }, - { Opt_acl, "acl" }, - { Opt_noacl, "noacl" }, - { Opt_locallease, "locallease" }, - { Opt_sign, "sign" }, - { Opt_seal, "seal" }, - { Opt_direct, "direct" }, - { Opt_direct, "forceddirectio" }, - { Opt_strictcache, "strictcache" }, - { Opt_noac, "noac" }, - { Opt_fsc, "fsc" }, - { Opt_mfsymlinks, "mfsymlinks" }, - { Opt_multiuser, "multiuser" }, - { Opt_sloppy, "sloppy" }, - - { Opt_backupuid, "backupuid=%s" }, - { Opt_backupgid, "backupgid=%s" }, - { Opt_uid, "uid=%s" }, - { Opt_cruid, "cruid=%s" }, - { Opt_gid, "gid=%s" }, - { Opt_file_mode, "file_mode=%s" }, - { Opt_dirmode, "dirmode=%s" }, - { Opt_dirmode, "dir_mode=%s" }, - { Opt_port, "port=%s" }, - { Opt_rsize, "rsize=%s" }, - { Opt_wsize, "wsize=%s" }, - { Opt_actimeo, "actimeo=%s" }, - - { Opt_blank_user, "user=" }, - { Opt_blank_user, "username=" }, - { Opt_user, "user=%s" }, - { Opt_user, "username=%s" }, - { Opt_blank_pass, "pass=" }, - { Opt_pass, "pass=%s" }, - { Opt_pass, "password=%s" }, - { Opt_blank_ip, "ip=" }, - { Opt_blank_ip, "addr=" }, - { Opt_ip, "ip=%s" }, - { Opt_ip, "addr=%s" }, - { Opt_unc, "unc=%s" }, - { Opt_unc, "target=%s" }, - { Opt_unc, "path=%s" }, - { Opt_domain, "dom=%s" }, - { Opt_domain, "domain=%s" }, - { Opt_domain, "workgroup=%s" }, - { 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" }, - { Opt_ver, "vers=%s" }, - { Opt_ver, "version=%s" }, - { Opt_sec, "sec=%s" }, - - { Opt_ignore, "cred" }, - { Opt_ignore, "credentials" }, - { Opt_ignore, "cred=%s" }, - { Opt_ignore, "credentials=%s" }, - { Opt_ignore, "guest" }, - { Opt_ignore, "rw" }, - { Opt_ignore, "ro" }, - { Opt_ignore, "suid" }, - { Opt_ignore, "nosuid" }, - { Opt_ignore, "exec" }, - { Opt_ignore, "noexec" }, - { Opt_ignore, "nodev" }, - { Opt_ignore, "noauto" }, - { Opt_ignore, "dev" }, - { Opt_ignore, "mand" }, - { Opt_ignore, "nomand" }, - { Opt_ignore, "_netdev" }, - - { Opt_err, NULL } -}; - -enum { - Opt_sec_krb5, Opt_sec_krb5i, Opt_sec_krb5p, - Opt_sec_ntlmsspi, Opt_sec_ntlmssp, - Opt_ntlm, Opt_sec_ntlmi, Opt_sec_ntlmv2i, - Opt_sec_nontlm, Opt_sec_lanman, - Opt_sec_none, - - Opt_sec_err -}; - -static const match_table_t cifs_secflavor_tokens = { - { Opt_sec_krb5, "krb5" }, - { Opt_sec_krb5i, "krb5i" }, - { Opt_sec_krb5p, "krb5p" }, - { Opt_sec_ntlmsspi, "ntlmsspi" }, - { Opt_sec_ntlmssp, "ntlmssp" }, - { Opt_ntlm, "ntlm" }, - { Opt_sec_ntlmi, "ntlmi" }, - { Opt_sec_ntlmv2i, "ntlmv2i" }, - { Opt_sec_nontlm, "nontlm" }, - { Opt_sec_lanman, "lanman" }, - { Opt_sec_none, "none" }, - - { Opt_sec_err, NULL } -}; - static int ip_connect(struct TCP_Server_Info *server); static int generic_ip_connect(struct TCP_Server_Info *server); static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); @@ -340,8 +143,8 @@ cifs_reconnect(struct TCP_Server_Info *server) spin_lock(&GlobalMid_Lock); list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { mid_entry = list_entry(tmp, struct mid_q_entry, qhead); - if (mid_entry->mid_state == MID_REQUEST_SUBMITTED) - mid_entry->mid_state = MID_RETRY_NEEDED; + if (mid_entry->midState == MID_REQUEST_SUBMITTED) + mid_entry->midState = MID_RETRY_NEEDED; list_move(&mid_entry->qhead, &retry_list); } spin_unlock(&GlobalMid_Lock); @@ -380,9 +183,8 @@ cifs_reconnect(struct TCP_Server_Info *server) -EINVAL = invalid transact2 */ -static int check2ndT2(char *buf) +static int check2ndT2(struct smb_hdr *pSMB) { - struct smb_hdr *pSMB = (struct smb_hdr *)buf; struct smb_t2_rsp *pSMBt; int remaining; __u16 total_data_size, data_in_this_rsp; @@ -422,10 +224,10 @@ static int check2ndT2(char *buf) return remaining; } -static int coalesce_t2(char *second_buf, struct smb_hdr *target_hdr) +static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB) { - struct smb_t2_rsp *pSMBs = (struct smb_t2_rsp *)second_buf; - struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)target_hdr; + struct smb_t2_rsp *pSMBs = (struct smb_t2_rsp *)psecond; + struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB; char *data_area_of_tgt; char *data_area_of_src; int remaining; @@ -478,23 +280,23 @@ static int coalesce_t2(char *second_buf, struct smb_hdr *target_hdr) put_unaligned_le16(total_in_tgt, &pSMBt->t2_rsp.DataCount); /* fix up the BCC */ - byte_count = get_bcc(target_hdr); + byte_count = get_bcc(pTargetSMB); byte_count += total_in_src; /* is the result too big for the field? */ if (byte_count > USHRT_MAX) { cFYI(1, "coalesced BCC too large (%u)", byte_count); return -EPROTO; } - put_bcc(byte_count, target_hdr); + put_bcc(byte_count, pTargetSMB); - byte_count = be32_to_cpu(target_hdr->smb_buf_length); + byte_count = be32_to_cpu(pTargetSMB->smb_buf_length); byte_count += total_in_src; /* don't allow buffer to overflow */ if (byte_count > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { cFYI(1, "coalesced BCC exceeds buffer size (%u)", byte_count); return -ENOBUFS; } - target_hdr->smb_buf_length = cpu_to_be32(byte_count); + pTargetSMB->smb_buf_length = cpu_to_be32(byte_count); /* copy second buffer into end of first buffer */ memcpy(data_area_of_tgt, data_area_of_src, total_in_src); @@ -532,7 +334,7 @@ cifs_echo_request(struct work_struct *work) server->hostname); requeue_echo: - queue_delayed_work(cifsiod_wq, &server->echo, SMB_ECHO_INTERVAL); + queue_delayed_work(system_nrt_wq, &server->echo, SMB_ECHO_INTERVAL); } static bool @@ -548,7 +350,7 @@ allocate_buffers(struct TCP_Server_Info *server) } } else if (server->large_buf) { /* we are reusing a dirty large buf, clear its start */ - memset(server->bigbuf, 0, header_size()); + memset(server->bigbuf, 0, sizeof(struct smb_hdr)); } if (!server->smallbuf) { @@ -562,7 +364,7 @@ allocate_buffers(struct TCP_Server_Info *server) /* beginning of smb buffer is cleared in our buf_get */ } else { /* if existing small buf clear beginning */ - memset(server->smallbuf, 0, header_size()); + memset(server->smallbuf, 0, sizeof(struct smb_hdr)); } return true; @@ -764,16 +566,15 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type) } static struct mid_q_entry * -find_mid(struct TCP_Server_Info *server, char *buffer) +find_mid(struct TCP_Server_Info *server, struct smb_hdr *buf) { - struct smb_hdr *buf = (struct smb_hdr *)buffer; struct mid_q_entry *mid; spin_lock(&GlobalMid_Lock); list_for_each_entry(mid, &server->pending_mid_q, qhead) { if (mid->mid == buf->Mid && - mid->mid_state == MID_REQUEST_SUBMITTED && - le16_to_cpu(mid->command) == buf->Command) { + mid->midState == MID_REQUEST_SUBMITTED && + mid->command == buf->Command) { spin_unlock(&GlobalMid_Lock); return mid; } @@ -790,16 +591,16 @@ dequeue_mid(struct mid_q_entry *mid, bool malformed) #endif spin_lock(&GlobalMid_Lock); if (!malformed) - mid->mid_state = MID_RESPONSE_RECEIVED; + mid->midState = MID_RESPONSE_RECEIVED; else - mid->mid_state = MID_RESPONSE_MALFORMED; + mid->midState = MID_RESPONSE_MALFORMED; list_del_init(&mid->qhead); spin_unlock(&GlobalMid_Lock); } static void handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server, - char *buf, int malformed) + struct smb_hdr *buf, int malformed) { if (malformed == 0 && check2ndT2(buf) > 0) { mid->multiRsp = true; @@ -819,13 +620,13 @@ handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server, } else { /* Have first buffer */ mid->resp_buf = buf; - mid->large_buf = true; + mid->largeBuf = true; server->bigbuf = NULL; } return; } mid->resp_buf = buf; - mid->large_buf = server->large_buf; + mid->largeBuf = server->large_buf; /* Was previous buf put in mpx struct for multi-rsp? */ if (!mid->multiRsp) { /* smb buffer will be freed by user thread */ @@ -881,8 +682,8 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server) spin_lock(&GlobalMid_Lock); list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { mid_entry = list_entry(tmp, struct mid_q_entry, qhead); - cFYI(1, "Clearing mid 0x%llx", mid_entry->mid); - mid_entry->mid_state = MID_SHUTDOWN; + cFYI(1, "Clearing mid 0x%x", mid_entry->mid); + mid_entry->midState = MID_SHUTDOWN; list_move(&mid_entry->qhead, &dispose_list); } spin_unlock(&GlobalMid_Lock); @@ -890,7 +691,7 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server) /* now walk dispose list and issue callbacks */ list_for_each_safe(tmp, tmp2, &dispose_list) { mid_entry = list_entry(tmp, struct mid_q_entry, qhead); - cFYI(1, "Callback mid 0x%llx", mid_entry->mid); + cFYI(1, "Callback mid 0x%x", mid_entry->mid); list_del_init(&mid_entry->qhead); mid_entry->callback(mid_entry); } @@ -930,10 +731,11 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid) { int length; char *buf = server->smallbuf; - unsigned int pdu_length = get_rfc1002_length(buf); + struct smb_hdr *smb_buffer = (struct smb_hdr *)buf; + unsigned int pdu_length = be32_to_cpu(smb_buffer->smb_buf_length); /* make sure this will fit in a large buffer */ - if (pdu_length > CIFSMaxBufSize + max_header_size() - 4) { + if (pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { cERROR(1, "SMB response too long (%u bytes)", pdu_length); cifs_reconnect(server); @@ -944,18 +746,20 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid) /* switch to large buffer if too big for a small one */ if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) { server->large_buf = true; - memcpy(server->bigbuf, buf, server->total_read); + memcpy(server->bigbuf, server->smallbuf, server->total_read); buf = server->bigbuf; + smb_buffer = (struct smb_hdr *)buf; } /* now read the rest */ - length = cifs_read_from_socket(server, buf + header_size() - 1, - pdu_length - header_size() + 1 + 4); + length = cifs_read_from_socket(server, + buf + sizeof(struct smb_hdr) - 1, + pdu_length - sizeof(struct smb_hdr) + 1 + 4); if (length < 0) return length; server->total_read += length; - dump_smb(buf, server->total_read); + dump_smb(smb_buffer, server->total_read); /* * We know that we received enough to get to the MID as we @@ -966,7 +770,7 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid) * 48 bytes is enough to display the header and a little bit * into the payload for debugging purposes. */ - length = checkSMB(buf, server->total_read); + length = checkSMB(smb_buffer, smb_buffer->Mid, server->total_read); if (length != 0) cifs_dump_mem("Bad SMB: ", buf, min_t(unsigned int, server->total_read, 48)); @@ -974,7 +778,7 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid) if (!mid) return length; - handle_mid(mid, server, buf, length); + handle_mid(mid, server, smb_buffer, length); return 0; } @@ -985,6 +789,7 @@ cifs_demultiplex_thread(void *p) struct TCP_Server_Info *server = p; unsigned int pdu_length; char *buf = NULL; + struct smb_hdr *smb_buffer = NULL; struct task_struct *task_to_wake = NULL; struct mid_q_entry *mid_entry; @@ -1005,6 +810,7 @@ cifs_demultiplex_thread(void *p) continue; server->large_buf = false; + smb_buffer = (struct smb_hdr *)server->smallbuf; buf = server->smallbuf; pdu_length = 4; /* enough to get RFC1001 header */ @@ -1017,14 +823,14 @@ cifs_demultiplex_thread(void *p) * The right amount was read from socket - 4 bytes, * so we can now interpret the length field. */ - pdu_length = get_rfc1002_length(buf); + pdu_length = be32_to_cpu(smb_buffer->smb_buf_length); cFYI(1, "RFC1002 header 0x%x", pdu_length); if (!is_smb_response(server, buf[0])) continue; /* make sure we have enough to get to the MID */ - if (pdu_length < header_size() - 1 - 4) { + if (pdu_length < sizeof(struct smb_hdr) - 1 - 4) { cERROR(1, "SMB response too short (%u bytes)", pdu_length); cifs_reconnect(server); @@ -1034,12 +840,12 @@ cifs_demultiplex_thread(void *p) /* read down to the MID */ length = cifs_read_from_socket(server, buf + 4, - header_size() - 1 - 4); + sizeof(struct smb_hdr) - 1 - 4); if (length < 0) continue; server->total_read += length; - mid_entry = find_mid(server, buf); + mid_entry = find_mid(server, smb_buffer); if (!mid_entry || !mid_entry->receive) length = standard_receive3(server, mid_entry); @@ -1049,19 +855,22 @@ cifs_demultiplex_thread(void *p) if (length < 0) continue; - if (server->large_buf) + if (server->large_buf) { buf = server->bigbuf; + smb_buffer = (struct smb_hdr *)buf; + } server->lstrp = jiffies; if (mid_entry != NULL) { if (!mid_entry->multiRsp || mid_entry->multiEnd) mid_entry->callback(mid_entry); - } else if (!is_valid_oplock_break(buf, server)) { + } else if (!is_valid_oplock_break(smb_buffer, server)) { cERROR(1, "No task to wake, unknown frame received! " "NumMids %d", atomic_read(&midCount)); - cifs_dump_mem("Received Data is: ", buf, header_size()); + cifs_dump_mem("Received Data is: ", buf, + sizeof(struct smb_hdr)); #ifdef CONFIG_CIFS_DEBUG2 - cifs_dump_detail(buf); + cifs_dump_detail(smb_buffer); cifs_dump_mids(server); #endif /* CIFS_DEBUG2 */ @@ -1117,95 +926,23 @@ extract_hostname(const char *unc) return dst; } -static int get_option_ul(substring_t args[], unsigned long *option) -{ - int rc; - char *string; - - string = match_strdup(args); - if (string == NULL) - return -ENOMEM; - rc = kstrtoul(string, 0, option); - kfree(string); - - return rc; -} - - -static int cifs_parse_security_flavors(char *value, - struct smb_vol *vol) -{ - - substring_t args[MAX_OPT_ARGS]; - - switch (match_token(value, cifs_secflavor_tokens, args)) { - case Opt_sec_krb5: - vol->secFlg |= CIFSSEC_MAY_KRB5; - break; - case Opt_sec_krb5i: - vol->secFlg |= CIFSSEC_MAY_KRB5 | CIFSSEC_MUST_SIGN; - break; - case Opt_sec_krb5p: - /* vol->secFlg |= CIFSSEC_MUST_SEAL | CIFSSEC_MAY_KRB5; */ - cERROR(1, "Krb5 cifs privacy not supported"); - break; - case Opt_sec_ntlmssp: - vol->secFlg |= CIFSSEC_MAY_NTLMSSP; - break; - case Opt_sec_ntlmsspi: - vol->secFlg |= CIFSSEC_MAY_NTLMSSP | CIFSSEC_MUST_SIGN; - break; - case Opt_ntlm: - /* ntlm is default so can be turned off too */ - vol->secFlg |= CIFSSEC_MAY_NTLM; - break; - case Opt_sec_ntlmi: - vol->secFlg |= CIFSSEC_MAY_NTLM | CIFSSEC_MUST_SIGN; - break; - case Opt_sec_nontlm: - vol->secFlg |= CIFSSEC_MAY_NTLMV2; - break; - case Opt_sec_ntlmv2i: - vol->secFlg |= CIFSSEC_MAY_NTLMV2 | CIFSSEC_MUST_SIGN; - break; -#ifdef CONFIG_CIFS_WEAK_PW_HASH - case Opt_sec_lanman: - vol->secFlg |= CIFSSEC_MAY_LANMAN; - break; -#endif - case Opt_sec_none: - vol->nullauth = 1; - break; - default: - cERROR(1, "bad security option: %s", value); - return 1; - } - - return 0; -} - static int cifs_parse_mount_options(const char *mountdata, const char *devname, struct smb_vol *vol) { - char *data, *end; + char *value, *data, *end; char *mountdata_copy = NULL, *options; + int err; unsigned int temp_len, i, j; char separator[2]; short int override_uid = -1; short int override_gid = -1; bool uid_specified = false; bool gid_specified = false; - bool sloppy = false; - char *invalid = NULL; char *nodename = utsname()->nodename; - char *string = NULL; - char *tmp_end, *value; - char delim; separator[0] = ','; separator[1] = 0; - delim = separator[0]; /* * does not have to be perfect mapping since field is @@ -1244,7 +981,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, options = mountdata_copy; end = options + strlen(options); - if (strncmp(options, "sep=", 4) == 0) { if (options[4] != 0) { separator[0] = options[4]; @@ -1257,603 +993,609 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, vol->backupgid_specified = false; /* no backup intent for a group */ while ((data = strsep(&options, separator)) != NULL) { - substring_t args[MAX_OPT_ARGS]; - unsigned long option; - int token; - if (!*data) continue; + if ((value = strchr(data, '=')) != NULL) + *value++ = '\0'; - token = match_token(data, cifs_mount_option_tokens, args); - - switch (token) { - - /* Ingnore the following */ - case Opt_ignore: - break; - - /* Boolean values */ - case Opt_user_xattr: + /* Have to parse this before we parse for "user" */ + if (strnicmp(data, "user_xattr", 10) == 0) { vol->no_xattr = 0; - break; - case Opt_nouser_xattr: + } else if (strnicmp(data, "nouser_xattr", 12) == 0) { vol->no_xattr = 1; - break; - case Opt_forceuid: + } else if (strnicmp(data, "user", 4) == 0) { + if (!value) { + printk(KERN_WARNING + "CIFS: invalid or missing username\n"); + goto cifs_parse_mount_err; + } else if (!*value) { + /* null user, ie anonymous, authentication */ + vol->nullauth = 1; + } + if (strnlen(value, MAX_USERNAME_SIZE) < + MAX_USERNAME_SIZE) { + vol->username = kstrdup(value, GFP_KERNEL); + if (!vol->username) { + printk(KERN_WARNING "CIFS: no memory " + "for username\n"); + goto cifs_parse_mount_err; + } + } else { + printk(KERN_WARNING "CIFS: username too long\n"); + goto cifs_parse_mount_err; + } + } else if (strnicmp(data, "pass", 4) == 0) { + if (!value) { + vol->password = NULL; + continue; + } else if (value[0] == 0) { + /* check if string begins with double comma + since that would mean the password really + does start with a comma, and would not + indicate an empty string */ + if (value[1] != separator[0]) { + vol->password = NULL; + continue; + } + } + temp_len = strlen(value); + /* removed password length check, NTLM passwords + can be arbitrarily long */ + + /* if comma in password, the string will be + prematurely null terminated. Commas in password are + specified across the cifs mount interface by a double + comma ie ,, and a comma used as in other cases ie ',' + as a parameter delimiter/separator is single and due + to the strsep above is temporarily zeroed. */ + + /* NB: password legally can have multiple commas and + the only illegal character in a password is null */ + + if ((value[temp_len] == 0) && + (value + temp_len < end) && + (value[temp_len+1] == separator[0])) { + /* reinsert comma */ + value[temp_len] = separator[0]; + temp_len += 2; /* move after second comma */ + while (value[temp_len] != 0) { + if (value[temp_len] == separator[0]) { + if (value[temp_len+1] == + separator[0]) { + /* skip second comma */ + temp_len++; + } else { + /* single comma indicating start + of next parm */ + break; + } + } + temp_len++; + } + if (value[temp_len] == 0) { + options = NULL; + } else { + value[temp_len] = 0; + /* point option to start of next parm */ + options = value + temp_len + 1; + } + /* go from value to value + temp_len condensing + double commas to singles. Note that this ends up + allocating a few bytes too many, which is ok */ + vol->password = kzalloc(temp_len, GFP_KERNEL); + if (vol->password == NULL) { + printk(KERN_WARNING "CIFS: no memory " + "for password\n"); + goto cifs_parse_mount_err; + } + for (i = 0, j = 0; i < temp_len; i++, j++) { + vol->password[j] = value[i]; + if (value[i] == separator[0] + && value[i+1] == separator[0]) { + /* skip second comma */ + i++; + } + } + vol->password[j] = 0; + } else { + vol->password = kzalloc(temp_len+1, GFP_KERNEL); + if (vol->password == NULL) { + printk(KERN_WARNING "CIFS: no memory " + "for password\n"); + goto cifs_parse_mount_err; + } + strcpy(vol->password, value); + } + } else if (!strnicmp(data, "ip", 2) || + !strnicmp(data, "addr", 4)) { + if (!value || !*value) { + vol->UNCip = NULL; + } else if (strnlen(value, INET6_ADDRSTRLEN) < + INET6_ADDRSTRLEN) { + vol->UNCip = kstrdup(value, GFP_KERNEL); + if (!vol->UNCip) { + printk(KERN_WARNING "CIFS: no memory " + "for UNC IP\n"); + goto cifs_parse_mount_err; + } + } else { + printk(KERN_WARNING "CIFS: ip address " + "too long\n"); + goto cifs_parse_mount_err; + } + } else if (strnicmp(data, "sec", 3) == 0) { + if (!value || !*value) { + cERROR(1, "no security value specified"); + continue; + } else if (strnicmp(value, "krb5i", 5) == 0) { + vol->secFlg |= CIFSSEC_MAY_KRB5 | + CIFSSEC_MUST_SIGN; + } else if (strnicmp(value, "krb5p", 5) == 0) { + /* vol->secFlg |= CIFSSEC_MUST_SEAL | + CIFSSEC_MAY_KRB5; */ + cERROR(1, "Krb5 cifs privacy not supported"); + goto cifs_parse_mount_err; + } else if (strnicmp(value, "krb5", 4) == 0) { + vol->secFlg |= CIFSSEC_MAY_KRB5; + } else if (strnicmp(value, "ntlmsspi", 8) == 0) { + vol->secFlg |= CIFSSEC_MAY_NTLMSSP | + CIFSSEC_MUST_SIGN; + } else if (strnicmp(value, "ntlmssp", 7) == 0) { + vol->secFlg |= CIFSSEC_MAY_NTLMSSP; + } else if (strnicmp(value, "ntlmv2i", 7) == 0) { + vol->secFlg |= CIFSSEC_MAY_NTLMV2 | + CIFSSEC_MUST_SIGN; + } else if (strnicmp(value, "ntlmv2", 6) == 0) { + vol->secFlg |= CIFSSEC_MAY_NTLMV2; + } else if (strnicmp(value, "ntlmi", 5) == 0) { + vol->secFlg |= CIFSSEC_MAY_NTLM | + CIFSSEC_MUST_SIGN; + } else if (strnicmp(value, "ntlm", 4) == 0) { + /* ntlm is default so can be turned off too */ + vol->secFlg |= CIFSSEC_MAY_NTLM; + } else if (strnicmp(value, "nontlm", 6) == 0) { + /* BB is there a better way to do this? */ + vol->secFlg |= CIFSSEC_MAY_NTLMV2; +#ifdef CONFIG_CIFS_WEAK_PW_HASH + } else if (strnicmp(value, "lanman", 6) == 0) { + vol->secFlg |= CIFSSEC_MAY_LANMAN; +#endif + } else if (strnicmp(value, "none", 4) == 0) { + vol->nullauth = 1; + } else { + cERROR(1, "bad security option: %s", value); + goto cifs_parse_mount_err; + } + } else if (strnicmp(data, "vers", 3) == 0) { + if (!value || !*value) { + cERROR(1, "no protocol version specified" + " after vers= mount option"); + } else if ((strnicmp(value, "cifs", 4) == 0) || + (strnicmp(value, "1", 1) == 0)) { + /* this is the default */ + continue; + } + } else if ((strnicmp(data, "unc", 3) == 0) + || (strnicmp(data, "target", 6) == 0) + || (strnicmp(data, "path", 4) == 0)) { + if (!value || !*value) { + printk(KERN_WARNING "CIFS: invalid path to " + "network resource\n"); + goto cifs_parse_mount_err; + } + if ((temp_len = strnlen(value, 300)) < 300) { + vol->UNC = kmalloc(temp_len+1, GFP_KERNEL); + if (vol->UNC == NULL) + goto cifs_parse_mount_err; + strcpy(vol->UNC, value); + if (strncmp(vol->UNC, "//", 2) == 0) { + vol->UNC[0] = '\\'; + vol->UNC[1] = '\\'; + } else if (strncmp(vol->UNC, "\\\\", 2) != 0) { + printk(KERN_WARNING + "CIFS: UNC Path does not begin " + "with // or \\\\ \n"); + goto cifs_parse_mount_err; + } + } else { + printk(KERN_WARNING "CIFS: UNC name too long\n"); + goto cifs_parse_mount_err; + } + } else if ((strnicmp(data, "domain", 3) == 0) + || (strnicmp(data, "workgroup", 5) == 0)) { + if (!value || !*value) { + printk(KERN_WARNING "CIFS: invalid domain name\n"); + goto cifs_parse_mount_err; + } + /* BB are there cases in which a comma can be valid in + a domain name and need special handling? */ + if (strnlen(value, 256) < 256) { + vol->domainname = kstrdup(value, GFP_KERNEL); + if (!vol->domainname) { + printk(KERN_WARNING "CIFS: no memory " + "for domainname\n"); + goto cifs_parse_mount_err; + } + cFYI(1, "Domain name set"); + } else { + printk(KERN_WARNING "CIFS: domain name too " + "long\n"); + goto cifs_parse_mount_err; + } + } else if (strnicmp(data, "srcaddr", 7) == 0) { + vol->srcaddr.ss_family = AF_UNSPEC; + + if (!value || !*value) { + printk(KERN_WARNING "CIFS: srcaddr value" + " not specified.\n"); + goto cifs_parse_mount_err; + } + i = cifs_convert_address((struct sockaddr *)&vol->srcaddr, + value, strlen(value)); + if (i == 0) { + printk(KERN_WARNING "CIFS: Could not parse" + " srcaddr: %s\n", + value); + goto cifs_parse_mount_err; + } + } else if (strnicmp(data, "prefixpath", 10) == 0) { + if (!value || !*value) { + printk(KERN_WARNING + "CIFS: invalid path prefix\n"); + goto cifs_parse_mount_err; + } + if ((temp_len = strnlen(value, 1024)) < 1024) { + if (value[0] != '/') + temp_len++; /* missing leading slash */ + vol->prepath = kmalloc(temp_len+1, GFP_KERNEL); + if (vol->prepath == NULL) + goto cifs_parse_mount_err; + if (value[0] != '/') { + vol->prepath[0] = '/'; + strcpy(vol->prepath+1, value); + } else + strcpy(vol->prepath, value); + cFYI(1, "prefix path %s", vol->prepath); + } else { + printk(KERN_WARNING "CIFS: prefix too long\n"); + goto cifs_parse_mount_err; + } + } else if (strnicmp(data, "iocharset", 9) == 0) { + if (!value || !*value) { + printk(KERN_WARNING "CIFS: invalid iocharset " + "specified\n"); + goto cifs_parse_mount_err; + } + if (strnlen(value, 65) < 65) { + if (strnicmp(value, "default", 7)) { + vol->iocharset = kstrdup(value, + GFP_KERNEL); + + if (!vol->iocharset) { + printk(KERN_WARNING "CIFS: no " + "memory for" + "charset\n"); + goto cifs_parse_mount_err; + } + } + /* if iocharset not set then load_nls_default + is used by caller */ + cFYI(1, "iocharset set to %s", value); + } else { + printk(KERN_WARNING "CIFS: iocharset name " + "too long.\n"); + goto cifs_parse_mount_err; + } + } else if (!strnicmp(data, "uid", 3) && value && *value) { + vol->linux_uid = simple_strtoul(value, &value, 0); + uid_specified = true; + } else if (!strnicmp(data, "cruid", 5) && value && *value) { + vol->cred_uid = simple_strtoul(value, &value, 0); + } else if (!strnicmp(data, "forceuid", 8)) { override_uid = 1; - break; - case Opt_noforceuid: + } else if (!strnicmp(data, "noforceuid", 10)) { override_uid = 0; - break; - case Opt_noblocksend: + } else if (!strnicmp(data, "gid", 3) && value && *value) { + vol->linux_gid = simple_strtoul(value, &value, 0); + gid_specified = true; + } else if (!strnicmp(data, "forcegid", 8)) { + override_gid = 1; + } else if (!strnicmp(data, "noforcegid", 10)) { + override_gid = 0; + } else if (strnicmp(data, "file_mode", 4) == 0) { + if (value && *value) { + vol->file_mode = + simple_strtoul(value, &value, 0); + } + } else if (strnicmp(data, "dir_mode", 4) == 0) { + if (value && *value) { + vol->dir_mode = + simple_strtoul(value, &value, 0); + } + } else if (strnicmp(data, "dirmode", 4) == 0) { + if (value && *value) { + vol->dir_mode = + simple_strtoul(value, &value, 0); + } + } else if (strnicmp(data, "port", 4) == 0) { + if (value && *value) { + vol->port = + simple_strtoul(value, &value, 0); + } + } else if (strnicmp(data, "rsize", 5) == 0) { + if (value && *value) { + vol->rsize = + simple_strtoul(value, &value, 0); + } + } else if (strnicmp(data, "wsize", 5) == 0) { + if (value && *value) { + vol->wsize = + simple_strtoul(value, &value, 0); + } + } else if (strnicmp(data, "sockopt", 5) == 0) { + if (!value || !*value) { + cERROR(1, "no socket option specified"); + continue; + } else if (strnicmp(value, "TCP_NODELAY", 11) == 0) { + vol->sockopt_tcp_nodelay = 1; + } + } else if (strnicmp(data, "netbiosname", 4) == 0) { + if (!value || !*value || (*value == ' ')) { + cFYI(1, "invalid (empty) netbiosname"); + } else { + memset(vol->source_rfc1001_name, 0x20, + RFC1001_NAME_LEN); + /* + * FIXME: are there cases in which a comma can + * be valid in workstation netbios name (and + * need special handling)? + */ + for (i = 0; i < RFC1001_NAME_LEN; i++) { + /* don't ucase netbiosname for user */ + if (value[i] == 0) + break; + vol->source_rfc1001_name[i] = value[i]; + } + /* The string has 16th byte zero still from + set at top of the function */ + if (i == RFC1001_NAME_LEN && value[i] != 0) + printk(KERN_WARNING "CIFS: netbiosname" + " longer than 15 truncated.\n"); + } + } else if (strnicmp(data, "servern", 7) == 0) { + /* servernetbiosname specified override *SMBSERVER */ + if (!value || !*value || (*value == ' ')) { + cFYI(1, "empty server netbiosname specified"); + } else { + /* last byte, type, is 0x20 for servr type */ + memset(vol->target_rfc1001_name, 0x20, + RFC1001_NAME_LEN_WITH_NULL); + + for (i = 0; i < 15; i++) { + /* BB are there cases in which a comma can be + valid in this workstation netbios name + (and need special handling)? */ + + /* user or mount helper must uppercase + the netbiosname */ + if (value[i] == 0) + break; + else + vol->target_rfc1001_name[i] = + value[i]; + } + /* The string has 16th byte zero still from + set at top of the function */ + if (i == RFC1001_NAME_LEN && value[i] != 0) + printk(KERN_WARNING "CIFS: server net" + "biosname longer than 15 truncated.\n"); + } + } else if (strnicmp(data, "actimeo", 7) == 0) { + if (value && *value) { + vol->actimeo = HZ * simple_strtoul(value, + &value, 0); + if (vol->actimeo > CIFS_MAX_ACTIMEO) { + cERROR(1, "CIFS: attribute cache" + "timeout too large"); + goto cifs_parse_mount_err; + } + } + } else if (strnicmp(data, "credentials", 4) == 0) { + /* ignore */ + } else if (strnicmp(data, "version", 3) == 0) { + /* ignore */ + } else if (strnicmp(data, "guest", 5) == 0) { + /* ignore */ + } else if (strnicmp(data, "rw", 2) == 0 && strlen(data) == 2) { + /* ignore */ + } else if (strnicmp(data, "ro", 2) == 0) { + /* ignore */ + } else if (strnicmp(data, "noblocksend", 11) == 0) { vol->noblocksnd = 1; - break; - case Opt_noautotune: + } else if (strnicmp(data, "noautotune", 10) == 0) { vol->noautotune = 1; - break; - case Opt_hard: + } else if ((strnicmp(data, "suid", 4) == 0) || + (strnicmp(data, "nosuid", 6) == 0) || + (strnicmp(data, "exec", 4) == 0) || + (strnicmp(data, "noexec", 6) == 0) || + (strnicmp(data, "nodev", 5) == 0) || + (strnicmp(data, "noauto", 6) == 0) || + (strnicmp(data, "dev", 3) == 0)) { + /* The mount tool or mount.cifs helper (if present) + uses these opts to set flags, and the flags are read + by the kernel vfs layer before we get here (ie + before read super) so there is no point trying to + parse these options again and set anything and it + is ok to just ignore them */ + continue; + } else if (strnicmp(data, "hard", 4) == 0) { vol->retry = 1; - break; - case Opt_soft: + } else if (strnicmp(data, "soft", 4) == 0) { vol->retry = 0; - break; - case Opt_perm: + } else if (strnicmp(data, "perm", 4) == 0) { vol->noperm = 0; - break; - case Opt_noperm: + } else if (strnicmp(data, "noperm", 6) == 0) { vol->noperm = 1; - break; - case Opt_mapchars: + } else if (strnicmp(data, "mapchars", 8) == 0) { vol->remap = 1; - break; - case Opt_nomapchars: + } else if (strnicmp(data, "nomapchars", 10) == 0) { vol->remap = 0; - break; - case Opt_sfu: + } else if (strnicmp(data, "sfu", 3) == 0) { vol->sfu_emul = 1; - break; - case Opt_nosfu: + } else if (strnicmp(data, "nosfu", 5) == 0) { vol->sfu_emul = 0; - break; - case Opt_nodfs: + } else if (strnicmp(data, "nodfs", 5) == 0) { vol->nodfs = 1; - break; - case Opt_posixpaths: + } else if (strnicmp(data, "posixpaths", 10) == 0) { vol->posix_paths = 1; - break; - case Opt_noposixpaths: + } else if (strnicmp(data, "noposixpaths", 12) == 0) { vol->posix_paths = 0; - break; - case Opt_nounix: + } else if (strnicmp(data, "nounix", 6) == 0) { vol->no_linux_ext = 1; - break; - case Opt_nocase: + } else if (strnicmp(data, "nolinux", 7) == 0) { + vol->no_linux_ext = 1; + } else if ((strnicmp(data, "nocase", 6) == 0) || + (strnicmp(data, "ignorecase", 10) == 0)) { vol->nocase = 1; - break; - case Opt_brl: + } else if (strnicmp(data, "mand", 4) == 0) { + /* ignore */ + } else if (strnicmp(data, "nomand", 6) == 0) { + /* ignore */ + } else if (strnicmp(data, "_netdev", 7) == 0) { + /* ignore */ + } else if (strnicmp(data, "brl", 3) == 0) { vol->nobrl = 0; - break; - case Opt_nobrl: + } else if ((strnicmp(data, "nobrl", 5) == 0) || + (strnicmp(data, "nolock", 6) == 0)) { vol->nobrl = 1; - /* - * turn off mandatory locking in mode - * if remote locking is turned off since the - * local vfs will do advisory - */ + /* turn off mandatory locking in mode + if remote locking is turned off since the + local vfs will do advisory */ if (vol->file_mode == (S_IALLUGO & ~(S_ISUID | S_IXGRP))) vol->file_mode = S_IALLUGO; - break; - case Opt_forcemandatorylock: + } else if (strnicmp(data, "forcemandatorylock", 9) == 0) { + /* will take the shorter form "forcemand" as well */ + /* This mount option will force use of mandatory + (DOS/Windows style) byte range locks, instead of + using posix advisory byte range locks, even if the + Unix extensions are available and posix locks would + be supported otherwise. If Unix extensions are not + negotiated this has no effect since mandatory locks + would be used (mandatory locks is all that those + those servers support) */ vol->mand_lock = 1; - break; - case Opt_setuids: + } else if (strnicmp(data, "setuids", 7) == 0) { vol->setuids = 1; - break; - case Opt_nosetuids: + } else if (strnicmp(data, "nosetuids", 9) == 0) { vol->setuids = 0; - break; - case Opt_dynperm: + } else if (strnicmp(data, "dynperm", 7) == 0) { vol->dynperm = true; - break; - case Opt_nodynperm: + } else if (strnicmp(data, "nodynperm", 9) == 0) { vol->dynperm = false; - break; - case Opt_nohard: + } else if (strnicmp(data, "nohard", 6) == 0) { vol->retry = 0; - break; - case Opt_nosoft: + } else if (strnicmp(data, "nosoft", 6) == 0) { vol->retry = 1; - break; - case Opt_nointr: + } else if (strnicmp(data, "nointr", 6) == 0) { vol->intr = 0; - break; - case Opt_intr: + } else if (strnicmp(data, "intr", 4) == 0) { vol->intr = 1; - break; - case Opt_nostrictsync: + } else if (strnicmp(data, "nostrictsync", 12) == 0) { vol->nostrictsync = 1; - break; - case Opt_strictsync: + } else if (strnicmp(data, "strictsync", 10) == 0) { vol->nostrictsync = 0; - break; - case Opt_serverino: + } else if (strnicmp(data, "serverino", 7) == 0) { vol->server_ino = 1; - break; - case Opt_noserverino: + } else if (strnicmp(data, "noserverino", 9) == 0) { vol->server_ino = 0; - break; - case Opt_rwpidforward: + } else if (strnicmp(data, "rwpidforward", 12) == 0) { vol->rwpidforward = 1; - break; - case Opt_cifsacl: + } else if (strnicmp(data, "cifsacl", 7) == 0) { vol->cifs_acl = 1; - break; - case Opt_nocifsacl: + } else if (strnicmp(data, "nocifsacl", 9) == 0) { vol->cifs_acl = 0; - break; - case Opt_acl: + } else if (strnicmp(data, "acl", 3) == 0) { vol->no_psx_acl = 0; - break; - case Opt_noacl: + } else if (strnicmp(data, "noacl", 5) == 0) { vol->no_psx_acl = 1; - break; - case Opt_locallease: + } else if (strnicmp(data, "locallease", 6) == 0) { vol->local_lease = 1; - break; - case Opt_sign: + } else if (strnicmp(data, "sign", 4) == 0) { vol->secFlg |= CIFSSEC_MUST_SIGN; - break; - case Opt_seal: + } else if (strnicmp(data, "seal", 4) == 0) { /* we do not do the following in secFlags because seal - * is a per tree connection (mount) not a per socket - * or per-smb connection option in the protocol - * vol->secFlg |= CIFSSEC_MUST_SEAL; - */ + is a per tree connection (mount) not a per socket + or per-smb connection option in the protocol */ + /* vol->secFlg |= CIFSSEC_MUST_SEAL; */ vol->seal = 1; - break; - case Opt_direct: + } else if (strnicmp(data, "direct", 6) == 0) { vol->direct_io = 1; - break; - case Opt_strictcache: + } else if (strnicmp(data, "forcedirectio", 13) == 0) { + vol->direct_io = 1; + } else if (strnicmp(data, "strictcache", 11) == 0) { vol->strict_io = 1; - break; - case Opt_noac: + } else if (strnicmp(data, "noac", 4) == 0) { printk(KERN_WARNING "CIFS: Mount option noac not " "supported. Instead set " "/proc/fs/cifs/LookupCacheEnabled to 0\n"); - break; - case Opt_fsc: + } else if (strnicmp(data, "fsc", 3) == 0) { #ifndef CONFIG_CIFS_FSCACHE cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE " "kernel config option set"); goto cifs_parse_mount_err; #endif vol->fsc = true; - break; - case Opt_mfsymlinks: + } else if (strnicmp(data, "mfsymlinks", 10) == 0) { vol->mfsymlinks = true; - break; - case Opt_multiuser: + } else if (strnicmp(data, "multiuser", 8) == 0) { vol->multiuser = true; - break; - case Opt_sloppy: - sloppy = true; - break; - - /* Numeric Values */ - case Opt_backupuid: - if (get_option_ul(args, &option)) { + } else if (!strnicmp(data, "backupuid", 9) && value && *value) { + err = kstrtouint(value, 0, &vol->backupuid); + if (err < 0) { cERROR(1, "%s: Invalid backupuid value", __func__); goto cifs_parse_mount_err; } - vol->backupuid = option; vol->backupuid_specified = true; - break; - case Opt_backupgid: - if (get_option_ul(args, &option)) { + } else if (!strnicmp(data, "backupgid", 9) && value && *value) { + err = kstrtouint(value, 0, &vol->backupgid); + if (err < 0) { cERROR(1, "%s: Invalid backupgid value", __func__); goto cifs_parse_mount_err; } - vol->backupgid = option; vol->backupgid_specified = true; - break; - case Opt_uid: - if (get_option_ul(args, &option)) { - cERROR(1, "%s: Invalid uid value", - __func__); - goto cifs_parse_mount_err; - } - vol->linux_uid = option; - uid_specified = true; - break; - case Opt_cruid: - if (get_option_ul(args, &option)) { - cERROR(1, "%s: Invalid cruid value", - __func__); - goto cifs_parse_mount_err; - } - vol->cred_uid = option; - break; - case Opt_gid: - if (get_option_ul(args, &option)) { - cERROR(1, "%s: Invalid gid value", - __func__); - goto cifs_parse_mount_err; - } - vol->linux_gid = option; - gid_specified = true; - break; - case Opt_file_mode: - if (get_option_ul(args, &option)) { - cERROR(1, "%s: Invalid file_mode value", - __func__); - goto cifs_parse_mount_err; - } - vol->file_mode = option; - break; - case Opt_dirmode: - if (get_option_ul(args, &option)) { - cERROR(1, "%s: Invalid dir_mode value", - __func__); - goto cifs_parse_mount_err; - } - vol->dir_mode = option; - break; - case Opt_port: - if (get_option_ul(args, &option)) { - cERROR(1, "%s: Invalid port value", - __func__); - goto cifs_parse_mount_err; - } - vol->port = option; - break; - case Opt_rsize: - if (get_option_ul(args, &option)) { - cERROR(1, "%s: Invalid rsize value", - __func__); - goto cifs_parse_mount_err; - } - vol->rsize = option; - break; - case Opt_wsize: - if (get_option_ul(args, &option)) { - cERROR(1, "%s: Invalid wsize value", - __func__); - goto cifs_parse_mount_err; - } - vol->wsize = option; - break; - case Opt_actimeo: - if (get_option_ul(args, &option)) { - cERROR(1, "%s: Invalid actimeo value", - __func__); - goto cifs_parse_mount_err; - } - vol->actimeo = HZ * option; - if (vol->actimeo > CIFS_MAX_ACTIMEO) { - cERROR(1, "CIFS: attribute cache" - "timeout too large"); - goto cifs_parse_mount_err; - } - break; - - /* String Arguments */ - - case Opt_blank_user: - /* null user, ie. anonymous authentication */ - vol->nullauth = 1; - vol->username = NULL; - break; - case Opt_user: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - - if (strnlen(string, MAX_USERNAME_SIZE) > - MAX_USERNAME_SIZE) { - printk(KERN_WARNING "CIFS: username too long\n"); - goto cifs_parse_mount_err; - } - vol->username = kstrdup(string, GFP_KERNEL); - if (!vol->username) { - printk(KERN_WARNING "CIFS: no memory " - "for username\n"); - goto cifs_parse_mount_err; - } - break; - case Opt_blank_pass: - vol->password = NULL; - break; - case Opt_pass: - /* passwords have to be handled differently - * to allow the character used for deliminator - * to be passed within them - */ - - /* Obtain the value string */ - value = strchr(data, '='); - value++; - - /* Set tmp_end to end of the string */ - tmp_end = (char *) value + strlen(value); - - /* Check if following character is the deliminator - * If yes, we have encountered a double deliminator - * reset the NULL character to the deliminator - */ - if (tmp_end < end && tmp_end[1] == delim) - tmp_end[0] = delim; - - /* Keep iterating until we get to a single deliminator - * OR the end - */ - while ((tmp_end = strchr(tmp_end, delim)) != NULL && - (tmp_end[1] == delim)) { - tmp_end = (char *) &tmp_end[2]; - } - - /* Reset var options to point to next element */ - if (tmp_end) { - tmp_end[0] = '\0'; - options = (char *) &tmp_end[1]; - } else - /* Reached the end of the mount option string */ - options = end; - - /* Now build new password string */ - temp_len = strlen(value); - vol->password = kzalloc(temp_len+1, GFP_KERNEL); - if (vol->password == NULL) { - printk(KERN_WARNING "CIFS: no memory " - "for password\n"); - goto cifs_parse_mount_err; - } - - for (i = 0, j = 0; i < temp_len; i++, j++) { - vol->password[j] = value[i]; - if ((value[i] == delim) && - value[i+1] == delim) - /* skip the second deliminator */ - i++; - } - vol->password[j] = '\0'; - break; - case Opt_blank_ip: - vol->UNCip = NULL; - break; - case Opt_ip: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - - if (strnlen(string, INET6_ADDRSTRLEN) > - INET6_ADDRSTRLEN) { - printk(KERN_WARNING "CIFS: ip address " - "too long\n"); - goto cifs_parse_mount_err; - } - vol->UNCip = kstrdup(string, GFP_KERNEL); - if (!vol->UNCip) { - printk(KERN_WARNING "CIFS: no memory " - "for UNC IP\n"); - goto cifs_parse_mount_err; - } - break; - case Opt_unc: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - - temp_len = strnlen(string, 300); - if (temp_len == 300) { - printk(KERN_WARNING "CIFS: UNC name too long\n"); - goto cifs_parse_mount_err; - } - + } else + printk(KERN_WARNING "CIFS: Unknown mount option %s\n", + data); + } + if (vol->UNC == NULL) { + if (devname == NULL) { + printk(KERN_WARNING "CIFS: Missing UNC name for mount " + "target\n"); + goto cifs_parse_mount_err; + } + if ((temp_len = strnlen(devname, 300)) < 300) { vol->UNC = kmalloc(temp_len+1, GFP_KERNEL); - if (vol->UNC == NULL) { - printk(KERN_WARNING "CIFS: no memory for UNC\n"); + if (vol->UNC == NULL) goto cifs_parse_mount_err; - } - strcpy(vol->UNC, string); - - if (strncmp(string, "//", 2) == 0) { + strcpy(vol->UNC, devname); + if (strncmp(vol->UNC, "//", 2) == 0) { vol->UNC[0] = '\\'; vol->UNC[1] = '\\'; - } else if (strncmp(string, "\\\\", 2) != 0) { + } else if (strncmp(vol->UNC, "\\\\", 2) != 0) { printk(KERN_WARNING "CIFS: UNC Path does not " - "begin with // or \\\\\n"); - goto cifs_parse_mount_err; - } - - break; - case Opt_domain: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - - if (strnlen(string, 256) == 256) { - printk(KERN_WARNING "CIFS: domain name too" - " long\n"); - goto cifs_parse_mount_err; - } - - vol->domainname = kstrdup(string, GFP_KERNEL); - if (!vol->domainname) { - printk(KERN_WARNING "CIFS: no memory " - "for domainname\n"); - goto cifs_parse_mount_err; - } - cFYI(1, "Domain name set"); - break; - case Opt_srcaddr: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - - if (!cifs_convert_address( - (struct sockaddr *)&vol->srcaddr, - string, strlen(string))) { - printk(KERN_WARNING "CIFS: Could not parse" - " srcaddr: %s\n", string); - goto cifs_parse_mount_err; - } - break; - case Opt_prefixpath: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - - temp_len = strnlen(string, 1024); - if (string[0] != '/') - temp_len++; /* missing leading slash */ - if (temp_len > 1024) { - printk(KERN_WARNING "CIFS: prefix too long\n"); - goto cifs_parse_mount_err; - } - - vol->prepath = kmalloc(temp_len+1, GFP_KERNEL); - if (vol->prepath == NULL) { - printk(KERN_WARNING "CIFS: no memory " - "for path prefix\n"); - goto cifs_parse_mount_err; - } - - if (string[0] != '/') { - vol->prepath[0] = '/'; - strcpy(vol->prepath+1, string); - } else - strcpy(vol->prepath, string); - - break; - case Opt_iocharset: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - - if (strnlen(string, 1024) >= 65) { - printk(KERN_WARNING "CIFS: iocharset name " - "too long.\n"); + "begin with // or \\\\ \n"); goto cifs_parse_mount_err; } - - if (strnicmp(string, "default", 7) != 0) { - vol->iocharset = kstrdup(string, - GFP_KERNEL); - if (!vol->iocharset) { - printk(KERN_WARNING "CIFS: no memory" - "for charset\n"); - goto cifs_parse_mount_err; - } - } - /* if iocharset not set then load_nls_default - * is used by caller - */ - 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) - vol->sockopt_tcp_nodelay = 1; - break; - case Opt_netbiosname: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - - memset(vol->source_rfc1001_name, 0x20, - RFC1001_NAME_LEN); - /* - * FIXME: are there cases in which a comma can - * be valid in workstation netbios name (and - * need special handling)? - */ - for (i = 0; i < RFC1001_NAME_LEN; i++) { - /* don't ucase netbiosname for user */ - if (string[i] == 0) - break; - vol->source_rfc1001_name[i] = string[i]; - } - /* The string has 16th byte zero still from - * set at top of the function - */ - if (i == RFC1001_NAME_LEN && string[i] != 0) - printk(KERN_WARNING "CIFS: netbiosname" - " longer than 15 truncated.\n"); - - break; - case Opt_servern: - /* servernetbiosname specified override *SMBSERVER */ - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - - /* last byte, type, is 0x20 for servr type */ - memset(vol->target_rfc1001_name, 0x20, - RFC1001_NAME_LEN_WITH_NULL); - - /* BB are there cases in which a comma can be - valid in this workstation netbios name - (and need special handling)? */ - - /* user or mount helper must uppercase the - netbios name */ - for (i = 0; i < 15; i++) { - if (string[i] == 0) - break; - vol->target_rfc1001_name[i] = string[i]; - } - /* The string has 16th byte zero still from - set at top of the function */ - if (i == RFC1001_NAME_LEN && string[i] != 0) - printk(KERN_WARNING "CIFS: server net" - "biosname longer than 15 truncated.\n"); - break; - case Opt_ver: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - - if (strnicmp(string, "cifs", 4) == 0 || - strnicmp(string, "1", 1) == 0) { - /* This is the default */ - break; - } - /* For all other value, error */ - printk(KERN_WARNING "CIFS: Invalid version" - " specified\n"); + value = strpbrk(vol->UNC+2, "/\\"); + if (value) + *value = '\\'; + } else { + printk(KERN_WARNING "CIFS: UNC name too long\n"); goto cifs_parse_mount_err; - case Opt_sec: - string = match_strdup(args); - if (string == NULL) - goto out_nomem; - - if (cifs_parse_security_flavors(string, vol) != 0) - goto cifs_parse_mount_err; - break; - default: - /* - * An option we don't recognize. Save it off for later - * if we haven't already found one - */ - if (!invalid) - invalid = data; - break; } - /* Free up any allocated string */ - kfree(string); - string = NULL; - } - - if (!sloppy && invalid) { - printk(KERN_ERR "CIFS: Unknown mount option \"%s\"\n", invalid); - goto cifs_parse_mount_err; } #ifndef CONFIG_KEYS @@ -1883,10 +1625,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, kfree(mountdata_copy); return 0; -out_nomem: - printk(KERN_WARNING "Could not allocate temporary buffer\n"); cifs_parse_mount_err: - kfree(string); kfree(mountdata_copy); return 1; } @@ -2185,7 +1924,6 @@ cifs_get_tcp_session(struct smb_vol *volume_info) tcp_ses->session_estab = false; tcp_ses->sequence_number = 0; tcp_ses->lstrp = jiffies; - spin_lock_init(&tcp_ses->req_lock); INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); INIT_LIST_HEAD(&tcp_ses->smb_ses_list); INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request); @@ -2239,7 +1977,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info) cifs_fscache_get_client_cookie(tcp_ses); /* queue echo request delayed work */ - queue_delayed_work(cifsiod_wq, &tcp_ses->echo, SMB_ECHO_INTERVAL); + queue_delayed_work(system_nrt_wq, &tcp_ses->echo, SMB_ECHO_INTERVAL); return tcp_ses; @@ -3231,6 +2969,10 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, cifs_sb->mnt_uid = pvolume_info->linux_uid; cifs_sb->mnt_gid = pvolume_info->linux_gid; + if (pvolume_info->backupuid_specified) + cifs_sb->mnt_backupuid = pvolume_info->backupuid; + if (pvolume_info->backupgid_specified) + cifs_sb->mnt_backupgid = pvolume_info->backupgid; cifs_sb->mnt_file_mode = pvolume_info->file_mode; cifs_sb->mnt_dir_mode = pvolume_info->dir_mode; cFYI(1, "file mode: 0x%hx dir mode: 0x%hx", @@ -3261,14 +3003,10 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD; if (pvolume_info->cifs_acl) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; - if (pvolume_info->backupuid_specified) { + if (pvolume_info->backupuid_specified) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID; - cifs_sb->mnt_backupuid = pvolume_info->backupuid; - } - if (pvolume_info->backupgid_specified) { + if (pvolume_info->backupgid_specified) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID; - cifs_sb->mnt_backupgid = pvolume_info->backupgid; - } if (pvolume_info->override_uid) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID; if (pvolume_info->override_gid) @@ -3617,6 +3355,22 @@ cifs_get_volume_info(char *mount_data, const char *devname) return volume_info; } +/* make sure ra_pages is a multiple of rsize */ +static inline unsigned int +cifs_ra_pages(struct cifs_sb_info *cifs_sb) +{ + unsigned int reads; + unsigned int rsize_pages = cifs_sb->rsize / PAGE_CACHE_SIZE; + + if (rsize_pages >= default_backing_dev_info.ra_pages) + return default_backing_dev_info.ra_pages; + else if (rsize_pages == 0) + return rsize_pages; + + reads = default_backing_dev_info.ra_pages / rsize_pages; + return reads * rsize_pages; +} + int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) { @@ -3704,7 +3458,7 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) cifs_sb->rsize = cifs_negotiate_rsize(tcon, volume_info); /* tune readahead according to rsize */ - cifs_sb->bdi.ra_pages = cifs_sb->rsize / PAGE_CACHE_SIZE; + cifs_sb->bdi.ra_pages = cifs_ra_pages(cifs_sb); remote_path_check: #ifdef CONFIG_CIFS_DFS_UPCALL @@ -3789,7 +3543,7 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) tlink_rb_insert(&cifs_sb->tlink_tree, tlink); spin_unlock(&cifs_sb->tlink_tree_lock); - queue_delayed_work(cifsiod_wq, &cifs_sb->prune_tlinks, + queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks, TLINK_IDLE_EXPIRE); mount_fail_check: @@ -4343,6 +4097,6 @@ cifs_prune_tlinks(struct work_struct *work) } spin_unlock(&cifs_sb->tlink_tree_lock); - queue_delayed_work(cifsiod_wq, &cifs_sb->prune_tlinks, + queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks, TLINK_IDLE_EXPIRE); } diff --git a/trunk/fs/cifs/dir.c b/trunk/fs/cifs/dir.c index ec4e9a2a12f8..d172c8ed9017 100644 --- a/trunk/fs/cifs/dir.c +++ b/trunk/fs/cifs/dir.c @@ -668,19 +668,12 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) return 0; else { /* - * If the inode wasn't known to be a dfs entry when - * the dentry was instantiated, such as when created - * via ->readdir(), it needs to be set now since the - * attributes will have been updated by - * cifs_revalidate_dentry(). + * Forcibly invalidate automounting directory inodes + * (remote DFS directories) so to have them + * instantiated again for automount */ - if (IS_AUTOMOUNT(direntry->d_inode) && - !(direntry->d_flags & DCACHE_NEED_AUTOMOUNT)) { - spin_lock(&direntry->d_lock); - direntry->d_flags |= DCACHE_NEED_AUTOMOUNT; - spin_unlock(&direntry->d_lock); - } - + if (IS_AUTOMOUNT(direntry->d_inode)) + return 0; return 1; } } diff --git a/trunk/fs/cifs/file.c b/trunk/fs/cifs/file.c index 81725e9286e9..159fcc56dc2d 100644 --- a/trunk/fs/cifs/file.c +++ b/trunk/fs/cifs/file.c @@ -835,21 +835,13 @@ cifs_posix_lock_set(struct file *file, struct file_lock *flock) if ((flock->fl_flags & FL_POSIX) == 0) return rc; -try_again: mutex_lock(&cinode->lock_mutex); if (!cinode->can_cache_brlcks) { mutex_unlock(&cinode->lock_mutex); return rc; } - - rc = posix_lock_file(file, flock, NULL); + rc = posix_lock_file_wait(file, flock); mutex_unlock(&cinode->lock_mutex); - if (rc == FILE_LOCK_DEFERRED) { - rc = wait_event_interruptible(flock->fl_wait, !flock->fl_next); - if (!rc) - goto try_again; - locks_delete_block(flock); - } return rc; } @@ -1407,10 +1399,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock) return rc; } -/* - * update the file size (if needed) after a write. Should be called with - * the inode->i_lock held - */ +/* update the file size (if needed) after a write */ void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, unsigned int bytes_written) @@ -1482,9 +1471,7 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file, __u32 pid, return rc; } } else { - spin_lock(&dentry->d_inode->i_lock); cifs_update_eof(cifsi, *poffset, bytes_written); - spin_unlock(&dentry->d_inode->i_lock); *poffset += bytes_written; } } @@ -1661,27 +1648,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) return rc; } -/* - * Marshal up the iov array, reserving the first one for the header. Also, - * set wdata->bytes. - */ -static void -cifs_writepages_marshal_iov(struct kvec *iov, struct cifs_writedata *wdata) -{ - int i; - struct inode *inode = wdata->cfile->dentry->d_inode; - loff_t size = i_size_read(inode); - - /* marshal up the pages into iov array */ - wdata->bytes = 0; - for (i = 0; i < wdata->nr_pages; i++) { - iov[i + 1].iov_len = min(size - page_offset(wdata->pages[i]), - (loff_t)PAGE_CACHE_SIZE); - iov[i + 1].iov_base = kmap(wdata->pages[i]); - wdata->bytes += iov[i + 1].iov_len; - } -} - static int cifs_writepages(struct address_space *mapping, struct writeback_control *wbc) { @@ -1718,8 +1684,7 @@ static int cifs_writepages(struct address_space *mapping, tofind = min((cifs_sb->wsize / PAGE_CACHE_SIZE) - 1, end - index) + 1; - wdata = cifs_writedata_alloc((unsigned int)tofind, - cifs_writev_complete); + wdata = cifs_writedata_alloc((unsigned int)tofind); if (!wdata) { rc = -ENOMEM; break; @@ -1826,7 +1791,6 @@ static int cifs_writepages(struct address_space *mapping, wdata->sync_mode = wbc->sync_mode; wdata->nr_pages = nr_pages; wdata->offset = page_offset(wdata->pages[0]); - wdata->marshal_iov = cifs_writepages_marshal_iov; do { if (wdata->cfile != NULL) @@ -1838,7 +1802,6 @@ static int cifs_writepages(struct address_space *mapping, rc = -EBADF; break; } - wdata->pid = wdata->cfile->pid; rc = cifs_async_writev(wdata); } while (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN); @@ -2080,7 +2043,7 @@ cifs_write_allocate_pages(struct page **pages, unsigned long num_pages) unsigned long i; for (i = 0; i < num_pages; i++) { - pages[i] = alloc_page(GFP_KERNEL|__GFP_HIGHMEM); + pages[i] = alloc_page(__GFP_HIGHMEM); if (!pages[i]) { /* * save number of pages we have already allocated and @@ -2088,14 +2051,15 @@ cifs_write_allocate_pages(struct page **pages, unsigned long num_pages) */ num_pages = i; rc = -ENOMEM; - break; + goto error; } } - if (rc) { - for (i = 0; i < num_pages; i++) - put_page(pages[i]); - } + return rc; + +error: + for (i = 0; i < num_pages; i++) + put_page(pages[i]); return rc; } @@ -2106,7 +2070,9 @@ size_t get_numpages(const size_t wsize, const size_t len, size_t *cur_len) size_t clen; clen = min_t(const size_t, len, wsize); - num_pages = DIV_ROUND_UP(clen, PAGE_SIZE); + num_pages = clen / PAGE_CACHE_SIZE; + if (clen % PAGE_CACHE_SIZE) + num_pages++; if (cur_len) *cur_len = clen; @@ -2114,79 +2080,24 @@ size_t get_numpages(const size_t wsize, const size_t len, size_t *cur_len) return num_pages; } -static void -cifs_uncached_marshal_iov(struct kvec *iov, struct cifs_writedata *wdata) -{ - int i; - size_t bytes = wdata->bytes; - - /* marshal up the pages into iov array */ - for (i = 0; i < wdata->nr_pages; i++) { - iov[i + 1].iov_len = min_t(size_t, bytes, PAGE_SIZE); - iov[i + 1].iov_base = kmap(wdata->pages[i]); - bytes -= iov[i + 1].iov_len; - } -} - -static void -cifs_uncached_writev_complete(struct work_struct *work) -{ - int i; - struct cifs_writedata *wdata = container_of(work, - struct cifs_writedata, work); - struct inode *inode = wdata->cfile->dentry->d_inode; - struct cifsInodeInfo *cifsi = CIFS_I(inode); - - spin_lock(&inode->i_lock); - cifs_update_eof(cifsi, wdata->offset, wdata->bytes); - if (cifsi->server_eof > inode->i_size) - i_size_write(inode, cifsi->server_eof); - spin_unlock(&inode->i_lock); - - complete(&wdata->done); - - if (wdata->result != -EAGAIN) { - for (i = 0; i < wdata->nr_pages; i++) - put_page(wdata->pages[i]); - } - - kref_put(&wdata->refcount, cifs_writedata_release); -} - -/* attempt to send write to server, retry on any -EAGAIN errors */ -static int -cifs_uncached_retry_writev(struct cifs_writedata *wdata) -{ - int rc; - - do { - if (wdata->cfile->invalidHandle) { - rc = cifs_reopen_file(wdata->cfile, false); - if (rc != 0) - continue; - } - rc = cifs_async_writev(wdata); - } while (rc == -EAGAIN); - - return rc; -} - static ssize_t cifs_iovec_write(struct file *file, const struct iovec *iov, unsigned long nr_segs, loff_t *poffset) { - unsigned long nr_pages, i; + unsigned int written; + unsigned long num_pages, npages, i; size_t copied, len, cur_len; ssize_t total_written = 0; - loff_t offset; + struct kvec *to_send; + struct page **pages; struct iov_iter it; + struct inode *inode; struct cifsFileInfo *open_file; - struct cifs_tcon *tcon; + struct cifs_tcon *pTcon; struct cifs_sb_info *cifs_sb; - struct cifs_writedata *wdata, *tmp; - struct list_head wdata_list; - int rc; - pid_t pid; + struct cifs_io_parms io_parms; + int xid, rc; + __u32 pid; len = iov_length(iov, nr_segs); if (!len) @@ -2196,104 +2107,103 @@ cifs_iovec_write(struct file *file, const struct iovec *iov, if (rc) return rc; - INIT_LIST_HEAD(&wdata_list); cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); + num_pages = get_numpages(cifs_sb->wsize, len, &cur_len); + + pages = kmalloc(sizeof(struct pages *)*num_pages, GFP_KERNEL); + if (!pages) + return -ENOMEM; + + to_send = kmalloc(sizeof(struct kvec)*(num_pages + 1), GFP_KERNEL); + if (!to_send) { + kfree(pages); + return -ENOMEM; + } + + rc = cifs_write_allocate_pages(pages, num_pages); + if (rc) { + kfree(pages); + kfree(to_send); + return rc; + } + + xid = GetXid(); open_file = file->private_data; - tcon = tlink_tcon(open_file->tlink); - offset = *poffset; if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) pid = open_file->pid; else pid = current->tgid; - iov_iter_init(&it, iov, nr_segs, len, 0); - do { - size_t save_len; - - nr_pages = get_numpages(cifs_sb->wsize, len, &cur_len); - wdata = cifs_writedata_alloc(nr_pages, - cifs_uncached_writev_complete); - if (!wdata) { - rc = -ENOMEM; - break; - } + pTcon = tlink_tcon(open_file->tlink); + inode = file->f_path.dentry->d_inode; - rc = cifs_write_allocate_pages(wdata->pages, nr_pages); - if (rc) { - kfree(wdata); - break; - } + iov_iter_init(&it, iov, nr_segs, len, 0); + npages = num_pages; - save_len = cur_len; - for (i = 0; i < nr_pages; i++) { - copied = min_t(const size_t, cur_len, PAGE_SIZE); - copied = iov_iter_copy_from_user(wdata->pages[i], &it, - 0, copied); + do { + size_t save_len = cur_len; + for (i = 0; i < npages; i++) { + copied = min_t(const size_t, cur_len, PAGE_CACHE_SIZE); + copied = iov_iter_copy_from_user(pages[i], &it, 0, + copied); cur_len -= copied; iov_iter_advance(&it, copied); + to_send[i+1].iov_base = kmap(pages[i]); + to_send[i+1].iov_len = copied; } + cur_len = save_len - cur_len; - wdata->sync_mode = WB_SYNC_ALL; - wdata->nr_pages = nr_pages; - wdata->offset = (__u64)offset; - wdata->cfile = cifsFileInfo_get(open_file); - wdata->pid = pid; - wdata->bytes = cur_len; - wdata->marshal_iov = cifs_uncached_marshal_iov; - rc = cifs_uncached_retry_writev(wdata); - if (rc) { - kref_put(&wdata->refcount, cifs_writedata_release); + do { + if (open_file->invalidHandle) { + rc = cifs_reopen_file(open_file, false); + if (rc != 0) + break; + } + io_parms.netfid = open_file->netfid; + io_parms.pid = pid; + io_parms.tcon = pTcon; + io_parms.offset = *poffset; + io_parms.length = cur_len; + rc = CIFSSMBWrite2(xid, &io_parms, &written, to_send, + npages, 0); + } while (rc == -EAGAIN); + + for (i = 0; i < npages; i++) + kunmap(pages[i]); + + if (written) { + len -= written; + total_written += written; + cifs_update_eof(CIFS_I(inode), *poffset, written); + *poffset += written; + } else if (rc < 0) { + if (!total_written) + total_written = rc; break; } - list_add_tail(&wdata->list, &wdata_list); - offset += cur_len; - len -= cur_len; + /* get length and number of kvecs of the next write */ + npages = get_numpages(cifs_sb->wsize, len, &cur_len); } while (len > 0); - /* - * If at least one write was successfully sent, then discard any rc - * value from the later writes. If the other write succeeds, then - * we'll end up returning whatever was written. If it fails, then - * we'll get a new rc value from that. - */ - if (!list_empty(&wdata_list)) - rc = 0; - - /* - * Wait for and collect replies for any successful sends in order of - * increasing offset. Once an error is hit or we get a fatal signal - * while waiting, then return without waiting for any more replies. - */ -restart_loop: - list_for_each_entry_safe(wdata, tmp, &wdata_list, list) { - if (!rc) { - /* FIXME: freezable too? */ - rc = wait_for_completion_killable(&wdata->done); - if (rc) - rc = -EINTR; - else if (wdata->result) - rc = wdata->result; - else - total_written += wdata->bytes; - - /* resend call if it's a retryable error */ - if (rc == -EAGAIN) { - rc = cifs_uncached_retry_writev(wdata); - goto restart_loop; - } - } - list_del_init(&wdata->list); - kref_put(&wdata->refcount, cifs_writedata_release); + if (total_written > 0) { + spin_lock(&inode->i_lock); + if (*poffset > inode->i_size) + i_size_write(inode, *poffset); + spin_unlock(&inode->i_lock); } - if (total_written > 0) - *poffset += total_written; + cifs_stats_bytes_written(pTcon, total_written); + mark_inode_dirty_sync(inode); - cifs_stats_bytes_written(tcon, total_written); - return total_written ? total_written : (ssize_t)rc; + for (i = 0; i < num_pages; i++) + put_page(pages[i]); + kfree(to_send); + kfree(pages); + FreeXid(xid); + return total_written; } ssize_t cifs_user_writev(struct kiocb *iocb, const struct iovec *iov, diff --git a/trunk/fs/cifs/misc.c b/trunk/fs/cifs/misc.c index c29d1aa2c54f..c273c12de98e 100644 --- a/trunk/fs/cifs/misc.c +++ b/trunk/fs/cifs/misc.c @@ -213,62 +213,55 @@ cifs_small_buf_release(void *buf_to_free) } /* - * Find a free multiplex id (SMB mid). Otherwise there could be - * mid collisions which might cause problems, demultiplexing the - * wrong response to this request. Multiplex ids could collide if - * one of a series requests takes much longer than the others, or - * if a very large number of long lived requests (byte range - * locks or FindNotify requests) are pending. No more than - * 64K-1 requests can be outstanding at one time. If no - * mids are available, return zero. A future optimization - * could make the combination of mids and uid the key we use - * to demultiplex on (rather than mid alone). - * In addition to the above check, the cifs demultiplex - * code already used the command code as a secondary - * check of the frame and if signing is negotiated the - * response would be discarded if the mid were the same - * but the signature was wrong. Since the mid is not put in the - * pending queue until later (when it is about to be dispatched) - * we do have to limit the number of outstanding requests - * to somewhat less than 64K-1 although it is hard to imagine - * so many threads being in the vfs at one time. - */ -__u64 GetNextMid(struct TCP_Server_Info *server) + Find a free multiplex id (SMB mid). Otherwise there could be + mid collisions which might cause problems, demultiplexing the + wrong response to this request. Multiplex ids could collide if + one of a series requests takes much longer than the others, or + if a very large number of long lived requests (byte range + locks or FindNotify requests) are pending. No more than + 64K-1 requests can be outstanding at one time. If no + mids are available, return zero. A future optimization + could make the combination of mids and uid the key we use + to demultiplex on (rather than mid alone). + In addition to the above check, the cifs demultiplex + code already used the command code as a secondary + check of the frame and if signing is negotiated the + response would be discarded if the mid were the same + but the signature was wrong. Since the mid is not put in the + pending queue until later (when it is about to be dispatched) + we do have to limit the number of outstanding requests + to somewhat less than 64K-1 although it is hard to imagine + so many threads being in the vfs at one time. +*/ +__u16 GetNextMid(struct TCP_Server_Info *server) { - __u64 mid = 0; - __u16 last_mid, cur_mid; + __u16 mid = 0; + __u16 last_mid; bool collision; spin_lock(&GlobalMid_Lock); - - /* mid is 16 bit only for CIFS/SMB */ - cur_mid = (__u16)((server->CurrentMid) & 0xffff); - /* we do not want to loop forever */ - last_mid = cur_mid; - cur_mid++; - - /* - * This nested loop looks more expensive than it is. - * In practice the list of pending requests is short, - * fewer than 50, and the mids are likely to be unique - * on the first pass through the loop unless some request - * takes longer than the 64 thousand requests before it - * (and it would also have to have been a request that - * did not time out). - */ - while (cur_mid != last_mid) { + last_mid = server->CurrentMid; /* we do not want to loop forever */ + server->CurrentMid++; + /* This nested loop looks more expensive than it is. + In practice the list of pending requests is short, + fewer than 50, and the mids are likely to be unique + on the first pass through the loop unless some request + takes longer than the 64 thousand requests before it + (and it would also have to have been a request that + did not time out) */ + while (server->CurrentMid != last_mid) { struct mid_q_entry *mid_entry; unsigned int num_mids; collision = false; - if (cur_mid == 0) - cur_mid++; + if (server->CurrentMid == 0) + server->CurrentMid++; num_mids = 0; list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) { ++num_mids; - if (mid_entry->mid == cur_mid && - mid_entry->mid_state == MID_REQUEST_SUBMITTED) { + if (mid_entry->mid == server->CurrentMid && + mid_entry->midState == MID_REQUEST_SUBMITTED) { /* This mid is in use, try a different one */ collision = true; break; @@ -289,11 +282,10 @@ __u64 GetNextMid(struct TCP_Server_Info *server) server->tcpStatus = CifsNeedReconnect; if (!collision) { - mid = (__u64)cur_mid; - server->CurrentMid = mid; + mid = server->CurrentMid; break; } - cur_mid++; + server->CurrentMid++; } spin_unlock(&GlobalMid_Lock); return mid; @@ -428,10 +420,8 @@ check_smb_hdr(struct smb_hdr *smb, __u16 mid) } int -checkSMB(char *buf, unsigned int total_read) +checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int total_read) { - struct smb_hdr *smb = (struct smb_hdr *)buf; - __u16 mid = smb->Mid; __u32 rfclen = be32_to_cpu(smb->smb_buf_length); __u32 clc_len; /* calculated length */ cFYI(0, "checkSMB Length: 0x%x, smb_buf_length: 0x%x", @@ -512,9 +502,8 @@ checkSMB(char *buf, unsigned int total_read) } bool -is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) +is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) { - struct smb_hdr *buf = (struct smb_hdr *)buffer; struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf; struct list_head *tmp, *tmp1, *tmp2; struct cifs_ses *ses; @@ -595,7 +584,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) cifs_set_oplock_level(pCifsInode, pSMB->OplockLevel ? OPLOCK_READ : 0); - queue_work(cifsiod_wq, + queue_work(system_nrt_wq, &netfile->oplock_break); netfile->oplock_break_cancelled = false; @@ -615,15 +604,16 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) } void -dump_smb(void *buf, int smb_buf_length) +dump_smb(struct smb_hdr *smb_buf, int smb_buf_length) { int i, j; char debug_line[17]; - unsigned char *buffer = buf; + unsigned char *buffer; if (traceSMB == 0) return; + buffer = (unsigned char *) smb_buf; for (i = 0, j = 0; i < smb_buf_length; i++, j++) { if (i % 8 == 0) { /* have reached the beginning of line */ diff --git a/trunk/fs/cifs/netmisc.c b/trunk/fs/cifs/netmisc.c index 581c225f7f50..73e47e84b61a 100644 --- a/trunk/fs/cifs/netmisc.c +++ b/trunk/fs/cifs/netmisc.c @@ -197,7 +197,8 @@ cifs_convert_address(struct sockaddr *dst, const char *src, int len) memcpy(scope_id, pct + 1, slen); scope_id[slen] = '\0'; - rc = kstrtouint(scope_id, 0, &s6->sin6_scope_id); + rc = strict_strtoul(scope_id, 0, + (unsigned long *)&s6->sin6_scope_id); rc = (rc == 0) ? 1 : 0; } @@ -835,9 +836,8 @@ ntstatus_to_dos(__u32 ntstatus, __u8 *eclass, __u16 *ecode) } int -map_smb_to_linux_error(char *buf, bool logErr) +map_smb_to_linux_error(struct smb_hdr *smb, bool logErr) { - struct smb_hdr *smb = (struct smb_hdr *)buf; unsigned int i; int rc = -EIO; /* if transport error smb error may not be set */ __u8 smberrclass; diff --git a/trunk/fs/cifs/transport.c b/trunk/fs/cifs/transport.c index 0961336513d5..310918b6fcb4 100644 --- a/trunk/fs/cifs/transport.c +++ b/trunk/fs/cifs/transport.c @@ -60,8 +60,8 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server) memset(temp, 0, sizeof(struct mid_q_entry)); temp->mid = smb_buffer->Mid; /* always LE */ temp->pid = current->pid; - temp->command = cpu_to_le16(smb_buffer->Command); - cFYI(1, "For smb_command %d", smb_buffer->Command); + temp->command = smb_buffer->Command; + cFYI(1, "For smb_command %d", temp->command); /* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */ /* when mid allocated can be before when sent */ temp->when_alloc = jiffies; @@ -75,7 +75,7 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server) } atomic_inc(&midCount); - temp->mid_state = MID_REQUEST_ALLOCATED; + temp->midState = MID_REQUEST_ALLOCATED; return temp; } @@ -85,9 +85,9 @@ DeleteMidQEntry(struct mid_q_entry *midEntry) #ifdef CONFIG_CIFS_STATS2 unsigned long now; #endif - midEntry->mid_state = MID_FREE; + midEntry->midState = MID_FREE; atomic_dec(&midCount); - if (midEntry->large_buf) + if (midEntry->largeBuf) cifs_buf_release(midEntry->resp_buf); else cifs_small_buf_release(midEntry->resp_buf); @@ -97,8 +97,8 @@ DeleteMidQEntry(struct mid_q_entry *midEntry) something is wrong, unless it is quite a slow link or server */ if ((now - midEntry->when_alloc) > HZ) { if ((cifsFYI & CIFS_TIMER) && - (midEntry->command != cpu_to_le16(SMB_COM_LOCKING_ANDX))) { - printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %llu", + (midEntry->command != SMB_COM_LOCKING_ANDX)) { + printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d", midEntry->command, midEntry->mid); printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n", now - midEntry->when_alloc, @@ -126,11 +126,11 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec) int rc = 0; int i = 0; struct msghdr smb_msg; - __be32 *buf_len = (__be32 *)(iov[0].iov_base); + struct smb_hdr *smb_buffer = iov[0].iov_base; unsigned int len = iov[0].iov_len; unsigned int total_len; int first_vec = 0; - unsigned int smb_buf_length = get_rfc1002_length(iov[0].iov_base); + unsigned int smb_buf_length = be32_to_cpu(smb_buffer->smb_buf_length); struct socket *ssocket = server->ssocket; if (ssocket == NULL) @@ -150,7 +150,7 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec) total_len += iov[i].iov_len; cFYI(1, "Sending smb: total_len %d", total_len); - dump_smb(iov[0].iov_base, len); + dump_smb(smb_buffer, len); i = 0; while (total_len) { @@ -158,24 +158,24 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec) n_vec - first_vec, total_len); if ((rc == -ENOSPC) || (rc == -EAGAIN)) { i++; - /* - * If blocking send we try 3 times, since each can block - * for 5 seconds. For nonblocking we have to try more - * but wait increasing amounts of time allowing time for - * socket to clear. The overall time we wait in either - * case to send on the socket is about 15 seconds. - * Similarly we wait for 15 seconds for a response from - * the server in SendReceive[2] for the server to send - * a response back for most types of requests (except - * SMB Write past end of file which can be slow, and - * blocking lock operations). NFS waits slightly longer - * than CIFS, but this can make it take longer for - * nonresponsive servers to be detected and 15 seconds - * is more than enough time for modern networks to - * send a packet. In most cases if we fail to send - * after the retries we will kill the socket and - * reconnect which may clear the network problem. - */ + /* if blocking send we try 3 times, since each can block + for 5 seconds. For nonblocking we have to try more + but wait increasing amounts of time allowing time for + socket to clear. The overall time we wait in either + case to send on the socket is about 15 seconds. + Similarly we wait for 15 seconds for + a response from the server in SendReceive[2] + for the server to send a response back for + most types of requests (except SMB Write + past end of file which can be slow, and + blocking lock operations). NFS waits slightly longer + than CIFS, but this can make it take longer for + nonresponsive servers to be detected and 15 seconds + is more than enough time for modern networks to + send a packet. In most cases if we fail to send + after the retries we will kill the socket and + reconnect which may clear the network problem. + */ if ((i >= 14) || (!server->noblocksnd && (i > 2))) { cERROR(1, "sends on sock %p stuck for 15 seconds", ssocket); @@ -235,8 +235,9 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec) else rc = 0; - /* Don't want to modify the buffer as a side effect of this call. */ - *buf_len = cpu_to_be32(smb_buf_length); + /* Don't want to modify the buffer as a + side effect of this call. */ + smb_buffer->smb_buf_length = cpu_to_be32(smb_buf_length); return rc; } @@ -341,40 +342,13 @@ wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ) int error; error = wait_event_freezekillable(server->response_q, - midQ->mid_state != MID_REQUEST_SUBMITTED); + midQ->midState != MID_REQUEST_SUBMITTED); if (error < 0) return -ERESTARTSYS; return 0; } -static int -cifs_setup_async_request(struct TCP_Server_Info *server, struct kvec *iov, - unsigned int nvec, struct mid_q_entry **ret_mid) -{ - int rc; - struct smb_hdr *hdr = (struct smb_hdr *)iov[0].iov_base; - struct mid_q_entry *mid; - - /* enable signing if server requires it */ - if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) - hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; - - mid = AllocMidQEntry(hdr, server); - if (mid == NULL) - return -ENOMEM; - - /* put it on the pending_mid_q */ - spin_lock(&GlobalMid_Lock); - list_add_tail(&mid->qhead, &server->pending_mid_q); - spin_unlock(&GlobalMid_Lock); - - rc = cifs_sign_smb2(iov, nvec, server, &mid->sequence_number); - if (rc) - delete_mid(mid); - *ret_mid = mid; - return rc; -} /* * Send a SMB request and set the callback function in the mid to handle @@ -387,24 +361,40 @@ cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov, { int rc; struct mid_q_entry *mid; + struct smb_hdr *hdr = (struct smb_hdr *)iov[0].iov_base; rc = wait_for_free_request(server, ignore_pend ? CIFS_ASYNC_OP : 0); if (rc) return rc; + /* enable signing if server requires it */ + if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) + hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; + mutex_lock(&server->srv_mutex); - rc = cifs_setup_async_request(server, iov, nvec, &mid); - if (rc) { + mid = AllocMidQEntry(hdr, server); + if (mid == NULL) { mutex_unlock(&server->srv_mutex); cifs_add_credits(server, 1); wake_up(&server->request_q); - return rc; + return -ENOMEM; + } + + /* put it on the pending_mid_q */ + spin_lock(&GlobalMid_Lock); + list_add_tail(&mid->qhead, &server->pending_mid_q); + spin_unlock(&GlobalMid_Lock); + + rc = cifs_sign_smb2(iov, nvec, server, &mid->sequence_number); + if (rc) { + mutex_unlock(&server->srv_mutex); + goto out_err; } mid->receive = receive; mid->callback = callback; mid->callback_data = cbdata; - mid->mid_state = MID_REQUEST_SUBMITTED; + mid->midState = MID_REQUEST_SUBMITTED; cifs_in_send_inc(server); rc = smb_sendv(server, iov, nvec); @@ -434,14 +424,14 @@ cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov, */ int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses, - char *in_buf, int flags) + struct smb_hdr *in_buf, int flags) { int rc; struct kvec iov[1]; int resp_buf_type; - iov[0].iov_base = in_buf; - iov[0].iov_len = get_rfc1002_length(in_buf) + 4; + iov[0].iov_base = (char *)in_buf; + iov[0].iov_len = be32_to_cpu(in_buf->smb_buf_length) + 4; flags |= CIFS_NO_RESP; rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags); cFYI(DBG2, "SendRcvNoRsp flags %d rc %d", flags, rc); @@ -454,11 +444,11 @@ cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) { int rc = 0; - cFYI(1, "%s: cmd=%d mid=%llu state=%d", __func__, - le16_to_cpu(mid->command), mid->mid, mid->mid_state); + cFYI(1, "%s: cmd=%d mid=%d state=%d", __func__, mid->command, + mid->mid, mid->midState); spin_lock(&GlobalMid_Lock); - switch (mid->mid_state) { + switch (mid->midState) { case MID_RESPONSE_RECEIVED: spin_unlock(&GlobalMid_Lock); return rc; @@ -473,8 +463,8 @@ cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) break; default: list_del_init(&mid->qhead); - cERROR(1, "%s: invalid mid state mid=%llu state=%d", __func__, - mid->mid, mid->mid_state); + cERROR(1, "%s: invalid mid state mid=%d state=%d", __func__, + mid->mid, mid->midState); rc = -EIO; } spin_unlock(&GlobalMid_Lock); @@ -524,7 +514,7 @@ int cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server, bool log_error) { - unsigned int len = get_rfc1002_length(mid->resp_buf) + 4; + unsigned int len = be32_to_cpu(mid->resp_buf->smb_buf_length) + 4; dump_smb(mid->resp_buf, min_t(u32, 92, len)); @@ -544,24 +534,6 @@ cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server, return map_smb_to_linux_error(mid->resp_buf, log_error); } -static int -cifs_setup_request(struct cifs_ses *ses, struct kvec *iov, - unsigned int nvec, struct mid_q_entry **ret_mid) -{ - int rc; - struct smb_hdr *hdr = (struct smb_hdr *)iov[0].iov_base; - struct mid_q_entry *mid; - - rc = allocate_mid(ses, hdr, &mid); - if (rc) - return rc; - rc = cifs_sign_smb2(iov, nvec, ses->server, &mid->sequence_number); - if (rc) - delete_mid(mid); - *ret_mid = mid; - return rc; -} - int SendReceive2(const unsigned int xid, struct cifs_ses *ses, struct kvec *iov, int n_vec, int *pRespBufType /* ret */, @@ -570,53 +542,55 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, int rc = 0; int long_op; struct mid_q_entry *midQ; - char *buf = iov[0].iov_base; + struct smb_hdr *in_buf = iov[0].iov_base; long_op = flags & CIFS_TIMEOUT_MASK; *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ if ((ses == NULL) || (ses->server == NULL)) { - cifs_small_buf_release(buf); + cifs_small_buf_release(in_buf); cERROR(1, "Null session"); return -EIO; } if (ses->server->tcpStatus == CifsExiting) { - cifs_small_buf_release(buf); + cifs_small_buf_release(in_buf); return -ENOENT; } - /* - * Ensure that we do not send more than 50 overlapping requests - * to the same server. We may make this configurable later or - * use ses->maxReq. - */ + /* Ensure that we do not send more than 50 overlapping requests + to the same server. We may make this configurable later or + use ses->maxReq */ rc = wait_for_free_request(ses->server, long_op); if (rc) { - cifs_small_buf_release(buf); + cifs_small_buf_release(in_buf); return rc; } - /* - * Make sure that we sign in the same order that we send on this socket - * and avoid races inside tcp sendmsg code that could cause corruption - * of smb data. - */ + /* make sure that we sign in the same order that we send on this socket + and avoid races inside tcp sendmsg code that could cause corruption + of smb data */ mutex_lock(&ses->server->srv_mutex); - rc = cifs_setup_request(ses, iov, n_vec, &midQ); + rc = allocate_mid(ses, in_buf, &midQ); if (rc) { mutex_unlock(&ses->server->srv_mutex); - cifs_small_buf_release(buf); + cifs_small_buf_release(in_buf); /* Update # of requests on wire to server */ cifs_add_credits(ses->server, 1); return rc; } + rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); + if (rc) { + mutex_unlock(&ses->server->srv_mutex); + cifs_small_buf_release(in_buf); + goto out; + } - midQ->mid_state = MID_REQUEST_SUBMITTED; + midQ->midState = MID_REQUEST_SUBMITTED; cifs_in_send_inc(ses->server); rc = smb_sendv(ses->server, iov, n_vec); cifs_in_send_dec(ses->server); @@ -625,30 +599,30 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, mutex_unlock(&ses->server->srv_mutex); if (rc < 0) { - cifs_small_buf_release(buf); + cifs_small_buf_release(in_buf); goto out; } if (long_op == CIFS_ASYNC_OP) { - cifs_small_buf_release(buf); + cifs_small_buf_release(in_buf); goto out; } rc = wait_for_response(ses->server, midQ); if (rc != 0) { - send_nt_cancel(ses->server, (struct smb_hdr *)buf, midQ); + send_nt_cancel(ses->server, in_buf, midQ); spin_lock(&GlobalMid_Lock); - if (midQ->mid_state == MID_REQUEST_SUBMITTED) { + if (midQ->midState == MID_REQUEST_SUBMITTED) { midQ->callback = DeleteMidQEntry; spin_unlock(&GlobalMid_Lock); - cifs_small_buf_release(buf); + cifs_small_buf_release(in_buf); cifs_add_credits(ses->server, 1); return rc; } spin_unlock(&GlobalMid_Lock); } - cifs_small_buf_release(buf); + cifs_small_buf_release(in_buf); rc = cifs_sync_mid_result(midQ, ses->server); if (rc != 0) { @@ -656,16 +630,15 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, return rc; } - if (!midQ->resp_buf || midQ->mid_state != MID_RESPONSE_RECEIVED) { + if (!midQ->resp_buf || midQ->midState != MID_RESPONSE_RECEIVED) { rc = -EIO; cFYI(1, "Bad MID state?"); goto out; } - buf = (char *)midQ->resp_buf; - iov[0].iov_base = buf; - iov[0].iov_len = get_rfc1002_length(buf) + 4; - if (midQ->large_buf) + iov[0].iov_base = (char *)midQ->resp_buf; + iov[0].iov_len = be32_to_cpu(midQ->resp_buf->smb_buf_length) + 4; + if (midQ->largeBuf) *pRespBufType = CIFS_LARGE_BUFFER; else *pRespBufType = CIFS_SMALL_BUFFER; @@ -737,7 +710,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, goto out; } - midQ->mid_state = MID_REQUEST_SUBMITTED; + midQ->midState = MID_REQUEST_SUBMITTED; cifs_in_send_inc(ses->server); rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length)); @@ -755,7 +728,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, if (rc != 0) { send_nt_cancel(ses->server, in_buf, midQ); spin_lock(&GlobalMid_Lock); - if (midQ->mid_state == MID_REQUEST_SUBMITTED) { + if (midQ->midState == MID_REQUEST_SUBMITTED) { /* no longer considered to be "in-flight" */ midQ->callback = DeleteMidQEntry; spin_unlock(&GlobalMid_Lock); @@ -772,13 +745,13 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, } if (!midQ->resp_buf || !out_buf || - midQ->mid_state != MID_RESPONSE_RECEIVED) { + midQ->midState != MID_RESPONSE_RECEIVED) { rc = -EIO; cERROR(1, "Bad MID state?"); goto out; } - *pbytes_returned = get_rfc1002_length(midQ->resp_buf); + *pbytes_returned = be32_to_cpu(midQ->resp_buf->smb_buf_length); memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4); rc = cifs_check_receive(midQ, ses->server, 0); out: @@ -871,7 +844,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, return rc; } - midQ->mid_state = MID_REQUEST_SUBMITTED; + midQ->midState = MID_REQUEST_SUBMITTED; cifs_in_send_inc(ses->server); rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length)); cifs_in_send_dec(ses->server); @@ -885,13 +858,13 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, /* Wait for a reply - allow signals to interrupt. */ rc = wait_event_interruptible(ses->server->response_q, - (!(midQ->mid_state == MID_REQUEST_SUBMITTED)) || + (!(midQ->midState == MID_REQUEST_SUBMITTED)) || ((ses->server->tcpStatus != CifsGood) && (ses->server->tcpStatus != CifsNew))); /* Were we interrupted by a signal ? */ if ((rc == -ERESTARTSYS) && - (midQ->mid_state == MID_REQUEST_SUBMITTED) && + (midQ->midState == MID_REQUEST_SUBMITTED) && ((ses->server->tcpStatus == CifsGood) || (ses->server->tcpStatus == CifsNew))) { @@ -921,7 +894,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, if (rc) { send_nt_cancel(ses->server, in_buf, midQ); spin_lock(&GlobalMid_Lock); - if (midQ->mid_state == MID_REQUEST_SUBMITTED) { + if (midQ->midState == MID_REQUEST_SUBMITTED) { /* no longer considered to be "in-flight" */ midQ->callback = DeleteMidQEntry; spin_unlock(&GlobalMid_Lock); @@ -939,13 +912,13 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, return rc; /* rcvd frame is ok */ - if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) { + if (out_buf == NULL || midQ->midState != MID_RESPONSE_RECEIVED) { rc = -EIO; cERROR(1, "Bad MID state?"); goto out; } - *pbytes_returned = get_rfc1002_length(midQ->resp_buf); + *pbytes_returned = be32_to_cpu(midQ->resp_buf->smb_buf_length); memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4); rc = cifs_check_receive(midQ, ses->server, 0); out: diff --git a/trunk/fs/dcache.c b/trunk/fs/dcache.c index b80531c91779..b60ddc41d783 100644 --- a/trunk/fs/dcache.c +++ b/trunk/fs/dcache.c @@ -141,29 +141,18 @@ int proc_nr_dentry(ctl_table *table, int write, void __user *buffer, * Compare 2 name strings, return 0 if they match, otherwise non-zero. * The strings are both count bytes long, and count is non-zero. */ -#ifdef CONFIG_DCACHE_WORD_ACCESS - -#include -/* - * NOTE! 'cs' and 'scount' come from a dentry, so it has a - * aligned allocation for this particular component. We don't - * strictly need the load_unaligned_zeropad() safety, but it - * doesn't hurt either. - * - * In contrast, 'ct' and 'tcount' can be from a pathname, and do - * need the careful unaligned handling. - */ static inline int dentry_cmp(const unsigned char *cs, size_t scount, const unsigned char *ct, size_t tcount) { +#ifdef CONFIG_DCACHE_WORD_ACCESS unsigned long a,b,mask; if (unlikely(scount != tcount)) return 1; for (;;) { - a = load_unaligned_zeropad(cs); - b = load_unaligned_zeropad(ct); + a = *(unsigned long *)cs; + b = *(unsigned long *)ct; if (tcount < sizeof(unsigned long)) break; if (unlikely(a != b)) @@ -176,13 +165,7 @@ static inline int dentry_cmp(const unsigned char *cs, size_t scount, } mask = ~(~0ul << tcount*8); return unlikely(!!((a ^ b) & mask)); -} - #else - -static inline int dentry_cmp(const unsigned char *cs, size_t scount, - const unsigned char *ct, size_t tcount) -{ if (scount != tcount) return 1; @@ -194,9 +177,8 @@ static inline int dentry_cmp(const unsigned char *cs, size_t scount, tcount--; } while (tcount); return 0; -} - #endif +} static void __d_free(struct rcu_head *head) { diff --git a/trunk/fs/debugfs/file.c b/trunk/fs/debugfs/file.c index 5dfafdd1dbd3..21e93605161c 100644 --- a/trunk/fs/debugfs/file.c +++ b/trunk/fs/debugfs/file.c @@ -33,10 +33,18 @@ static ssize_t default_write_file(struct file *file, const char __user *buf, return count; } +static int default_open(struct inode *inode, struct file *file) +{ + if (inode->i_private) + file->private_data = inode->i_private; + + return 0; +} + const struct file_operations debugfs_file_operations = { .read = default_read_file, .write = default_write_file, - .open = simple_open, + .open = default_open, .llseek = noop_llseek, }; @@ -439,7 +447,7 @@ static ssize_t write_file_bool(struct file *file, const char __user *user_buf, static const struct file_operations fops_bool = { .read = read_file_bool, .write = write_file_bool, - .open = simple_open, + .open = default_open, .llseek = default_llseek, }; @@ -484,7 +492,7 @@ static ssize_t read_file_blob(struct file *file, char __user *user_buf, static const struct file_operations fops_blob = { .read = read_file_blob, - .open = simple_open, + .open = default_open, .llseek = default_llseek, }; diff --git a/trunk/fs/dlm/debug_fs.c b/trunk/fs/dlm/debug_fs.c index 1c9b08095f98..3dca2b39e83f 100644 --- a/trunk/fs/dlm/debug_fs.c +++ b/trunk/fs/dlm/debug_fs.c @@ -609,6 +609,13 @@ static const struct file_operations format3_fops = { /* * dump lkb's on the ls_waiters list */ + +static int waiters_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static ssize_t waiters_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { @@ -637,7 +644,7 @@ static ssize_t waiters_read(struct file *file, char __user *userbuf, static const struct file_operations waiters_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = waiters_open, .read = waiters_read, .llseek = default_llseek, }; diff --git a/trunk/fs/dlm/lock.c b/trunk/fs/dlm/lock.c index 4c58d4a3adc4..fa5c07d51dcc 100644 --- a/trunk/fs/dlm/lock.c +++ b/trunk/fs/dlm/lock.c @@ -1736,18 +1736,6 @@ static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now) if (now && conv && !(lkb->lkb_exflags & DLM_LKF_QUECVT)) return 1; - /* - * Even if the convert is compat with all granted locks, - * QUECVT forces it behind other locks on the convert queue. - */ - - if (now && conv && (lkb->lkb_exflags & DLM_LKF_QUECVT)) { - if (list_empty(&r->res_convertqueue)) - return 1; - else - goto out; - } - /* * The NOORDER flag is set to avoid the standard vms rules on grant * order. diff --git a/trunk/fs/eventpoll.c b/trunk/fs/eventpoll.c index c0b3c70ee87a..739b0985b398 100644 --- a/trunk/fs/eventpoll.c +++ b/trunk/fs/eventpoll.c @@ -1663,10 +1663,8 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, if (op == EPOLL_CTL_ADD) { if (is_file_epoll(tfile)) { error = -ELOOP; - if (ep_loop_check(ep, tfile) != 0) { - clear_tfile_check_list(); + if (ep_loop_check(ep, tfile) != 0) goto error_tgt_fput; - } } else list_add(&tfile->f_tfile_llink, &tfile_check_list); } diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index b1fd2025e59a..9a1d9f0a60ab 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -1371,7 +1371,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) unsigned int depth = bprm->recursion_depth; int try,retval; struct linux_binfmt *fmt; - pid_t old_pid, old_vpid; + pid_t old_pid; retval = security_bprm_check(bprm); if (retval) @@ -1382,9 +1382,8 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) return retval; /* Need to fetch pid before load_binary changes it */ - old_pid = current->pid; rcu_read_lock(); - old_vpid = task_pid_nr_ns(current, task_active_pid_ns(current->parent)); + old_pid = task_pid_nr_ns(current, task_active_pid_ns(current->parent)); rcu_read_unlock(); retval = -ENOENT; @@ -1407,7 +1406,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) if (retval >= 0) { if (depth == 0) { trace_sched_process_exec(current, old_pid, bprm); - ptrace_event(PTRACE_EVENT_EXEC, old_vpid); + ptrace_event(PTRACE_EVENT_EXEC, old_pid); } put_binfmt(fmt); allow_write_access(bprm->file); diff --git a/trunk/fs/ext2/ext2.h b/trunk/fs/ext2/ext2.h index 0b2b4db5bdcd..75ad433c6691 100644 --- a/trunk/fs/ext2/ext2.h +++ b/trunk/fs/ext2/ext2.h @@ -1,636 +1,5 @@ -/* - * Copyright (C) 1992, 1993, 1994, 1995 - * Remy Card (card@masi.ibp.fr) - * Laboratoire MASI - Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * from - * - * linux/include/linux/minix_fs.h - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ #include #include -#include -#include -#include - -/* XXX Here for now... not interested in restructing headers JUST now */ - -/* data type for block offset of block group */ -typedef int ext2_grpblk_t; - -/* data type for filesystem-wide blocks number */ -typedef unsigned long ext2_fsblk_t; - -#define E2FSBLK "%lu" - -struct ext2_reserve_window { - ext2_fsblk_t _rsv_start; /* First byte reserved */ - ext2_fsblk_t _rsv_end; /* Last byte reserved or 0 */ -}; - -struct ext2_reserve_window_node { - struct rb_node rsv_node; - __u32 rsv_goal_size; - __u32 rsv_alloc_hit; - struct ext2_reserve_window rsv_window; -}; - -struct ext2_block_alloc_info { - /* information about reservation window */ - struct ext2_reserve_window_node rsv_window_node; - /* - * was i_next_alloc_block in ext2_inode_info - * is the logical (file-relative) number of the - * most-recently-allocated block in this file. - * We use this for detecting linearly ascending allocation requests. - */ - __u32 last_alloc_logical_block; - /* - * Was i_next_alloc_goal in ext2_inode_info - * is the *physical* companion to i_next_alloc_block. - * it the the physical block number of the block which was most-recentl - * allocated to this file. This give us the goal (target) for the next - * allocation when we detect linearly ascending requests. - */ - ext2_fsblk_t last_alloc_physical_block; -}; - -#define rsv_start rsv_window._rsv_start -#define rsv_end rsv_window._rsv_end - -/* - * second extended-fs super-block data in memory - */ -struct ext2_sb_info { - unsigned long s_frag_size; /* Size of a fragment in bytes */ - unsigned long s_frags_per_block;/* Number of fragments per block */ - unsigned long s_inodes_per_block;/* Number of inodes per block */ - unsigned long s_frags_per_group;/* Number of fragments in a group */ - unsigned long s_blocks_per_group;/* Number of blocks in a group */ - unsigned long s_inodes_per_group;/* Number of inodes in a group */ - unsigned long s_itb_per_group; /* Number of inode table blocks per group */ - unsigned long s_gdb_count; /* Number of group descriptor blocks */ - unsigned long s_desc_per_block; /* Number of group descriptors per block */ - unsigned long s_groups_count; /* Number of groups in the fs */ - unsigned long s_overhead_last; /* Last calculated overhead */ - unsigned long s_blocks_last; /* Last seen block count */ - struct buffer_head * s_sbh; /* Buffer containing the super block */ - struct ext2_super_block * s_es; /* Pointer to the super block in the buffer */ - struct buffer_head ** s_group_desc; - unsigned long s_mount_opt; - unsigned long s_sb_block; - uid_t s_resuid; - gid_t s_resgid; - unsigned short s_mount_state; - unsigned short s_pad; - int s_addr_per_block_bits; - int s_desc_per_block_bits; - int s_inode_size; - int s_first_ino; - spinlock_t s_next_gen_lock; - u32 s_next_generation; - unsigned long s_dir_count; - u8 *s_debts; - struct percpu_counter s_freeblocks_counter; - struct percpu_counter s_freeinodes_counter; - struct percpu_counter s_dirs_counter; - struct blockgroup_lock *s_blockgroup_lock; - /* root of the per fs reservation window tree */ - spinlock_t s_rsv_window_lock; - struct rb_root s_rsv_window_root; - struct ext2_reserve_window_node s_rsv_window_head; - /* - * s_lock protects against concurrent modifications of s_mount_state, - * s_blocks_last, s_overhead_last and the content of superblock's - * buffer pointed to by sbi->s_es. - * - * Note: It is used in ext2_show_options() to provide a consistent view - * of the mount options. - */ - spinlock_t s_lock; -}; - -static inline spinlock_t * -sb_bgl_lock(struct ext2_sb_info *sbi, unsigned int block_group) -{ - return bgl_lock_ptr(sbi->s_blockgroup_lock, block_group); -} - -/* - * Define EXT2FS_DEBUG to produce debug messages - */ -#undef EXT2FS_DEBUG - -/* - * Define EXT2_RESERVATION to reserve data blocks for expanding files - */ -#define EXT2_DEFAULT_RESERVE_BLOCKS 8 -/*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */ -#define EXT2_MAX_RESERVE_BLOCKS 1027 -#define EXT2_RESERVE_WINDOW_NOT_ALLOCATED 0 -/* - * The second extended file system version - */ -#define EXT2FS_DATE "95/08/09" -#define EXT2FS_VERSION "0.5b" - -/* - * Debug code - */ -#ifdef EXT2FS_DEBUG -# define ext2_debug(f, a...) { \ - printk ("EXT2-fs DEBUG (%s, %d): %s:", \ - __FILE__, __LINE__, __func__); \ - printk (f, ## a); \ - } -#else -# define ext2_debug(f, a...) /**/ -#endif - -/* - * Special inode numbers - */ -#define EXT2_BAD_INO 1 /* Bad blocks inode */ -#define EXT2_ROOT_INO 2 /* Root inode */ -#define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */ -#define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */ - -/* First non-reserved inode for old ext2 filesystems */ -#define EXT2_GOOD_OLD_FIRST_INO 11 - -static inline struct ext2_sb_info *EXT2_SB(struct super_block *sb) -{ - return sb->s_fs_info; -} - -/* - * Macro-instructions used to manage several block sizes - */ -#define EXT2_MIN_BLOCK_SIZE 1024 -#define EXT2_MAX_BLOCK_SIZE 4096 -#define EXT2_MIN_BLOCK_LOG_SIZE 10 -#define EXT2_BLOCK_SIZE(s) ((s)->s_blocksize) -#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32)) -#define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) -#define EXT2_ADDR_PER_BLOCK_BITS(s) (EXT2_SB(s)->s_addr_per_block_bits) -#define EXT2_INODE_SIZE(s) (EXT2_SB(s)->s_inode_size) -#define EXT2_FIRST_INO(s) (EXT2_SB(s)->s_first_ino) - -/* - * Macro-instructions used to manage fragments - */ -#define EXT2_MIN_FRAG_SIZE 1024 -#define EXT2_MAX_FRAG_SIZE 4096 -#define EXT2_MIN_FRAG_LOG_SIZE 10 -#define EXT2_FRAG_SIZE(s) (EXT2_SB(s)->s_frag_size) -#define EXT2_FRAGS_PER_BLOCK(s) (EXT2_SB(s)->s_frags_per_block) - -/* - * Structure of a blocks group descriptor - */ -struct ext2_group_desc -{ - __le32 bg_block_bitmap; /* Blocks bitmap block */ - __le32 bg_inode_bitmap; /* Inodes bitmap block */ - __le32 bg_inode_table; /* Inodes table block */ - __le16 bg_free_blocks_count; /* Free blocks count */ - __le16 bg_free_inodes_count; /* Free inodes count */ - __le16 bg_used_dirs_count; /* Directories count */ - __le16 bg_pad; - __le32 bg_reserved[3]; -}; - -/* - * Macro-instructions used to manage group descriptors - */ -#define EXT2_BLOCKS_PER_GROUP(s) (EXT2_SB(s)->s_blocks_per_group) -#define EXT2_DESC_PER_BLOCK(s) (EXT2_SB(s)->s_desc_per_block) -#define EXT2_INODES_PER_GROUP(s) (EXT2_SB(s)->s_inodes_per_group) -#define EXT2_DESC_PER_BLOCK_BITS(s) (EXT2_SB(s)->s_desc_per_block_bits) - -/* - * Constants relative to the data blocks - */ -#define EXT2_NDIR_BLOCKS 12 -#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS -#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1) -#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1) -#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1) - -/* - * Inode flags (GETFLAGS/SETFLAGS) - */ -#define EXT2_SECRM_FL FS_SECRM_FL /* Secure deletion */ -#define EXT2_UNRM_FL FS_UNRM_FL /* Undelete */ -#define EXT2_COMPR_FL FS_COMPR_FL /* Compress file */ -#define EXT2_SYNC_FL FS_SYNC_FL /* Synchronous updates */ -#define EXT2_IMMUTABLE_FL FS_IMMUTABLE_FL /* Immutable file */ -#define EXT2_APPEND_FL FS_APPEND_FL /* writes to file may only append */ -#define EXT2_NODUMP_FL FS_NODUMP_FL /* do not dump file */ -#define EXT2_NOATIME_FL FS_NOATIME_FL /* do not update atime */ -/* Reserved for compression usage... */ -#define EXT2_DIRTY_FL FS_DIRTY_FL -#define EXT2_COMPRBLK_FL FS_COMPRBLK_FL /* One or more compressed clusters */ -#define EXT2_NOCOMP_FL FS_NOCOMP_FL /* Don't compress */ -#define EXT2_ECOMPR_FL FS_ECOMPR_FL /* Compression error */ -/* End compression flags --- maybe not all used */ -#define EXT2_BTREE_FL FS_BTREE_FL /* btree format dir */ -#define EXT2_INDEX_FL FS_INDEX_FL /* hash-indexed directory */ -#define EXT2_IMAGIC_FL FS_IMAGIC_FL /* AFS directory */ -#define EXT2_JOURNAL_DATA_FL FS_JOURNAL_DATA_FL /* Reserved for ext3 */ -#define EXT2_NOTAIL_FL FS_NOTAIL_FL /* file tail should not be merged */ -#define EXT2_DIRSYNC_FL FS_DIRSYNC_FL /* dirsync behaviour (directories only) */ -#define EXT2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/ -#define EXT2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */ - -#define EXT2_FL_USER_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */ -#define EXT2_FL_USER_MODIFIABLE FS_FL_USER_MODIFIABLE /* User modifiable flags */ - -/* Flags that should be inherited by new inodes from their parent. */ -#define EXT2_FL_INHERITED (EXT2_SECRM_FL | EXT2_UNRM_FL | EXT2_COMPR_FL |\ - EXT2_SYNC_FL | EXT2_NODUMP_FL |\ - EXT2_NOATIME_FL | EXT2_COMPRBLK_FL |\ - EXT2_NOCOMP_FL | EXT2_JOURNAL_DATA_FL |\ - EXT2_NOTAIL_FL | EXT2_DIRSYNC_FL) - -/* Flags that are appropriate for regular files (all but dir-specific ones). */ -#define EXT2_REG_FLMASK (~(EXT2_DIRSYNC_FL | EXT2_TOPDIR_FL)) - -/* Flags that are appropriate for non-directories/regular files. */ -#define EXT2_OTHER_FLMASK (EXT2_NODUMP_FL | EXT2_NOATIME_FL) - -/* Mask out flags that are inappropriate for the given type of inode. */ -static inline __u32 ext2_mask_flags(umode_t mode, __u32 flags) -{ - if (S_ISDIR(mode)) - return flags; - else if (S_ISREG(mode)) - return flags & EXT2_REG_FLMASK; - else - return flags & EXT2_OTHER_FLMASK; -} - -/* - * ioctl commands - */ -#define EXT2_IOC_GETFLAGS FS_IOC_GETFLAGS -#define EXT2_IOC_SETFLAGS FS_IOC_SETFLAGS -#define EXT2_IOC_GETVERSION FS_IOC_GETVERSION -#define EXT2_IOC_SETVERSION FS_IOC_SETVERSION -#define EXT2_IOC_GETRSVSZ _IOR('f', 5, long) -#define EXT2_IOC_SETRSVSZ _IOW('f', 6, long) - -/* - * ioctl commands in 32 bit emulation - */ -#define EXT2_IOC32_GETFLAGS FS_IOC32_GETFLAGS -#define EXT2_IOC32_SETFLAGS FS_IOC32_SETFLAGS -#define EXT2_IOC32_GETVERSION FS_IOC32_GETVERSION -#define EXT2_IOC32_SETVERSION FS_IOC32_SETVERSION - -/* - * Structure of an inode on the disk - */ -struct ext2_inode { - __le16 i_mode; /* File mode */ - __le16 i_uid; /* Low 16 bits of Owner Uid */ - __le32 i_size; /* Size in bytes */ - __le32 i_atime; /* Access time */ - __le32 i_ctime; /* Creation time */ - __le32 i_mtime; /* Modification time */ - __le32 i_dtime; /* Deletion Time */ - __le16 i_gid; /* Low 16 bits of Group Id */ - __le16 i_links_count; /* Links count */ - __le32 i_blocks; /* Blocks count */ - __le32 i_flags; /* File flags */ - union { - struct { - __le32 l_i_reserved1; - } linux1; - struct { - __le32 h_i_translator; - } hurd1; - struct { - __le32 m_i_reserved1; - } masix1; - } osd1; /* OS dependent 1 */ - __le32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */ - __le32 i_generation; /* File version (for NFS) */ - __le32 i_file_acl; /* File ACL */ - __le32 i_dir_acl; /* Directory ACL */ - __le32 i_faddr; /* Fragment address */ - union { - struct { - __u8 l_i_frag; /* Fragment number */ - __u8 l_i_fsize; /* Fragment size */ - __u16 i_pad1; - __le16 l_i_uid_high; /* these 2 fields */ - __le16 l_i_gid_high; /* were reserved2[0] */ - __u32 l_i_reserved2; - } linux2; - struct { - __u8 h_i_frag; /* Fragment number */ - __u8 h_i_fsize; /* Fragment size */ - __le16 h_i_mode_high; - __le16 h_i_uid_high; - __le16 h_i_gid_high; - __le32 h_i_author; - } hurd2; - struct { - __u8 m_i_frag; /* Fragment number */ - __u8 m_i_fsize; /* Fragment size */ - __u16 m_pad1; - __u32 m_i_reserved2[2]; - } masix2; - } osd2; /* OS dependent 2 */ -}; - -#define i_size_high i_dir_acl - -#define i_reserved1 osd1.linux1.l_i_reserved1 -#define i_frag osd2.linux2.l_i_frag -#define i_fsize osd2.linux2.l_i_fsize -#define i_uid_low i_uid -#define i_gid_low i_gid -#define i_uid_high osd2.linux2.l_i_uid_high -#define i_gid_high osd2.linux2.l_i_gid_high -#define i_reserved2 osd2.linux2.l_i_reserved2 - -/* - * File system states - */ -#define EXT2_VALID_FS 0x0001 /* Unmounted cleanly */ -#define EXT2_ERROR_FS 0x0002 /* Errors detected */ - -/* - * Mount flags - */ -#define EXT2_MOUNT_CHECK 0x000001 /* Do mount-time checks */ -#define EXT2_MOUNT_OLDALLOC 0x000002 /* Don't use the new Orlov allocator */ -#define EXT2_MOUNT_GRPID 0x000004 /* Create files with directory's group */ -#define EXT2_MOUNT_DEBUG 0x000008 /* Some debugging messages */ -#define EXT2_MOUNT_ERRORS_CONT 0x000010 /* Continue on errors */ -#define EXT2_MOUNT_ERRORS_RO 0x000020 /* Remount fs ro on errors */ -#define EXT2_MOUNT_ERRORS_PANIC 0x000040 /* Panic on errors */ -#define EXT2_MOUNT_MINIX_DF 0x000080 /* Mimics the Minix statfs */ -#define EXT2_MOUNT_NOBH 0x000100 /* No buffer_heads */ -#define EXT2_MOUNT_NO_UID32 0x000200 /* Disable 32-bit UIDs */ -#define EXT2_MOUNT_XATTR_USER 0x004000 /* Extended user attributes */ -#define EXT2_MOUNT_POSIX_ACL 0x008000 /* POSIX Access Control Lists */ -#define EXT2_MOUNT_XIP 0x010000 /* Execute in place */ -#define EXT2_MOUNT_USRQUOTA 0x020000 /* user quota */ -#define EXT2_MOUNT_GRPQUOTA 0x040000 /* group quota */ -#define EXT2_MOUNT_RESERVATION 0x080000 /* Preallocation */ - - -#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt -#define set_opt(o, opt) o |= EXT2_MOUNT_##opt -#define test_opt(sb, opt) (EXT2_SB(sb)->s_mount_opt & \ - EXT2_MOUNT_##opt) -/* - * Maximal mount counts between two filesystem checks - */ -#define EXT2_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */ -#define EXT2_DFL_CHECKINTERVAL 0 /* Don't use interval check */ - -/* - * Behaviour when detecting errors - */ -#define EXT2_ERRORS_CONTINUE 1 /* Continue execution */ -#define EXT2_ERRORS_RO 2 /* Remount fs read-only */ -#define EXT2_ERRORS_PANIC 3 /* Panic */ -#define EXT2_ERRORS_DEFAULT EXT2_ERRORS_CONTINUE - -/* - * Structure of the super block - */ -struct ext2_super_block { - __le32 s_inodes_count; /* Inodes count */ - __le32 s_blocks_count; /* Blocks count */ - __le32 s_r_blocks_count; /* Reserved blocks count */ - __le32 s_free_blocks_count; /* Free blocks count */ - __le32 s_free_inodes_count; /* Free inodes count */ - __le32 s_first_data_block; /* First Data Block */ - __le32 s_log_block_size; /* Block size */ - __le32 s_log_frag_size; /* Fragment size */ - __le32 s_blocks_per_group; /* # Blocks per group */ - __le32 s_frags_per_group; /* # Fragments per group */ - __le32 s_inodes_per_group; /* # Inodes per group */ - __le32 s_mtime; /* Mount time */ - __le32 s_wtime; /* Write time */ - __le16 s_mnt_count; /* Mount count */ - __le16 s_max_mnt_count; /* Maximal mount count */ - __le16 s_magic; /* Magic signature */ - __le16 s_state; /* File system state */ - __le16 s_errors; /* Behaviour when detecting errors */ - __le16 s_minor_rev_level; /* minor revision level */ - __le32 s_lastcheck; /* time of last check */ - __le32 s_checkinterval; /* max. time between checks */ - __le32 s_creator_os; /* OS */ - __le32 s_rev_level; /* Revision level */ - __le16 s_def_resuid; /* Default uid for reserved blocks */ - __le16 s_def_resgid; /* Default gid for reserved blocks */ - /* - * These fields are for EXT2_DYNAMIC_REV superblocks only. - * - * Note: the difference between the compatible feature set and - * the incompatible feature set is that if there is a bit set - * in the incompatible feature set that the kernel doesn't - * know about, it should refuse to mount the filesystem. - * - * e2fsck's requirements are more strict; if it doesn't know - * about a feature in either the compatible or incompatible - * feature set, it must abort and not try to meddle with - * things it doesn't understand... - */ - __le32 s_first_ino; /* First non-reserved inode */ - __le16 s_inode_size; /* size of inode structure */ - __le16 s_block_group_nr; /* block group # of this superblock */ - __le32 s_feature_compat; /* compatible feature set */ - __le32 s_feature_incompat; /* incompatible feature set */ - __le32 s_feature_ro_compat; /* readonly-compatible feature set */ - __u8 s_uuid[16]; /* 128-bit uuid for volume */ - char s_volume_name[16]; /* volume name */ - char s_last_mounted[64]; /* directory where last mounted */ - __le32 s_algorithm_usage_bitmap; /* For compression */ - /* - * Performance hints. Directory preallocation should only - * happen if the EXT2_COMPAT_PREALLOC flag is on. - */ - __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ - __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ - __u16 s_padding1; - /* - * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set. - */ - __u8 s_journal_uuid[16]; /* uuid of journal superblock */ - __u32 s_journal_inum; /* inode number of journal file */ - __u32 s_journal_dev; /* device number of journal file */ - __u32 s_last_orphan; /* start of list of inodes to delete */ - __u32 s_hash_seed[4]; /* HTREE hash seed */ - __u8 s_def_hash_version; /* Default hash version to use */ - __u8 s_reserved_char_pad; - __u16 s_reserved_word_pad; - __le32 s_default_mount_opts; - __le32 s_first_meta_bg; /* First metablock block group */ - __u32 s_reserved[190]; /* Padding to the end of the block */ -}; - -/* - * Codes for operating systems - */ -#define EXT2_OS_LINUX 0 -#define EXT2_OS_HURD 1 -#define EXT2_OS_MASIX 2 -#define EXT2_OS_FREEBSD 3 -#define EXT2_OS_LITES 4 - -/* - * Revision levels - */ -#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */ -#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */ - -#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV -#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV - -#define EXT2_GOOD_OLD_INODE_SIZE 128 - -/* - * Feature set definitions - */ - -#define EXT2_HAS_COMPAT_FEATURE(sb,mask) \ - ( EXT2_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) ) -#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask) \ - ( EXT2_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) ) -#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask) \ - ( EXT2_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) ) -#define EXT2_SET_COMPAT_FEATURE(sb,mask) \ - EXT2_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask) -#define EXT2_SET_RO_COMPAT_FEATURE(sb,mask) \ - EXT2_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask) -#define EXT2_SET_INCOMPAT_FEATURE(sb,mask) \ - EXT2_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask) -#define EXT2_CLEAR_COMPAT_FEATURE(sb,mask) \ - EXT2_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask) -#define EXT2_CLEAR_RO_COMPAT_FEATURE(sb,mask) \ - EXT2_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask) -#define EXT2_CLEAR_INCOMPAT_FEATURE(sb,mask) \ - EXT2_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask) - -#define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001 -#define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002 -#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 -#define EXT2_FEATURE_COMPAT_EXT_ATTR 0x0008 -#define EXT2_FEATURE_COMPAT_RESIZE_INO 0x0010 -#define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020 -#define EXT2_FEATURE_COMPAT_ANY 0xffffffff - -#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 -#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 -#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 -#define EXT2_FEATURE_RO_COMPAT_ANY 0xffffffff - -#define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001 -#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 -#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 -#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 -#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010 -#define EXT2_FEATURE_INCOMPAT_ANY 0xffffffff - -#define EXT2_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR -#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ - EXT2_FEATURE_INCOMPAT_META_BG) -#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ - EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ - EXT2_FEATURE_RO_COMPAT_BTREE_DIR) -#define EXT2_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT2_FEATURE_RO_COMPAT_SUPP -#define EXT2_FEATURE_INCOMPAT_UNSUPPORTED ~EXT2_FEATURE_INCOMPAT_SUPP - -/* - * Default values for user and/or group using reserved blocks - */ -#define EXT2_DEF_RESUID 0 -#define EXT2_DEF_RESGID 0 - -/* - * Default mount options - */ -#define EXT2_DEFM_DEBUG 0x0001 -#define EXT2_DEFM_BSDGROUPS 0x0002 -#define EXT2_DEFM_XATTR_USER 0x0004 -#define EXT2_DEFM_ACL 0x0008 -#define EXT2_DEFM_UID16 0x0010 - /* Not used by ext2, but reserved for use by ext3 */ -#define EXT3_DEFM_JMODE 0x0060 -#define EXT3_DEFM_JMODE_DATA 0x0020 -#define EXT3_DEFM_JMODE_ORDERED 0x0040 -#define EXT3_DEFM_JMODE_WBACK 0x0060 - -/* - * Structure of a directory entry - */ - -struct ext2_dir_entry { - __le32 inode; /* Inode number */ - __le16 rec_len; /* Directory entry length */ - __le16 name_len; /* Name length */ - char name[]; /* File name, up to EXT2_NAME_LEN */ -}; - -/* - * The new version of the directory entry. Since EXT2 structures are - * stored in intel byte order, and the name_len field could never be - * bigger than 255 chars, it's safe to reclaim the extra byte for the - * file_type field. - */ -struct ext2_dir_entry_2 { - __le32 inode; /* Inode number */ - __le16 rec_len; /* Directory entry length */ - __u8 name_len; /* Name length */ - __u8 file_type; - char name[]; /* File name, up to EXT2_NAME_LEN */ -}; - -/* - * Ext2 directory file types. Only the low 3 bits are used. The - * other bits are reserved for now. - */ -enum { - EXT2_FT_UNKNOWN = 0, - EXT2_FT_REG_FILE = 1, - EXT2_FT_DIR = 2, - EXT2_FT_CHRDEV = 3, - EXT2_FT_BLKDEV = 4, - EXT2_FT_FIFO = 5, - EXT2_FT_SOCK = 6, - EXT2_FT_SYMLINK = 7, - EXT2_FT_MAX -}; - -/* - * EXT2_DIR_PAD defines the directory entries boundaries - * - * NOTE: It must be a multiple of 4 - */ -#define EXT2_DIR_PAD 4 -#define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1) -#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \ - ~EXT2_DIR_ROUND) -#define EXT2_MAX_REC_LEN ((1<<16)-1) - -static inline void verify_offsets(void) -{ -#define A(x,y) BUILD_BUG_ON(x != offsetof(struct ext2_super_block, y)); - A(EXT2_SB_MAGIC_OFFSET, s_magic); - A(EXT2_SB_BLOCKS_OFFSET, s_blocks_count); - A(EXT2_SB_BSIZE_OFFSET, s_log_block_size); -#undef A -} /* * ext2 mount options diff --git a/trunk/fs/ext2/xattr_security.c b/trunk/fs/ext2/xattr_security.c index cfedb2cb0d8c..be7a8d02c9a7 100644 --- a/trunk/fs/ext2/xattr_security.c +++ b/trunk/fs/ext2/xattr_security.c @@ -3,7 +3,10 @@ * Handler for storing security labels as extended attributes. */ -#include "ext2.h" +#include +#include +#include +#include #include #include "xattr.h" diff --git a/trunk/fs/ext2/xattr_trusted.c b/trunk/fs/ext2/xattr_trusted.c index 7e192574c001..2989467d3595 100644 --- a/trunk/fs/ext2/xattr_trusted.c +++ b/trunk/fs/ext2/xattr_trusted.c @@ -5,7 +5,10 @@ * Copyright (C) 2003 by Andreas Gruenbacher, */ -#include "ext2.h" +#include +#include +#include +#include #include "xattr.h" static size_t diff --git a/trunk/fs/ext2/xip.c b/trunk/fs/ext2/xip.c index 1c3312858fcf..322a56b2dfb1 100644 --- a/trunk/fs/ext2/xip.c +++ b/trunk/fs/ext2/xip.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include "ext2.h" #include "xip.h" diff --git a/trunk/fs/ext3/acl.c b/trunk/fs/ext3/acl.c index c76832c8d192..3091f62e55b6 100644 --- a/trunk/fs/ext3/acl.c +++ b/trunk/fs/ext3/acl.c @@ -4,7 +4,13 @@ * Copyright (C) 2001-2003 Andreas Gruenbacher, */ -#include "ext3.h" +#include +#include +#include +#include +#include +#include +#include #include "xattr.h" #include "acl.h" diff --git a/trunk/fs/ext3/balloc.c b/trunk/fs/ext3/balloc.c index baac1b129fba..1e036b79384c 100644 --- a/trunk/fs/ext3/balloc.c +++ b/trunk/fs/ext3/balloc.c @@ -11,9 +11,17 @@ * David S. Miller (davem@caip.rutgers.edu), 1995 */ +#include +#include +#include +#include +#include +#include +#include #include +#include #include -#include "ext3.h" +#include /* * balloc.c contains the blocks allocation and deallocation routines diff --git a/trunk/fs/ext3/bitmap.c b/trunk/fs/ext3/bitmap.c index 909d13e26560..6afc39d80253 100644 --- a/trunk/fs/ext3/bitmap.c +++ b/trunk/fs/ext3/bitmap.c @@ -7,7 +7,9 @@ * Universite Pierre et Marie Curie (Paris VI) */ -#include "ext3.h" +#include +#include +#include #ifdef EXT3FS_DEBUG diff --git a/trunk/fs/ext3/dir.c b/trunk/fs/ext3/dir.c index cc761ad8fa57..34f0a072b935 100644 --- a/trunk/fs/ext3/dir.c +++ b/trunk/fs/ext3/dir.c @@ -21,7 +21,12 @@ * */ -#include "ext3.h" +#include +#include +#include +#include +#include +#include static unsigned char ext3_filetype_table[] = { DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK diff --git a/trunk/fs/ext3/ext3_jbd.c b/trunk/fs/ext3/ext3_jbd.c index 785a3261a26c..d401f148d74d 100644 --- a/trunk/fs/ext3/ext3_jbd.c +++ b/trunk/fs/ext3/ext3_jbd.c @@ -2,7 +2,7 @@ * Interface between ext3 and JBD */ -#include "ext3.h" +#include int __ext3_journal_get_undo_access(const char *where, handle_t *handle, struct buffer_head *bh) diff --git a/trunk/fs/ext3/file.c b/trunk/fs/ext3/file.c index 25cb413277e9..724df69847dc 100644 --- a/trunk/fs/ext3/file.c +++ b/trunk/fs/ext3/file.c @@ -18,8 +18,12 @@ * (jj@sunsite.ms.mff.cuni.cz) */ +#include +#include +#include #include -#include "ext3.h" +#include +#include #include "xattr.h" #include "acl.h" diff --git a/trunk/fs/ext3/fsync.c b/trunk/fs/ext3/fsync.c index d4dff278cbd8..1860ed356323 100644 --- a/trunk/fs/ext3/fsync.c +++ b/trunk/fs/ext3/fsync.c @@ -22,9 +22,15 @@ * we can depend on generic_block_fdatasync() to sync the data blocks. */ +#include #include +#include +#include #include -#include "ext3.h" +#include +#include +#include +#include /* * akpm: A new design for ext3_sync_file(). diff --git a/trunk/fs/ext3/hash.c b/trunk/fs/ext3/hash.c index d10231ddcf8a..7d215b4d4f2e 100644 --- a/trunk/fs/ext3/hash.c +++ b/trunk/fs/ext3/hash.c @@ -9,7 +9,9 @@ * License. */ -#include "ext3.h" +#include +#include +#include #include #define DELTA 0x9E3779B9 diff --git a/trunk/fs/ext3/ialloc.c b/trunk/fs/ext3/ialloc.c index e3c39e4cec19..1cde28438014 100644 --- a/trunk/fs/ext3/ialloc.c +++ b/trunk/fs/ext3/ialloc.c @@ -12,10 +12,21 @@ * David S. Miller (davem@caip.rutgers.edu), 1995 */ +#include +#include +#include +#include +#include +#include +#include #include +#include #include +#include +#include + +#include -#include "ext3.h" #include "xattr.h" #include "acl.h" diff --git a/trunk/fs/ext3/inode.c b/trunk/fs/ext3/inode.c index 10d7812f6021..6d3418662b54 100644 --- a/trunk/fs/ext3/inode.c +++ b/trunk/fs/ext3/inode.c @@ -22,12 +22,22 @@ * Assorted race fixes, rewrite of ext3_get_block() by Al Viro, 2000 */ +#include +#include +#include +#include #include +#include #include +#include +#include #include #include +#include +#include +#include #include -#include "ext3.h" +#include #include "xattr.h" #include "acl.h" diff --git a/trunk/fs/ext3/ioctl.c b/trunk/fs/ext3/ioctl.c index 677a5c27dc69..4af574ce4a46 100644 --- a/trunk/fs/ext3/ioctl.c +++ b/trunk/fs/ext3/ioctl.c @@ -7,10 +7,15 @@ * Universite Pierre et Marie Curie (Paris VI) */ +#include +#include +#include +#include +#include #include +#include #include #include -#include "ext3.h" long ext3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { diff --git a/trunk/fs/ext3/namei.c b/trunk/fs/ext3/namei.c index d7940b24cf68..e8e211795e9f 100644 --- a/trunk/fs/ext3/namei.c +++ b/trunk/fs/ext3/namei.c @@ -24,8 +24,20 @@ * Theodore Ts'o, 2002 */ +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include "ext3.h" +#include +#include +#include + #include "namei.h" #include "xattr.h" #include "acl.h" diff --git a/trunk/fs/ext3/resize.c b/trunk/fs/ext3/resize.c index 0f814f3450de..7916e4ce166a 100644 --- a/trunk/fs/ext3/resize.c +++ b/trunk/fs/ext3/resize.c @@ -11,7 +11,10 @@ #define EXT3FS_DEBUG -#include "ext3.h" +#include + +#include +#include #define outside(b, first, last) ((b) < (first) || (b) >= (last)) diff --git a/trunk/fs/ext3/super.c b/trunk/fs/ext3/super.c index cf0b5921cf0f..e0b45b93327b 100644 --- a/trunk/fs/ext3/super.c +++ b/trunk/fs/ext3/super.c @@ -17,12 +17,22 @@ */ #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include #include -#include +#include #include #include +#include #include #include #include @@ -30,13 +40,13 @@ #include -#define CREATE_TRACE_POINTS - -#include "ext3.h" #include "xattr.h" #include "acl.h" #include "namei.h" +#define CREATE_TRACE_POINTS +#include + #ifdef CONFIG_EXT3_DEFAULTS_TO_ORDERED #define EXT3_MOUNT_DEFAULT_DATA_MODE EXT3_MOUNT_ORDERED_DATA #else diff --git a/trunk/fs/ext3/symlink.c b/trunk/fs/ext3/symlink.c index 6b01c3eab1f3..7c4898207776 100644 --- a/trunk/fs/ext3/symlink.c +++ b/trunk/fs/ext3/symlink.c @@ -17,8 +17,10 @@ * ext3 symlink handling code */ +#include +#include +#include #include -#include "ext3.h" #include "xattr.h" static void * ext3_follow_link(struct dentry *dentry, struct nameidata *nd) diff --git a/trunk/fs/ext3/xattr.c b/trunk/fs/ext3/xattr.c index d22ebb7a4f55..d565759d82ee 100644 --- a/trunk/fs/ext3/xattr.c +++ b/trunk/fs/ext3/xattr.c @@ -50,9 +50,14 @@ * by the buffer lock. */ -#include "ext3.h" +#include +#include +#include +#include +#include #include #include +#include #include "xattr.h" #include "acl.h" diff --git a/trunk/fs/ext3/xattr_security.c b/trunk/fs/ext3/xattr_security.c index 3387664ad70e..ea26f2acab94 100644 --- a/trunk/fs/ext3/xattr_security.c +++ b/trunk/fs/ext3/xattr_security.c @@ -3,8 +3,12 @@ * Handler for storing security labels as extended attributes. */ +#include +#include +#include +#include +#include #include -#include "ext3.h" #include "xattr.h" static size_t diff --git a/trunk/fs/ext3/xattr_trusted.c b/trunk/fs/ext3/xattr_trusted.c index d75727cc67fa..2526a8829de8 100644 --- a/trunk/fs/ext3/xattr_trusted.c +++ b/trunk/fs/ext3/xattr_trusted.c @@ -5,7 +5,11 @@ * Copyright (C) 2003 by Andreas Gruenbacher, */ -#include "ext3.h" +#include +#include +#include +#include +#include #include "xattr.h" static size_t diff --git a/trunk/fs/ext3/xattr_user.c b/trunk/fs/ext3/xattr_user.c index 5612af3567e0..b32e473a1e33 100644 --- a/trunk/fs/ext3/xattr_user.c +++ b/trunk/fs/ext3/xattr_user.c @@ -5,7 +5,10 @@ * Copyright (C) 2001 by Andreas Gruenbacher, */ -#include "ext3.h" +#include +#include +#include +#include #include "xattr.h" static size_t diff --git a/trunk/fs/ext4/ext4.h b/trunk/fs/ext4/ext4.h index 0e01e90add8b..ab2594a30f86 100644 --- a/trunk/fs/ext4/ext4.h +++ b/trunk/fs/ext4/ext4.h @@ -1203,6 +1203,9 @@ struct ext4_sb_info { unsigned long s_ext_blocks; unsigned long s_ext_extents; #endif + /* ext4 extent cache stats */ + unsigned long extent_cache_hits; + unsigned long extent_cache_misses; /* for buddy allocator */ struct ext4_group_info ***s_group_info; diff --git a/trunk/fs/ext4/extents.c b/trunk/fs/ext4/extents.c index abcdeab67f52..1421938e6792 100644 --- a/trunk/fs/ext4/extents.c +++ b/trunk/fs/ext4/extents.c @@ -2066,6 +2066,10 @@ static int ext4_ext_check_cache(struct inode *inode, ext4_lblk_t block, ret = 1; } errout: + if (!ret) + sbi->extent_cache_misses++; + else + sbi->extent_cache_hits++; trace_ext4_ext_in_cache(inode, block, ret); spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); return ret; @@ -2878,7 +2882,7 @@ static int ext4_split_extent_at(handle_t *handle, if (err) goto fix_extent_len; /* update the extent length and mark as initialized */ - ex->ee_len = cpu_to_le16(ee_len); + ex->ee_len = cpu_to_le32(ee_len); ext4_ext_try_to_merge(inode, path, ex); err = ext4_ext_dirty(handle, inode, path + depth); goto out; diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index e1fb1d5de58e..ceebaf853beb 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -1305,20 +1305,20 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args) ext4_msg(sb, KERN_ERR, "Cannot change journaled " "quota options when quota turned on"); - return -1; + return 0; } qname = match_strdup(args); if (!qname) { ext4_msg(sb, KERN_ERR, "Not enough memory for storing quotafile name"); - return -1; + return 0; } if (sbi->s_qf_names[qtype] && strcmp(sbi->s_qf_names[qtype], qname)) { ext4_msg(sb, KERN_ERR, "%s quota file already specified", QTYPE2NAME(qtype)); kfree(qname); - return -1; + return 0; } sbi->s_qf_names[qtype] = qname; if (strchr(sbi->s_qf_names[qtype], '/')) { @@ -1326,7 +1326,7 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args) "quotafile must be on filesystem root"); kfree(sbi->s_qf_names[qtype]); sbi->s_qf_names[qtype] = NULL; - return -1; + return 0; } set_opt(sb, QUOTA); return 1; @@ -1341,7 +1341,7 @@ static int clear_qf_name(struct super_block *sb, int qtype) sbi->s_qf_names[qtype]) { ext4_msg(sb, KERN_ERR, "Cannot change journaled quota options" " when quota turned on"); - return -1; + return 0; } /* * The space will be released later when all options are confirmed @@ -1450,16 +1450,6 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, const struct mount_opts *m; int arg = 0; -#ifdef CONFIG_QUOTA - if (token == Opt_usrjquota) - return set_qf_name(sb, USRQUOTA, &args[0]); - else if (token == Opt_grpjquota) - return set_qf_name(sb, GRPQUOTA, &args[0]); - else if (token == Opt_offusrjquota) - return clear_qf_name(sb, USRQUOTA); - else if (token == Opt_offgrpjquota) - return clear_qf_name(sb, GRPQUOTA); -#endif if (args->from && match_int(args, &arg)) return -1; switch (token) { @@ -1559,6 +1549,18 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, sbi->s_mount_opt |= m->mount_opt; } #ifdef CONFIG_QUOTA + } else if (token == Opt_usrjquota) { + if (!set_qf_name(sb, USRQUOTA, &args[0])) + return -1; + } else if (token == Opt_grpjquota) { + if (!set_qf_name(sb, GRPQUOTA, &args[0])) + return -1; + } else if (token == Opt_offusrjquota) { + if (!clear_qf_name(sb, USRQUOTA)) + return -1; + } else if (token == Opt_offgrpjquota) { + if (!clear_qf_name(sb, GRPQUOTA)) + return -1; } else if (m->flags & MOPT_QFMT) { if (sb_any_quota_loaded(sb) && sbi->s_jquota_fmt != m->mount_opt) { @@ -1597,9 +1599,7 @@ static int parse_options(char *options, struct super_block *sb, unsigned int *journal_ioprio, int is_remount) { -#ifdef CONFIG_QUOTA struct ext4_sb_info *sbi = EXT4_SB(sb); -#endif char *p; substring_t args[MAX_OPT_ARGS]; int token; @@ -2366,6 +2366,18 @@ static ssize_t lifetime_write_kbytes_show(struct ext4_attr *a, EXT4_SB(sb)->s_sectors_written_start) >> 1))); } +static ssize_t extent_cache_hits_show(struct ext4_attr *a, + struct ext4_sb_info *sbi, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%lu\n", sbi->extent_cache_hits); +} + +static ssize_t extent_cache_misses_show(struct ext4_attr *a, + struct ext4_sb_info *sbi, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%lu\n", sbi->extent_cache_misses); +} + static ssize_t inode_readahead_blks_store(struct ext4_attr *a, struct ext4_sb_info *sbi, const char *buf, size_t count) @@ -2423,6 +2435,8 @@ static struct ext4_attr ext4_attr_##name = __ATTR(name, mode, show, store) EXT4_RO_ATTR(delayed_allocation_blocks); EXT4_RO_ATTR(session_write_kbytes); EXT4_RO_ATTR(lifetime_write_kbytes); +EXT4_RO_ATTR(extent_cache_hits); +EXT4_RO_ATTR(extent_cache_misses); EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, sbi_ui_show, inode_readahead_blks_store, s_inode_readahead_blks); EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal); @@ -2438,6 +2452,8 @@ static struct attribute *ext4_attrs[] = { ATTR_LIST(delayed_allocation_blocks), ATTR_LIST(session_write_kbytes), ATTR_LIST(lifetime_write_kbytes), + ATTR_LIST(extent_cache_hits), + ATTR_LIST(extent_cache_misses), ATTR_LIST(inode_readahead_blks), ATTR_LIST(inode_goal), ATTR_LIST(mb_stats), diff --git a/trunk/fs/fuse/dir.c b/trunk/fs/fuse/dir.c index df5ac048dc74..206632887bb4 100644 --- a/trunk/fs/fuse/dir.c +++ b/trunk/fs/fuse/dir.c @@ -387,6 +387,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, if (fc->no_create) return -ENOSYS; + if (flags & O_DIRECT) + return -EINVAL; + forget = fuse_alloc_forget(); if (!forget) return -ENOMEM; @@ -641,12 +644,13 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry) fuse_put_request(fc, req); if (!err) { struct inode *inode = entry->d_inode; - struct fuse_inode *fi = get_fuse_inode(inode); - spin_lock(&fc->lock); - fi->attr_version = ++fc->attr_version; - drop_nlink(inode); - spin_unlock(&fc->lock); + /* + * Set nlink to zero so the inode can be cleared, if the inode + * does have more links this will be discovered at the next + * lookup/getattr. + */ + clear_nlink(inode); fuse_invalidate_attr(inode); fuse_invalidate_attr(dir); fuse_invalidate_entry_cache(entry); @@ -758,17 +762,8 @@ static int fuse_link(struct dentry *entry, struct inode *newdir, will reflect changes in the backing inode (link count, etc.) */ - if (!err) { - struct fuse_inode *fi = get_fuse_inode(inode); - - spin_lock(&fc->lock); - fi->attr_version = ++fc->attr_version; - inc_nlink(inode); - spin_unlock(&fc->lock); - fuse_invalidate_attr(inode); - } else if (err == -EINTR) { + if (!err || err == -EINTR) fuse_invalidate_attr(inode); - } return err; } diff --git a/trunk/fs/fuse/file.c b/trunk/fs/fuse/file.c index 504e61b7fd75..a841868bf9ce 100644 --- a/trunk/fs/fuse/file.c +++ b/trunk/fs/fuse/file.c @@ -194,6 +194,10 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir) struct fuse_conn *fc = get_fuse_conn(inode); int err; + /* VFS checks this, but only _after_ ->open() */ + if (file->f_flags & O_DIRECT) + return -EINVAL; + err = generic_file_open(inode, file); if (err) return err; @@ -928,23 +932,17 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; size_t count = 0; - size_t ocount = 0; ssize_t written = 0; - ssize_t written_buffered = 0; struct inode *inode = mapping->host; ssize_t err; struct iov_iter i; - loff_t endbyte = 0; WARN_ON(iocb->ki_pos != pos); - ocount = 0; - err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); + err = generic_segment_checks(iov, &nr_segs, &count, VERIFY_READ); if (err) return err; - count = ocount; - mutex_lock(&inode->i_mutex); vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); @@ -964,41 +962,11 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, file_update_time(file); - if (file->f_flags & O_DIRECT) { - written = generic_file_direct_write(iocb, iov, &nr_segs, - pos, &iocb->ki_pos, - count, ocount); - if (written < 0 || written == count) - goto out; - - pos += written; - count -= written; + iov_iter_init(&i, iov, nr_segs, count, 0); + written = fuse_perform_write(file, mapping, &i, pos); + if (written >= 0) + iocb->ki_pos = pos + written; - iov_iter_init(&i, iov, nr_segs, count, written); - written_buffered = fuse_perform_write(file, mapping, &i, pos); - if (written_buffered < 0) { - err = written_buffered; - goto out; - } - endbyte = pos + written_buffered - 1; - - err = filemap_write_and_wait_range(file->f_mapping, pos, - endbyte); - if (err) - goto out; - - invalidate_mapping_pages(file->f_mapping, - pos >> PAGE_CACHE_SHIFT, - endbyte >> PAGE_CACHE_SHIFT); - - written += written_buffered; - iocb->ki_pos = pos + written_buffered; - } else { - iov_iter_init(&i, iov, nr_segs, count, 0); - written = fuse_perform_write(file, mapping, &i, pos); - if (written >= 0) - iocb->ki_pos = pos + written; - } out: current->backing_dev_info = NULL; mutex_unlock(&inode->i_mutex); @@ -1133,24 +1101,6 @@ static ssize_t fuse_direct_read(struct file *file, char __user *buf, return res; } -static ssize_t __fuse_direct_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct inode *inode = file->f_path.dentry->d_inode; - ssize_t res; - - res = generic_write_checks(file, ppos, &count, 0); - if (!res) { - res = fuse_direct_io(file, buf, count, ppos, 1); - if (res > 0) - fuse_write_update_size(inode, *ppos); - } - - fuse_invalidate_attr(inode); - - return res; -} - static ssize_t fuse_direct_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { @@ -1162,9 +1112,16 @@ static ssize_t fuse_direct_write(struct file *file, const char __user *buf, /* Don't allow parallel writes to the same file */ mutex_lock(&inode->i_mutex); - res = __fuse_direct_write(file, buf, count, ppos); + res = generic_write_checks(file, ppos, &count, 0); + if (!res) { + res = fuse_direct_io(file, buf, count, ppos, 1); + if (res > 0) + fuse_write_update_size(inode, *ppos); + } mutex_unlock(&inode->i_mutex); + fuse_invalidate_attr(inode); + return res; } @@ -2120,57 +2077,6 @@ int fuse_notify_poll_wakeup(struct fuse_conn *fc, return 0; } -static ssize_t fuse_loop_dio(struct file *filp, const struct iovec *iov, - unsigned long nr_segs, loff_t *ppos, int rw) -{ - const struct iovec *vector = iov; - ssize_t ret = 0; - - while (nr_segs > 0) { - void __user *base; - size_t len; - ssize_t nr; - - base = vector->iov_base; - len = vector->iov_len; - vector++; - nr_segs--; - - if (rw == WRITE) - nr = __fuse_direct_write(filp, base, len, ppos); - else - nr = fuse_direct_read(filp, base, len, ppos); - - if (nr < 0) { - if (!ret) - ret = nr; - break; - } - ret += nr; - if (nr != len) - break; - } - - return ret; -} - - -static ssize_t -fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, - loff_t offset, unsigned long nr_segs) -{ - ssize_t ret = 0; - struct file *file = NULL; - loff_t pos = 0; - - file = iocb->ki_filp; - pos = offset; - - ret = fuse_loop_dio(file, iov, nr_segs, &pos, rw); - - return ret; -} - static const struct file_operations fuse_file_operations = { .llseek = fuse_file_llseek, .read = do_sync_read, @@ -2214,7 +2120,6 @@ static const struct address_space_operations fuse_file_aops = { .readpages = fuse_readpages, .set_page_dirty = __set_page_dirty_nobuffers, .bmap = fuse_bmap, - .direct_IO = fuse_direct_IO, }; void fuse_init_file_inode(struct inode *inode) diff --git a/trunk/fs/fuse/inode.c b/trunk/fs/fuse/inode.c index 26783eb2b1fc..4aec5995867e 100644 --- a/trunk/fs/fuse/inode.c +++ b/trunk/fs/fuse/inode.c @@ -947,7 +947,6 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) sb->s_magic = FUSE_SUPER_MAGIC; sb->s_op = &fuse_super_operations; sb->s_maxbytes = MAX_LFS_FILESIZE; - sb->s_time_gran = 1; sb->s_export_op = &fuse_export_operations; file = fget(d.fd); diff --git a/trunk/fs/gfs2/Kconfig b/trunk/fs/gfs2/Kconfig index eb08c9e43c2a..c465ae066c62 100644 --- a/trunk/fs/gfs2/Kconfig +++ b/trunk/fs/gfs2/Kconfig @@ -1,6 +1,10 @@ config GFS2_FS tristate "GFS2 file system support" depends on (64BIT || LBDAF) + select DLM if GFS2_FS_LOCKING_DLM + select CONFIGFS_FS if GFS2_FS_LOCKING_DLM + select SYSFS if GFS2_FS_LOCKING_DLM + select IP_SCTP if DLM_SCTP select FS_POSIX_ACL select CRC32 select QUOTACTL @@ -25,8 +29,7 @@ config GFS2_FS config GFS2_FS_LOCKING_DLM bool "GFS2 DLM locking" - depends on (GFS2_FS!=n) && NET && INET && (IPV6 || IPV6=n) && \ - HOTPLUG && DLM && CONFIGFS_FS && SYSFS + depends on (GFS2_FS!=n) && NET && INET && (IPV6 || IPV6=n) && HOTPLUG help Multiple node locking module for GFS2 diff --git a/trunk/fs/gfs2/aops.c b/trunk/fs/gfs2/aops.c index 9b2ff0e851b1..38b7a74a0f91 100644 --- a/trunk/fs/gfs2/aops.c +++ b/trunk/fs/gfs2/aops.c @@ -807,7 +807,7 @@ static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh, if (inode == sdp->sd_rindex) { adjust_fs_space(inode); - sdp->sd_rindex_uptodate = 0; + ip->i_gh.gh_flags |= GL_NOCACHE; } brelse(dibh); @@ -873,7 +873,7 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping, if (inode == sdp->sd_rindex) { adjust_fs_space(inode); - sdp->sd_rindex_uptodate = 0; + ip->i_gh.gh_flags |= GL_NOCACHE; } brelse(dibh); diff --git a/trunk/fs/gfs2/bmap.c b/trunk/fs/gfs2/bmap.c index 03c04febe26f..197c5c47e577 100644 --- a/trunk/fs/gfs2/bmap.c +++ b/trunk/fs/gfs2/bmap.c @@ -724,11 +724,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, int metadata; unsigned int revokes = 0; int x; - int error; - - error = gfs2_rindex_update(sdp); - if (error) - return error; + int error = 0; if (!*top) sm->sm_first = 0; diff --git a/trunk/fs/gfs2/dir.c b/trunk/fs/gfs2/dir.c index a836056343f0..c35573abd371 100644 --- a/trunk/fs/gfs2/dir.c +++ b/trunk/fs/gfs2/dir.c @@ -1844,10 +1844,6 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, unsigned int x, size = len * sizeof(u64); int error; - error = gfs2_rindex_update(sdp); - if (error) - return error; - memset(&rlist, 0, sizeof(struct gfs2_rgrp_list)); ht = kzalloc(size, GFP_NOFS); diff --git a/trunk/fs/gfs2/file.c b/trunk/fs/gfs2/file.c index a3d2c9ee8d66..76834587a8a4 100644 --- a/trunk/fs/gfs2/file.c +++ b/trunk/fs/gfs2/file.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/fs/gfs2/inode.c b/trunk/fs/gfs2/inode.c index a9ba2444e077..c98a60ee6dfd 100644 --- a/trunk/fs/gfs2/inode.c +++ b/trunk/fs/gfs2/inode.c @@ -1031,13 +1031,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry) struct buffer_head *bh; struct gfs2_holder ghs[3]; struct gfs2_rgrpd *rgd; - int error; - - error = gfs2_rindex_update(sdp); - if (error) - return error; - - error = -EROFS; + int error = -EROFS; gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); @@ -1230,10 +1224,6 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, return 0; } - error = gfs2_rindex_update(sdp); - if (error) - return error; - if (odip != ndip) { error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, 0, &r_gh); @@ -1355,6 +1345,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, error = alloc_required; if (error < 0) goto out_gunlock; + error = 0; if (alloc_required) { struct gfs2_qadata *qa = gfs2_qadata_get(ndip); diff --git a/trunk/fs/gfs2/lock_dlm.c b/trunk/fs/gfs2/lock_dlm.c index 5f5e70e047dc..f8411bd1b805 100644 --- a/trunk/fs/gfs2/lock_dlm.c +++ b/trunk/fs/gfs2/lock_dlm.c @@ -200,11 +200,10 @@ static int make_mode(const unsigned int lmstate) return -1; } -static u32 make_flags(struct gfs2_glock *gl, const unsigned int gfs_flags, +static u32 make_flags(const u32 lkid, const unsigned int gfs_flags, const int req) { u32 lkf = DLM_LKF_VALBLK; - u32 lkid = gl->gl_lksb.sb_lkid; if (gfs_flags & LM_FLAG_TRY) lkf |= DLM_LKF_NOQUEUE; @@ -228,11 +227,8 @@ static u32 make_flags(struct gfs2_glock *gl, const unsigned int gfs_flags, BUG(); } - if (lkid != 0) { + if (lkid != 0) lkf |= DLM_LKF_CONVERT; - if (test_bit(GLF_BLOCKING, &gl->gl_flags)) - lkf |= DLM_LKF_QUECVT; - } return lkf; } @@ -254,7 +250,7 @@ static int gdlm_lock(struct gfs2_glock *gl, unsigned int req_state, char strname[GDLM_STRNAME_BYTES] = ""; req = make_mode(req_state); - lkf = make_flags(gl, flags, req); + lkf = make_flags(gl->gl_lksb.sb_lkid, flags, req); gfs2_glstats_inc(gl, GFS2_LKS_DCOUNT); gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT); if (gl->gl_lksb.sb_lkid) { diff --git a/trunk/fs/gfs2/rgrp.c b/trunk/fs/gfs2/rgrp.c index 3df65c9ab73b..19bde40b4864 100644 --- a/trunk/fs/gfs2/rgrp.c +++ b/trunk/fs/gfs2/rgrp.c @@ -332,6 +332,9 @@ struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk, bool exact) struct rb_node *n, *next; struct gfs2_rgrpd *cur; + if (gfs2_rindex_update(sdp)) + return NULL; + spin_lock(&sdp->sd_rindex_spin); n = sdp->sd_rindex_tree.rb_node; while (n) { @@ -637,7 +640,6 @@ static int read_rindex_entry(struct gfs2_inode *ip, return 0; error = 0; /* someone else read in the rgrp; free it and ignore it */ - gfs2_glock_put(rgd->rd_gl); fail: kfree(rgd->rd_bits); @@ -925,10 +927,6 @@ int gfs2_fitrim(struct file *filp, void __user *argp) } else if (copy_from_user(&r, argp, sizeof(r))) return -EFAULT; - ret = gfs2_rindex_update(sdp); - if (ret) - return ret; - rgd = gfs2_blk2rgrpd(sdp, r.start, 0); rgd_end = gfs2_blk2rgrpd(sdp, r.start + r.len, 0); diff --git a/trunk/fs/gfs2/xattr.c b/trunk/fs/gfs2/xattr.c index 927f4df874ae..2e5ba425cae7 100644 --- a/trunk/fs/gfs2/xattr.c +++ b/trunk/fs/gfs2/xattr.c @@ -238,10 +238,6 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, unsigned int x; int error; - error = gfs2_rindex_update(sdp); - if (error) - return error; - if (GFS2_EA_IS_STUFFED(ea)) return 0; @@ -1334,10 +1330,6 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) unsigned int x; int error; - error = gfs2_rindex_update(sdp); - if (error) - return error; - memset(&rlist, 0, sizeof(struct gfs2_rgrp_list)); error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &indbh); @@ -1447,10 +1439,6 @@ static int ea_dealloc_block(struct gfs2_inode *ip) struct gfs2_holder gh; int error; - error = gfs2_rindex_update(sdp); - if (error) - return error; - rgd = gfs2_blk2rgrpd(sdp, ip->i_eattr, 1); if (!rgd) { gfs2_consist_inode(ip); diff --git a/trunk/fs/hfsplus/catalog.c b/trunk/fs/hfsplus/catalog.c index ec2a9c23f0c9..4dfbfec357e8 100644 --- a/trunk/fs/hfsplus/catalog.c +++ b/trunk/fs/hfsplus/catalog.c @@ -366,10 +366,6 @@ int hfsplus_rename_cat(u32 cnid, err = hfs_brec_find(&src_fd); if (err) goto out; - if (src_fd.entrylength > sizeof(entry) || src_fd.entrylength < 0) { - err = -EIO; - goto out; - } hfs_bnode_read(src_fd.bnode, &entry, src_fd.entryoffset, src_fd.entrylength); diff --git a/trunk/fs/hfsplus/dir.c b/trunk/fs/hfsplus/dir.c index 26b53fb09f68..88e155f895c6 100644 --- a/trunk/fs/hfsplus/dir.c +++ b/trunk/fs/hfsplus/dir.c @@ -150,11 +150,6 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) filp->f_pos++; /* fall through */ case 1: - if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { - err = -EIO; - goto out; - } - hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); if (be16_to_cpu(entry.type) != HFSPLUS_FOLDER_THREAD) { @@ -186,12 +181,6 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) err = -EIO; goto out; } - - if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { - err = -EIO; - goto out; - } - hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); type = be16_to_cpu(entry.type); diff --git a/trunk/fs/hugetlbfs/inode.c b/trunk/fs/hugetlbfs/inode.c index 001ef01d2fe2..ea251749d9d5 100644 --- a/trunk/fs/hugetlbfs/inode.c +++ b/trunk/fs/hugetlbfs/inode.c @@ -485,7 +485,6 @@ static struct inode *hugetlbfs_get_root(struct super_block *sb, inode->i_fop = &simple_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ inc_nlink(inode); - lockdep_annotate_inode_mutex_key(inode); } return inode; } @@ -1032,6 +1031,7 @@ static int __init init_hugetlbfs_fs(void) } error = PTR_ERR(vfsmount); + unregister_filesystem(&hugetlbfs_fs_type); out: kmem_cache_destroy(hugetlbfs_inode_cachep); diff --git a/trunk/fs/jbd2/commit.c b/trunk/fs/jbd2/commit.c index 840f70f50792..806525a7269c 100644 --- a/trunk/fs/jbd2/commit.c +++ b/trunk/fs/jbd2/commit.c @@ -723,7 +723,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) if (commit_transaction->t_need_data_flush && (journal->j_fs_dev != journal->j_dev) && (journal->j_flags & JBD2_BARRIER)) - blkdev_issue_flush(journal->j_fs_dev, GFP_NOFS, NULL); + blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); /* Done it all: now write the commit record asynchronously. */ if (JBD2_HAS_INCOMPAT_FEATURE(journal, @@ -859,7 +859,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT) && journal->j_flags & JBD2_BARRIER) { - blkdev_issue_flush(journal->j_dev, GFP_NOFS, NULL); + blkdev_issue_flush(journal->j_dev, GFP_KERNEL, NULL); } if (err) diff --git a/trunk/fs/jffs2/acl.c b/trunk/fs/jffs2/acl.c index 922f146e4235..926d02068a14 100644 --- a/trunk/fs/jffs2/acl.c +++ b/trunk/fs/jffs2/acl.c @@ -9,8 +9,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include diff --git a/trunk/fs/jffs2/background.c b/trunk/fs/jffs2/background.c index 2b60ce1996aa..404111b016c9 100644 --- a/trunk/fs/jffs2/background.c +++ b/trunk/fs/jffs2/background.c @@ -10,8 +10,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -44,13 +42,12 @@ int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c) tsk = kthread_run(jffs2_garbage_collect_thread, c, "jffs2_gcd_mtd%d", c->mtd->index); if (IS_ERR(tsk)) { - pr_warn("fork failed for JFFS2 garbage collect thread: %ld\n", - -PTR_ERR(tsk)); + printk(KERN_WARNING "fork failed for JFFS2 garbage collect thread: %ld\n", -PTR_ERR(tsk)); complete(&c->gc_thread_exit); ret = PTR_ERR(tsk); } else { /* Wait for it... */ - jffs2_dbg(1, "Garbage collect thread is pid %d\n", tsk->pid); + D1(printk(KERN_DEBUG "JFFS2: Garbage collect thread is pid %d\n", tsk->pid)); wait_for_completion(&c->gc_thread_start); ret = tsk->pid; } @@ -63,7 +60,7 @@ void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c) int wait = 0; spin_lock(&c->erase_completion_lock); if (c->gc_task) { - jffs2_dbg(1, "Killing GC task %d\n", c->gc_task->pid); + D1(printk(KERN_DEBUG "jffs2: Killing GC task %d\n", c->gc_task->pid)); send_sig(SIGKILL, c->gc_task, 1); wait = 1; } @@ -93,7 +90,7 @@ static int jffs2_garbage_collect_thread(void *_c) if (!jffs2_thread_should_wake(c)) { set_current_state (TASK_INTERRUPTIBLE); spin_unlock(&c->erase_completion_lock); - jffs2_dbg(1, "%s(): sleeping...\n", __func__); + D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n")); schedule(); } else spin_unlock(&c->erase_completion_lock); @@ -112,7 +109,7 @@ static int jffs2_garbage_collect_thread(void *_c) schedule_timeout_interruptible(msecs_to_jiffies(50)); if (kthread_should_stop()) { - jffs2_dbg(1, "%s(): kthread_stop() called\n", __func__); + D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread(): kthread_stop() called.\n")); goto die; } @@ -129,32 +126,28 @@ static int jffs2_garbage_collect_thread(void *_c) switch(signr) { case SIGSTOP: - jffs2_dbg(1, "%s(): SIGSTOP received\n", - __func__); + D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread(): SIGSTOP received.\n")); set_current_state(TASK_STOPPED); schedule(); break; case SIGKILL: - jffs2_dbg(1, "%s(): SIGKILL received\n", - __func__); + D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread(): SIGKILL received.\n")); goto die; case SIGHUP: - jffs2_dbg(1, "%s(): SIGHUP received\n", - __func__); + D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread(): SIGHUP received.\n")); break; default: - jffs2_dbg(1, "%s(): signal %ld received\n", - __func__, signr); + D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread(): signal %ld received\n", signr)); } } /* We don't want SIGHUP to interrupt us. STOP and KILL are OK though. */ disallow_signal(SIGHUP); - jffs2_dbg(1, "%s(): pass\n", __func__); + D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread(): pass\n")); if (jffs2_garbage_collect_pass(c) == -ENOSPC) { - pr_notice("No space for garbage collection. Aborting GC thread\n"); + printk(KERN_NOTICE "No space for garbage collection. Aborting GC thread\n"); goto die; } } diff --git a/trunk/fs/jffs2/build.c b/trunk/fs/jffs2/build.c index a3750f902adc..3005ec4520ad 100644 --- a/trunk/fs/jffs2/build.c +++ b/trunk/fs/jffs2/build.c @@ -10,8 +10,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -309,8 +307,8 @@ static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c) trying to GC to make more space. It'll be a fruitless task */ c->nospc_dirty_size = c->sector_size + (c->flash_size / 100); - dbg_fsbuild("trigger levels (size %d KiB, block size %d KiB, %d blocks)\n", - c->flash_size / 1024, c->sector_size / 1024, c->nr_blocks); + dbg_fsbuild("JFFS2 trigger levels (size %d KiB, block size %d KiB, %d blocks)\n", + c->flash_size / 1024, c->sector_size / 1024, c->nr_blocks); dbg_fsbuild("Blocks required to allow deletion: %d (%d KiB)\n", c->resv_blocks_deletion, c->resv_blocks_deletion*c->sector_size/1024); dbg_fsbuild("Blocks required to allow writes: %d (%d KiB)\n", diff --git a/trunk/fs/jffs2/compr.c b/trunk/fs/jffs2/compr.c index 4849a4c9a0e2..96ed3c9ec3fc 100644 --- a/trunk/fs/jffs2/compr.c +++ b/trunk/fs/jffs2/compr.c @@ -12,8 +12,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include "compr.h" static DEFINE_SPINLOCK(jffs2_compressor_list_lock); @@ -81,7 +79,7 @@ static int jffs2_selected_compress(u8 compr, unsigned char *data_in, output_buf = kmalloc(*cdatalen, GFP_KERNEL); if (!output_buf) { - pr_warn("No memory for compressor allocation. Compression failed.\n"); + printk(KERN_WARNING "JFFS2: No memory for compressor allocation. Compression failed.\n"); return ret; } orig_slen = *datalen; @@ -190,8 +188,7 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, tmp_buf = kmalloc(orig_slen, GFP_KERNEL); spin_lock(&jffs2_compressor_list_lock); if (!tmp_buf) { - pr_warn("No memory for compressor allocation. (%d bytes)\n", - orig_slen); + printk(KERN_WARNING "JFFS2: No memory for compressor allocation. (%d bytes)\n", orig_slen); continue; } else { @@ -238,7 +235,7 @@ uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, cpage_out, datalen, cdatalen); break; default: - pr_err("unknown compression mode\n"); + printk(KERN_ERR "JFFS2: unknown compression mode.\n"); } if (ret == JFFS2_COMPR_NONE) { @@ -280,8 +277,7 @@ int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, ret = this->decompress(cdata_in, data_out, cdatalen, datalen); spin_lock(&jffs2_compressor_list_lock); if (ret) { - pr_warn("Decompressor \"%s\" returned %d\n", - this->name, ret); + printk(KERN_WARNING "Decompressor \"%s\" returned %d\n", this->name, ret); } else { this->stat_decompr_blocks++; @@ -291,7 +287,7 @@ int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, return ret; } } - pr_warn("compression type 0x%02x not available\n", comprtype); + printk(KERN_WARNING "JFFS2 compression type 0x%02x not available.\n", comprtype); spin_unlock(&jffs2_compressor_list_lock); return -EIO; } @@ -303,7 +299,7 @@ int jffs2_register_compressor(struct jffs2_compressor *comp) struct jffs2_compressor *this; if (!comp->name) { - pr_warn("NULL compressor name at registering JFFS2 compressor. Failed.\n"); + printk(KERN_WARNING "NULL compressor name at registering JFFS2 compressor. Failed.\n"); return -1; } comp->compr_buf_size=0; @@ -313,7 +309,7 @@ int jffs2_register_compressor(struct jffs2_compressor *comp) comp->stat_compr_new_size=0; comp->stat_compr_blocks=0; comp->stat_decompr_blocks=0; - jffs2_dbg(1, "Registering JFFS2 compressor \"%s\"\n", comp->name); + D1(printk(KERN_DEBUG "Registering JFFS2 compressor \"%s\"\n", comp->name)); spin_lock(&jffs2_compressor_list_lock); @@ -336,15 +332,15 @@ int jffs2_register_compressor(struct jffs2_compressor *comp) int jffs2_unregister_compressor(struct jffs2_compressor *comp) { - D2(struct jffs2_compressor *this); + D2(struct jffs2_compressor *this;) - jffs2_dbg(1, "Unregistering JFFS2 compressor \"%s\"\n", comp->name); + D1(printk(KERN_DEBUG "Unregistering JFFS2 compressor \"%s\"\n", comp->name)); spin_lock(&jffs2_compressor_list_lock); if (comp->usecount) { spin_unlock(&jffs2_compressor_list_lock); - pr_warn("Compressor module is in use. Unregister failed.\n"); + printk(KERN_WARNING "JFFS2: Compressor module is in use. Unregister failed.\n"); return -1; } list_del(&comp->list); @@ -381,17 +377,17 @@ int __init jffs2_compressors_init(void) /* Setting default compression mode */ #ifdef CONFIG_JFFS2_CMODE_NONE jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; - jffs2_dbg(1, "default compression mode: none\n"); + D1(printk(KERN_INFO "JFFS2: default compression mode: none\n");) #else #ifdef CONFIG_JFFS2_CMODE_SIZE jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE; - jffs2_dbg(1, "default compression mode: size\n"); + D1(printk(KERN_INFO "JFFS2: default compression mode: size\n");) #else #ifdef CONFIG_JFFS2_CMODE_FAVOURLZO jffs2_compression_mode = JFFS2_COMPR_MODE_FAVOURLZO; - jffs2_dbg(1, "default compression mode: favourlzo\n"); + D1(printk(KERN_INFO "JFFS2: default compression mode: favourlzo\n");) #else - jffs2_dbg(1, "default compression mode: priority\n"); + D1(printk(KERN_INFO "JFFS2: default compression mode: priority\n");) #endif #endif #endif diff --git a/trunk/fs/jffs2/compr_lzo.c b/trunk/fs/jffs2/compr_lzo.c index c553bd6506da..af186ee674d8 100644 --- a/trunk/fs/jffs2/compr_lzo.c +++ b/trunk/fs/jffs2/compr_lzo.c @@ -33,6 +33,7 @@ static int __init alloc_workspace(void) lzo_compress_buf = vmalloc(lzo1x_worst_compress(PAGE_SIZE)); if (!lzo_mem || !lzo_compress_buf) { + printk(KERN_WARNING "Failed to allocate lzo deflate workspace\n"); free_workspace(); return -ENOMEM; } diff --git a/trunk/fs/jffs2/compr_rubin.c b/trunk/fs/jffs2/compr_rubin.c index 92e0644bf867..9e7cec808c4c 100644 --- a/trunk/fs/jffs2/compr_rubin.c +++ b/trunk/fs/jffs2/compr_rubin.c @@ -10,8 +10,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include diff --git a/trunk/fs/jffs2/compr_zlib.c b/trunk/fs/jffs2/compr_zlib.c index 0b9a1e44e833..5a001020c542 100644 --- a/trunk/fs/jffs2/compr_zlib.c +++ b/trunk/fs/jffs2/compr_zlib.c @@ -14,8 +14,6 @@ #error "The userspace support got too messy and was removed. Update your mkfs.jffs2" #endif -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -44,18 +42,18 @@ static int __init alloc_workspaces(void) { def_strm.workspace = vmalloc(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL)); - if (!def_strm.workspace) + if (!def_strm.workspace) { + printk(KERN_WARNING "Failed to allocate %d bytes for deflate workspace\n", zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL)); return -ENOMEM; - - jffs2_dbg(1, "Allocated %d bytes for deflate workspace\n", - zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL)); + } + D1(printk(KERN_DEBUG "Allocated %d bytes for deflate workspace\n", zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL))); inf_strm.workspace = vmalloc(zlib_inflate_workspacesize()); if (!inf_strm.workspace) { + printk(KERN_WARNING "Failed to allocate %d bytes for inflate workspace\n", zlib_inflate_workspacesize()); vfree(def_strm.workspace); return -ENOMEM; } - jffs2_dbg(1, "Allocated %d bytes for inflate workspace\n", - zlib_inflate_workspacesize()); + D1(printk(KERN_DEBUG "Allocated %d bytes for inflate workspace\n", zlib_inflate_workspacesize())); return 0; } @@ -81,7 +79,7 @@ static int jffs2_zlib_compress(unsigned char *data_in, mutex_lock(&deflate_mutex); if (Z_OK != zlib_deflateInit(&def_strm, 3)) { - pr_warn("deflateInit failed\n"); + printk(KERN_WARNING "deflateInit failed\n"); mutex_unlock(&deflate_mutex); return -1; } @@ -95,14 +93,13 @@ static int jffs2_zlib_compress(unsigned char *data_in, while (def_strm.total_out < *dstlen - STREAM_END_SPACE && def_strm.total_in < *sourcelen) { def_strm.avail_out = *dstlen - (def_strm.total_out + STREAM_END_SPACE); def_strm.avail_in = min((unsigned)(*sourcelen-def_strm.total_in), def_strm.avail_out); - jffs2_dbg(1, "calling deflate with avail_in %d, avail_out %d\n", - def_strm.avail_in, def_strm.avail_out); + D1(printk(KERN_DEBUG "calling deflate with avail_in %d, avail_out %d\n", + def_strm.avail_in, def_strm.avail_out)); ret = zlib_deflate(&def_strm, Z_PARTIAL_FLUSH); - jffs2_dbg(1, "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n", - def_strm.avail_in, def_strm.avail_out, - def_strm.total_in, def_strm.total_out); + D1(printk(KERN_DEBUG "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n", + def_strm.avail_in, def_strm.avail_out, def_strm.total_in, def_strm.total_out)); if (ret != Z_OK) { - jffs2_dbg(1, "deflate in loop returned %d\n", ret); + D1(printk(KERN_DEBUG "deflate in loop returned %d\n", ret)); zlib_deflateEnd(&def_strm); mutex_unlock(&deflate_mutex); return -1; @@ -114,20 +111,20 @@ static int jffs2_zlib_compress(unsigned char *data_in, zlib_deflateEnd(&def_strm); if (ret != Z_STREAM_END) { - jffs2_dbg(1, "final deflate returned %d\n", ret); + D1(printk(KERN_DEBUG "final deflate returned %d\n", ret)); ret = -1; goto out; } if (def_strm.total_out >= def_strm.total_in) { - jffs2_dbg(1, "zlib compressed %ld bytes into %ld; failing\n", - def_strm.total_in, def_strm.total_out); + D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld; failing\n", + def_strm.total_in, def_strm.total_out)); ret = -1; goto out; } - jffs2_dbg(1, "zlib compressed %ld bytes into %ld\n", - def_strm.total_in, def_strm.total_out); + D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld\n", + def_strm.total_in, def_strm.total_out)); *dstlen = def_strm.total_out; *sourcelen = def_strm.total_in; @@ -160,18 +157,18 @@ static int jffs2_zlib_decompress(unsigned char *data_in, ((data_in[0] & 0x0f) == Z_DEFLATED) && !(((data_in[0]<<8) + data_in[1]) % 31)) { - jffs2_dbg(2, "inflate skipping adler32\n"); + D2(printk(KERN_DEBUG "inflate skipping adler32\n")); wbits = -((data_in[0] >> 4) + 8); inf_strm.next_in += 2; inf_strm.avail_in -= 2; } else { /* Let this remain D1 for now -- it should never happen */ - jffs2_dbg(1, "inflate not skipping adler32\n"); + D1(printk(KERN_DEBUG "inflate not skipping adler32\n")); } if (Z_OK != zlib_inflateInit2(&inf_strm, wbits)) { - pr_warn("inflateInit failed\n"); + printk(KERN_WARNING "inflateInit failed\n"); mutex_unlock(&inflate_mutex); return 1; } @@ -179,7 +176,7 @@ static int jffs2_zlib_decompress(unsigned char *data_in, while((ret = zlib_inflate(&inf_strm, Z_FINISH)) == Z_OK) ; if (ret != Z_STREAM_END) { - pr_notice("inflate returned %d\n", ret); + printk(KERN_NOTICE "inflate returned %d\n", ret); } zlib_inflateEnd(&inf_strm); mutex_unlock(&inflate_mutex); diff --git a/trunk/fs/jffs2/debug.c b/trunk/fs/jffs2/debug.c index 1090eb64b90d..e0b76c87a91a 100644 --- a/trunk/fs/jffs2/debug.c +++ b/trunk/fs/jffs2/debug.c @@ -10,8 +10,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -263,15 +261,12 @@ void __jffs2_dbg_superblock_counts(struct jffs2_sb_info *c) bad += c->sector_size; } -#define check(sz) \ -do { \ - if (sz != c->sz##_size) { \ - pr_warn("%s_size mismatch counted 0x%x, c->%s_size 0x%x\n", \ - #sz, sz, #sz, c->sz##_size); \ - dump = 1; \ - } \ -} while (0) - +#define check(sz) \ + if (sz != c->sz##_size) { \ + printk(KERN_WARNING #sz "_size mismatch counted 0x%x, c->" #sz "_size 0x%x\n", \ + sz, c->sz##_size); \ + dump = 1; \ + } check(free); check(dirty); check(used); @@ -279,12 +274,11 @@ do { \ check(unchecked); check(bad); check(erasing); - #undef check if (nr_counted != c->nr_blocks) { - pr_warn("%s counted only 0x%x blocks of 0x%x. Where are the others?\n", - __func__, nr_counted, c->nr_blocks); + printk(KERN_WARNING "%s counted only 0x%x blocks of 0x%x. Where are the others?\n", + __func__, nr_counted, c->nr_blocks); dump = 1; } diff --git a/trunk/fs/jffs2/debug.h b/trunk/fs/jffs2/debug.h index 4fd9be4cbc98..c4f8eef5ca68 100644 --- a/trunk/fs/jffs2/debug.h +++ b/trunk/fs/jffs2/debug.h @@ -51,7 +51,6 @@ * superseded by nicer dbg_xxx() macros... */ #if CONFIG_JFFS2_FS_DEBUG > 0 -#define DEBUG #define D1(x) x #else #define D1(x) @@ -63,33 +62,50 @@ #define D2(x) #endif -#define jffs2_dbg(level, fmt, ...) \ -do { \ - if (CONFIG_JFFS2_FS_DEBUG >= level) \ - pr_debug(fmt, ##__VA_ARGS__); \ -} while (0) - /* The prefixes of JFFS2 messages */ -#define JFFS2_DBG KERN_DEBUG #define JFFS2_DBG_PREFIX "[JFFS2 DBG]" +#define JFFS2_ERR_PREFIX "JFFS2 error:" +#define JFFS2_WARN_PREFIX "JFFS2 warning:" +#define JFFS2_NOTICE_PREFIX "JFFS2 notice:" + +#define JFFS2_ERR KERN_ERR +#define JFFS2_WARN KERN_WARNING +#define JFFS2_NOT KERN_NOTICE +#define JFFS2_DBG KERN_DEBUG + #define JFFS2_DBG_MSG_PREFIX JFFS2_DBG JFFS2_DBG_PREFIX +#define JFFS2_ERR_MSG_PREFIX JFFS2_ERR JFFS2_ERR_PREFIX +#define JFFS2_WARN_MSG_PREFIX JFFS2_WARN JFFS2_WARN_PREFIX +#define JFFS2_NOTICE_MSG_PREFIX JFFS2_NOT JFFS2_NOTICE_PREFIX /* JFFS2 message macros */ -#define JFFS2_ERROR(fmt, ...) \ - pr_err("error: (%d) %s: " fmt, \ - task_pid_nr(current), __func__, ##__VA_ARGS__) +#define JFFS2_ERROR(fmt, ...) \ + do { \ + printk(JFFS2_ERR_MSG_PREFIX \ + " (%d) %s: " fmt, task_pid_nr(current), \ + __func__ , ##__VA_ARGS__); \ + } while(0) #define JFFS2_WARNING(fmt, ...) \ - pr_warn("warning: (%d) %s: " fmt, \ - task_pid_nr(current), __func__, ##__VA_ARGS__) + do { \ + printk(JFFS2_WARN_MSG_PREFIX \ + " (%d) %s: " fmt, task_pid_nr(current), \ + __func__ , ##__VA_ARGS__); \ + } while(0) #define JFFS2_NOTICE(fmt, ...) \ - pr_notice("notice: (%d) %s: " fmt, \ - task_pid_nr(current), __func__, ##__VA_ARGS__) + do { \ + printk(JFFS2_NOTICE_MSG_PREFIX \ + " (%d) %s: " fmt, task_pid_nr(current), \ + __func__ , ##__VA_ARGS__); \ + } while(0) #define JFFS2_DEBUG(fmt, ...) \ - printk(KERN_DEBUG "[JFFS2 DBG] (%d) %s: " fmt, \ - task_pid_nr(current), __func__, ##__VA_ARGS__) + do { \ + printk(JFFS2_DBG_MSG_PREFIX \ + " (%d) %s: " fmt, task_pid_nr(current), \ + __func__ , ##__VA_ARGS__); \ + } while(0) /* * We split our debugging messages on several parts, depending on the JFFS2 diff --git a/trunk/fs/jffs2/dir.c b/trunk/fs/jffs2/dir.c index b56018896d5e..973ac5822bd7 100644 --- a/trunk/fs/jffs2/dir.c +++ b/trunk/fs/jffs2/dir.c @@ -10,8 +10,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -81,7 +79,7 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target, uint32_t ino = 0; struct inode *inode = NULL; - jffs2_dbg(1, "jffs2_lookup()\n"); + D1(printk(KERN_DEBUG "jffs2_lookup()\n")); if (target->d_name.len > JFFS2_MAX_NAME_LEN) return ERR_PTR(-ENAMETOOLONG); @@ -105,7 +103,7 @@ static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target, if (ino) { inode = jffs2_iget(dir_i->i_sb, ino); if (IS_ERR(inode)) - pr_warn("iget() failed for ino #%u\n", ino); + printk(KERN_WARNING "iget() failed for ino #%u\n", ino); } return d_splice_alias(inode, target); @@ -121,22 +119,21 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir) struct jffs2_full_dirent *fd; unsigned long offset, curofs; - jffs2_dbg(1, "jffs2_readdir() for dir_i #%lu\n", - filp->f_path.dentry->d_inode->i_ino); + D1(printk(KERN_DEBUG "jffs2_readdir() for dir_i #%lu\n", filp->f_path.dentry->d_inode->i_ino)); f = JFFS2_INODE_INFO(inode); offset = filp->f_pos; if (offset == 0) { - jffs2_dbg(1, "Dirent 0: \".\", ino #%lu\n", inode->i_ino); + D1(printk(KERN_DEBUG "Dirent 0: \".\", ino #%lu\n", inode->i_ino)); if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0) goto out; offset++; } if (offset == 1) { unsigned long pino = parent_ino(filp->f_path.dentry); - jffs2_dbg(1, "Dirent 1: \"..\", ino #%lu\n", pino); + D1(printk(KERN_DEBUG "Dirent 1: \"..\", ino #%lu\n", pino)); if (filldir(dirent, "..", 2, 1, pino, DT_DIR) < 0) goto out; offset++; @@ -149,18 +146,16 @@ static int jffs2_readdir(struct file *filp, void *dirent, filldir_t filldir) curofs++; /* First loop: curofs = 2; offset = 2 */ if (curofs < offset) { - jffs2_dbg(2, "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n", - fd->name, fd->ino, fd->type, curofs, offset); + D2(printk(KERN_DEBUG "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n", + fd->name, fd->ino, fd->type, curofs, offset)); continue; } if (!fd->ino) { - jffs2_dbg(2, "Skipping deletion dirent \"%s\"\n", - fd->name); + D2(printk(KERN_DEBUG "Skipping deletion dirent \"%s\"\n", fd->name)); offset++; continue; } - jffs2_dbg(2, "Dirent %ld: \"%s\", ino #%u, type %d\n", - offset, fd->name, fd->ino, fd->type); + D2(printk(KERN_DEBUG "Dirent %ld: \"%s\", ino #%u, type %d\n", offset, fd->name, fd->ino, fd->type)); if (filldir(dirent, fd->name, strlen(fd->name), offset, fd->ino, fd->type) < 0) break; offset++; @@ -189,12 +184,12 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, c = JFFS2_SB_INFO(dir_i->i_sb); - jffs2_dbg(1, "%s()\n", __func__); + D1(printk(KERN_DEBUG "jffs2_create()\n")); inode = jffs2_new_inode(dir_i, mode, ri); if (IS_ERR(inode)) { - jffs2_dbg(1, "jffs2_new_inode() failed\n"); + D1(printk(KERN_DEBUG "jffs2_new_inode() failed\n")); jffs2_free_raw_inode(ri); return PTR_ERR(inode); } @@ -222,9 +217,9 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, jffs2_free_raw_inode(ri); - jffs2_dbg(1, "%s(): Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", - __func__, inode->i_ino, inode->i_mode, inode->i_nlink, - f->inocache->pino_nlink, inode->i_mapping->nrpages); + D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", + inode->i_ino, inode->i_mode, inode->i_nlink, + f->inocache->pino_nlink, inode->i_mapping->nrpages)); d_instantiate(dentry, inode); unlock_new_inode(inode); @@ -367,15 +362,14 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char /* We use f->target field to store the target path. */ f->target = kmemdup(target, targetlen + 1, GFP_KERNEL); if (!f->target) { - pr_warn("Can't allocate %d bytes of memory\n", targetlen + 1); + printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1); mutex_unlock(&f->sem); jffs2_complete_reservation(c); ret = -ENOMEM; goto fail; } - jffs2_dbg(1, "%s(): symlink's target '%s' cached\n", - __func__, (char *)f->target); + D1(printk(KERN_DEBUG "jffs2_symlink: symlink's target '%s' cached\n", (char *)f->target)); /* No data here. Only a metadata node, which will be obsoleted by the first data write @@ -862,8 +856,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, f->inocache->pino_nlink++; mutex_unlock(&f->sem); - pr_notice("%s(): Link succeeded, unlink failed (err %d). You now have a hard link\n", - __func__, ret); + printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ret); /* Might as well let the VFS know */ d_instantiate(new_dentry, old_dentry->d_inode); ihold(old_dentry->d_inode); diff --git a/trunk/fs/jffs2/erase.c b/trunk/fs/jffs2/erase.c index 4a6cf289be24..eafb8d37a6fb 100644 --- a/trunk/fs/jffs2/erase.c +++ b/trunk/fs/jffs2/erase.c @@ -10,8 +10,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -48,12 +46,11 @@ static void jffs2_erase_block(struct jffs2_sb_info *c, #else /* Linux */ struct erase_info *instr; - jffs2_dbg(1, "%s(): erase block %#08x (range %#08x-%#08x)\n", - __func__, - jeb->offset, jeb->offset, jeb->offset + c->sector_size); + D1(printk(KERN_DEBUG "jffs2_erase_block(): erase block %#08x (range %#08x-%#08x)\n", + jeb->offset, jeb->offset, jeb->offset + c->sector_size)); instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL); if (!instr) { - pr_warn("kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n"); + printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n"); mutex_lock(&c->erase_free_sem); spin_lock(&c->erase_completion_lock); list_move(&jeb->list, &c->erase_pending_list); @@ -72,6 +69,7 @@ static void jffs2_erase_block(struct jffs2_sb_info *c, instr->len = c->sector_size; instr->callback = jffs2_erase_callback; instr->priv = (unsigned long)(&instr[1]); + instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; ((struct erase_priv_struct *)instr->priv)->jeb = jeb; ((struct erase_priv_struct *)instr->priv)->c = c; @@ -86,8 +84,7 @@ static void jffs2_erase_block(struct jffs2_sb_info *c, if (ret == -ENOMEM || ret == -EAGAIN) { /* Erase failed immediately. Refile it on the list */ - jffs2_dbg(1, "Erase at 0x%08x failed: %d. Refiling on erase_pending_list\n", - jeb->offset, ret); + D1(printk(KERN_DEBUG "Erase at 0x%08x failed: %d. Refiling on erase_pending_list\n", jeb->offset, ret)); mutex_lock(&c->erase_free_sem); spin_lock(&c->erase_completion_lock); list_move(&jeb->list, &c->erase_pending_list); @@ -100,11 +97,9 @@ static void jffs2_erase_block(struct jffs2_sb_info *c, } if (ret == -EROFS) - pr_warn("Erase at 0x%08x failed immediately: -EROFS. Is the sector locked?\n", - jeb->offset); + printk(KERN_WARNING "Erase at 0x%08x failed immediately: -EROFS. Is the sector locked?\n", jeb->offset); else - pr_warn("Erase at 0x%08x failed immediately: errno %d\n", - jeb->offset, ret); + printk(KERN_WARNING "Erase at 0x%08x failed immediately: errno %d\n", jeb->offset, ret); jffs2_erase_failed(c, jeb, bad_offset); } @@ -130,14 +125,13 @@ int jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count) work_done++; if (!--count) { - jffs2_dbg(1, "Count reached. jffs2_erase_pending_blocks leaving\n"); + D1(printk(KERN_DEBUG "Count reached. jffs2_erase_pending_blocks leaving\n")); goto done; } } else if (!list_empty(&c->erase_pending_list)) { jeb = list_entry(c->erase_pending_list.next, struct jffs2_eraseblock, list); - jffs2_dbg(1, "Starting erase of pending block 0x%08x\n", - jeb->offset); + D1(printk(KERN_DEBUG "Starting erase of pending block 0x%08x\n", jeb->offset)); list_del(&jeb->list); c->erasing_size += c->sector_size; c->wasted_size -= jeb->wasted_size; @@ -165,13 +159,13 @@ int jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count) spin_unlock(&c->erase_completion_lock); mutex_unlock(&c->erase_free_sem); done: - jffs2_dbg(1, "jffs2_erase_pending_blocks completed\n"); + D1(printk(KERN_DEBUG "jffs2_erase_pending_blocks completed\n")); return work_done; } static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) { - jffs2_dbg(1, "Erase completed successfully at 0x%08x\n", jeb->offset); + D1(printk(KERN_DEBUG "Erase completed successfully at 0x%08x\n", jeb->offset)); mutex_lock(&c->erase_free_sem); spin_lock(&c->erase_completion_lock); list_move_tail(&jeb->list, &c->erase_complete_list); @@ -220,7 +214,7 @@ static void jffs2_erase_callback(struct erase_info *instr) struct erase_priv_struct *priv = (void *)instr->priv; if(instr->state != MTD_ERASE_DONE) { - pr_warn("Erase at 0x%08llx finished, but state != MTD_ERASE_DONE. State is 0x%x instead.\n", + printk(KERN_WARNING "Erase at 0x%08llx finished, but state != MTD_ERASE_DONE. State is 0x%x instead.\n", (unsigned long long)instr->addr, instr->state); jffs2_erase_failed(priv->c, priv->jeb, instr->fail_addr); } else { @@ -275,8 +269,8 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c, return; } - jffs2_dbg(1, "Removed nodes in range 0x%08x-0x%08x from ino #%u\n", - jeb->offset, jeb->offset + c->sector_size, ic->ino); + D1(printk(KERN_DEBUG "Removed nodes in range 0x%08x-0x%08x from ino #%u\n", + jeb->offset, jeb->offset + c->sector_size, ic->ino)); D2({ int i=0; @@ -287,7 +281,7 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c, printk(KERN_DEBUG); while(this) { - pr_cont("0x%08x(%d)->", + printk(KERN_CONT "0x%08x(%d)->", ref_offset(this), ref_flags(this)); if (++i == 5) { printk(KERN_DEBUG); @@ -295,7 +289,7 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c, } this = this->next_in_ino; } - pr_cont("\n"); + printk(KERN_CONT "\n"); }); switch (ic->class) { @@ -316,8 +310,7 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c, void jffs2_free_jeb_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) { struct jffs2_raw_node_ref *block, *ref; - jffs2_dbg(1, "Freeing all node refs for eraseblock offset 0x%08x\n", - jeb->offset); + D1(printk(KERN_DEBUG "Freeing all node refs for eraseblock offset 0x%08x\n", jeb->offset)); block = ref = jeb->first_node; @@ -349,13 +342,12 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl &ebuf, NULL); if (ret != -EOPNOTSUPP) { if (ret) { - jffs2_dbg(1, "MTD point failed %d\n", ret); + D1(printk(KERN_DEBUG "MTD point failed %d\n", ret)); goto do_flash_read; } if (retlen < c->sector_size) { /* Don't muck about if it won't let us point to the whole erase sector */ - jffs2_dbg(1, "MTD point returned len too short: 0x%zx\n", - retlen); + D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen)); mtd_unpoint(c->mtd, jeb->offset, retlen); goto do_flash_read; } @@ -367,10 +359,8 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl } while(--retlen); mtd_unpoint(c->mtd, jeb->offset, c->sector_size); if (retlen) { - pr_warn("Newly-erased block contained word 0x%lx at offset 0x%08tx\n", - *wordebuf, - jeb->offset + - c->sector_size-retlen * sizeof(*wordebuf)); + printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08tx\n", + *wordebuf, jeb->offset + c->sector_size-retlen*sizeof(*wordebuf)); return -EIO; } return 0; @@ -378,12 +368,11 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl do_flash_read: ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!ebuf) { - pr_warn("Failed to allocate page buffer for verifying erase at 0x%08x. Refiling\n", - jeb->offset); + printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Refiling\n", jeb->offset); return -EAGAIN; } - jffs2_dbg(1, "Verifying erase at 0x%08x\n", jeb->offset); + D1(printk(KERN_DEBUG "Verifying erase at 0x%08x\n", jeb->offset)); for (ofs = jeb->offset; ofs < jeb->offset + c->sector_size; ) { uint32_t readlen = min((uint32_t)PAGE_SIZE, jeb->offset + c->sector_size - ofs); @@ -393,14 +382,12 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl ret = mtd_read(c->mtd, ofs, readlen, &retlen, ebuf); if (ret) { - pr_warn("Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", - ofs, ret); + printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret); ret = -EIO; goto fail; } if (retlen != readlen) { - pr_warn("Short read from newly-erased block at 0x%08x. Wanted %d, got %zd\n", - ofs, readlen, retlen); + printk(KERN_WARNING "Short read from newly-erased block at 0x%08x. Wanted %d, got %zd\n", ofs, readlen, retlen); ret = -EIO; goto fail; } @@ -409,8 +396,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl unsigned long *datum = ebuf + i; if (*datum + 1) { *bad_offset += i; - pr_warn("Newly-erased block contained word 0x%lx at offset 0x%08x\n", - *datum, *bad_offset); + printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", *datum, *bad_offset); ret = -EIO; goto fail; } @@ -436,7 +422,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb } /* Write the erase complete marker */ - jffs2_dbg(1, "Writing erased marker to block at 0x%08x\n", jeb->offset); + D1(printk(KERN_DEBUG "Writing erased marker to block at 0x%08x\n", jeb->offset)); bad_offset = jeb->offset; /* Cleanmarker in oob area or no cleanmarker at all ? */ @@ -465,10 +451,10 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb if (ret || retlen != sizeof(marker)) { if (ret) - pr_warn("Write clean marker to block at 0x%08x failed: %d\n", + printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n", jeb->offset, ret); else - pr_warn("Short write to newly-erased block at 0x%08x: Wanted %zd, got %zd\n", + printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %zd, got %zd\n", jeb->offset, sizeof(marker), retlen); goto filebad; diff --git a/trunk/fs/jffs2/file.c b/trunk/fs/jffs2/file.c index db3889ba8818..61e6723535b9 100644 --- a/trunk/fs/jffs2/file.c +++ b/trunk/fs/jffs2/file.c @@ -10,8 +10,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -87,8 +85,7 @@ static int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg) unsigned char *pg_buf; int ret; - jffs2_dbg(2, "%s(): ino #%lu, page at offset 0x%lx\n", - __func__, inode->i_ino, pg->index << PAGE_CACHE_SHIFT); + D2(printk(KERN_DEBUG "jffs2_do_readpage_nolock(): ino #%lu, page at offset 0x%lx\n", inode->i_ino, pg->index << PAGE_CACHE_SHIFT)); BUG_ON(!PageLocked(pg)); @@ -108,7 +105,7 @@ static int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg) flush_dcache_page(pg); kunmap(pg); - jffs2_dbg(2, "readpage finished\n"); + D2(printk(KERN_DEBUG "readpage finished\n")); return ret; } @@ -147,7 +144,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, return -ENOMEM; *pagep = pg; - jffs2_dbg(1, "%s()\n", __func__); + D1(printk(KERN_DEBUG "jffs2_write_begin()\n")); if (pageofs > inode->i_size) { /* Make new hole frag from old EOF to new page */ @@ -156,8 +153,8 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, struct jffs2_full_dnode *fn; uint32_t alloc_len; - jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", - (unsigned int)inode->i_size, pageofs); + D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", + (unsigned int)inode->i_size, pageofs)); ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); @@ -201,8 +198,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, f->metadata = NULL; } if (ret) { - jffs2_dbg(1, "Eep. add_full_dnode_to_inode() failed in write_begin, returned %d\n", - ret); + D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in write_begin, returned %d\n", ret)); jffs2_mark_node_obsolete(c, fn->raw); jffs2_free_full_dnode(fn); jffs2_complete_reservation(c); @@ -226,7 +222,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, if (ret) goto out_page; } - jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags); + D1(printk(KERN_DEBUG "end write_begin(). pg->flags %lx\n", pg->flags)); return ret; out_page: @@ -252,9 +248,8 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping, int ret = 0; uint32_t writtenlen = 0; - jffs2_dbg(1, "%s(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n", - __func__, inode->i_ino, pg->index << PAGE_CACHE_SHIFT, - start, end, pg->flags); + D1(printk(KERN_DEBUG "jffs2_write_end(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n", + inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags)); /* We need to avoid deadlock with page_cache_read() in jffs2_garbage_collect_pass(). So the page must be @@ -273,8 +268,7 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping, ri = jffs2_alloc_raw_inode(); if (!ri) { - jffs2_dbg(1, "%s(): Allocation of raw inode failed\n", - __func__); + D1(printk(KERN_DEBUG "jffs2_write_end(): Allocation of raw inode failed\n")); unlock_page(pg); page_cache_release(pg); return -ENOMEM; @@ -321,14 +315,13 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping, /* generic_file_write has written more to the page cache than we've actually written to the medium. Mark the page !Uptodate so that it gets reread */ - jffs2_dbg(1, "%s(): Not all bytes written. Marking page !uptodate\n", - __func__); + D1(printk(KERN_DEBUG "jffs2_write_end(): Not all bytes written. Marking page !uptodate\n")); SetPageError(pg); ClearPageUptodate(pg); } - jffs2_dbg(1, "%s() returning %d\n", - __func__, writtenlen > 0 ? writtenlen : ret); + D1(printk(KERN_DEBUG "jffs2_write_end() returning %d\n", + writtenlen > 0 ? writtenlen : ret)); unlock_page(pg); page_cache_release(pg); return writtenlen > 0 ? writtenlen : ret; diff --git a/trunk/fs/jffs2/fs.c b/trunk/fs/jffs2/fs.c index bb6f993ebca9..c0d5c9d770da 100644 --- a/trunk/fs/jffs2/fs.c +++ b/trunk/fs/jffs2/fs.c @@ -10,8 +10,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -41,7 +39,7 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) int ret; int alloc_type = ALLOC_NORMAL; - jffs2_dbg(1, "%s(): ino #%lu\n", __func__, inode->i_ino); + D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino)); /* Special cases - we don't want more than one data node for these types on the medium at any time. So setattr @@ -52,8 +50,7 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) /* For these, we don't actually need to read the old node */ mdatalen = jffs2_encode_dev(&dev, inode->i_rdev); mdata = (char *)&dev; - jffs2_dbg(1, "%s(): Writing %d bytes of kdev_t\n", - __func__, mdatalen); + D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen)); } else if (S_ISLNK(inode->i_mode)) { mutex_lock(&f->sem); mdatalen = f->metadata->size; @@ -69,8 +66,7 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) return ret; } mutex_unlock(&f->sem); - jffs2_dbg(1, "%s(): Writing %d bytes of symlink target\n", - __func__, mdatalen); + D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen)); } ri = jffs2_alloc_raw_inode(); @@ -237,8 +233,7 @@ void jffs2_evict_inode (struct inode *inode) struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); - jffs2_dbg(1, "%s(): ino #%lu mode %o\n", - __func__, inode->i_ino, inode->i_mode); + D1(printk(KERN_DEBUG "jffs2_evict_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode)); truncate_inode_pages(&inode->i_data, 0); end_writeback(inode); jffs2_do_clear_inode(c, f); @@ -254,7 +249,7 @@ struct inode *jffs2_iget(struct super_block *sb, unsigned long ino) dev_t rdev = 0; int ret; - jffs2_dbg(1, "%s(): ino == %lu\n", __func__, ino); + D1(printk(KERN_DEBUG "jffs2_iget(): ino == %lu\n", ino)); inode = iget_locked(sb, ino); if (!inode) @@ -322,16 +317,14 @@ struct inode *jffs2_iget(struct super_block *sb, unsigned long ino) /* Read the device numbers from the media */ if (f->metadata->size != sizeof(jdev.old_id) && f->metadata->size != sizeof(jdev.new_id)) { - pr_notice("Device node has strange size %d\n", - f->metadata->size); + printk(KERN_NOTICE "Device node has strange size %d\n", f->metadata->size); goto error_io; } - jffs2_dbg(1, "Reading device numbers from flash\n"); + D1(printk(KERN_DEBUG "Reading device numbers from flash\n")); ret = jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, f->metadata->size); if (ret < 0) { /* Eep */ - pr_notice("Read device numbers for inode %lu failed\n", - (unsigned long)inode->i_ino); + printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino); goto error; } if (f->metadata->size == sizeof(jdev.old_id)) @@ -346,13 +339,12 @@ struct inode *jffs2_iget(struct super_block *sb, unsigned long ino) break; default: - pr_warn("%s(): Bogus i_mode %o for ino %lu\n", - __func__, inode->i_mode, (unsigned long)inode->i_ino); + printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu\n", inode->i_mode, (unsigned long)inode->i_ino); } mutex_unlock(&f->sem); - jffs2_dbg(1, "jffs2_read_inode() returning\n"); + D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n")); unlock_new_inode(inode); return inode; @@ -370,13 +362,11 @@ void jffs2_dirty_inode(struct inode *inode, int flags) struct iattr iattr; if (!(inode->i_state & I_DIRTY_DATASYNC)) { - jffs2_dbg(2, "%s(): not calling setattr() for ino #%lu\n", - __func__, inode->i_ino); + D2(printk(KERN_DEBUG "jffs2_dirty_inode() not calling setattr() for ino #%lu\n", inode->i_ino)); return; } - jffs2_dbg(1, "%s(): calling setattr() for ino #%lu\n", - __func__, inode->i_ino); + D1(printk(KERN_DEBUG "jffs2_dirty_inode() calling setattr() for ino #%lu\n", inode->i_ino)); iattr.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_MTIME|ATTR_CTIME; iattr.ia_mode = inode->i_mode; @@ -424,8 +414,7 @@ struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, struct jffs2_r struct jffs2_inode_info *f; int ret; - jffs2_dbg(1, "%s(): dir_i %ld, mode 0x%x\n", - __func__, dir_i->i_ino, mode); + D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode)); c = JFFS2_SB_INFO(sb); @@ -515,11 +504,11 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) #ifndef CONFIG_JFFS2_FS_WRITEBUFFER if (c->mtd->type == MTD_NANDFLASH) { - pr_err("Cannot operate on NAND flash unless jffs2 NAND support is compiled in\n"); + printk(KERN_ERR "jffs2: Cannot operate on NAND flash unless jffs2 NAND support is compiled in.\n"); return -EINVAL; } if (c->mtd->type == MTD_DATAFLASH) { - pr_err("Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in\n"); + printk(KERN_ERR "jffs2: Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in.\n"); return -EINVAL; } #endif @@ -533,13 +522,12 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) */ if ((c->sector_size * blocks) != c->flash_size) { c->flash_size = c->sector_size * blocks; - pr_info("Flash size not aligned to erasesize, reducing to %dKiB\n", + printk(KERN_INFO "jffs2: Flash size not aligned to erasesize, reducing to %dKiB\n", c->flash_size / 1024); } if (c->flash_size < 5*c->sector_size) { - pr_err("Too few erase blocks (%d)\n", - c->flash_size / c->sector_size); + printk(KERN_ERR "jffs2: Too few erase blocks (%d)\n", c->flash_size / c->sector_size); return -EINVAL; } @@ -562,17 +550,17 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) if ((ret = jffs2_do_mount_fs(c))) goto out_inohash; - jffs2_dbg(1, "%s(): Getting root inode\n", __func__); + D1(printk(KERN_DEBUG "jffs2_do_fill_super(): Getting root inode\n")); root_i = jffs2_iget(sb, 1); if (IS_ERR(root_i)) { - jffs2_dbg(1, "get root inode failed\n"); + D1(printk(KERN_WARNING "get root inode failed\n")); ret = PTR_ERR(root_i); goto out_root; } ret = -ENOMEM; - jffs2_dbg(1, "%s(): d_make_root()\n", __func__); + D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n")); sb->s_root = d_make_root(root_i); if (!sb->s_root) goto out_root; @@ -630,21 +618,20 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, */ inode = ilookup(OFNI_BS_2SFFJ(c), inum); if (!inode) { - jffs2_dbg(1, "ilookup() failed for ino #%u; inode is probably deleted.\n", - inum); + D1(printk(KERN_DEBUG "ilookup() failed for ino #%u; inode is probably deleted.\n", + inum)); spin_lock(&c->inocache_lock); ic = jffs2_get_ino_cache(c, inum); if (!ic) { - jffs2_dbg(1, "Inode cache for ino #%u is gone\n", - inum); + D1(printk(KERN_DEBUG "Inode cache for ino #%u is gone.\n", inum)); spin_unlock(&c->inocache_lock); return NULL; } if (ic->state != INO_STATE_CHECKEDABSENT) { /* Wait for progress. Don't just loop */ - jffs2_dbg(1, "Waiting for ino #%u in state %d\n", - ic->ino, ic->state); + D1(printk(KERN_DEBUG "Waiting for ino #%u in state %d\n", + ic->ino, ic->state)); sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); } else { spin_unlock(&c->inocache_lock); @@ -662,8 +649,8 @@ struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, return ERR_CAST(inode); } if (is_bad_inode(inode)) { - pr_notice("Eep. read_inode() failed for ino #%u. unlinked %d\n", - inum, unlinked); + printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. unlinked %d\n", + inum, unlinked); /* NB. This will happen again. We need to do something appropriate here. */ iput(inode); return ERR_PTR(-EIO); diff --git a/trunk/fs/jffs2/gc.c b/trunk/fs/jffs2/gc.c index ad271c70aa25..31dce611337c 100644 --- a/trunk/fs/jffs2/gc.c +++ b/trunk/fs/jffs2/gc.c @@ -10,8 +10,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -53,44 +51,44 @@ static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c) number of free blocks is low. */ again: if (!list_empty(&c->bad_used_list) && c->nr_free_blocks > c->resv_blocks_gcbad) { - jffs2_dbg(1, "Picking block from bad_used_list to GC next\n"); + D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n")); nextlist = &c->bad_used_list; } else if (n < 50 && !list_empty(&c->erasable_list)) { /* Note that most of them will have gone directly to be erased. So don't favour the erasable_list _too_ much. */ - jffs2_dbg(1, "Picking block from erasable_list to GC next\n"); + D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next\n")); nextlist = &c->erasable_list; } else if (n < 110 && !list_empty(&c->very_dirty_list)) { /* Most of the time, pick one off the very_dirty list */ - jffs2_dbg(1, "Picking block from very_dirty_list to GC next\n"); + D1(printk(KERN_DEBUG "Picking block from very_dirty_list to GC next\n")); nextlist = &c->very_dirty_list; } else if (n < 126 && !list_empty(&c->dirty_list)) { - jffs2_dbg(1, "Picking block from dirty_list to GC next\n"); + D1(printk(KERN_DEBUG "Picking block from dirty_list to GC next\n")); nextlist = &c->dirty_list; } else if (!list_empty(&c->clean_list)) { - jffs2_dbg(1, "Picking block from clean_list to GC next\n"); + D1(printk(KERN_DEBUG "Picking block from clean_list to GC next\n")); nextlist = &c->clean_list; } else if (!list_empty(&c->dirty_list)) { - jffs2_dbg(1, "Picking block from dirty_list to GC next (clean_list was empty)\n"); + D1(printk(KERN_DEBUG "Picking block from dirty_list to GC next (clean_list was empty)\n")); nextlist = &c->dirty_list; } else if (!list_empty(&c->very_dirty_list)) { - jffs2_dbg(1, "Picking block from very_dirty_list to GC next (clean_list and dirty_list were empty)\n"); + D1(printk(KERN_DEBUG "Picking block from very_dirty_list to GC next (clean_list and dirty_list were empty)\n")); nextlist = &c->very_dirty_list; } else if (!list_empty(&c->erasable_list)) { - jffs2_dbg(1, "Picking block from erasable_list to GC next (clean_list and {very_,}dirty_list were empty)\n"); + D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next (clean_list and {very_,}dirty_list were empty)\n")); nextlist = &c->erasable_list; } else if (!list_empty(&c->erasable_pending_wbuf_list)) { /* There are blocks are wating for the wbuf sync */ - jffs2_dbg(1, "Synching wbuf in order to reuse erasable_pending_wbuf_list blocks\n"); + D1(printk(KERN_DEBUG "Synching wbuf in order to reuse erasable_pending_wbuf_list blocks\n")); spin_unlock(&c->erase_completion_lock); jffs2_flush_wbuf_pad(c); spin_lock(&c->erase_completion_lock); goto again; } else { /* Eep. All were empty */ - jffs2_dbg(1, "No clean, dirty _or_ erasable blocks to GC from! Where are they all?\n"); + D1(printk(KERN_NOTICE "jffs2: No clean, dirty _or_ erasable blocks to GC from! Where are they all?\n")); return NULL; } @@ -99,15 +97,13 @@ static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c) c->gcblock = ret; ret->gc_node = ret->first_node; if (!ret->gc_node) { - pr_warn("Eep. ret->gc_node for block at 0x%08x is NULL\n", - ret->offset); + printk(KERN_WARNING "Eep. ret->gc_node for block at 0x%08x is NULL\n", ret->offset); BUG(); } /* Have we accidentally picked a clean block with wasted space ? */ if (ret->wasted_size) { - jffs2_dbg(1, "Converting wasted_size %08x to dirty_size\n", - ret->wasted_size); + D1(printk(KERN_DEBUG "Converting wasted_size %08x to dirty_size\n", ret->wasted_size)); ret->dirty_size += ret->wasted_size; c->wasted_size -= ret->wasted_size; c->dirty_size += ret->wasted_size; @@ -144,8 +140,8 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) /* checked_ino is protected by the alloc_sem */ if (c->checked_ino > c->highest_ino && xattr) { - pr_crit("Checked all inodes but still 0x%x bytes of unchecked space?\n", - c->unchecked_size); + printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n", + c->unchecked_size); jffs2_dbg_dump_block_lists_nolock(c); spin_unlock(&c->erase_completion_lock); mutex_unlock(&c->alloc_sem); @@ -167,8 +163,8 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) } if (!ic->pino_nlink) { - jffs2_dbg(1, "Skipping check of ino #%d with nlink/pino zero\n", - ic->ino); + D1(printk(KERN_DEBUG "Skipping check of ino #%d with nlink/pino zero\n", + ic->ino)); spin_unlock(&c->inocache_lock); jffs2_xattr_delete_inode(c, ic); continue; @@ -176,15 +172,13 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) switch(ic->state) { case INO_STATE_CHECKEDABSENT: case INO_STATE_PRESENT: - jffs2_dbg(1, "Skipping ino #%u already checked\n", - ic->ino); + D1(printk(KERN_DEBUG "Skipping ino #%u already checked\n", ic->ino)); spin_unlock(&c->inocache_lock); continue; case INO_STATE_GC: case INO_STATE_CHECKING: - pr_warn("Inode #%u is in state %d during CRC check phase!\n", - ic->ino, ic->state); + printk(KERN_WARNING "Inode #%u is in state %d during CRC check phase!\n", ic->ino, ic->state); spin_unlock(&c->inocache_lock); BUG(); @@ -192,8 +186,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) /* We need to wait for it to finish, lest we move on and trigger the BUG() above while we haven't yet finished checking all its nodes */ - jffs2_dbg(1, "Waiting for ino #%u to finish reading\n", - ic->ino); + D1(printk(KERN_DEBUG "Waiting for ino #%u to finish reading\n", ic->ino)); /* We need to come back again for the _same_ inode. We've made no progress in this case, but that should be OK */ c->checked_ino--; @@ -211,13 +204,11 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) ic->state = INO_STATE_CHECKING; spin_unlock(&c->inocache_lock); - jffs2_dbg(1, "%s(): triggering inode scan of ino#%u\n", - __func__, ic->ino); + D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() triggering inode scan of ino#%u\n", ic->ino)); ret = jffs2_do_crccheck_inode(c, ic); if (ret) - pr_warn("Returned error for crccheck of ino #%u. Expect badness...\n", - ic->ino); + printk(KERN_WARNING "Returned error for crccheck of ino #%u. Expect badness...\n", ic->ino); jffs2_set_inocache_state(c, ic, INO_STATE_CHECKEDABSENT); mutex_unlock(&c->alloc_sem); @@ -229,11 +220,11 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) !list_empty(&c->erase_pending_list)) { spin_unlock(&c->erase_completion_lock); mutex_unlock(&c->alloc_sem); - jffs2_dbg(1, "%s(): erasing pending blocks\n", __func__); + D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() erasing pending blocks\n")); if (jffs2_erase_pending_blocks(c, 1)) return 0; - jffs2_dbg(1, "No progress from erasing block; doing GC anyway\n"); + D1(printk(KERN_DEBUG "No progress from erasing blocks; doing GC anyway\n")); spin_lock(&c->erase_completion_lock); mutex_lock(&c->alloc_sem); } @@ -251,14 +242,13 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) mutex_unlock(&c->alloc_sem); return -EAGAIN; } - jffs2_dbg(1, "Couldn't find erase block to garbage collect!\n"); + D1(printk(KERN_NOTICE "jffs2: Couldn't find erase block to garbage collect!\n")); spin_unlock(&c->erase_completion_lock); mutex_unlock(&c->alloc_sem); return -EIO; } - jffs2_dbg(1, "GC from block %08x, used_size %08x, dirty_size %08x, free_size %08x\n", - jeb->offset, jeb->used_size, jeb->dirty_size, jeb->free_size); + D1(printk(KERN_DEBUG "GC from block %08x, used_size %08x, dirty_size %08x, free_size %08x\n", jeb->offset, jeb->used_size, jeb->dirty_size, jeb->free_size)); D1(if (c->nextblock) printk(KERN_DEBUG "Nextblock at %08x, used_size %08x, dirty_size %08x, wasted_size %08x, free_size %08x\n", c->nextblock->offset, c->nextblock->used_size, c->nextblock->dirty_size, c->nextblock->wasted_size, c->nextblock->free_size)); @@ -271,14 +261,12 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) gcblock_dirty = jeb->dirty_size; while(ref_obsolete(raw)) { - jffs2_dbg(1, "Node at 0x%08x is obsolete... skipping\n", - ref_offset(raw)); + D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", ref_offset(raw))); raw = ref_next(raw); if (unlikely(!raw)) { - pr_warn("eep. End of raw list while still supposedly nodes to GC\n"); - pr_warn("erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n", - jeb->offset, jeb->free_size, - jeb->dirty_size, jeb->used_size); + printk(KERN_WARNING "eep. End of raw list while still supposedly nodes to GC\n"); + printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n", + jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size); jeb->gc_node = raw; spin_unlock(&c->erase_completion_lock); mutex_unlock(&c->alloc_sem); @@ -287,8 +275,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) } jeb->gc_node = raw; - jffs2_dbg(1, "Going to garbage collect node at 0x%08x\n", - ref_offset(raw)); + D1(printk(KERN_DEBUG "Going to garbage collect node at 0x%08x\n", ref_offset(raw))); if (!raw->next_in_ino) { /* Inode-less node. Clean marker, snapshot or something like that */ @@ -329,9 +316,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) spin_unlock(&c->erase_completion_lock); - jffs2_dbg(1, "%s(): collecting from block @0x%08x. Node @0x%08x(%d), ino #%u\n", - __func__, jeb->offset, ref_offset(raw), ref_flags(raw), - ic->ino); + D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass collecting from block @0x%08x. Node @0x%08x(%d), ino #%u\n", jeb->offset, ref_offset(raw), ref_flags(raw), ic->ino)); /* Three possibilities: 1. Inode is already in-core. We must iget it and do proper @@ -351,8 +336,8 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) if (ref_flags(raw) == REF_PRISTINE) ic->state = INO_STATE_GC; else { - jffs2_dbg(1, "Ino #%u is absent but node not REF_PRISTINE. Reading.\n", - ic->ino); + D1(printk(KERN_DEBUG "Ino #%u is absent but node not REF_PRISTINE. Reading.\n", + ic->ino)); } break; @@ -368,8 +353,8 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) we're holding the alloc_sem, no other garbage collection can happen. */ - pr_crit("Inode #%u already in state %d in jffs2_garbage_collect_pass()!\n", - ic->ino, ic->state); + printk(KERN_CRIT "Inode #%u already in state %d in jffs2_garbage_collect_pass()!\n", + ic->ino, ic->state); mutex_unlock(&c->alloc_sem); spin_unlock(&c->inocache_lock); BUG(); @@ -382,8 +367,8 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) drop the alloc_sem before sleeping. */ mutex_unlock(&c->alloc_sem); - jffs2_dbg(1, "%s(): waiting for ino #%u in state %d\n", - __func__, ic->ino, ic->state); + D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() waiting for ino #%u in state %d\n", + ic->ino, ic->state)); sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); /* And because we dropped the alloc_sem we must start again from the beginning. Ponder chance of livelock here -- we're returning success @@ -448,8 +433,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) test_gcnode: if (jeb->dirty_size == gcblock_dirty && !ref_obsolete(jeb->gc_node)) { /* Eep. This really should never happen. GC is broken */ - pr_err("Error garbage collecting node at %08x!\n", - ref_offset(jeb->gc_node)); + printk(KERN_ERR "Error garbage collecting node at %08x!\n", ref_offset(jeb->gc_node)); ret = -ENOSPC; } release_sem: @@ -461,8 +445,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) eraseit: if (c->gcblock && !c->gcblock->used_size) { - jffs2_dbg(1, "Block at 0x%08x completely obsoleted by GC. Moving to erase_pending_list\n", - c->gcblock->offset); + D1(printk(KERN_DEBUG "Block at 0x%08x completely obsoleted by GC. Moving to erase_pending_list\n", c->gcblock->offset)); /* We're GC'ing an empty block? */ list_add_tail(&c->gcblock->list, &c->erase_pending_list); c->gcblock = NULL; @@ -492,12 +475,12 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era if (c->gcblock != jeb) { spin_unlock(&c->erase_completion_lock); - jffs2_dbg(1, "GC block is no longer gcblock. Restart\n"); + D1(printk(KERN_DEBUG "GC block is no longer gcblock. Restart\n")); goto upnout; } if (ref_obsolete(raw)) { spin_unlock(&c->erase_completion_lock); - jffs2_dbg(1, "node to be GC'd was obsoleted in the meantime.\n"); + D1(printk(KERN_DEBUG "node to be GC'd was obsoleted in the meantime.\n")); /* They'll call again */ goto upnout; } @@ -553,10 +536,10 @@ static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_era } else if (fd) { ret = jffs2_garbage_collect_deletion_dirent(c, jeb, f, fd); } else { - pr_warn("Raw node at 0x%08x wasn't in node lists for ino #%u\n", - ref_offset(raw), f->inocache->ino); + printk(KERN_WARNING "Raw node at 0x%08x wasn't in node lists for ino #%u\n", + ref_offset(raw), f->inocache->ino); if (ref_obsolete(raw)) { - pr_warn("But it's obsolete so we don't mind too much\n"); + printk(KERN_WARNING "But it's obsolete so we don't mind too much\n"); } else { jffs2_dbg_dump_node(c, ref_offset(raw)); BUG(); @@ -579,8 +562,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, uint32_t crc, rawlen; int retried = 0; - jffs2_dbg(1, "Going to GC REF_PRISTINE node at 0x%08x\n", - ref_offset(raw)); + D1(printk(KERN_DEBUG "Going to GC REF_PRISTINE node at 0x%08x\n", ref_offset(raw))); alloclen = rawlen = ref_totlen(c, c->gcblock, raw); @@ -613,8 +595,8 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, crc = crc32(0, node, sizeof(struct jffs2_unknown_node)-4); if (je32_to_cpu(node->u.hdr_crc) != crc) { - pr_warn("Header CRC failed on REF_PRISTINE node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", - ref_offset(raw), je32_to_cpu(node->u.hdr_crc), crc); + printk(KERN_WARNING "Header CRC failed on REF_PRISTINE node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", + ref_offset(raw), je32_to_cpu(node->u.hdr_crc), crc); goto bail; } @@ -622,18 +604,16 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, case JFFS2_NODETYPE_INODE: crc = crc32(0, node, sizeof(node->i)-8); if (je32_to_cpu(node->i.node_crc) != crc) { - pr_warn("Node CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", - ref_offset(raw), je32_to_cpu(node->i.node_crc), - crc); + printk(KERN_WARNING "Node CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", + ref_offset(raw), je32_to_cpu(node->i.node_crc), crc); goto bail; } if (je32_to_cpu(node->i.dsize)) { crc = crc32(0, node->i.data, je32_to_cpu(node->i.csize)); if (je32_to_cpu(node->i.data_crc) != crc) { - pr_warn("Data CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", - ref_offset(raw), - je32_to_cpu(node->i.data_crc), crc); + printk(KERN_WARNING "Data CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", + ref_offset(raw), je32_to_cpu(node->i.data_crc), crc); goto bail; } } @@ -642,24 +622,21 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, case JFFS2_NODETYPE_DIRENT: crc = crc32(0, node, sizeof(node->d)-8); if (je32_to_cpu(node->d.node_crc) != crc) { - pr_warn("Node CRC failed on REF_PRISTINE dirent node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", - ref_offset(raw), - je32_to_cpu(node->d.node_crc), crc); + printk(KERN_WARNING "Node CRC failed on REF_PRISTINE dirent node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", + ref_offset(raw), je32_to_cpu(node->d.node_crc), crc); goto bail; } if (strnlen(node->d.name, node->d.nsize) != node->d.nsize) { - pr_warn("Name in dirent node at 0x%08x contains zeroes\n", - ref_offset(raw)); + printk(KERN_WARNING "Name in dirent node at 0x%08x contains zeroes\n", ref_offset(raw)); goto bail; } if (node->d.nsize) { crc = crc32(0, node->d.name, node->d.nsize); if (je32_to_cpu(node->d.name_crc) != crc) { - pr_warn("Name CRC failed on REF_PRISTINE dirent node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", - ref_offset(raw), - je32_to_cpu(node->d.name_crc), crc); + printk(KERN_WARNING "Name CRC failed on REF_PRISTINE dirent node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", + ref_offset(raw), je32_to_cpu(node->d.name_crc), crc); goto bail; } } @@ -667,8 +644,8 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, default: /* If it's inode-less, we don't _know_ what it is. Just copy it intact */ if (ic) { - pr_warn("Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n", - ref_offset(raw), je16_to_cpu(node->u.nodetype)); + printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n", + ref_offset(raw), je16_to_cpu(node->u.nodetype)); goto bail; } } @@ -680,13 +657,12 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, ret = jffs2_flash_write(c, phys_ofs, rawlen, &retlen, (char *)node); if (ret || (retlen != rawlen)) { - pr_notice("Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n", - rawlen, phys_ofs, ret, retlen); + printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n", + rawlen, phys_ofs, ret, retlen); if (retlen) { jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, rawlen, NULL); } else { - pr_notice("Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", - phys_ofs); + printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", phys_ofs); } if (!retried) { /* Try to reallocate space and retry */ @@ -695,7 +671,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, retried = 1; - jffs2_dbg(1, "Retrying failed write of REF_PRISTINE node.\n"); + D1(printk(KERN_DEBUG "Retrying failed write of REF_PRISTINE node.\n")); jffs2_dbg_acct_sanity_check(c,jeb); jffs2_dbg_acct_paranoia_check(c, jeb); @@ -705,16 +681,14 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, it is only an upper estimation */ if (!ret) { - jffs2_dbg(1, "Allocated space at 0x%08x to retry failed write.\n", - phys_ofs); + D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", phys_ofs)); jffs2_dbg_acct_sanity_check(c,jeb); jffs2_dbg_acct_paranoia_check(c, jeb); goto retry; } - jffs2_dbg(1, "Failed to allocate space to retry failed write: %d!\n", - ret); + D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); } if (!ret) @@ -724,8 +698,7 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, rawlen, ic); jffs2_mark_node_obsolete(c, raw); - jffs2_dbg(1, "WHEEE! GC REF_PRISTINE node at 0x%08x succeeded\n", - ref_offset(raw)); + D1(printk(KERN_DEBUG "WHEEE! GC REF_PRISTINE node at 0x%08x succeeded\n", ref_offset(raw))); out_node: kfree(node); @@ -752,32 +725,29 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_ /* For these, we don't actually need to read the old node */ mdatalen = jffs2_encode_dev(&dev, JFFS2_F_I_RDEV(f)); mdata = (char *)&dev; - jffs2_dbg(1, "%s(): Writing %d bytes of kdev_t\n", - __func__, mdatalen); + D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bytes of kdev_t\n", mdatalen)); } else if (S_ISLNK(JFFS2_F_I_MODE(f))) { mdatalen = fn->size; mdata = kmalloc(fn->size, GFP_KERNEL); if (!mdata) { - pr_warn("kmalloc of mdata failed in jffs2_garbage_collect_metadata()\n"); + printk(KERN_WARNING "kmalloc of mdata failed in jffs2_garbage_collect_metadata()\n"); return -ENOMEM; } ret = jffs2_read_dnode(c, f, fn, mdata, 0, mdatalen); if (ret) { - pr_warn("read of old metadata failed in jffs2_garbage_collect_metadata(): %d\n", - ret); + printk(KERN_WARNING "read of old metadata failed in jffs2_garbage_collect_metadata(): %d\n", ret); kfree(mdata); return ret; } - jffs2_dbg(1, "%s(): Writing %d bites of symlink target\n", - __func__, mdatalen); + D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bites of symlink target\n", mdatalen)); } ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &alloclen, JFFS2_SUMMARY_INODE_SIZE); if (ret) { - pr_warn("jffs2_reserve_space_gc of %zd bytes for garbage_collect_metadata failed: %d\n", - sizeof(ri) + mdatalen, ret); + printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_metadata failed: %d\n", + sizeof(ri)+ mdatalen, ret); goto out; } @@ -814,7 +784,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_ new_fn = jffs2_write_dnode(c, f, &ri, mdata, mdatalen, ALLOC_GC); if (IS_ERR(new_fn)) { - pr_warn("Error writing new dnode: %ld\n", PTR_ERR(new_fn)); + printk(KERN_WARNING "Error writing new dnode: %ld\n", PTR_ERR(new_fn)); ret = PTR_ERR(new_fn); goto out; } @@ -857,15 +827,14 @@ static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_er ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &alloclen, JFFS2_SUMMARY_DIRENT_SIZE(rd.nsize)); if (ret) { - pr_warn("jffs2_reserve_space_gc of %zd bytes for garbage_collect_dirent failed: %d\n", - sizeof(rd)+rd.nsize, ret); + printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dirent failed: %d\n", + sizeof(rd)+rd.nsize, ret); return ret; } new_fd = jffs2_write_dirent(c, f, &rd, fd->name, rd.nsize, ALLOC_GC); if (IS_ERR(new_fd)) { - pr_warn("jffs2_write_dirent in garbage_collect_dirent failed: %ld\n", - PTR_ERR(new_fd)); + printk(KERN_WARNING "jffs2_write_dirent in garbage_collect_dirent failed: %ld\n", PTR_ERR(new_fd)); return PTR_ERR(new_fd); } jffs2_add_fd_to_list(c, new_fd, &f->dents); @@ -918,22 +887,19 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct if (SECTOR_ADDR(raw->flash_offset) == SECTOR_ADDR(fd->raw->flash_offset)) continue; - jffs2_dbg(1, "Check potential deletion dirent at %08x\n", - ref_offset(raw)); + D1(printk(KERN_DEBUG "Check potential deletion dirent at %08x\n", ref_offset(raw))); /* This is an obsolete node belonging to the same directory, and it's of the right length. We need to take a closer look...*/ ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (char *)rd); if (ret) { - pr_warn("%s(): Read error (%d) reading obsolete node at %08x\n", - __func__, ret, ref_offset(raw)); + printk(KERN_WARNING "jffs2_g_c_deletion_dirent(): Read error (%d) reading obsolete node at %08x\n", ret, ref_offset(raw)); /* If we can't read it, we don't need to continue to obsolete it. Continue */ continue; } if (retlen != rawlen) { - pr_warn("%s(): Short read (%zd not %u) reading header from obsolete node at %08x\n", - __func__, retlen, rawlen, - ref_offset(raw)); + printk(KERN_WARNING "jffs2_g_c_deletion_dirent(): Short read (%zd not %u) reading header from obsolete node at %08x\n", + retlen, rawlen, ref_offset(raw)); continue; } @@ -957,9 +923,8 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct a new deletion dirent to replace it */ mutex_unlock(&c->erase_free_sem); - jffs2_dbg(1, "Deletion dirent at %08x still obsoletes real dirent \"%s\" at %08x for ino #%u\n", - ref_offset(fd->raw), fd->name, - ref_offset(raw), je32_to_cpu(rd->ino)); + D1(printk(KERN_DEBUG "Deletion dirent at %08x still obsoletes real dirent \"%s\" at %08x for ino #%u\n", + ref_offset(fd->raw), fd->name, ref_offset(raw), je32_to_cpu(rd->ino))); kfree(rd); return jffs2_garbage_collect_dirent(c, jeb, f, fd); @@ -982,8 +947,7 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct fdp = &(*fdp)->next; } if (!found) { - pr_warn("Deletion dirent \"%s\" not found in list for ino #%u\n", - fd->name, f->inocache->ino); + printk(KERN_WARNING "Deletion dirent \"%s\" not found in list for ino #%u\n", fd->name, f->inocache->ino); } jffs2_mark_node_obsolete(c, fd->raw); jffs2_free_full_dirent(fd); @@ -1000,8 +964,8 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras uint32_t alloclen, ilen; int ret; - jffs2_dbg(1, "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n", - f->inocache->ino, start, end); + D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n", + f->inocache->ino, start, end)); memset(&ri, 0, sizeof(ri)); @@ -1012,37 +976,35 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras write it out again with the _same_ version as before */ ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(ri), &readlen, (char *)&ri); if (readlen != sizeof(ri) || ret) { - pr_warn("Node read failed in jffs2_garbage_collect_hole. Ret %d, retlen %zd. Data will be lost by writing new hole node\n", - ret, readlen); + printk(KERN_WARNING "Node read failed in jffs2_garbage_collect_hole. Ret %d, retlen %zd. Data will be lost by writing new hole node\n", ret, readlen); goto fill; } if (je16_to_cpu(ri.nodetype) != JFFS2_NODETYPE_INODE) { - pr_warn("%s(): Node at 0x%08x had node type 0x%04x instead of JFFS2_NODETYPE_INODE(0x%04x)\n", - __func__, ref_offset(fn->raw), - je16_to_cpu(ri.nodetype), JFFS2_NODETYPE_INODE); + printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had node type 0x%04x instead of JFFS2_NODETYPE_INODE(0x%04x)\n", + ref_offset(fn->raw), + je16_to_cpu(ri.nodetype), JFFS2_NODETYPE_INODE); return -EIO; } if (je32_to_cpu(ri.totlen) != sizeof(ri)) { - pr_warn("%s(): Node at 0x%08x had totlen 0x%x instead of expected 0x%zx\n", - __func__, ref_offset(fn->raw), - je32_to_cpu(ri.totlen), sizeof(ri)); + printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had totlen 0x%x instead of expected 0x%zx\n", + ref_offset(fn->raw), + je32_to_cpu(ri.totlen), sizeof(ri)); return -EIO; } crc = crc32(0, &ri, sizeof(ri)-8); if (crc != je32_to_cpu(ri.node_crc)) { - pr_warn("%s: Node at 0x%08x had CRC 0x%08x which doesn't match calculated CRC 0x%08x\n", - __func__, ref_offset(fn->raw), - je32_to_cpu(ri.node_crc), crc); + printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had CRC 0x%08x which doesn't match calculated CRC 0x%08x\n", + ref_offset(fn->raw), + je32_to_cpu(ri.node_crc), crc); /* FIXME: We could possibly deal with this by writing new holes for each frag */ - pr_warn("Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n", - start, end, f->inocache->ino); + printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n", + start, end, f->inocache->ino); goto fill; } if (ri.compr != JFFS2_COMPR_ZERO) { - pr_warn("%s(): Node 0x%08x wasn't a hole node!\n", - __func__, ref_offset(fn->raw)); - pr_warn("Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n", - start, end, f->inocache->ino); + printk(KERN_WARNING "jffs2_garbage_collect_hole: Node 0x%08x wasn't a hole node!\n", ref_offset(fn->raw)); + printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n", + start, end, f->inocache->ino); goto fill; } } else { @@ -1081,14 +1043,14 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras ret = jffs2_reserve_space_gc(c, sizeof(ri), &alloclen, JFFS2_SUMMARY_INODE_SIZE); if (ret) { - pr_warn("jffs2_reserve_space_gc of %zd bytes for garbage_collect_hole failed: %d\n", - sizeof(ri), ret); + printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_hole failed: %d\n", + sizeof(ri), ret); return ret; } new_fn = jffs2_write_dnode(c, f, &ri, NULL, 0, ALLOC_GC); if (IS_ERR(new_fn)) { - pr_warn("Error writing new hole node: %ld\n", PTR_ERR(new_fn)); + printk(KERN_WARNING "Error writing new hole node: %ld\n", PTR_ERR(new_fn)); return PTR_ERR(new_fn); } if (je32_to_cpu(ri.version) == f->highest_version) { @@ -1108,9 +1070,9 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras * above.) */ D1(if(unlikely(fn->frags <= 1)) { - pr_warn("%s(): Replacing fn with %d frag(s) but new ver %d != highest_version %d of ino #%d\n", - __func__, fn->frags, je32_to_cpu(ri.version), - f->highest_version, je32_to_cpu(ri.ino)); + printk(KERN_WARNING "jffs2_garbage_collect_hole: Replacing fn with %d frag(s) but new ver %d != highest_version %d of ino #%d\n", + fn->frags, je32_to_cpu(ri.version), f->highest_version, + je32_to_cpu(ri.ino)); }); /* This is a partially-overlapped hole node. Mark it REF_NORMAL not REF_PRISTINE */ @@ -1127,11 +1089,11 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras } } if (fn->frags) { - pr_warn("%s(): Old node still has frags!\n", __func__); + printk(KERN_WARNING "jffs2_garbage_collect_hole: Old node still has frags!\n"); BUG(); } if (!new_fn->frags) { - pr_warn("%s(): New node has no frags!\n", __func__); + printk(KERN_WARNING "jffs2_garbage_collect_hole: New node has no frags!\n"); BUG(); } @@ -1155,8 +1117,8 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era memset(&ri, 0, sizeof(ri)); - jffs2_dbg(1, "Writing replacement dnode for ino #%u from offset 0x%x to 0x%x\n", - f->inocache->ino, start, end); + D1(printk(KERN_DEBUG "Writing replacement dnode for ino #%u from offset 0x%x to 0x%x\n", + f->inocache->ino, start, end)); orig_end = end; orig_start = start; @@ -1187,15 +1149,15 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era /* If the previous frag doesn't even reach the beginning, there's excessive fragmentation. Just merge. */ if (frag->ofs > min) { - jffs2_dbg(1, "Expanding down to cover partial frag (0x%x-0x%x)\n", - frag->ofs, frag->ofs+frag->size); + D1(printk(KERN_DEBUG "Expanding down to cover partial frag (0x%x-0x%x)\n", + frag->ofs, frag->ofs+frag->size)); start = frag->ofs; continue; } /* OK. This frag holds the first byte of the page. */ if (!frag->node || !frag->node->raw) { - jffs2_dbg(1, "First frag in page is hole (0x%x-0x%x). Not expanding down.\n", - frag->ofs, frag->ofs+frag->size); + D1(printk(KERN_DEBUG "First frag in page is hole (0x%x-0x%x). Not expanding down.\n", + frag->ofs, frag->ofs+frag->size)); break; } else { @@ -1209,25 +1171,19 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era jeb = &c->blocks[raw->flash_offset / c->sector_size]; if (jeb == c->gcblock) { - jffs2_dbg(1, "Expanding down to cover frag (0x%x-0x%x) in gcblock at %08x\n", - frag->ofs, - frag->ofs + frag->size, - ref_offset(raw)); + D1(printk(KERN_DEBUG "Expanding down to cover frag (0x%x-0x%x) in gcblock at %08x\n", + frag->ofs, frag->ofs+frag->size, ref_offset(raw))); start = frag->ofs; break; } if (!ISDIRTY(jeb->dirty_size + jeb->wasted_size)) { - jffs2_dbg(1, "Not expanding down to cover frag (0x%x-0x%x) in clean block %08x\n", - frag->ofs, - frag->ofs + frag->size, - jeb->offset); + D1(printk(KERN_DEBUG "Not expanding down to cover frag (0x%x-0x%x) in clean block %08x\n", + frag->ofs, frag->ofs+frag->size, jeb->offset)); break; } - jffs2_dbg(1, "Expanding down to cover frag (0x%x-0x%x) in dirty block %08x\n", - frag->ofs, - frag->ofs + frag->size, - jeb->offset); + D1(printk(KERN_DEBUG "Expanding down to cover frag (0x%x-0x%x) in dirty block %08x\n", + frag->ofs, frag->ofs+frag->size, jeb->offset)); start = frag->ofs; break; } @@ -1243,15 +1199,15 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era /* If the previous frag doesn't even reach the beginning, there's lots of fragmentation. Just merge. */ if (frag->ofs+frag->size < max) { - jffs2_dbg(1, "Expanding up to cover partial frag (0x%x-0x%x)\n", - frag->ofs, frag->ofs+frag->size); + D1(printk(KERN_DEBUG "Expanding up to cover partial frag (0x%x-0x%x)\n", + frag->ofs, frag->ofs+frag->size)); end = frag->ofs + frag->size; continue; } if (!frag->node || !frag->node->raw) { - jffs2_dbg(1, "Last frag in page is hole (0x%x-0x%x). Not expanding up.\n", - frag->ofs, frag->ofs+frag->size); + D1(printk(KERN_DEBUG "Last frag in page is hole (0x%x-0x%x). Not expanding up.\n", + frag->ofs, frag->ofs+frag->size)); break; } else { @@ -1265,31 +1221,25 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era jeb = &c->blocks[raw->flash_offset / c->sector_size]; if (jeb == c->gcblock) { - jffs2_dbg(1, "Expanding up to cover frag (0x%x-0x%x) in gcblock at %08x\n", - frag->ofs, - frag->ofs + frag->size, - ref_offset(raw)); + D1(printk(KERN_DEBUG "Expanding up to cover frag (0x%x-0x%x) in gcblock at %08x\n", + frag->ofs, frag->ofs+frag->size, ref_offset(raw))); end = frag->ofs + frag->size; break; } if (!ISDIRTY(jeb->dirty_size + jeb->wasted_size)) { - jffs2_dbg(1, "Not expanding up to cover frag (0x%x-0x%x) in clean block %08x\n", - frag->ofs, - frag->ofs + frag->size, - jeb->offset); + D1(printk(KERN_DEBUG "Not expanding up to cover frag (0x%x-0x%x) in clean block %08x\n", + frag->ofs, frag->ofs+frag->size, jeb->offset)); break; } - jffs2_dbg(1, "Expanding up to cover frag (0x%x-0x%x) in dirty block %08x\n", - frag->ofs, - frag->ofs + frag->size, - jeb->offset); + D1(printk(KERN_DEBUG "Expanding up to cover frag (0x%x-0x%x) in dirty block %08x\n", + frag->ofs, frag->ofs+frag->size, jeb->offset)); end = frag->ofs + frag->size; break; } } - jffs2_dbg(1, "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n", - orig_start, orig_end, start, end); + D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n", + orig_start, orig_end, start, end)); D1(BUG_ON(end > frag_last(&f->fragtree)->ofs + frag_last(&f->fragtree)->size)); BUG_ON(end < orig_end); @@ -1306,8 +1256,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era pg_ptr = jffs2_gc_fetch_page(c, f, start, &pg); if (IS_ERR(pg_ptr)) { - pr_warn("read_cache_page() returned error: %ld\n", - PTR_ERR(pg_ptr)); + printk(KERN_WARNING "read_cache_page() returned error: %ld\n", PTR_ERR(pg_ptr)); return PTR_ERR(pg_ptr); } @@ -1321,8 +1270,8 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era &alloclen, JFFS2_SUMMARY_INODE_SIZE); if (ret) { - pr_warn("jffs2_reserve_space_gc of %zd bytes for garbage_collect_dnode failed: %d\n", - sizeof(ri) + JFFS2_MIN_DATA_LEN, ret); + printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dnode failed: %d\n", + sizeof(ri)+ JFFS2_MIN_DATA_LEN, ret); break; } cdatalen = min_t(uint32_t, alloclen - sizeof(ri), end - offset); @@ -1359,8 +1308,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era jffs2_free_comprbuf(comprbuf, writebuf); if (IS_ERR(new_fn)) { - pr_warn("Error writing new dnode: %ld\n", - PTR_ERR(new_fn)); + printk(KERN_WARNING "Error writing new dnode: %ld\n", PTR_ERR(new_fn)); ret = PTR_ERR(new_fn); break; } diff --git a/trunk/fs/jffs2/malloc.c b/trunk/fs/jffs2/malloc.c index 4f47aa24b556..c082868910f2 100644 --- a/trunk/fs/jffs2/malloc.c +++ b/trunk/fs/jffs2/malloc.c @@ -9,8 +9,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include diff --git a/trunk/fs/jffs2/nodelist.c b/trunk/fs/jffs2/nodelist.c index 975a1f562c10..5e03233c2363 100644 --- a/trunk/fs/jffs2/nodelist.c +++ b/trunk/fs/jffs2/nodelist.c @@ -9,8 +9,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -689,8 +687,8 @@ int jffs2_scan_dirty_space(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb if (!size) return 0; if (unlikely(size > jeb->free_size)) { - pr_crit("Dirty space 0x%x larger then free_size 0x%x (wasted 0x%x)\n", - size, jeb->free_size, jeb->wasted_size); + printk(KERN_CRIT "Dirty space 0x%x larger then free_size 0x%x (wasted 0x%x)\n", + size, jeb->free_size, jeb->wasted_size); BUG(); } /* REF_EMPTY_NODE is !obsolete, so that works OK */ @@ -728,10 +726,8 @@ static inline uint32_t __ref_totlen(struct jffs2_sb_info *c, /* Last node in block. Use free_space */ if (unlikely(ref != jeb->last_node)) { - pr_crit("ref %p @0x%08x is not jeb->last_node (%p @0x%08x)\n", - ref, ref_offset(ref), jeb->last_node, - jeb->last_node ? - ref_offset(jeb->last_node) : 0); + printk(KERN_CRIT "ref %p @0x%08x is not jeb->last_node (%p @0x%08x)\n", + ref, ref_offset(ref), jeb->last_node, jeb->last_node?ref_offset(jeb->last_node):0); BUG(); } ref_end = jeb->offset + c->sector_size - jeb->free_size; @@ -751,20 +747,16 @@ uint32_t __jffs2_ref_totlen(struct jffs2_sb_info *c, struct jffs2_eraseblock *je if (!jeb) jeb = &c->blocks[ref->flash_offset / c->sector_size]; - pr_crit("Totlen for ref at %p (0x%08x-0x%08x) miscalculated as 0x%x instead of %x\n", - ref, ref_offset(ref), ref_offset(ref) + ref->__totlen, - ret, ref->__totlen); + printk(KERN_CRIT "Totlen for ref at %p (0x%08x-0x%08x) miscalculated as 0x%x instead of %x\n", + ref, ref_offset(ref), ref_offset(ref)+ref->__totlen, + ret, ref->__totlen); if (ref_next(ref)) { - pr_crit("next %p (0x%08x-0x%08x)\n", - ref_next(ref), ref_offset(ref_next(ref)), - ref_offset(ref_next(ref)) + ref->__totlen); + printk(KERN_CRIT "next %p (0x%08x-0x%08x)\n", ref_next(ref), ref_offset(ref_next(ref)), + ref_offset(ref_next(ref))+ref->__totlen); } else - pr_crit("No next ref. jeb->last_node is %p\n", - jeb->last_node); + printk(KERN_CRIT "No next ref. jeb->last_node is %p\n", jeb->last_node); - pr_crit("jeb->wasted_size %x, dirty_size %x, used_size %x, free_size %x\n", - jeb->wasted_size, jeb->dirty_size, jeb->used_size, - jeb->free_size); + printk(KERN_CRIT "jeb->wasted_size %x, dirty_size %x, used_size %x, free_size %x\n", jeb->wasted_size, jeb->dirty_size, jeb->used_size, jeb->free_size); #if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS) __jffs2_dbg_dump_node_refs_nolock(c, jeb); diff --git a/trunk/fs/jffs2/nodemgmt.c b/trunk/fs/jffs2/nodemgmt.c index 6784d1e7a7eb..694aa5b03505 100644 --- a/trunk/fs/jffs2/nodemgmt.c +++ b/trunk/fs/jffs2/nodemgmt.c @@ -9,8 +9,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -48,10 +46,10 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, /* align it */ minsize = PAD(minsize); - jffs2_dbg(1, "%s(): Requested 0x%x bytes\n", __func__, minsize); + D1(printk(KERN_DEBUG "jffs2_reserve_space(): Requested 0x%x bytes\n", minsize)); mutex_lock(&c->alloc_sem); - jffs2_dbg(1, "%s(): alloc sem got\n", __func__); + D1(printk(KERN_DEBUG "jffs2_reserve_space(): alloc sem got\n")); spin_lock(&c->erase_completion_lock); @@ -75,13 +73,11 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size + c->unchecked_size; if (dirty < c->nospc_dirty_size) { if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) { - jffs2_dbg(1, "%s(): Low on dirty space to GC, but it's a deletion. Allowing...\n", - __func__); + D1(printk(KERN_NOTICE "jffs2_reserve_space(): Low on dirty space to GC, but it's a deletion. Allowing...\n")); break; } - jffs2_dbg(1, "dirty size 0x%08x + unchecked_size 0x%08x < nospc_dirty_size 0x%08x, returning -ENOSPC\n", - dirty, c->unchecked_size, - c->sector_size); + D1(printk(KERN_DEBUG "dirty size 0x%08x + unchecked_size 0x%08x < nospc_dirty_size 0x%08x, returning -ENOSPC\n", + dirty, c->unchecked_size, c->sector_size)); spin_unlock(&c->erase_completion_lock); mutex_unlock(&c->alloc_sem); @@ -100,13 +96,12 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, avail = c->free_size + c->dirty_size + c->erasing_size + c->unchecked_size; if ( (avail / c->sector_size) <= blocksneeded) { if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) { - jffs2_dbg(1, "%s(): Low on possibly available space, but it's a deletion. Allowing...\n", - __func__); + D1(printk(KERN_NOTICE "jffs2_reserve_space(): Low on possibly available space, but it's a deletion. Allowing...\n")); break; } - jffs2_dbg(1, "max. available size 0x%08x < blocksneeded * sector_size 0x%08x, returning -ENOSPC\n", - avail, blocksneeded * c->sector_size); + D1(printk(KERN_DEBUG "max. available size 0x%08x < blocksneeded * sector_size 0x%08x, returning -ENOSPC\n", + avail, blocksneeded * c->sector_size)); spin_unlock(&c->erase_completion_lock); mutex_unlock(&c->alloc_sem); return -ENOSPC; @@ -114,14 +109,9 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, mutex_unlock(&c->alloc_sem); - jffs2_dbg(1, "Triggering GC pass. nr_free_blocks %d, nr_erasing_blocks %d, free_size 0x%08x, dirty_size 0x%08x, wasted_size 0x%08x, used_size 0x%08x, erasing_size 0x%08x, bad_size 0x%08x (total 0x%08x of 0x%08x)\n", - c->nr_free_blocks, c->nr_erasing_blocks, - c->free_size, c->dirty_size, c->wasted_size, - c->used_size, c->erasing_size, c->bad_size, - c->free_size + c->dirty_size + - c->wasted_size + c->used_size + - c->erasing_size + c->bad_size, - c->flash_size); + D1(printk(KERN_DEBUG "Triggering GC pass. nr_free_blocks %d, nr_erasing_blocks %d, free_size 0x%08x, dirty_size 0x%08x, wasted_size 0x%08x, used_size 0x%08x, erasing_size 0x%08x, bad_size 0x%08x (total 0x%08x of 0x%08x)\n", + c->nr_free_blocks, c->nr_erasing_blocks, c->free_size, c->dirty_size, c->wasted_size, c->used_size, c->erasing_size, c->bad_size, + c->free_size + c->dirty_size + c->wasted_size + c->used_size + c->erasing_size + c->bad_size, c->flash_size)); spin_unlock(&c->erase_completion_lock); ret = jffs2_garbage_collect_pass(c); @@ -134,8 +124,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, DECLARE_WAITQUEUE(wait, current); set_current_state(TASK_UNINTERRUPTIBLE); add_wait_queue(&c->erase_wait, &wait); - jffs2_dbg(1, "%s waiting for erase to complete\n", - __func__); + D1(printk(KERN_DEBUG "%s waiting for erase to complete\n", __func__)); spin_unlock(&c->erase_completion_lock); schedule(); @@ -155,7 +144,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, ret = jffs2_do_reserve_space(c, minsize, len, sumsize); if (ret) { - jffs2_dbg(1, "%s(): ret is %d\n", __func__, ret); + D1(printk(KERN_DEBUG "jffs2_reserve_space: ret is %d\n", ret)); } } spin_unlock(&c->erase_completion_lock); @@ -172,14 +161,13 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, int ret = -EAGAIN; minsize = PAD(minsize); - jffs2_dbg(1, "%s(): Requested 0x%x bytes\n", __func__, minsize); + D1(printk(KERN_DEBUG "jffs2_reserve_space_gc(): Requested 0x%x bytes\n", minsize)); spin_lock(&c->erase_completion_lock); while(ret == -EAGAIN) { ret = jffs2_do_reserve_space(c, minsize, len, sumsize); if (ret) { - jffs2_dbg(1, "%s(): looping, ret is %d\n", - __func__, ret); + D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret)); } } spin_unlock(&c->erase_completion_lock); @@ -196,8 +184,8 @@ static void jffs2_close_nextblock(struct jffs2_sb_info *c, struct jffs2_eraseblo { if (c->nextblock == NULL) { - jffs2_dbg(1, "%s(): Erase block at 0x%08x has already been placed in a list\n", - __func__, jeb->offset); + D1(printk(KERN_DEBUG "jffs2_close_nextblock: Erase block at 0x%08x has already been placed in a list\n", + jeb->offset)); return; } /* Check, if we have a dirty block now, or if it was dirty already */ @@ -207,20 +195,17 @@ static void jffs2_close_nextblock(struct jffs2_sb_info *c, struct jffs2_eraseblo jeb->dirty_size += jeb->wasted_size; jeb->wasted_size = 0; if (VERYDIRTY(c, jeb->dirty_size)) { - jffs2_dbg(1, "Adding full erase block at 0x%08x to very_dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", - jeb->offset, jeb->free_size, jeb->dirty_size, - jeb->used_size); + D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to very_dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", + jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); list_add_tail(&jeb->list, &c->very_dirty_list); } else { - jffs2_dbg(1, "Adding full erase block at 0x%08x to dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", - jeb->offset, jeb->free_size, jeb->dirty_size, - jeb->used_size); + D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", + jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); list_add_tail(&jeb->list, &c->dirty_list); } } else { - jffs2_dbg(1, "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", - jeb->offset, jeb->free_size, jeb->dirty_size, - jeb->used_size); + D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", + jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); list_add_tail(&jeb->list, &c->clean_list); } c->nextblock = NULL; @@ -245,14 +230,13 @@ static int jffs2_find_nextblock(struct jffs2_sb_info *c) list_move_tail(&ejeb->list, &c->erase_pending_list); c->nr_erasing_blocks++; jffs2_garbage_collect_trigger(c); - jffs2_dbg(1, "%s(): Triggering erase of erasable block at 0x%08x\n", - __func__, ejeb->offset); + D1(printk(KERN_DEBUG "jffs2_find_nextblock: Triggering erase of erasable block at 0x%08x\n", + ejeb->offset)); } if (!c->nr_erasing_blocks && !list_empty(&c->erasable_pending_wbuf_list)) { - jffs2_dbg(1, "%s(): Flushing write buffer\n", - __func__); + D1(printk(KERN_DEBUG "jffs2_find_nextblock: Flushing write buffer\n")); /* c->nextblock is NULL, no update to c->nextblock allowed */ spin_unlock(&c->erase_completion_lock); jffs2_flush_wbuf_pad(c); @@ -264,11 +248,9 @@ static int jffs2_find_nextblock(struct jffs2_sb_info *c) if (!c->nr_erasing_blocks) { /* Ouch. We're in GC, or we wouldn't have got here. And there's no space left. At all. */ - pr_crit("Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasableempty: %s, erasingempty: %s, erasependingempty: %s)\n", - c->nr_erasing_blocks, c->nr_free_blocks, - list_empty(&c->erasable_list) ? "yes" : "no", - list_empty(&c->erasing_list) ? "yes" : "no", - list_empty(&c->erase_pending_list) ? "yes" : "no"); + printk(KERN_CRIT "Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasableempty: %s, erasingempty: %s, erasependingempty: %s)\n", + c->nr_erasing_blocks, c->nr_free_blocks, list_empty(&c->erasable_list)?"yes":"no", + list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no"); return -ENOSPC; } @@ -296,8 +278,7 @@ static int jffs2_find_nextblock(struct jffs2_sb_info *c) c->wbuf_ofs = 0xffffffff; #endif - jffs2_dbg(1, "%s(): new nextblock = 0x%08x\n", - __func__, c->nextblock->offset); + D1(printk(KERN_DEBUG "jffs2_find_nextblock(): new nextblock = 0x%08x\n", c->nextblock->offset)); return 0; } @@ -364,8 +345,7 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, if (jffs2_wbuf_dirty(c)) { spin_unlock(&c->erase_completion_lock); - jffs2_dbg(1, "%s(): Flushing write buffer\n", - __func__); + D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Flushing write buffer\n")); jffs2_flush_wbuf_pad(c); spin_lock(&c->erase_completion_lock); jeb = c->nextblock; @@ -407,8 +387,7 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, jeb = c->nextblock; if (jeb->free_size != c->sector_size - c->cleanmarker_size) { - pr_warn("Eep. Block 0x%08x taken from free_list had free_size of 0x%08x!!\n", - jeb->offset, jeb->free_size); + printk(KERN_WARNING "Eep. Block 0x%08x taken from free_list had free_size of 0x%08x!!\n", jeb->offset, jeb->free_size); goto restart; } } @@ -429,9 +408,8 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, spin_lock(&c->erase_completion_lock); } - jffs2_dbg(1, "%s(): Giving 0x%x bytes at 0x%x\n", - __func__, - *len, jeb->offset + (c->sector_size - jeb->free_size)); + D1(printk(KERN_DEBUG "jffs2_do_reserve_space(): Giving 0x%x bytes at 0x%x\n", + *len, jeb->offset + (c->sector_size - jeb->free_size))); return 0; } @@ -456,22 +434,20 @@ struct jffs2_raw_node_ref *jffs2_add_physical_node_ref(struct jffs2_sb_info *c, jeb = &c->blocks[ofs / c->sector_size]; - jffs2_dbg(1, "%s(): Node at 0x%x(%d), size 0x%x\n", - __func__, ofs & ~3, ofs & 3, len); + D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n", + ofs & ~3, ofs & 3, len)); #if 1 /* Allow non-obsolete nodes only to be added at the end of c->nextblock, if c->nextblock is set. Note that wbuf.c will file obsolete nodes even after refiling c->nextblock */ if ((c->nextblock || ((ofs & 3) != REF_OBSOLETE)) && (jeb != c->nextblock || (ofs & ~3) != jeb->offset + (c->sector_size - jeb->free_size))) { - pr_warn("argh. node added in wrong place at 0x%08x(%d)\n", - ofs & ~3, ofs & 3); + printk(KERN_WARNING "argh. node added in wrong place at 0x%08x(%d)\n", ofs & ~3, ofs & 3); if (c->nextblock) - pr_warn("nextblock 0x%08x", c->nextblock->offset); + printk(KERN_WARNING "nextblock 0x%08x", c->nextblock->offset); else - pr_warn("No nextblock"); - pr_cont(", expected at %08x\n", - jeb->offset + (c->sector_size - jeb->free_size)); + printk(KERN_WARNING "No nextblock"); + printk(", expected at %08x\n", jeb->offset + (c->sector_size - jeb->free_size)); return ERR_PTR(-EINVAL); } #endif @@ -481,9 +457,8 @@ struct jffs2_raw_node_ref *jffs2_add_physical_node_ref(struct jffs2_sb_info *c, if (!jeb->free_size && !jeb->dirty_size && !ISDIRTY(jeb->wasted_size)) { /* If it lives on the dirty_list, jffs2_reserve_space will put it there */ - jffs2_dbg(1, "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", - jeb->offset, jeb->free_size, jeb->dirty_size, - jeb->used_size); + D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", + jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); if (jffs2_wbuf_dirty(c)) { /* Flush the last write in the block if it's outstanding */ spin_unlock(&c->erase_completion_lock); @@ -505,7 +480,7 @@ struct jffs2_raw_node_ref *jffs2_add_physical_node_ref(struct jffs2_sb_info *c, void jffs2_complete_reservation(struct jffs2_sb_info *c) { - jffs2_dbg(1, "jffs2_complete_reservation()\n"); + D1(printk(KERN_DEBUG "jffs2_complete_reservation()\n")); spin_lock(&c->erase_completion_lock); jffs2_garbage_collect_trigger(c); spin_unlock(&c->erase_completion_lock); @@ -518,7 +493,7 @@ static inline int on_list(struct list_head *obj, struct list_head *head) list_for_each(this, head) { if (this == obj) { - jffs2_dbg(1, "%p is on list at %p\n", obj, head); + D1(printk("%p is on list at %p\n", obj, head)); return 1; } @@ -536,18 +511,16 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref uint32_t freed_len; if(unlikely(!ref)) { - pr_notice("EEEEEK. jffs2_mark_node_obsolete called with NULL node\n"); + printk(KERN_NOTICE "EEEEEK. jffs2_mark_node_obsolete called with NULL node\n"); return; } if (ref_obsolete(ref)) { - jffs2_dbg(1, "%s(): called with already obsolete node at 0x%08x\n", - __func__, ref_offset(ref)); + D1(printk(KERN_DEBUG "jffs2_mark_node_obsolete called with already obsolete node at 0x%08x\n", ref_offset(ref))); return; } blocknr = ref->flash_offset / c->sector_size; if (blocknr >= c->nr_blocks) { - pr_notice("raw node at 0x%08x is off the end of device!\n", - ref->flash_offset); + printk(KERN_NOTICE "raw node at 0x%08x is off the end of device!\n", ref->flash_offset); BUG(); } jeb = &c->blocks[blocknr]; @@ -569,31 +542,27 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref if (ref_flags(ref) == REF_UNCHECKED) { D1(if (unlikely(jeb->unchecked_size < freed_len)) { - pr_notice("raw unchecked node of size 0x%08x freed from erase block %d at 0x%08x, but unchecked_size was already 0x%08x\n", - freed_len, blocknr, - ref->flash_offset, jeb->used_size); + printk(KERN_NOTICE "raw unchecked node of size 0x%08x freed from erase block %d at 0x%08x, but unchecked_size was already 0x%08x\n", + freed_len, blocknr, ref->flash_offset, jeb->used_size); BUG(); }) - jffs2_dbg(1, "Obsoleting previously unchecked node at 0x%08x of len %x\n", - ref_offset(ref), freed_len); + D1(printk(KERN_DEBUG "Obsoleting previously unchecked node at 0x%08x of len %x: ", ref_offset(ref), freed_len)); jeb->unchecked_size -= freed_len; c->unchecked_size -= freed_len; } else { D1(if (unlikely(jeb->used_size < freed_len)) { - pr_notice("raw node of size 0x%08x freed from erase block %d at 0x%08x, but used_size was already 0x%08x\n", - freed_len, blocknr, - ref->flash_offset, jeb->used_size); + printk(KERN_NOTICE "raw node of size 0x%08x freed from erase block %d at 0x%08x, but used_size was already 0x%08x\n", + freed_len, blocknr, ref->flash_offset, jeb->used_size); BUG(); }) - jffs2_dbg(1, "Obsoleting node at 0x%08x of len %#x: ", - ref_offset(ref), freed_len); + D1(printk(KERN_DEBUG "Obsoleting node at 0x%08x of len %#x: ", ref_offset(ref), freed_len)); jeb->used_size -= freed_len; c->used_size -= freed_len; } // Take care, that wasted size is taken into concern if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + freed_len)) && jeb != c->nextblock) { - jffs2_dbg(1, "Dirtying\n"); + D1(printk("Dirtying\n")); addedsize = freed_len; jeb->dirty_size += freed_len; c->dirty_size += freed_len; @@ -601,12 +570,12 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref /* Convert wasted space to dirty, if not a bad block */ if (jeb->wasted_size) { if (on_list(&jeb->list, &c->bad_used_list)) { - jffs2_dbg(1, "Leaving block at %08x on the bad_used_list\n", - jeb->offset); + D1(printk(KERN_DEBUG "Leaving block at %08x on the bad_used_list\n", + jeb->offset)); addedsize = 0; /* To fool the refiling code later */ } else { - jffs2_dbg(1, "Converting %d bytes of wasted space to dirty in block at %08x\n", - jeb->wasted_size, jeb->offset); + D1(printk(KERN_DEBUG "Converting %d bytes of wasted space to dirty in block at %08x\n", + jeb->wasted_size, jeb->offset)); addedsize += jeb->wasted_size; jeb->dirty_size += jeb->wasted_size; c->dirty_size += jeb->wasted_size; @@ -615,7 +584,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref } } } else { - jffs2_dbg(1, "Wasting\n"); + D1(printk("Wasting\n")); addedsize = 0; jeb->wasted_size += freed_len; c->wasted_size += freed_len; @@ -637,57 +606,50 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref } if (jeb == c->nextblock) { - jffs2_dbg(2, "Not moving nextblock 0x%08x to dirty/erase_pending list\n", - jeb->offset); + D2(printk(KERN_DEBUG "Not moving nextblock 0x%08x to dirty/erase_pending list\n", jeb->offset)); } else if (!jeb->used_size && !jeb->unchecked_size) { if (jeb == c->gcblock) { - jffs2_dbg(1, "gcblock at 0x%08x completely dirtied. Clearing gcblock...\n", - jeb->offset); + D1(printk(KERN_DEBUG "gcblock at 0x%08x completely dirtied. Clearing gcblock...\n", jeb->offset)); c->gcblock = NULL; } else { - jffs2_dbg(1, "Eraseblock at 0x%08x completely dirtied. Removing from (dirty?) list...\n", - jeb->offset); + D1(printk(KERN_DEBUG "Eraseblock at 0x%08x completely dirtied. Removing from (dirty?) list...\n", jeb->offset)); list_del(&jeb->list); } if (jffs2_wbuf_dirty(c)) { - jffs2_dbg(1, "...and adding to erasable_pending_wbuf_list\n"); + D1(printk(KERN_DEBUG "...and adding to erasable_pending_wbuf_list\n")); list_add_tail(&jeb->list, &c->erasable_pending_wbuf_list); } else { if (jiffies & 127) { /* Most of the time, we just erase it immediately. Otherwise we spend ages scanning it on mount, etc. */ - jffs2_dbg(1, "...and adding to erase_pending_list\n"); + D1(printk(KERN_DEBUG "...and adding to erase_pending_list\n")); list_add_tail(&jeb->list, &c->erase_pending_list); c->nr_erasing_blocks++; jffs2_garbage_collect_trigger(c); } else { /* Sometimes, however, we leave it elsewhere so it doesn't get immediately reused, and we spread the load a bit. */ - jffs2_dbg(1, "...and adding to erasable_list\n"); + D1(printk(KERN_DEBUG "...and adding to erasable_list\n")); list_add_tail(&jeb->list, &c->erasable_list); } } - jffs2_dbg(1, "Done OK\n"); + D1(printk(KERN_DEBUG "Done OK\n")); } else if (jeb == c->gcblock) { - jffs2_dbg(2, "Not moving gcblock 0x%08x to dirty_list\n", - jeb->offset); + D2(printk(KERN_DEBUG "Not moving gcblock 0x%08x to dirty_list\n", jeb->offset)); } else if (ISDIRTY(jeb->dirty_size) && !ISDIRTY(jeb->dirty_size - addedsize)) { - jffs2_dbg(1, "Eraseblock at 0x%08x is freshly dirtied. Removing from clean list...\n", - jeb->offset); + D1(printk(KERN_DEBUG "Eraseblock at 0x%08x is freshly dirtied. Removing from clean list...\n", jeb->offset)); list_del(&jeb->list); - jffs2_dbg(1, "...and adding to dirty_list\n"); + D1(printk(KERN_DEBUG "...and adding to dirty_list\n")); list_add_tail(&jeb->list, &c->dirty_list); } else if (VERYDIRTY(c, jeb->dirty_size) && !VERYDIRTY(c, jeb->dirty_size - addedsize)) { - jffs2_dbg(1, "Eraseblock at 0x%08x is now very dirty. Removing from dirty list...\n", - jeb->offset); + D1(printk(KERN_DEBUG "Eraseblock at 0x%08x is now very dirty. Removing from dirty list...\n", jeb->offset)); list_del(&jeb->list); - jffs2_dbg(1, "...and adding to very_dirty_list\n"); + D1(printk(KERN_DEBUG "...and adding to very_dirty_list\n")); list_add_tail(&jeb->list, &c->very_dirty_list); } else { - jffs2_dbg(1, "Eraseblock at 0x%08x not moved anywhere. (free 0x%08x, dirty 0x%08x, used 0x%08x)\n", - jeb->offset, jeb->free_size, jeb->dirty_size, - jeb->used_size); + D1(printk(KERN_DEBUG "Eraseblock at 0x%08x not moved anywhere. (free 0x%08x, dirty 0x%08x, used 0x%08x)\n", + jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); } spin_unlock(&c->erase_completion_lock); @@ -703,40 +665,33 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref the block hasn't _already_ been erased, and that 'ref' itself hasn't been freed yet by jffs2_free_jeb_node_refs() in erase.c. Which is nice. */ - jffs2_dbg(1, "obliterating obsoleted node at 0x%08x\n", - ref_offset(ref)); + D1(printk(KERN_DEBUG "obliterating obsoleted node at 0x%08x\n", ref_offset(ref))); ret = jffs2_flash_read(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n); if (ret) { - pr_warn("Read error reading from obsoleted node at 0x%08x: %d\n", - ref_offset(ref), ret); + printk(KERN_WARNING "Read error reading from obsoleted node at 0x%08x: %d\n", ref_offset(ref), ret); goto out_erase_sem; } if (retlen != sizeof(n)) { - pr_warn("Short read from obsoleted node at 0x%08x: %zd\n", - ref_offset(ref), retlen); + printk(KERN_WARNING "Short read from obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen); goto out_erase_sem; } if (PAD(je32_to_cpu(n.totlen)) != PAD(freed_len)) { - pr_warn("Node totlen on flash (0x%08x) != totlen from node ref (0x%08x)\n", - je32_to_cpu(n.totlen), freed_len); + printk(KERN_WARNING "Node totlen on flash (0x%08x) != totlen from node ref (0x%08x)\n", je32_to_cpu(n.totlen), freed_len); goto out_erase_sem; } if (!(je16_to_cpu(n.nodetype) & JFFS2_NODE_ACCURATE)) { - jffs2_dbg(1, "Node at 0x%08x was already marked obsolete (nodetype 0x%04x)\n", - ref_offset(ref), je16_to_cpu(n.nodetype)); + D1(printk(KERN_DEBUG "Node at 0x%08x was already marked obsolete (nodetype 0x%04x)\n", ref_offset(ref), je16_to_cpu(n.nodetype))); goto out_erase_sem; } /* XXX FIXME: This is ugly now */ n.nodetype = cpu_to_je16(je16_to_cpu(n.nodetype) & ~JFFS2_NODE_ACCURATE); ret = jffs2_flash_write(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n); if (ret) { - pr_warn("Write error in obliterating obsoleted node at 0x%08x: %d\n", - ref_offset(ref), ret); + printk(KERN_WARNING "Write error in obliterating obsoleted node at 0x%08x: %d\n", ref_offset(ref), ret); goto out_erase_sem; } if (retlen != sizeof(n)) { - pr_warn("Short write in obliterating obsoleted node at 0x%08x: %zd\n", - ref_offset(ref), retlen); + printk(KERN_WARNING "Short write in obliterating obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen); goto out_erase_sem; } @@ -796,8 +751,8 @@ int jffs2_thread_should_wake(struct jffs2_sb_info *c) return 1; if (c->unchecked_size) { - jffs2_dbg(1, "jffs2_thread_should_wake(): unchecked_size %d, checked_ino #%d\n", - c->unchecked_size, c->checked_ino); + D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): unchecked_size %d, checked_ino #%d\n", + c->unchecked_size, c->checked_ino)); return 1; } @@ -825,9 +780,8 @@ int jffs2_thread_should_wake(struct jffs2_sb_info *c) } } - jffs2_dbg(1, "%s(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x, vdirty_blocks %d: %s\n", - __func__, c->nr_free_blocks, c->nr_erasing_blocks, - c->dirty_size, nr_very_dirty, ret ? "yes" : "no"); + D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x, vdirty_blocks %d: %s\n", + c->nr_free_blocks, c->nr_erasing_blocks, c->dirty_size, nr_very_dirty, ret?"yes":"no")); return ret; } diff --git a/trunk/fs/jffs2/os-linux.h b/trunk/fs/jffs2/os-linux.h index 1cd3aec9d9ae..ab65ee3ec858 100644 --- a/trunk/fs/jffs2/os-linux.h +++ b/trunk/fs/jffs2/os-linux.h @@ -76,7 +76,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) #define jffs2_write_nand_cleanmarker(c,jeb) (-EIO) #define jffs2_flash_write(c, ofs, len, retlen, buf) jffs2_flash_direct_write(c, ofs, len, retlen, buf) -#define jffs2_flash_read(c, ofs, len, retlen, buf) (mtd_read((c)->mtd, ofs, len, retlen, buf)) +#define jffs2_flash_read(c, ofs, len, retlen, buf) ((c)->mtd->read((c)->mtd, ofs, len, retlen, buf)) #define jffs2_flush_wbuf_pad(c) ({ do{} while(0); (void)(c), 0; }) #define jffs2_flush_wbuf_gc(c, i) ({ do{} while(0); (void)(c), (void) i, 0; }) #define jffs2_write_nand_badblock(c,jeb,bad_offset) (1) @@ -108,6 +108,8 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) #define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH) +#define jffs2_flash_write_oob(c, ofs, len, retlen, buf) ((c)->mtd->write_oob((c)->mtd, ofs, len, retlen, buf)) +#define jffs2_flash_read_oob(c, ofs, len, retlen, buf) ((c)->mtd->read_oob((c)->mtd, ofs, len, retlen, buf)) #define jffs2_wbuf_dirty(c) (!!(c)->wbuf_len) /* wbuf.c */ diff --git a/trunk/fs/jffs2/read.c b/trunk/fs/jffs2/read.c index 0b042b1fc82f..3f39be1b0455 100644 --- a/trunk/fs/jffs2/read.c +++ b/trunk/fs/jffs2/read.c @@ -9,8 +9,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -38,25 +36,24 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, ret = jffs2_flash_read(c, ref_offset(fd->raw), sizeof(*ri), &readlen, (char *)ri); if (ret) { jffs2_free_raw_inode(ri); - pr_warn("Error reading node from 0x%08x: %d\n", - ref_offset(fd->raw), ret); + printk(KERN_WARNING "Error reading node from 0x%08x: %d\n", ref_offset(fd->raw), ret); return ret; } if (readlen != sizeof(*ri)) { jffs2_free_raw_inode(ri); - pr_warn("Short read from 0x%08x: wanted 0x%zx bytes, got 0x%zx\n", - ref_offset(fd->raw), sizeof(*ri), readlen); + printk(KERN_WARNING "Short read from 0x%08x: wanted 0x%zx bytes, got 0x%zx\n", + ref_offset(fd->raw), sizeof(*ri), readlen); return -EIO; } crc = crc32(0, ri, sizeof(*ri)-8); - jffs2_dbg(1, "Node read from %08x: node_crc %08x, calculated CRC %08x. dsize %x, csize %x, offset %x, buf %p\n", + D1(printk(KERN_DEBUG "Node read from %08x: node_crc %08x, calculated CRC %08x. dsize %x, csize %x, offset %x, buf %p\n", ref_offset(fd->raw), je32_to_cpu(ri->node_crc), crc, je32_to_cpu(ri->dsize), je32_to_cpu(ri->csize), - je32_to_cpu(ri->offset), buf); + je32_to_cpu(ri->offset), buf)); if (crc != je32_to_cpu(ri->node_crc)) { - pr_warn("Node CRC %08x != calculated CRC %08x for node at %08x\n", - je32_to_cpu(ri->node_crc), crc, ref_offset(fd->raw)); + printk(KERN_WARNING "Node CRC %08x != calculated CRC %08x for node at %08x\n", + je32_to_cpu(ri->node_crc), crc, ref_offset(fd->raw)); ret = -EIO; goto out_ri; } @@ -69,8 +66,8 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, } D1(if(ofs + len > je32_to_cpu(ri->dsize)) { - pr_warn("jffs2_read_dnode() asked for %d bytes at %d from %d-byte node\n", - len, ofs, je32_to_cpu(ri->dsize)); + printk(KERN_WARNING "jffs2_read_dnode() asked for %d bytes at %d from %d-byte node\n", + len, ofs, je32_to_cpu(ri->dsize)); ret = -EINVAL; goto out_ri; }); @@ -110,8 +107,8 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, decomprbuf = readbuf; } - jffs2_dbg(2, "Read %d bytes to %p\n", je32_to_cpu(ri->csize), - readbuf); + D2(printk(KERN_DEBUG "Read %d bytes to %p\n", je32_to_cpu(ri->csize), + readbuf)); ret = jffs2_flash_read(c, (ref_offset(fd->raw)) + sizeof(*ri), je32_to_cpu(ri->csize), &readlen, readbuf); @@ -122,19 +119,18 @@ int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, crc = crc32(0, readbuf, je32_to_cpu(ri->csize)); if (crc != je32_to_cpu(ri->data_crc)) { - pr_warn("Data CRC %08x != calculated CRC %08x for node at %08x\n", - je32_to_cpu(ri->data_crc), crc, ref_offset(fd->raw)); + printk(KERN_WARNING "Data CRC %08x != calculated CRC %08x for node at %08x\n", + je32_to_cpu(ri->data_crc), crc, ref_offset(fd->raw)); ret = -EIO; goto out_decomprbuf; } - jffs2_dbg(2, "Data CRC matches calculated CRC %08x\n", crc); + D2(printk(KERN_DEBUG "Data CRC matches calculated CRC %08x\n", crc)); if (ri->compr != JFFS2_COMPR_NONE) { - jffs2_dbg(2, "Decompress %d bytes from %p to %d bytes at %p\n", - je32_to_cpu(ri->csize), readbuf, - je32_to_cpu(ri->dsize), decomprbuf); + D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %p\n", + je32_to_cpu(ri->csize), readbuf, je32_to_cpu(ri->dsize), decomprbuf)); ret = jffs2_decompress(c, f, ri->compr | (ri->usercompr << 8), readbuf, decomprbuf, je32_to_cpu(ri->csize), je32_to_cpu(ri->dsize)); if (ret) { - pr_warn("Error: jffs2_decompress returned %d\n", ret); + printk(KERN_WARNING "Error: jffs2_decompress returned %d\n", ret); goto out_decomprbuf; } } @@ -161,8 +157,8 @@ int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_node_frag *frag; int ret; - jffs2_dbg(1, "%s(): ino #%u, range 0x%08x-0x%08x\n", - __func__, f->inocache->ino, offset, offset + len); + D1(printk(KERN_DEBUG "jffs2_read_inode_range: ino #%u, range 0x%08x-0x%08x\n", + f->inocache->ino, offset, offset+len)); frag = jffs2_lookup_node_frag(&f->fragtree, offset); @@ -172,27 +168,22 @@ int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, * (or perhaps is before it, if we've been asked to read off the * end of the file). */ while(offset < end) { - jffs2_dbg(2, "%s(): offset %d, end %d\n", - __func__, offset, end); + D2(printk(KERN_DEBUG "jffs2_read_inode_range: offset %d, end %d\n", offset, end)); if (unlikely(!frag || frag->ofs > offset || frag->ofs + frag->size <= offset)) { uint32_t holesize = end - offset; if (frag && frag->ofs > offset) { - jffs2_dbg(1, "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", - f->inocache->ino, frag->ofs, offset); + D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset)); holesize = min(holesize, frag->ofs - offset); } - jffs2_dbg(1, "Filling non-frag hole from %d-%d\n", - offset, offset + holesize); + D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize)); memset(buf, 0, holesize); buf += holesize; offset += holesize; continue; } else if (unlikely(!frag->node)) { uint32_t holeend = min(end, frag->ofs + frag->size); - jffs2_dbg(1, "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n", - offset, holeend, frag->ofs, - frag->ofs + frag->size); + D1(printk(KERN_DEBUG "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n", offset, holeend, frag->ofs, frag->ofs + frag->size)); memset(buf, 0, holeend - offset); buf += holeend - offset; offset = holeend; @@ -204,23 +195,20 @@ int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, fragofs = offset - frag->ofs; readlen = min(frag->size - fragofs, end - offset); - jffs2_dbg(1, "Reading %d-%d from node at 0x%08x (%d)\n", - frag->ofs+fragofs, - frag->ofs + fragofs+readlen, - ref_offset(frag->node->raw), - ref_flags(frag->node->raw)); + D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%08x (%d)\n", + frag->ofs+fragofs, frag->ofs+fragofs+readlen, + ref_offset(frag->node->raw), ref_flags(frag->node->raw))); ret = jffs2_read_dnode(c, f, frag->node, buf, fragofs + frag->ofs - frag->node->ofs, readlen); - jffs2_dbg(2, "node read done\n"); + D2(printk(KERN_DEBUG "node read done\n")); if (ret) { - jffs2_dbg(1, "%s(): error %d\n", - __func__, ret); + D1(printk(KERN_DEBUG"jffs2_read_inode_range error %d\n",ret)); memset(buf, 0, readlen); return ret; } buf += readlen; offset += readlen; frag = frag_next(frag); - jffs2_dbg(2, "node read was OK. Looping\n"); + D2(printk(KERN_DEBUG "node read was OK. Looping\n")); } } return 0; diff --git a/trunk/fs/jffs2/readinode.c b/trunk/fs/jffs2/readinode.c index dc0437e84763..3093ac4fb24c 100644 --- a/trunk/fs/jffs2/readinode.c +++ b/trunk/fs/jffs2/readinode.c @@ -9,8 +9,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include diff --git a/trunk/fs/jffs2/scan.c b/trunk/fs/jffs2/scan.c index 7654e87b0428..f99464833bb2 100644 --- a/trunk/fs/jffs2/scan.c +++ b/trunk/fs/jffs2/scan.c @@ -9,8 +9,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -24,15 +22,15 @@ #define DEFAULT_EMPTY_SCAN_SIZE 256 -#define noisy_printk(noise, fmt, ...) \ -do { \ - if (*(noise)) { \ - pr_notice(fmt, ##__VA_ARGS__); \ - (*(noise))--; \ - if (!(*(noise))) \ - pr_notice("Further such events for this erase block will not be printed\n"); \ - } \ -} while (0) +#define noisy_printk(noise, args...) do { \ + if (*(noise)) { \ + printk(KERN_NOTICE args); \ + (*(noise))--; \ + if (!(*(noise))) { \ + printk(KERN_NOTICE "Further such events for this erase block will not be printed\n"); \ + } \ + } \ +} while(0) static uint32_t pseudo_random; @@ -98,17 +96,18 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) #ifndef __ECOS size_t pointlen, try_size; - ret = mtd_point(c->mtd, 0, c->mtd->size, &pointlen, - (void **)&flashbuf, NULL); - if (!ret && pointlen < c->mtd->size) { - /* Don't muck about if it won't let us point to the whole flash */ - jffs2_dbg(1, "MTD point returned len too short: 0x%zx\n", - pointlen); - mtd_unpoint(c->mtd, 0, pointlen); - flashbuf = NULL; + if (c->mtd->point) { + ret = mtd_point(c->mtd, 0, c->mtd->size, &pointlen, + (void **)&flashbuf, NULL); + if (!ret && pointlen < c->mtd->size) { + /* Don't muck about if it won't let us point to the whole flash */ + D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", pointlen)); + mtd_unpoint(c->mtd, 0, pointlen); + flashbuf = NULL; + } + if (ret && ret != -EOPNOTSUPP) + D1(printk(KERN_DEBUG "MTD point failed %d\n", ret)); } - if (ret && ret != -EOPNOTSUPP) - jffs2_dbg(1, "MTD point failed %d\n", ret); #endif if (!flashbuf) { /* For NAND it's quicker to read a whole eraseblock at a time, @@ -118,15 +117,15 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) else try_size = PAGE_SIZE; - jffs2_dbg(1, "Trying to allocate readbuf of %zu " - "bytes\n", try_size); + D1(printk(KERN_DEBUG "Trying to allocate readbuf of %zu " + "bytes\n", try_size)); flashbuf = mtd_kmalloc_up_to(c->mtd, &try_size); if (!flashbuf) return -ENOMEM; - jffs2_dbg(1, "Allocated readbuf of %zu bytes\n", - try_size); + D1(printk(KERN_DEBUG "Allocated readbuf of %zu bytes\n", + try_size)); buf_size = (uint32_t)try_size; } @@ -179,8 +178,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) c->nr_free_blocks++; } else { /* Dirt */ - jffs2_dbg(1, "Adding all-dirty block at 0x%08x to erase_pending_list\n", - jeb->offset); + D1(printk(KERN_DEBUG "Adding all-dirty block at 0x%08x to erase_pending_list\n", jeb->offset)); list_add(&jeb->list, &c->erase_pending_list); c->nr_erasing_blocks++; } @@ -207,8 +205,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) } /* update collected summary information for the current nextblock */ jffs2_sum_move_collected(c, s); - jffs2_dbg(1, "%s(): new nextblock = 0x%08x\n", - __func__, jeb->offset); + D1(printk(KERN_DEBUG "jffs2_scan_medium(): new nextblock = 0x%08x\n", jeb->offset)); c->nextblock = jeb; } else { ret = file_dirty(c, jeb); @@ -220,21 +217,20 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) case BLK_STATE_ALLDIRTY: /* Nothing valid - not even a clean marker. Needs erasing. */ /* For now we just put it on the erasing list. We'll start the erases later */ - jffs2_dbg(1, "Erase block at 0x%08x is not formatted. It will be erased\n", - jeb->offset); + D1(printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset)); list_add(&jeb->list, &c->erase_pending_list); c->nr_erasing_blocks++; break; case BLK_STATE_BADBLOCK: - jffs2_dbg(1, "Block at 0x%08x is bad\n", jeb->offset); + D1(printk(KERN_NOTICE "JFFS2: Block at 0x%08x is bad\n", jeb->offset)); list_add(&jeb->list, &c->bad_list); c->bad_size += c->sector_size; c->free_size -= c->sector_size; bad_blocks++; break; default: - pr_warn("%s(): unknown block state\n", __func__); + printk(KERN_WARNING "jffs2_scan_medium(): unknown block state\n"); BUG(); } } @@ -254,17 +250,16 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) uint32_t skip = c->nextblock->free_size % c->wbuf_pagesize; - jffs2_dbg(1, "%s(): Skipping %d bytes in nextblock to ensure page alignment\n", - __func__, skip); + D1(printk(KERN_DEBUG "jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment\n", + skip)); jffs2_prealloc_raw_node_refs(c, c->nextblock, 1); jffs2_scan_dirty_space(c, c->nextblock, skip); } #endif if (c->nr_erasing_blocks) { if ( !c->used_size && ((c->nr_free_blocks+empty_blocks+bad_blocks)!= c->nr_blocks || bad_blocks == c->nr_blocks) ) { - pr_notice("Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n"); - pr_notice("empty_blocks %d, bad_blocks %d, c->nr_blocks %d\n", - empty_blocks, bad_blocks, c->nr_blocks); + printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n"); + printk(KERN_NOTICE "empty_blocks %d, bad_blocks %d, c->nr_blocks %d\n",empty_blocks,bad_blocks,c->nr_blocks); ret = -EIO; goto out; } @@ -292,13 +287,11 @@ static int jffs2_fill_scan_buf(struct jffs2_sb_info *c, void *buf, ret = jffs2_flash_read(c, ofs, len, &retlen, buf); if (ret) { - jffs2_dbg(1, "mtd->read(0x%x bytes from 0x%x) returned %d\n", - len, ofs, ret); + D1(printk(KERN_WARNING "mtd->read(0x%x bytes from 0x%x) returned %d\n", len, ofs, ret)); return ret; } if (retlen < len) { - jffs2_dbg(1, "Read at 0x%x gave only 0x%zx bytes\n", - ofs, retlen); + D1(printk(KERN_WARNING "Read at 0x%x gave only 0x%zx bytes\n", ofs, retlen)); return -EIO; } return 0; @@ -375,7 +368,7 @@ static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_erasebloc if (jffs2_sum_active()) jffs2_sum_add_xattr_mem(s, rx, ofs - jeb->offset); - dbg_xattr("scanning xdatum at %#08x (xid=%u, version=%u)\n", + dbg_xattr("scaning xdatum at %#08x (xid=%u, version=%u)\n", ofs, xd->xid, xd->version); return 0; } @@ -456,7 +449,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo ofs = jeb->offset; prevofs = jeb->offset - 1; - jffs2_dbg(1, "%s(): Scanning block at 0x%x\n", __func__, ofs); + D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs)); #ifdef CONFIG_JFFS2_FS_WRITEBUFFER if (jffs2_cleanmarker_oob(c)) { @@ -466,7 +459,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo return BLK_STATE_BADBLOCK; ret = jffs2_check_nand_cleanmarker(c, jeb); - jffs2_dbg(2, "jffs_check_nand_cleanmarker returned %d\n", ret); + D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret)); /* Even if it's not found, we still scan to see if the block is empty. We use this information @@ -568,8 +561,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo if (jffs2_cleanmarker_oob(c)) { /* scan oob, take care of cleanmarker */ int ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound); - jffs2_dbg(2, "jffs2_check_oob_empty returned %d\n", - ret); + D2(printk(KERN_NOTICE "jffs2_check_oob_empty returned %d\n",ret)); switch (ret) { case 0: return cleanmarkerfound ? BLK_STATE_CLEANMARKER : BLK_STATE_ALLFF; case 1: return BLK_STATE_ALLDIRTY; @@ -577,16 +569,15 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo } } #endif - jffs2_dbg(1, "Block at 0x%08x is empty (erased)\n", - jeb->offset); + D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset)); if (c->cleanmarker_size == 0) return BLK_STATE_CLEANMARKER; /* don't bother with re-erase */ else return BLK_STATE_ALLFF; /* OK to erase if all blocks are like this */ } if (ofs) { - jffs2_dbg(1, "Free space at %08x ends at %08x\n", jeb->offset, - jeb->offset + ofs); + D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset, + jeb->offset + ofs)); if ((err = jffs2_prealloc_raw_node_refs(c, jeb, 1))) return err; if ((err = jffs2_scan_dirty_space(c, jeb, ofs))) @@ -613,13 +604,12 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo cond_resched(); if (ofs & 3) { - pr_warn("Eep. ofs 0x%08x not word-aligned!\n", ofs); + printk(KERN_WARNING "Eep. ofs 0x%08x not word-aligned!\n", ofs); ofs = PAD(ofs); continue; } if (ofs == prevofs) { - pr_warn("ofs 0x%08x has already been seen. Skipping\n", - ofs); + printk(KERN_WARNING "ofs 0x%08x has already been seen. Skipping\n", ofs); if ((err = jffs2_scan_dirty_space(c, jeb, 4))) return err; ofs += 4; @@ -628,10 +618,8 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo prevofs = ofs; if (jeb->offset + c->sector_size < ofs + sizeof(*node)) { - jffs2_dbg(1, "Fewer than %zd bytes left to end of block. (%x+%x<%x+%zx) Not reading\n", - sizeof(struct jffs2_unknown_node), - jeb->offset, c->sector_size, ofs, - sizeof(*node)); + D1(printk(KERN_DEBUG "Fewer than %zd bytes left to end of block. (%x+%x<%x+%zx) Not reading\n", sizeof(struct jffs2_unknown_node), + jeb->offset, c->sector_size, ofs, sizeof(*node))); if ((err = jffs2_scan_dirty_space(c, jeb, (jeb->offset + c->sector_size)-ofs))) return err; break; @@ -639,9 +627,8 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo if (buf_ofs + buf_len < ofs + sizeof(*node)) { buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); - jffs2_dbg(1, "Fewer than %zd bytes (node header) left to end of buf. Reading 0x%x at 0x%08x\n", - sizeof(struct jffs2_unknown_node), - buf_len, ofs); + D1(printk(KERN_DEBUG "Fewer than %zd bytes (node header) left to end of buf. Reading 0x%x at 0x%08x\n", + sizeof(struct jffs2_unknown_node), buf_len, ofs)); err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); if (err) return err; @@ -658,13 +645,13 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo ofs += 4; scan_end = min_t(uint32_t, EMPTY_SCAN_SIZE(c->sector_size)/8, buf_len); - jffs2_dbg(1, "Found empty flash at 0x%08x\n", ofs); + D1(printk(KERN_DEBUG "Found empty flash at 0x%08x\n", ofs)); more_empty: inbuf_ofs = ofs - buf_ofs; while (inbuf_ofs < scan_end) { if (unlikely(*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff)) { - pr_warn("Empty flash at 0x%08x ends at 0x%08x\n", - empty_start, ofs); + printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n", + empty_start, ofs); if ((err = jffs2_scan_dirty_space(c, jeb, ofs-empty_start))) return err; goto scan_more; @@ -674,15 +661,13 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo ofs += 4; } /* Ran off end. */ - jffs2_dbg(1, "Empty flash to end of buffer at 0x%08x\n", - ofs); + D1(printk(KERN_DEBUG "Empty flash to end of buffer at 0x%08x\n", ofs)); /* If we're only checking the beginning of a block with a cleanmarker, bail now */ if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) && c->cleanmarker_size && !jeb->dirty_size && !ref_next(jeb->first_node)) { - jffs2_dbg(1, "%d bytes at start of block seems clean... assuming all clean\n", - EMPTY_SCAN_SIZE(c->sector_size)); + D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size))); return BLK_STATE_CLEANMARKER; } if (!buf_size && (scan_end != buf_len)) {/* XIP/point case */ @@ -695,14 +680,13 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo if (!buf_len) { /* No more to read. Break out of main loop without marking this range of empty space as dirty (because it's not) */ - jffs2_dbg(1, "Empty flash at %08x runs to end of block. Treating as free_space\n", - empty_start); + D1(printk(KERN_DEBUG "Empty flash at %08x runs to end of block. Treating as free_space\n", + empty_start)); break; } /* point never reaches here */ scan_end = buf_len; - jffs2_dbg(1, "Reading another 0x%x at 0x%08x\n", - buf_len, ofs); + D1(printk(KERN_DEBUG "Reading another 0x%x at 0x%08x\n", buf_len, ofs)); err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); if (err) return err; @@ -711,23 +695,22 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo } if (ofs == jeb->offset && je16_to_cpu(node->magic) == KSAMTIB_CIGAM_2SFFJ) { - pr_warn("Magic bitmask is backwards at offset 0x%08x. Wrong endian filesystem?\n", - ofs); + printk(KERN_WARNING "Magic bitmask is backwards at offset 0x%08x. Wrong endian filesystem?\n", ofs); if ((err = jffs2_scan_dirty_space(c, jeb, 4))) return err; ofs += 4; continue; } if (je16_to_cpu(node->magic) == JFFS2_DIRTY_BITMASK) { - jffs2_dbg(1, "Dirty bitmask at 0x%08x\n", ofs); + D1(printk(KERN_DEBUG "Dirty bitmask at 0x%08x\n", ofs)); if ((err = jffs2_scan_dirty_space(c, jeb, 4))) return err; ofs += 4; continue; } if (je16_to_cpu(node->magic) == JFFS2_OLD_MAGIC_BITMASK) { - pr_warn("Old JFFS2 bitmask found at 0x%08x\n", ofs); - pr_warn("You cannot use older JFFS2 filesystems with newer kernels\n"); + printk(KERN_WARNING "Old JFFS2 bitmask found at 0x%08x\n", ofs); + printk(KERN_WARNING "You cannot use older JFFS2 filesystems with newer kernels\n"); if ((err = jffs2_scan_dirty_space(c, jeb, 4))) return err; ofs += 4; @@ -735,8 +718,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo } if (je16_to_cpu(node->magic) != JFFS2_MAGIC_BITMASK) { /* OK. We're out of possibilities. Whinge and move on */ - noisy_printk(&noise, "%s(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n", - __func__, + noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n", JFFS2_MAGIC_BITMASK, ofs, je16_to_cpu(node->magic)); if ((err = jffs2_scan_dirty_space(c, jeb, 4))) @@ -751,8 +733,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo hdr_crc = crc32(0, &crcnode, sizeof(crcnode)-4); if (hdr_crc != je32_to_cpu(node->hdr_crc)) { - noisy_printk(&noise, "%s(): Node at 0x%08x {0x%04x, 0x%04x, 0x%08x) has invalid CRC 0x%08x (calculated 0x%08x)\n", - __func__, + noisy_printk(&noise, "jffs2_scan_eraseblock(): Node at 0x%08x {0x%04x, 0x%04x, 0x%08x) has invalid CRC 0x%08x (calculated 0x%08x)\n", ofs, je16_to_cpu(node->magic), je16_to_cpu(node->nodetype), je32_to_cpu(node->totlen), @@ -766,9 +747,9 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo if (ofs + je32_to_cpu(node->totlen) > jeb->offset + c->sector_size) { /* Eep. Node goes over the end of the erase block. */ - pr_warn("Node at 0x%08x with length 0x%08x would run over the end of the erase block\n", - ofs, je32_to_cpu(node->totlen)); - pr_warn("Perhaps the file system was created with the wrong erase size?\n"); + printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n", + ofs, je32_to_cpu(node->totlen)); + printk(KERN_WARNING "Perhaps the file system was created with the wrong erase size?\n"); if ((err = jffs2_scan_dirty_space(c, jeb, 4))) return err; ofs += 4; @@ -777,8 +758,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo if (!(je16_to_cpu(node->nodetype) & JFFS2_NODE_ACCURATE)) { /* Wheee. This is an obsoleted node */ - jffs2_dbg(2, "Node at 0x%08x is obsolete. Skipping\n", - ofs); + D2(printk(KERN_DEBUG "Node at 0x%08x is obsolete. Skipping\n", ofs)); if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen))))) return err; ofs += PAD(je32_to_cpu(node->totlen)); @@ -789,9 +769,8 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo case JFFS2_NODETYPE_INODE: if (buf_ofs + buf_len < ofs + sizeof(struct jffs2_raw_inode)) { buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); - jffs2_dbg(1, "Fewer than %zd bytes (inode node) left to end of buf. Reading 0x%x at 0x%08x\n", - sizeof(struct jffs2_raw_inode), - buf_len, ofs); + D1(printk(KERN_DEBUG "Fewer than %zd bytes (inode node) left to end of buf. Reading 0x%x at 0x%08x\n", + sizeof(struct jffs2_raw_inode), buf_len, ofs)); err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); if (err) return err; @@ -806,9 +785,8 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo case JFFS2_NODETYPE_DIRENT: if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) { buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); - jffs2_dbg(1, "Fewer than %d bytes (dirent node) left to end of buf. Reading 0x%x at 0x%08x\n", - je32_to_cpu(node->totlen), buf_len, - ofs); + D1(printk(KERN_DEBUG "Fewer than %d bytes (dirent node) left to end of buf. Reading 0x%x at 0x%08x\n", + je32_to_cpu(node->totlen), buf_len, ofs)); err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); if (err) return err; @@ -824,9 +802,9 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo case JFFS2_NODETYPE_XATTR: if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) { buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); - jffs2_dbg(1, "Fewer than %d bytes (xattr node) left to end of buf. Reading 0x%x at 0x%08x\n", - je32_to_cpu(node->totlen), buf_len, - ofs); + D1(printk(KERN_DEBUG "Fewer than %d bytes (xattr node)" + " left to end of buf. Reading 0x%x at 0x%08x\n", + je32_to_cpu(node->totlen), buf_len, ofs)); err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); if (err) return err; @@ -841,9 +819,9 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo case JFFS2_NODETYPE_XREF: if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) { buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); - jffs2_dbg(1, "Fewer than %d bytes (xref node) left to end of buf. Reading 0x%x at 0x%08x\n", - je32_to_cpu(node->totlen), buf_len, - ofs); + D1(printk(KERN_DEBUG "Fewer than %d bytes (xref node)" + " left to end of buf. Reading 0x%x at 0x%08x\n", + je32_to_cpu(node->totlen), buf_len, ofs)); err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); if (err) return err; @@ -858,17 +836,15 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo #endif /* CONFIG_JFFS2_FS_XATTR */ case JFFS2_NODETYPE_CLEANMARKER: - jffs2_dbg(1, "CLEANMARKER node found at 0x%08x\n", ofs); + D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs)); if (je32_to_cpu(node->totlen) != c->cleanmarker_size) { - pr_notice("CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n", - ofs, je32_to_cpu(node->totlen), - c->cleanmarker_size); + printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n", + ofs, je32_to_cpu(node->totlen), c->cleanmarker_size); if ((err = jffs2_scan_dirty_space(c, jeb, PAD(sizeof(struct jffs2_unknown_node))))) return err; ofs += PAD(sizeof(struct jffs2_unknown_node)); } else if (jeb->first_node) { - pr_notice("CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)\n", - ofs, jeb->offset); + printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)\n", ofs, jeb->offset); if ((err = jffs2_scan_dirty_space(c, jeb, PAD(sizeof(struct jffs2_unknown_node))))) return err; ofs += PAD(sizeof(struct jffs2_unknown_node)); @@ -890,8 +866,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo default: switch (je16_to_cpu(node->nodetype) & JFFS2_COMPAT_MASK) { case JFFS2_FEATURE_ROCOMPAT: - pr_notice("Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", - je16_to_cpu(node->nodetype), ofs); + printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs); c->flags |= JFFS2_SB_FLAG_RO; if (!(jffs2_is_readonly(c))) return -EROFS; @@ -901,21 +876,18 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo break; case JFFS2_FEATURE_INCOMPAT: - pr_notice("Incompatible feature node (0x%04x) found at offset 0x%08x\n", - je16_to_cpu(node->nodetype), ofs); + printk(KERN_NOTICE "Incompatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs); return -EINVAL; case JFFS2_FEATURE_RWCOMPAT_DELETE: - jffs2_dbg(1, "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", - je16_to_cpu(node->nodetype), ofs); + D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs)); if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(node->totlen))))) return err; ofs += PAD(je32_to_cpu(node->totlen)); break; case JFFS2_FEATURE_RWCOMPAT_COPY: { - jffs2_dbg(1, "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", - je16_to_cpu(node->nodetype), ofs); + D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs)); jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(node->totlen)), NULL); @@ -936,9 +908,8 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo } } - jffs2_dbg(1, "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x, wasted 0x%08x\n", - jeb->offset, jeb->free_size, jeb->dirty_size, - jeb->unchecked_size, jeb->used_size, jeb->wasted_size); + D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x, wasted 0x%08x\n", + jeb->offset,jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size, jeb->wasted_size)); /* mark_node_obsolete can add to wasted !! */ if (jeb->wasted_size) { @@ -964,7 +935,7 @@ struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uin ic = jffs2_alloc_inode_cache(); if (!ic) { - pr_notice("%s(): allocation of inode cache failed\n", __func__); + printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of inode cache failed\n"); return NULL; } memset(ic, 0, sizeof(*ic)); @@ -983,7 +954,7 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc struct jffs2_inode_cache *ic; uint32_t crc, ino = je32_to_cpu(ri->ino); - jffs2_dbg(1, "%s(): Node at 0x%08x\n", __func__, ofs); + D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs)); /* We do very little here now. Just check the ino# to which we should attribute this node; we can do all the CRC checking etc. later. There's a tradeoff here -- @@ -997,8 +968,9 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc /* Check the node CRC in any case. */ crc = crc32(0, ri, sizeof(*ri)-8); if (crc != je32_to_cpu(ri->node_crc)) { - pr_notice("%s(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", - __func__, ofs, je32_to_cpu(ri->node_crc), crc); + printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on " + "node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", + ofs, je32_to_cpu(ri->node_crc), crc); /* * We believe totlen because the CRC on the node * _header_ was OK, just the node itself failed. @@ -1017,10 +989,10 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc /* Wheee. It worked */ jffs2_link_node_ref(c, jeb, ofs | REF_UNCHECKED, PAD(je32_to_cpu(ri->totlen)), ic); - jffs2_dbg(1, "Node is ino #%u, version %d. Range 0x%x-0x%x\n", + D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n", je32_to_cpu(ri->ino), je32_to_cpu(ri->version), je32_to_cpu(ri->offset), - je32_to_cpu(ri->offset)+je32_to_cpu(ri->dsize)); + je32_to_cpu(ri->offset)+je32_to_cpu(ri->dsize))); pseudo_random += je32_to_cpu(ri->version); @@ -1040,15 +1012,15 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo uint32_t crc; int err; - jffs2_dbg(1, "%s(): Node at 0x%08x\n", __func__, ofs); + D1(printk(KERN_DEBUG "jffs2_scan_dirent_node(): Node at 0x%08x\n", ofs)); /* We don't get here unless the node is still valid, so we don't have to mask in the ACCURATE bit any more. */ crc = crc32(0, rd, sizeof(*rd)-8); if (crc != je32_to_cpu(rd->node_crc)) { - pr_notice("%s(): Node CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", - __func__, ofs, je32_to_cpu(rd->node_crc), crc); + printk(KERN_NOTICE "jffs2_scan_dirent_node(): Node CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", + ofs, je32_to_cpu(rd->node_crc), crc); /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */ if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rd->totlen))))) return err; @@ -1060,7 +1032,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo /* Should never happen. Did. (OLPC trac #4184)*/ checkedlen = strnlen(rd->name, rd->nsize); if (checkedlen < rd->nsize) { - pr_err("Dirent at %08x has zeroes in name. Truncating to %d chars\n", + printk(KERN_ERR "Dirent at %08x has zeroes in name. Truncating to %d chars\n", ofs, checkedlen); } fd = jffs2_alloc_full_dirent(checkedlen+1); @@ -1072,10 +1044,9 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo crc = crc32(0, fd->name, rd->nsize); if (crc != je32_to_cpu(rd->name_crc)) { - pr_notice("%s(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", - __func__, ofs, je32_to_cpu(rd->name_crc), crc); - jffs2_dbg(1, "Name for which CRC failed is (now) '%s', ino #%d\n", - fd->name, je32_to_cpu(rd->ino)); + printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", + ofs, je32_to_cpu(rd->name_crc), crc); + D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, je32_to_cpu(rd->ino))); jffs2_free_full_dirent(fd); /* FIXME: Why do we believe totlen? */ /* We believe totlen because the CRC on the node _header_ was OK, just the name failed. */ diff --git a/trunk/fs/jffs2/security.c b/trunk/fs/jffs2/security.c index aca97f35b292..0f20208df602 100644 --- a/trunk/fs/jffs2/security.c +++ b/trunk/fs/jffs2/security.c @@ -23,8 +23,8 @@ #include "nodelist.h" /* ---- Initial Security Label(s) Attachment callback --- */ -static int jffs2_initxattrs(struct inode *inode, - const struct xattr *xattr_array, void *fs_info) +int jffs2_initxattrs(struct inode *inode, const struct xattr *xattr_array, + void *fs_info) { const struct xattr *xattr; int err = 0; diff --git a/trunk/fs/jffs2/summary.c b/trunk/fs/jffs2/summary.c index c522d098bb4f..e537fb0e0184 100644 --- a/trunk/fs/jffs2/summary.c +++ b/trunk/fs/jffs2/summary.c @@ -11,8 +11,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -444,16 +442,13 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras /* This should never happen, but https://dev.laptop.org/ticket/4184 */ checkedlen = strnlen(spd->name, spd->nsize); if (!checkedlen) { - pr_err("Dirent at %08x has zero at start of name. Aborting mount.\n", - jeb->offset + - je32_to_cpu(spd->offset)); + printk(KERN_ERR "Dirent at %08x has zero at start of name. Aborting mount.\n", + jeb->offset + je32_to_cpu(spd->offset)); return -EIO; } if (checkedlen < spd->nsize) { - pr_err("Dirent at %08x has zeroes in name. Truncating to %d chars\n", - jeb->offset + - je32_to_cpu(spd->offset), - checkedlen); + printk(KERN_ERR "Dirent at %08x has zeroes in name. Truncating to %d chars\n", + jeb->offset + je32_to_cpu(spd->offset), checkedlen); } @@ -813,7 +808,8 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock sum_ofs = jeb->offset + c->sector_size - jeb->free_size; - dbg_summary("writing out data to flash to pos : 0x%08x\n", sum_ofs); + dbg_summary("JFFS2: writing out data to flash to pos : 0x%08x\n", + sum_ofs); ret = jffs2_flash_writev(c, vecs, 2, sum_ofs, &retlen, 0); diff --git a/trunk/fs/jffs2/super.c b/trunk/fs/jffs2/super.c index f9916f312bd8..f2d96b5e64f6 100644 --- a/trunk/fs/jffs2/super.c +++ b/trunk/fs/jffs2/super.c @@ -9,8 +9,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -71,7 +69,7 @@ static void jffs2_write_super(struct super_block *sb) sb->s_dirt = 0; if (!(sb->s_flags & MS_RDONLY)) { - jffs2_dbg(1, "%s()\n", __func__); + D1(printk(KERN_DEBUG "jffs2_write_super()\n")); jffs2_flush_wbuf_gc(c, 0); } @@ -216,8 +214,8 @@ static int jffs2_parse_options(struct jffs2_sb_info *c, char *data) JFFS2_COMPR_MODE_FORCEZLIB; #endif else { - pr_err("Error: unknown compressor \"%s\"\n", - name); + printk(KERN_ERR "JFFS2 Error: unknown compressor \"%s\"", + name); kfree(name); return -EINVAL; } @@ -225,8 +223,8 @@ static int jffs2_parse_options(struct jffs2_sb_info *c, char *data) c->mount_opts.override_compr = true; break; default: - pr_err("Error: unrecognized mount option '%s' or missing value\n", - p); + printk(KERN_ERR "JFFS2 Error: unrecognized mount option '%s' or missing value\n", + p); return -EINVAL; } } @@ -268,9 +266,9 @@ static int jffs2_fill_super(struct super_block *sb, void *data, int silent) struct jffs2_sb_info *c; int ret; - jffs2_dbg(1, "jffs2_get_sb_mtd():" + D1(printk(KERN_DEBUG "jffs2_get_sb_mtd():" " New superblock for device %d (\"%s\")\n", - sb->s_mtd->index, sb->s_mtd->name); + sb->s_mtd->index, sb->s_mtd->name)); c = kzalloc(sizeof(*c), GFP_KERNEL); if (!c) @@ -317,7 +315,7 @@ static void jffs2_put_super (struct super_block *sb) { struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); - jffs2_dbg(2, "%s()\n", __func__); + D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n")); if (sb->s_dirt) jffs2_write_super(sb); @@ -338,7 +336,7 @@ static void jffs2_put_super (struct super_block *sb) kfree(c->inocache_list); jffs2_clear_xattr_subsystem(c); mtd_sync(c->mtd); - jffs2_dbg(1, "%s(): returning\n", __func__); + D1(printk(KERN_DEBUG "jffs2_put_super returning\n")); } static void jffs2_kill_sb(struct super_block *sb) @@ -373,7 +371,7 @@ static int __init init_jffs2_fs(void) BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68); BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32); - pr_info("version 2.2." + printk(KERN_INFO "JFFS2 version 2.2." #ifdef CONFIG_JFFS2_FS_WRITEBUFFER " (NAND)" #endif @@ -388,22 +386,22 @@ static int __init init_jffs2_fs(void) SLAB_MEM_SPREAD), jffs2_i_init_once); if (!jffs2_inode_cachep) { - pr_err("error: Failed to initialise inode cache\n"); + printk(KERN_ERR "JFFS2 error: Failed to initialise inode cache\n"); return -ENOMEM; } ret = jffs2_compressors_init(); if (ret) { - pr_err("error: Failed to initialise compressors\n"); + printk(KERN_ERR "JFFS2 error: Failed to initialise compressors\n"); goto out; } ret = jffs2_create_slab_caches(); if (ret) { - pr_err("error: Failed to initialise slab caches\n"); + printk(KERN_ERR "JFFS2 error: Failed to initialise slab caches\n"); goto out_compressors; } ret = register_filesystem(&jffs2_fs_type); if (ret) { - pr_err("error: Failed to register filesystem\n"); + printk(KERN_ERR "JFFS2 error: Failed to register filesystem\n"); goto out_slab; } return 0; diff --git a/trunk/fs/jffs2/symlink.c b/trunk/fs/jffs2/symlink.c index 6e563332bb24..e3035afb1814 100644 --- a/trunk/fs/jffs2/symlink.c +++ b/trunk/fs/jffs2/symlink.c @@ -9,8 +9,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -49,11 +47,10 @@ static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd) */ if (!p) { - pr_err("%s(): can't find symlink target\n", __func__); + printk(KERN_ERR "jffs2_follow_link(): can't find symlink target\n"); p = ERR_PTR(-EIO); } - jffs2_dbg(1, "%s(): target path is '%s'\n", - __func__, (char *)f->target); + D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->target)); nd_set_link(nd, p); diff --git a/trunk/fs/jffs2/wbuf.c b/trunk/fs/jffs2/wbuf.c index 74d9be19df3f..30e8f47e8a23 100644 --- a/trunk/fs/jffs2/wbuf.c +++ b/trunk/fs/jffs2/wbuf.c @@ -11,8 +11,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -93,7 +91,7 @@ static void jffs2_wbuf_dirties_inode(struct jffs2_sb_info *c, uint32_t ino) new = kmalloc(sizeof(*new), GFP_KERNEL); if (!new) { - jffs2_dbg(1, "No memory to allocate inodirty. Fallback to all considered dirty\n"); + D1(printk(KERN_DEBUG "No memory to allocate inodirty. Fallback to all considered dirty\n")); jffs2_clear_wbuf_ino_list(c); c->wbuf_inodes = &inodirty_nomem; return; @@ -115,20 +113,19 @@ static inline void jffs2_refile_wbuf_blocks(struct jffs2_sb_info *c) list_for_each_safe(this, next, &c->erasable_pending_wbuf_list) { struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); - jffs2_dbg(1, "Removing eraseblock at 0x%08x from erasable_pending_wbuf_list...\n", - jeb->offset); + D1(printk(KERN_DEBUG "Removing eraseblock at 0x%08x from erasable_pending_wbuf_list...\n", jeb->offset)); list_del(this); if ((jiffies + (n++)) & 127) { /* Most of the time, we just erase it immediately. Otherwise we spend ages scanning it on mount, etc. */ - jffs2_dbg(1, "...and adding to erase_pending_list\n"); + D1(printk(KERN_DEBUG "...and adding to erase_pending_list\n")); list_add_tail(&jeb->list, &c->erase_pending_list); c->nr_erasing_blocks++; jffs2_garbage_collect_trigger(c); } else { /* Sometimes, however, we leave it elsewhere so it doesn't get immediately reused, and we spread the load a bit. */ - jffs2_dbg(1, "...and adding to erasable_list\n"); + D1(printk(KERN_DEBUG "...and adding to erasable_list\n")); list_add_tail(&jeb->list, &c->erasable_list); } } @@ -139,7 +136,7 @@ static inline void jffs2_refile_wbuf_blocks(struct jffs2_sb_info *c) static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, int allow_empty) { - jffs2_dbg(1, "About to refile bad block at %08x\n", jeb->offset); + D1(printk("About to refile bad block at %08x\n", jeb->offset)); /* File the existing block on the bad_used_list.... */ if (c->nextblock == jeb) @@ -147,14 +144,12 @@ static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock else /* Not sure this should ever happen... need more coffee */ list_del(&jeb->list); if (jeb->first_node) { - jffs2_dbg(1, "Refiling block at %08x to bad_used_list\n", - jeb->offset); + D1(printk("Refiling block at %08x to bad_used_list\n", jeb->offset)); list_add(&jeb->list, &c->bad_used_list); } else { BUG_ON(allow_empty == REFILE_NOTEMPTY); /* It has to have had some nodes or we couldn't be here */ - jffs2_dbg(1, "Refiling block at %08x to erase_pending_list\n", - jeb->offset); + D1(printk("Refiling block at %08x to erase_pending_list\n", jeb->offset)); list_add(&jeb->list, &c->erase_pending_list); c->nr_erasing_blocks++; jffs2_garbage_collect_trigger(c); @@ -235,12 +230,10 @@ static int jffs2_verify_write(struct jffs2_sb_info *c, unsigned char *buf, ret = mtd_read(c->mtd, ofs, c->wbuf_pagesize, &retlen, c->wbuf_verify); if (ret && ret != -EUCLEAN && ret != -EBADMSG) { - pr_warn("%s(): Read back of page at %08x failed: %d\n", - __func__, c->wbuf_ofs, ret); + printk(KERN_WARNING "jffs2_verify_write(): Read back of page at %08x failed: %d\n", c->wbuf_ofs, ret); return ret; } else if (retlen != c->wbuf_pagesize) { - pr_warn("%s(): Read back of page at %08x gave short read: %zd not %d\n", - __func__, ofs, retlen, c->wbuf_pagesize); + printk(KERN_WARNING "jffs2_verify_write(): Read back of page at %08x gave short read: %zd not %d.\n", ofs, retlen, c->wbuf_pagesize); return -EIO; } if (!memcmp(buf, c->wbuf_verify, c->wbuf_pagesize)) @@ -253,12 +246,12 @@ static int jffs2_verify_write(struct jffs2_sb_info *c, unsigned char *buf, else eccstr = "OK or unused"; - pr_warn("Write verify error (ECC %s) at %08x. Wrote:\n", - eccstr, c->wbuf_ofs); + printk(KERN_WARNING "Write verify error (ECC %s) at %08x. Wrote:\n", + eccstr, c->wbuf_ofs); print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1, c->wbuf, c->wbuf_pagesize, 0); - pr_warn("Read back:\n"); + printk(KERN_WARNING "Read back:\n"); print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1, c->wbuf_verify, c->wbuf_pagesize, 0); @@ -315,7 +308,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) if (!first_raw) { /* All nodes were obsolete. Nothing to recover. */ - jffs2_dbg(1, "No non-obsolete nodes to be recovered. Just filing block bad\n"); + D1(printk(KERN_DEBUG "No non-obsolete nodes to be recovered. Just filing block bad\n")); c->wbuf_len = 0; return; } @@ -338,7 +331,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) buf = kmalloc(end - start, GFP_KERNEL); if (!buf) { - pr_crit("Malloc failure in wbuf recovery. Data loss ensues.\n"); + printk(KERN_CRIT "Malloc failure in wbuf recovery. Data loss ensues.\n"); goto read_failed; } @@ -353,7 +346,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) ret = 0; if (ret || retlen != c->wbuf_ofs - start) { - pr_crit("Old data are already lost in wbuf recovery. Data loss ensues.\n"); + printk(KERN_CRIT "Old data are already lost in wbuf recovery. Data loss ensues.\n"); kfree(buf); buf = NULL; @@ -387,7 +380,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) /* ... and get an allocation of space from a shiny new block instead */ ret = jffs2_reserve_space_gc(c, end-start, &len, JFFS2_SUMMARY_NOSUM_SIZE); if (ret) { - pr_warn("Failed to allocate space for wbuf recovery. Data loss ensues.\n"); + printk(KERN_WARNING "Failed to allocate space for wbuf recovery. Data loss ensues.\n"); kfree(buf); return; } @@ -397,7 +390,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, nr_refile); if (ret) { - pr_warn("Failed to allocate node refs for wbuf recovery. Data loss ensues.\n"); + printk(KERN_WARNING "Failed to allocate node refs for wbuf recovery. Data loss ensues.\n"); kfree(buf); return; } @@ -413,13 +406,13 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) unsigned char *rewrite_buf = buf?:c->wbuf; uint32_t towrite = (end-start) - ((end-start)%c->wbuf_pagesize); - jffs2_dbg(1, "Write 0x%x bytes at 0x%08x in wbuf recover\n", - towrite, ofs); + D1(printk(KERN_DEBUG "Write 0x%x bytes at 0x%08x in wbuf recover\n", + towrite, ofs)); #ifdef BREAKMEHEADER static int breakme; if (breakme++ == 20) { - pr_notice("Faking write error at 0x%08x\n", ofs); + printk(KERN_NOTICE "Faking write error at 0x%08x\n", ofs); breakme = 0; mtd_write(c->mtd, ofs, towrite, &retlen, brokenbuf); ret = -EIO; @@ -430,7 +423,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) if (ret || retlen != towrite || jffs2_verify_write(c, rewrite_buf, ofs)) { /* Argh. We tried. Really we did. */ - pr_crit("Recovery of wbuf failed due to a second write error\n"); + printk(KERN_CRIT "Recovery of wbuf failed due to a second write error\n"); kfree(buf); if (retlen) @@ -438,7 +431,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) return; } - pr_notice("Recovery of wbuf succeeded to %08x\n", ofs); + printk(KERN_NOTICE "Recovery of wbuf succeeded to %08x\n", ofs); c->wbuf_len = (end - start) - towrite; c->wbuf_ofs = ofs + towrite; @@ -466,8 +459,8 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) struct jffs2_raw_node_ref **adjust_ref = NULL; struct jffs2_inode_info *f = NULL; - jffs2_dbg(1, "Refiling block of %08x at %08x(%d) to %08x\n", - rawlen, ref_offset(raw), ref_flags(raw), ofs); + D1(printk(KERN_DEBUG "Refiling block of %08x at %08x(%d) to %08x\n", + rawlen, ref_offset(raw), ref_flags(raw), ofs)); ic = jffs2_raw_ref_to_ic(raw); @@ -547,8 +540,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) /* Fix up the original jeb now it's on the bad_list */ if (first_raw == jeb->first_node) { - jffs2_dbg(1, "Failing block at %08x is now empty. Moving to erase_pending_list\n", - jeb->offset); + D1(printk(KERN_DEBUG "Failing block at %08x is now empty. Moving to erase_pending_list\n", jeb->offset)); list_move(&jeb->list, &c->erase_pending_list); c->nr_erasing_blocks++; jffs2_garbage_collect_trigger(c); @@ -562,8 +554,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) spin_unlock(&c->erase_completion_lock); - jffs2_dbg(1, "wbuf recovery completed OK. wbuf_ofs 0x%08x, len 0x%x\n", - c->wbuf_ofs, c->wbuf_len); + D1(printk(KERN_DEBUG "wbuf recovery completed OK. wbuf_ofs 0x%08x, len 0x%x\n", c->wbuf_ofs, c->wbuf_len)); } @@ -588,7 +579,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad) return 0; if (!mutex_is_locked(&c->alloc_sem)) { - pr_crit("jffs2_flush_wbuf() called with alloc_sem not locked!\n"); + printk(KERN_CRIT "jffs2_flush_wbuf() called with alloc_sem not locked!\n"); BUG(); } @@ -626,7 +617,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad) #ifdef BREAKME static int breakme; if (breakme++ == 20) { - pr_notice("Faking write error at 0x%08x\n", c->wbuf_ofs); + printk(KERN_NOTICE "Faking write error at 0x%08x\n", c->wbuf_ofs); breakme = 0; mtd_write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, brokenbuf); @@ -638,11 +629,11 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad) &retlen, c->wbuf); if (ret) { - pr_warn("jffs2_flush_wbuf(): Write failed with %d\n", ret); + printk(KERN_WARNING "jffs2_flush_wbuf(): Write failed with %d\n", ret); goto wfail; } else if (retlen != c->wbuf_pagesize) { - pr_warn("jffs2_flush_wbuf(): Write was short: %zd instead of %d\n", - retlen, c->wbuf_pagesize); + printk(KERN_WARNING "jffs2_flush_wbuf(): Write was short: %zd instead of %d\n", + retlen, c->wbuf_pagesize); ret = -EIO; goto wfail; } else if ((ret = jffs2_verify_write(c, c->wbuf, c->wbuf_ofs))) { @@ -656,18 +647,17 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad) if (pad) { uint32_t waste = c->wbuf_pagesize - c->wbuf_len; - jffs2_dbg(1, "jffs2_flush_wbuf() adjusting free_size of %sblock at %08x\n", - (wbuf_jeb == c->nextblock) ? "next" : "", - wbuf_jeb->offset); + D1(printk(KERN_DEBUG "jffs2_flush_wbuf() adjusting free_size of %sblock at %08x\n", + (wbuf_jeb==c->nextblock)?"next":"", wbuf_jeb->offset)); /* wbuf_pagesize - wbuf_len is the amount of space that's to be padded. If there is less free space in the block than that, something screwed up */ if (wbuf_jeb->free_size < waste) { - pr_crit("jffs2_flush_wbuf(): Accounting error. wbuf at 0x%08x has 0x%03x bytes, 0x%03x left.\n", - c->wbuf_ofs, c->wbuf_len, waste); - pr_crit("jffs2_flush_wbuf(): But free_size for block at 0x%08x is only 0x%08x\n", - wbuf_jeb->offset, wbuf_jeb->free_size); + printk(KERN_CRIT "jffs2_flush_wbuf(): Accounting error. wbuf at 0x%08x has 0x%03x bytes, 0x%03x left.\n", + c->wbuf_ofs, c->wbuf_len, waste); + printk(KERN_CRIT "jffs2_flush_wbuf(): But free_size for block at 0x%08x is only 0x%08x\n", + wbuf_jeb->offset, wbuf_jeb->free_size); BUG(); } @@ -704,14 +694,14 @@ int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino) uint32_t old_wbuf_len; int ret = 0; - jffs2_dbg(1, "jffs2_flush_wbuf_gc() called for ino #%u...\n", ino); + D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() called for ino #%u...\n", ino)); if (!c->wbuf) return 0; mutex_lock(&c->alloc_sem); if (!jffs2_wbuf_pending_for_ino(c, ino)) { - jffs2_dbg(1, "Ino #%d not pending in wbuf. Returning\n", ino); + D1(printk(KERN_DEBUG "Ino #%d not pending in wbuf. Returning\n", ino)); mutex_unlock(&c->alloc_sem); return 0; } @@ -721,8 +711,7 @@ int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino) if (c->unchecked_size) { /* GC won't make any progress for a while */ - jffs2_dbg(1, "%s(): padding. Not finished checking\n", - __func__); + D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() padding. Not finished checking\n")); down_write(&c->wbuf_sem); ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING); /* retry flushing wbuf in case jffs2_wbuf_recover @@ -735,7 +724,7 @@ int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino) mutex_unlock(&c->alloc_sem); - jffs2_dbg(1, "%s(): calls gc pass\n", __func__); + D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() calls gc pass\n")); ret = jffs2_garbage_collect_pass(c); if (ret) { @@ -753,7 +742,7 @@ int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino) mutex_lock(&c->alloc_sem); } - jffs2_dbg(1, "%s(): ends...\n", __func__); + D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() ends...\n")); mutex_unlock(&c->alloc_sem); return ret; @@ -822,8 +811,9 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, if (SECTOR_ADDR(to) != SECTOR_ADDR(c->wbuf_ofs)) { /* It's a write to a new block */ if (c->wbuf_len) { - jffs2_dbg(1, "%s(): to 0x%lx causes flush of wbuf at 0x%08x\n", - __func__, (unsigned long)to, c->wbuf_ofs); + D1(printk(KERN_DEBUG "jffs2_flash_writev() to 0x%lx " + "causes flush of wbuf at 0x%08x\n", + (unsigned long)to, c->wbuf_ofs)); ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT); if (ret) goto outerr; @@ -835,11 +825,11 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, if (to != PAD(c->wbuf_ofs + c->wbuf_len)) { /* We're not writing immediately after the writebuffer. Bad. */ - pr_crit("%s(): Non-contiguous write to %08lx\n", - __func__, (unsigned long)to); + printk(KERN_CRIT "jffs2_flash_writev(): Non-contiguous write " + "to %08lx\n", (unsigned long)to); if (c->wbuf_len) - pr_crit("wbuf was previously %08x-%08x\n", - c->wbuf_ofs, c->wbuf_ofs + c->wbuf_len); + printk(KERN_CRIT "wbuf was previously %08x-%08x\n", + c->wbuf_ofs, c->wbuf_ofs+c->wbuf_len); BUG(); } @@ -967,8 +957,8 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re if ( (ret == -EBADMSG || ret == -EUCLEAN) && (*retlen == len) ) { if (ret == -EBADMSG) - pr_warn("mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n", - len, ofs); + printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx)" + " returned ECC error\n", len, ofs); /* * We have the raw data without ECC correction in the buffer, * maybe we are lucky and all data or parts are correct. We @@ -1044,8 +1034,9 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c, ret = mtd_read_oob(c->mtd, jeb->offset, &ops); if (ret || ops.oobretlen != ops.ooblen) { - pr_err("cannot read OOB for EB at %08x, requested %zd bytes, read %zd bytes, error %d\n", - jeb->offset, ops.ooblen, ops.oobretlen, ret); + printk(KERN_ERR "cannot read OOB for EB at %08x, requested %zd" + " bytes, read %zd bytes, error %d\n", + jeb->offset, ops.ooblen, ops.oobretlen, ret); if (!ret) ret = -EIO; return ret; @@ -1057,8 +1048,8 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c, continue; if (ops.oobbuf[i] != 0xFF) { - jffs2_dbg(2, "Found %02x at %x in OOB for " - "%08x\n", ops.oobbuf[i], i, jeb->offset); + D2(printk(KERN_DEBUG "Found %02x at %x in OOB for " + "%08x\n", ops.oobbuf[i], i, jeb->offset)); return 1; } } @@ -1086,8 +1077,9 @@ int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, ret = mtd_read_oob(c->mtd, jeb->offset, &ops); if (ret || ops.oobretlen != ops.ooblen) { - pr_err("cannot read OOB for EB at %08x, requested %zd bytes, read %zd bytes, error %d\n", - jeb->offset, ops.ooblen, ops.oobretlen, ret); + printk(KERN_ERR "cannot read OOB for EB at %08x, requested %zd" + " bytes, read %zd bytes, error %d\n", + jeb->offset, ops.ooblen, ops.oobretlen, ret); if (!ret) ret = -EIO; return ret; @@ -1111,8 +1103,9 @@ int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, ret = mtd_write_oob(c->mtd, jeb->offset, &ops); if (ret || ops.oobretlen != ops.ooblen) { - pr_err("cannot write OOB for EB at %08x, requested %zd bytes, read %zd bytes, error %d\n", - jeb->offset, ops.ooblen, ops.oobretlen, ret); + printk(KERN_ERR "cannot write OOB for EB at %08x, requested %zd" + " bytes, read %zd bytes, error %d\n", + jeb->offset, ops.ooblen, ops.oobretlen, ret); if (!ret) ret = -EIO; return ret; @@ -1137,12 +1130,11 @@ int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock * if( ++jeb->bad_count < MAX_ERASE_FAILURES) return 0; - pr_warn("marking eraseblock at %08x as bad\n", bad_offset); + printk(KERN_WARNING "JFFS2: marking eraseblock at %08x\n as bad", bad_offset); ret = mtd_block_markbad(c->mtd, bad_offset); if (ret) { - jffs2_dbg(1, "%s(): Write failed for block at %08x: error %d\n", - __func__, jeb->offset, ret); + D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Write failed for block at %08x: error %d\n", jeb->offset, ret)); return ret; } return 1; @@ -1159,11 +1151,11 @@ int jffs2_nand_flash_setup(struct jffs2_sb_info *c) c->cleanmarker_size = 0; if (!oinfo || oinfo->oobavail == 0) { - pr_err("inconsistent device description\n"); + printk(KERN_ERR "inconsistent device description\n"); return -EINVAL; } - jffs2_dbg(1, "using OOB on NAND\n"); + D1(printk(KERN_DEBUG "JFFS2 using OOB on NAND\n")); c->oobavail = oinfo->oobavail; @@ -1230,7 +1222,7 @@ int jffs2_dataflash_setup(struct jffs2_sb_info *c) { if ((c->flash_size % c->sector_size) != 0) { c->flash_size = (c->flash_size / c->sector_size) * c->sector_size; - pr_warn("flash size adjusted to %dKiB\n", c->flash_size); + printk(KERN_WARNING "JFFS2 flash size adjusted to %dKiB\n", c->flash_size); }; c->wbuf_ofs = 0xFFFFFFFF; @@ -1247,8 +1239,7 @@ int jffs2_dataflash_setup(struct jffs2_sb_info *c) { } #endif - pr_info("write-buffering enabled buffer (%d) erasesize (%d)\n", - c->wbuf_pagesize, c->sector_size); + printk(KERN_INFO "JFFS2 write-buffering enabled buffer (%d) erasesize (%d)\n", c->wbuf_pagesize, c->sector_size); return 0; } @@ -1306,8 +1297,7 @@ int jffs2_ubivol_setup(struct jffs2_sb_info *c) { if (!c->wbuf) return -ENOMEM; - pr_info("write-buffering enabled buffer (%d) erasesize (%d)\n", - c->wbuf_pagesize, c->sector_size); + printk(KERN_INFO "JFFS2 write-buffering enabled buffer (%d) erasesize (%d)\n", c->wbuf_pagesize, c->sector_size); return 0; } diff --git a/trunk/fs/jffs2/write.c b/trunk/fs/jffs2/write.c index b634de4c8101..30d175b6d290 100644 --- a/trunk/fs/jffs2/write.c +++ b/trunk/fs/jffs2/write.c @@ -9,8 +9,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -38,7 +36,7 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, f->inocache->state = INO_STATE_PRESENT; jffs2_add_ino_cache(c, f->inocache); - jffs2_dbg(1, "%s(): Assigned ino# %d\n", __func__, f->inocache->ino); + D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino)); ri->ino = cpu_to_je32(f->inocache->ino); ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); @@ -70,7 +68,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 unsigned long cnt = 2; D1(if(je32_to_cpu(ri->hdr_crc) != crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)) { - pr_crit("Eep. CRC not correct in jffs2_write_dnode()\n"); + printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dnode()\n"); BUG(); } ); @@ -80,9 +78,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 vecs[1].iov_len = datalen; if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) { - pr_warn("%s(): ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", - __func__, je32_to_cpu(ri->totlen), - sizeof(*ri), datalen); + printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen); } fn = jffs2_alloc_full_dnode(); @@ -99,9 +95,9 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) { BUG_ON(!retried); - jffs2_dbg(1, "%s(): dnode_version %d, highest version %d -> updating dnode\n", - __func__, - je32_to_cpu(ri->version), f->highest_version); + D1(printk(KERN_DEBUG "jffs2_write_dnode : dnode_version %d, " + "highest version %d -> updating dnode\n", + je32_to_cpu(ri->version), f->highest_version)); ri->version = cpu_to_je32(++f->highest_version); ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); } @@ -110,8 +106,8 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 (alloc_mode==ALLOC_GC)?0:f->inocache->ino); if (ret || (retlen != sizeof(*ri) + datalen)) { - pr_notice("Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", - sizeof(*ri) + datalen, flash_ofs, ret, retlen); + printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", + sizeof(*ri)+datalen, flash_ofs, ret, retlen); /* Mark the space as dirtied */ if (retlen) { @@ -122,8 +118,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 this node */ jffs2_add_physical_node_ref(c, flash_ofs | REF_OBSOLETE, PAD(sizeof(*ri)+datalen), NULL); } else { - pr_notice("Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", - flash_ofs); + printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", flash_ofs); } if (!retried && alloc_mode != ALLOC_NORETRY) { /* Try to reallocate space and retry */ @@ -132,7 +127,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 retried = 1; - jffs2_dbg(1, "Retrying failed write.\n"); + D1(printk(KERN_DEBUG "Retrying failed write.\n")); jffs2_dbg_acct_sanity_check(c,jeb); jffs2_dbg_acct_paranoia_check(c, jeb); @@ -152,16 +147,14 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 if (!ret) { flash_ofs = write_ofs(c); - jffs2_dbg(1, "Allocated space at 0x%08x to retry failed write.\n", - flash_ofs); + D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); jffs2_dbg_acct_sanity_check(c,jeb); jffs2_dbg_acct_paranoia_check(c, jeb); goto retry; } - jffs2_dbg(1, "Failed to allocate space to retry failed write: %d!\n", - ret); + D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); } /* Release the full_dnode which is now useless, and return */ jffs2_free_full_dnode(fn); @@ -190,10 +183,10 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2 fn->size = je32_to_cpu(ri->dsize); fn->frags = 0; - jffs2_dbg(1, "jffs2_write_dnode wrote node at 0x%08x(%d) with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n", + D1(printk(KERN_DEBUG "jffs2_write_dnode wrote node at 0x%08x(%d) with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n", flash_ofs & ~3, flash_ofs & 3, je32_to_cpu(ri->dsize), je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc), - je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen)); + je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen))); if (retried) { jffs2_dbg_acct_sanity_check(c,NULL); @@ -213,23 +206,22 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff int retried = 0; int ret; - jffs2_dbg(1, "%s(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n", - __func__, + D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n", je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino), - je32_to_cpu(rd->name_crc)); + je32_to_cpu(rd->name_crc))); D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) { - pr_crit("Eep. CRC not correct in jffs2_write_dirent()\n"); + printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n"); BUG(); }); if (strnlen(name, namelen) != namelen) { /* This should never happen, but seems to have done on at least one occasion: https://dev.laptop.org/ticket/4184 */ - pr_crit("Error in jffs2_write_dirent() -- name contains zero bytes!\n"); - pr_crit("Directory inode #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x\n", - je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino), - je32_to_cpu(rd->name_crc)); + printk(KERN_CRIT "Error in jffs2_write_dirent() -- name contains zero bytes!\n"); + printk(KERN_CRIT "Directory inode #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x\n", + je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino), + je32_to_cpu(rd->name_crc)); WARN_ON(1); return ERR_PTR(-EIO); } @@ -257,9 +249,9 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(rd->version) < f->highest_version)) { BUG_ON(!retried); - jffs2_dbg(1, "%s(): dirent_version %d, highest version %d -> updating dirent\n", - __func__, - je32_to_cpu(rd->version), f->highest_version); + D1(printk(KERN_DEBUG "jffs2_write_dirent : dirent_version %d, " + "highest version %d -> updating dirent\n", + je32_to_cpu(rd->version), f->highest_version)); rd->version = cpu_to_je32(++f->highest_version); fd->version = je32_to_cpu(rd->version); rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); @@ -268,14 +260,13 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen, (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino)); if (ret || (retlen != sizeof(*rd) + namelen)) { - pr_notice("Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", - sizeof(*rd) + namelen, flash_ofs, ret, retlen); + printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", + sizeof(*rd)+namelen, flash_ofs, ret, retlen); /* Mark the space as dirtied */ if (retlen) { jffs2_add_physical_node_ref(c, flash_ofs | REF_OBSOLETE, PAD(sizeof(*rd)+namelen), NULL); } else { - pr_notice("Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", - flash_ofs); + printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", flash_ofs); } if (!retried) { /* Try to reallocate space and retry */ @@ -284,7 +275,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff retried = 1; - jffs2_dbg(1, "Retrying failed write.\n"); + D1(printk(KERN_DEBUG "Retrying failed write.\n")); jffs2_dbg_acct_sanity_check(c,jeb); jffs2_dbg_acct_paranoia_check(c, jeb); @@ -304,14 +295,12 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff if (!ret) { flash_ofs = write_ofs(c); - jffs2_dbg(1, "Allocated space at 0x%08x to retry failed write\n", - flash_ofs); + D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); jffs2_dbg_acct_sanity_check(c,jeb); jffs2_dbg_acct_paranoia_check(c, jeb); goto retry; } - jffs2_dbg(1, "Failed to allocate space to retry failed write: %d!\n", - ret); + D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); } /* Release the full_dnode which is now useless, and return */ jffs2_free_full_dirent(fd); @@ -344,8 +333,8 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, int ret = 0; uint32_t writtenlen = 0; - jffs2_dbg(1, "%s(): Ino #%u, ofs 0x%x, len 0x%x\n", - __func__, f->inocache->ino, offset, writelen); + D1(printk(KERN_DEBUG "jffs2_write_inode_range(): Ino #%u, ofs 0x%x, len 0x%x\n", + f->inocache->ino, offset, writelen)); while(writelen) { struct jffs2_full_dnode *fn; @@ -356,13 +345,12 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, int retried = 0; retry: - jffs2_dbg(2, "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", - writelen, offset); + D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset)); ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); if (ret) { - jffs2_dbg(1, "jffs2_reserve_space returned %d\n", ret); + D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret)); break; } mutex_lock(&f->sem); @@ -398,7 +386,7 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, if (!retried) { /* Write error to be retried */ retried = 1; - jffs2_dbg(1, "Retrying node write in jffs2_write_inode_range()\n"); + D1(printk(KERN_DEBUG "Retrying node write in jffs2_write_inode_range()\n")); goto retry; } break; @@ -411,8 +399,7 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, } if (ret) { /* Eep */ - jffs2_dbg(1, "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n", - ret); + D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n", ret)); jffs2_mark_node_obsolete(c, fn->raw); jffs2_free_full_dnode(fn); @@ -423,11 +410,11 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, mutex_unlock(&f->sem); jffs2_complete_reservation(c); if (!datalen) { - pr_warn("Eep. We didn't actually write any data in jffs2_write_inode_range()\n"); + printk(KERN_WARNING "Eep. We didn't actually write any data in jffs2_write_inode_range()\n"); ret = -EIO; break; } - jffs2_dbg(1, "increasing writtenlen by %d\n", datalen); + D1(printk(KERN_DEBUG "increasing writtenlen by %d\n", datalen)); writtenlen += datalen; offset += datalen; writelen -= datalen; @@ -452,7 +439,7 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, */ ret = jffs2_reserve_space(c, sizeof(*ri), &alloclen, ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); - jffs2_dbg(1, "%s(): reserved 0x%x bytes\n", __func__, alloclen); + D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen)); if (ret) return ret; @@ -463,11 +450,11 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, fn = jffs2_write_dnode(c, f, ri, NULL, 0, ALLOC_NORMAL); - jffs2_dbg(1, "jffs2_do_create created file with mode 0x%x\n", - jemode_to_cpu(ri->mode)); + D1(printk(KERN_DEBUG "jffs2_do_create created file with mode 0x%x\n", + jemode_to_cpu(ri->mode))); if (IS_ERR(fn)) { - jffs2_dbg(1, "jffs2_write_dnode() failed\n"); + D1(printk(KERN_DEBUG "jffs2_write_dnode() failed\n")); /* Eeek. Wave bye bye */ mutex_unlock(&f->sem); jffs2_complete_reservation(c); @@ -493,7 +480,7 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, if (ret) { /* Eep. */ - jffs2_dbg(1, "jffs2_reserve_space() for dirent failed\n"); + D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n")); return ret; } @@ -610,8 +597,8 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, !memcmp(fd->name, name, namelen) && !fd->name[namelen]) { - jffs2_dbg(1, "Marking old dirent node (ino #%u) @%08x obsolete\n", - fd->ino, ref_offset(fd->raw)); + D1(printk(KERN_DEBUG "Marking old dirent node (ino #%u) @%08x obsolete\n", + fd->ino, ref_offset(fd->raw))); jffs2_mark_node_obsolete(c, fd->raw); /* We don't want to remove it from the list immediately, because that screws up getdents()/seek() semantics even @@ -640,13 +627,11 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, dead_f->dents = fd->next; if (fd->ino) { - pr_warn("Deleting inode #%u with active dentry \"%s\"->ino #%u\n", - dead_f->inocache->ino, - fd->name, fd->ino); + printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n", + dead_f->inocache->ino, fd->name, fd->ino); } else { - jffs2_dbg(1, "Removing deletion dirent for \"%s\" from dir ino #%u\n", - fd->name, - dead_f->inocache->ino); + D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", + fd->name, dead_f->inocache->ino)); } if (fd->raw) jffs2_mark_node_obsolete(c, fd->raw); diff --git a/trunk/fs/jffs2/xattr.c b/trunk/fs/jffs2/xattr.c index b55b803eddcb..3e93cdd19005 100644 --- a/trunk/fs/jffs2/xattr.c +++ b/trunk/fs/jffs2/xattr.c @@ -9,8 +9,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include diff --git a/trunk/fs/libfs.c b/trunk/fs/libfs.c index 18d08f5db53a..4a0d1f06da57 100644 --- a/trunk/fs/libfs.c +++ b/trunk/fs/libfs.c @@ -264,13 +264,6 @@ struct dentry *mount_pseudo(struct file_system_type *fs_type, char *name, return ERR_PTR(-ENOMEM); } -int simple_open(struct inode *inode, struct file *file) -{ - if (inode->i_private) - file->private_data = inode->i_private; - return 0; -} - int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) { struct inode *inode = old_dentry->d_inode; @@ -529,7 +522,6 @@ int simple_fill_super(struct super_block *s, unsigned long magic, return 0; out: d_genocide(root); - shrink_dcache_parent(root); dput(root); return -ENOMEM; } @@ -992,7 +984,6 @@ EXPORT_SYMBOL(simple_dir_operations); EXPORT_SYMBOL(simple_empty); EXPORT_SYMBOL(simple_fill_super); EXPORT_SYMBOL(simple_getattr); -EXPORT_SYMBOL(simple_open); EXPORT_SYMBOL(simple_link); EXPORT_SYMBOL(simple_lookup); EXPORT_SYMBOL(simple_pin_fs); diff --git a/trunk/fs/lockd/clnt4xdr.c b/trunk/fs/lockd/clnt4xdr.c index 13ad1539fbf2..3ddcbb1c0a43 100644 --- a/trunk/fs/lockd/clnt4xdr.c +++ b/trunk/fs/lockd/clnt4xdr.c @@ -241,7 +241,7 @@ static int decode_nlm4_stat(struct xdr_stream *xdr, __be32 *stat) p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) goto out_overflow; - if (unlikely(ntohl(*p) > ntohl(nlm4_failed))) + if (unlikely(*p > nlm4_failed)) goto out_bad_xdr; *stat = *p; return 0; diff --git a/trunk/fs/lockd/clntxdr.c b/trunk/fs/lockd/clntxdr.c index d269ada7670e..3d35e3e80c1c 100644 --- a/trunk/fs/lockd/clntxdr.c +++ b/trunk/fs/lockd/clntxdr.c @@ -236,7 +236,7 @@ static int decode_nlm_stat(struct xdr_stream *xdr, p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) goto out_overflow; - if (unlikely(ntohl(*p) > ntohl(nlm_lck_denied_grace_period))) + if (unlikely(*p > nlm_lck_denied_grace_period)) goto out_enum; *stat = *p; return 0; diff --git a/trunk/fs/locks.c b/trunk/fs/locks.c index 0d68f1f81799..637694bf3a03 100644 --- a/trunk/fs/locks.c +++ b/trunk/fs/locks.c @@ -510,13 +510,12 @@ static void __locks_delete_block(struct file_lock *waiter) /* */ -void locks_delete_block(struct file_lock *waiter) +static void locks_delete_block(struct file_lock *waiter) { lock_flocks(); __locks_delete_block(waiter); unlock_flocks(); } -EXPORT_SYMBOL(locks_delete_block); /* Insert waiter into blocker's block list. * We use a circular list so that processes can be easily woken up in diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index c42791914f82..e615ff37e27d 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -1054,65 +1054,53 @@ static void follow_dotdot(struct nameidata *nd) } /* - * This looks up the name in dcache, possibly revalidates the old dentry and - * allocates a new one if not found or not valid. In the need_lookup argument - * returns whether i_op->lookup is necessary. - * - * dir->d_inode->i_mutex must be held + * Allocate a dentry with name and parent, and perform a parent + * directory ->lookup on it. Returns the new dentry, or ERR_PTR + * on error. parent->d_inode->i_mutex must be held. d_lookup must + * have verified that no child exists while under i_mutex. */ -static struct dentry *lookup_dcache(struct qstr *name, struct dentry *dir, - struct nameidata *nd, bool *need_lookup) +static struct dentry *d_alloc_and_lookup(struct dentry *parent, + struct qstr *name, struct nameidata *nd) { + struct inode *inode = parent->d_inode; struct dentry *dentry; - int error; + struct dentry *old; - *need_lookup = false; - dentry = d_lookup(dir, name); - if (dentry) { - if (d_need_lookup(dentry)) { - *need_lookup = true; - } else if (dentry->d_flags & DCACHE_OP_REVALIDATE) { - error = d_revalidate(dentry, nd); - if (unlikely(error <= 0)) { - if (error < 0) { - dput(dentry); - return ERR_PTR(error); - } else if (!d_invalidate(dentry)) { - dput(dentry); - dentry = NULL; - } - } - } - } + /* Don't create child dentry for a dead directory. */ + if (unlikely(IS_DEADDIR(inode))) + return ERR_PTR(-ENOENT); - if (!dentry) { - dentry = d_alloc(dir, name); - if (unlikely(!dentry)) - return ERR_PTR(-ENOMEM); + dentry = d_alloc(parent, name); + if (unlikely(!dentry)) + return ERR_PTR(-ENOMEM); - *need_lookup = true; + old = inode->i_op->lookup(inode, dentry, nd); + if (unlikely(old)) { + dput(dentry); + dentry = old; } return dentry; } /* - * Call i_op->lookup on the dentry. The dentry must be negative but may be - * hashed if it was pouplated with DCACHE_NEED_LOOKUP. - * - * dir->d_inode->i_mutex must be held + * We already have a dentry, but require a lookup to be performed on the parent + * directory to fill in d_inode. Returns the new dentry, or ERR_PTR on error. + * parent->d_inode->i_mutex must be held. d_lookup must have verified that no + * child exists while under i_mutex. */ -static struct dentry *lookup_real(struct inode *dir, struct dentry *dentry, - struct nameidata *nd) +static struct dentry *d_inode_lookup(struct dentry *parent, struct dentry *dentry, + struct nameidata *nd) { + struct inode *inode = parent->d_inode; struct dentry *old; /* Don't create child dentry for a dead directory. */ - if (unlikely(IS_DEADDIR(dir))) { + if (unlikely(IS_DEADDIR(inode))) { dput(dentry); return ERR_PTR(-ENOENT); } - old = dir->i_op->lookup(dir, dentry, nd); + old = inode->i_op->lookup(inode, dentry, nd); if (unlikely(old)) { dput(dentry); dentry = old; @@ -1120,19 +1108,6 @@ static struct dentry *lookup_real(struct inode *dir, struct dentry *dentry, return dentry; } -static struct dentry *__lookup_hash(struct qstr *name, - struct dentry *base, struct nameidata *nd) -{ - bool need_lookup; - struct dentry *dentry; - - dentry = lookup_dcache(name, base, nd, &need_lookup); - if (!need_lookup) - return dentry; - - return lookup_real(base->d_inode, dentry, nd); -} - /* * It's more convoluted than I'd like it to be, but... it's still fairly * small and for now I'd prefer to have fast path as straight as possible. @@ -1164,8 +1139,6 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, return -ECHILD; nd->seq = seq; - if (unlikely(d_need_lookup(dentry))) - goto unlazy; if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) { status = d_revalidate(dentry, nd); if (unlikely(status <= 0)) { @@ -1174,6 +1147,8 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, goto unlazy; } } + if (unlikely(d_need_lookup(dentry))) + goto unlazy; path->mnt = mnt; path->dentry = dentry; if (unlikely(!__follow_mount_rcu(nd, path, inode))) @@ -1188,14 +1163,38 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, dentry = __d_lookup(parent, name); } - if (unlikely(!dentry)) - goto need_lookup; - - if (unlikely(d_need_lookup(dentry))) { + if (dentry && unlikely(d_need_lookup(dentry))) { dput(dentry); - goto need_lookup; + dentry = NULL; + } +retry: + if (unlikely(!dentry)) { + struct inode *dir = parent->d_inode; + BUG_ON(nd->inode != dir); + + mutex_lock(&dir->i_mutex); + dentry = d_lookup(parent, name); + if (likely(!dentry)) { + dentry = d_alloc_and_lookup(parent, name, nd); + if (IS_ERR(dentry)) { + mutex_unlock(&dir->i_mutex); + return PTR_ERR(dentry); + } + /* known good */ + need_reval = 0; + status = 1; + } else if (unlikely(d_need_lookup(dentry))) { + dentry = d_inode_lookup(parent, dentry, nd); + if (IS_ERR(dentry)) { + mutex_unlock(&dir->i_mutex); + return PTR_ERR(dentry); + } + /* known good */ + need_reval = 0; + status = 1; + } + mutex_unlock(&dir->i_mutex); } - if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE) && need_reval) status = d_revalidate(dentry, nd); if (unlikely(status <= 0)) { @@ -1205,10 +1204,12 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, } if (!d_invalidate(dentry)) { dput(dentry); - goto need_lookup; + dentry = NULL; + need_reval = 1; + goto retry; } } -done: + path->mnt = mnt; path->dentry = dentry; err = follow_managed(path, nd->flags); @@ -1220,16 +1221,6 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, nd->flags |= LOOKUP_JUMPED; *inode = path->dentry->d_inode; return 0; - -need_lookup: - BUG_ON(nd->inode != parent->d_inode); - - mutex_lock(&parent->d_inode->i_mutex); - dentry = __lookup_hash(name, parent, nd); - mutex_unlock(&parent->d_inode->i_mutex); - if (IS_ERR(dentry)) - return PTR_ERR(dentry); - goto done; } static inline int may_lookup(struct nameidata *nd) @@ -1407,10 +1398,19 @@ static inline int can_lookup(struct inode *inode) */ #ifdef CONFIG_DCACHE_WORD_ACCESS -#include - #ifdef CONFIG_64BIT +/* + * Jan Achrenius on G+: microoptimized version of + * the simpler "(mask & ONEBYTES) * ONEBYTES >> 56" + * that works for the bytemasks without having to + * mask them first. + */ +static inline long count_masked_bytes(unsigned long mask) +{ + return mask*0x0001020304050608ul >> 56; +} + static inline unsigned int fold_hash(unsigned long hash) { hash += hash >> (8*sizeof(int)); @@ -1419,6 +1419,15 @@ static inline unsigned int fold_hash(unsigned long hash) #else /* 32-bit case */ +/* Carl Chatfield / Jan Achrenius G+ version for 32-bit */ +static inline long count_masked_bytes(long mask) +{ + /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */ + long a = (0x0ff0001+mask) >> 23; + /* Fix the 1 for 00 case */ + return a & mask; +} + #define fold_hash(x) (x) #endif @@ -1429,7 +1438,7 @@ unsigned int full_name_hash(const unsigned char *name, unsigned int len) unsigned long hash = 0; for (;;) { - a = load_unaligned_zeropad(name); + a = *(unsigned long *)name; if (len < sizeof(unsigned long)) break; hash += a; @@ -1446,6 +1455,17 @@ unsigned int full_name_hash(const unsigned char *name, unsigned int len) } EXPORT_SYMBOL(full_name_hash); +#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x)) +#define ONEBYTES REPEAT_BYTE(0x01) +#define SLASHBYTES REPEAT_BYTE('/') +#define HIGHBITS REPEAT_BYTE(0x80) + +/* Return the high bit set in the first byte that is a zero */ +static inline unsigned long has_zero(unsigned long a) +{ + return ((a - ONEBYTES) & ~a) & HIGHBITS; +} + /* * Calculate the length and hash of the path component, and * return the length of the component; @@ -1459,9 +1479,9 @@ static inline unsigned long hash_name(const char *name, unsigned int *hashp) do { hash = (hash + a) * 9; len += sizeof(unsigned long); - a = load_unaligned_zeropad(name+len); + a = *(unsigned long *)(name+len); /* Do we have any NUL or '/' bytes in this word? */ - mask = has_zero(a) | has_zero(a ^ REPEAT_BYTE('/')); + mask = has_zero(a) | has_zero(a ^ SLASHBYTES); } while (!mask); /* The mask *below* the first high bit set */ @@ -1826,6 +1846,59 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, return err; } +static struct dentry *__lookup_hash(struct qstr *name, + struct dentry *base, struct nameidata *nd) +{ + struct inode *inode = base->d_inode; + struct dentry *dentry; + int err; + + err = inode_permission(inode, MAY_EXEC); + if (err) + return ERR_PTR(err); + + /* + * Don't bother with __d_lookup: callers are for creat as + * well as unlink, so a lot of the time it would cost + * a double lookup. + */ + dentry = d_lookup(base, name); + + if (dentry && d_need_lookup(dentry)) { + /* + * __lookup_hash is called with the parent dir's i_mutex already + * held, so we are good to go here. + */ + dentry = d_inode_lookup(base, dentry, nd); + if (IS_ERR(dentry)) + return dentry; + } + + if (dentry && (dentry->d_flags & DCACHE_OP_REVALIDATE)) { + int status = d_revalidate(dentry, nd); + if (unlikely(status <= 0)) { + /* + * The dentry failed validation. + * If d_revalidate returned 0 attempt to invalidate + * the dentry otherwise d_revalidate is asking us + * to return a fail status. + */ + if (status < 0) { + dput(dentry); + return ERR_PTR(status); + } else if (!d_invalidate(dentry)) { + dput(dentry); + dentry = NULL; + } + } + } + + if (!dentry) + dentry = d_alloc_and_lookup(base, name, nd); + + return dentry; +} + /* * Restricted form of lookup. Doesn't follow links, single-component only, * needs parent already locked. Doesn't follow mounts. @@ -1851,7 +1924,6 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) { struct qstr this; unsigned int c; - int err; WARN_ON_ONCE(!mutex_is_locked(&base->d_inode->i_mutex)); @@ -1876,10 +1948,6 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) return ERR_PTR(err); } - err = inode_permission(base->d_inode, MAY_EXEC); - if (err) - return ERR_PTR(err); - return __lookup_hash(&this, base, NULL); } @@ -2681,7 +2749,7 @@ SYSCALL_DEFINE2(mkdir, const char __user *, pathname, umode_t, mode) /* * The dentry_unhash() helper will try to drop the dentry early: we - * should have a usage count of 1 if we're the only user of this + * should have a usage count of 2 if we're the only user of this * dentry, and if that is true (possibly after pruning the dcache), * then we drop the dentry now. * diff --git a/trunk/fs/nfs/blocklayout/blocklayout.c b/trunk/fs/nfs/blocklayout/blocklayout.c index 7f6a23f0244e..9c94297bb70e 100644 --- a/trunk/fs/nfs/blocklayout/blocklayout.c +++ b/trunk/fs/nfs/blocklayout/blocklayout.c @@ -38,8 +38,6 @@ #include /* various write calls */ #include -#include "../pnfs.h" -#include "../internal.h" #include "blocklayout.h" #define NFSDBG_FACILITY NFSDBG_PNFS_LD @@ -870,7 +868,7 @@ nfs4_blk_get_deviceinfo(struct nfs_server *server, const struct nfs_fh *fh, * GETDEVICEINFO's maxcount */ max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; - max_pages = nfs_page_array_len(0, max_resp_sz); + max_pages = max_resp_sz >> PAGE_SHIFT; dprintk("%s max_resp_sz %u max_pages %d\n", __func__, max_resp_sz, max_pages); diff --git a/trunk/fs/nfs/client.c b/trunk/fs/nfs/client.c index 60f7e4ec842c..da7b5e4ff9ec 100644 --- a/trunk/fs/nfs/client.c +++ b/trunk/fs/nfs/client.c @@ -1729,8 +1729,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, */ struct nfs_server *nfs_clone_server(struct nfs_server *source, struct nfs_fh *fh, - struct nfs_fattr *fattr, - rpc_authflavor_t flavor) + struct nfs_fattr *fattr) { struct nfs_server *server; struct nfs_fattr *fattr_fsinfo; @@ -1759,7 +1758,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source, error = nfs_init_server_rpcclient(server, source->client->cl_timeout, - flavor); + source->client->cl_auth->au_flavor); if (error < 0) goto out_free_server; if (!IS_ERR(source->client_acl)) diff --git a/trunk/fs/nfs/dir.c b/trunk/fs/nfs/dir.c index 8789210c6905..4aaf0316d76a 100644 --- a/trunk/fs/nfs/dir.c +++ b/trunk/fs/nfs/dir.c @@ -1429,7 +1429,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry } open_flags = nd->intent.open.flags; - attr.ia_valid = ATTR_OPEN; + attr.ia_valid = 0; ctx = create_nfs_open_context(dentry, open_flags); res = ERR_CAST(ctx); @@ -1536,7 +1536,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) if (IS_ERR(ctx)) goto out; - attr.ia_valid = ATTR_OPEN; + attr.ia_valid = 0; if (openflags & O_TRUNC) { attr.ia_valid |= ATTR_SIZE; attr.ia_size = 0; diff --git a/trunk/fs/nfs/idmap.c b/trunk/fs/nfs/idmap.c index ba3019f5934c..b7f348bb618b 100644 --- a/trunk/fs/nfs/idmap.c +++ b/trunk/fs/nfs/idmap.c @@ -554,16 +554,12 @@ static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event, struct nfs_client *clp; int error = 0; - if (!try_module_get(THIS_MODULE)) - return 0; - while ((clp = nfs_get_client_for_event(sb->s_fs_info, event))) { error = __rpc_pipefs_event(clp, event, sb); nfs_put_client(clp); if (error) break; } - module_put(THIS_MODULE); return error; } diff --git a/trunk/fs/nfs/internal.h b/trunk/fs/nfs/internal.h index b777bdaba4c5..2476dc69365f 100644 --- a/trunk/fs/nfs/internal.h +++ b/trunk/fs/nfs/internal.h @@ -165,8 +165,7 @@ extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *, extern void nfs_free_server(struct nfs_server *server); extern struct nfs_server *nfs_clone_server(struct nfs_server *, struct nfs_fh *, - struct nfs_fattr *, - rpc_authflavor_t); + struct nfs_fattr *); extern void nfs_mark_client_ready(struct nfs_client *clp, int state); extern int nfs4_check_client_ready(struct nfs_client *clp); extern struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp, @@ -187,10 +186,10 @@ static inline void nfs_fs_proc_exit(void) /* nfs4namespace.c */ #ifdef CONFIG_NFS_V4 -extern struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry); +extern struct vfsmount *nfs_do_refmount(struct dentry *dentry); #else static inline -struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry) +struct vfsmount *nfs_do_refmount(struct dentry *dentry) { return ERR_PTR(-ENOENT); } @@ -235,6 +234,7 @@ extern const u32 nfs41_maxwrite_overhead; /* nfs4proc.c */ #ifdef CONFIG_NFS_V4 extern struct rpc_procinfo nfs4_procedures[]; +void nfs_fixup_secinfo_attributes(struct nfs_fattr *, struct nfs_fh *); #endif extern int nfs4_init_ds_session(struct nfs_client *clp); diff --git a/trunk/fs/nfs/namespace.c b/trunk/fs/nfs/namespace.c index d51868e5683c..1807866bb3ab 100644 --- a/trunk/fs/nfs/namespace.c +++ b/trunk/fs/nfs/namespace.c @@ -148,31 +148,66 @@ rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors) return pseudoflavor; } -static struct rpc_clnt *nfs_lookup_mountpoint(struct inode *dir, - struct qstr *name, - struct nfs_fh *fh, - struct nfs_fattr *fattr) +static int nfs_negotiate_security(const struct dentry *parent, + const struct dentry *dentry, + rpc_authflavor_t *flavor) { - int err; + struct page *page; + struct nfs4_secinfo_flavors *flavors; + int (*secinfo)(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *); + int ret = -EPERM; + + secinfo = NFS_PROTO(parent->d_inode)->secinfo; + if (secinfo != NULL) { + page = alloc_page(GFP_KERNEL); + if (!page) { + ret = -ENOMEM; + goto out; + } + flavors = page_address(page); + ret = secinfo(parent->d_inode, &dentry->d_name, flavors); + *flavor = nfs_find_best_sec(flavors); + put_page(page); + } - if (NFS_PROTO(dir)->version == 4) - return nfs4_proc_lookup_mountpoint(dir, name, fh, fattr); +out: + return ret; +} - err = NFS_PROTO(dir)->lookup(NFS_SERVER(dir)->client, dir, name, fh, fattr); - if (err) - return ERR_PTR(err); - return rpc_clone_client(NFS_SERVER(dir)->client); +static int nfs_lookup_with_sec(struct nfs_server *server, struct dentry *parent, + struct dentry *dentry, struct path *path, + struct nfs_fh *fh, struct nfs_fattr *fattr, + rpc_authflavor_t *flavor) +{ + struct rpc_clnt *clone; + struct rpc_auth *auth; + int err; + + err = nfs_negotiate_security(parent, path->dentry, flavor); + if (err < 0) + goto out; + clone = rpc_clone_client(server->client); + auth = rpcauth_create(*flavor, clone); + if (!auth) { + err = -EIO; + goto out_shutdown; + } + err = server->nfs_client->rpc_ops->lookup(clone, parent->d_inode, + &path->dentry->d_name, + fh, fattr); +out_shutdown: + rpc_shutdown_client(clone); +out: + return err; } #else /* CONFIG_NFS_V4 */ -static inline struct rpc_clnt *nfs_lookup_mountpoint(struct inode *dir, - struct qstr *name, - struct nfs_fh *fh, - struct nfs_fattr *fattr) +static inline int nfs_lookup_with_sec(struct nfs_server *server, + struct dentry *parent, struct dentry *dentry, + struct path *path, struct nfs_fh *fh, + struct nfs_fattr *fattr, + rpc_authflavor_t *flavor) { - int err = NFS_PROTO(dir)->lookup(NFS_SERVER(dir)->client, dir, name, fh, fattr); - if (err) - return ERR_PTR(err); - return rpc_clone_client(NFS_SERVER(dir)->client); + return -EPERM; } #endif /* CONFIG_NFS_V4 */ @@ -191,10 +226,12 @@ static inline struct rpc_clnt *nfs_lookup_mountpoint(struct inode *dir, struct vfsmount *nfs_d_automount(struct path *path) { struct vfsmount *mnt; + struct nfs_server *server = NFS_SERVER(path->dentry->d_inode); struct dentry *parent; struct nfs_fh *fh = NULL; struct nfs_fattr *fattr = NULL; - struct rpc_clnt *client; + int err; + rpc_authflavor_t flavor = RPC_AUTH_UNIX; dprintk("--> nfs_d_automount()\n"); @@ -212,19 +249,21 @@ struct vfsmount *nfs_d_automount(struct path *path) /* Look it up again to get its attributes */ parent = dget_parent(path->dentry); - client = nfs_lookup_mountpoint(parent->d_inode, &path->dentry->d_name, fh, fattr); + err = server->nfs_client->rpc_ops->lookup(server->client, parent->d_inode, + &path->dentry->d_name, + fh, fattr); + if (err == -EPERM && NFS_PROTO(parent->d_inode)->secinfo != NULL) + err = nfs_lookup_with_sec(server, parent, path->dentry, path, fh, fattr, &flavor); dput(parent); - if (IS_ERR(client)) { - mnt = ERR_CAST(client); + if (err != 0) { + mnt = ERR_PTR(err); goto out; } if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) - mnt = nfs_do_refmount(client, path->dentry); + mnt = nfs_do_refmount(path->dentry); else - mnt = nfs_do_submount(path->dentry, fh, fattr, client->cl_auth->au_flavor); - rpc_shutdown_client(client); - + mnt = nfs_do_submount(path->dentry, fh, fattr, flavor); if (IS_ERR(mnt)) goto out; diff --git a/trunk/fs/nfs/nfs4_fs.h b/trunk/fs/nfs/nfs4_fs.h index 8d75021020b3..97ecc863dd76 100644 --- a/trunk/fs/nfs/nfs4_fs.h +++ b/trunk/fs/nfs/nfs4_fs.h @@ -59,7 +59,6 @@ struct nfs_unique_id { #define NFS_SEQID_CONFIRMED 1 struct nfs_seqid_counter { - ktime_t create_time; int owner_id; int flags; u32 counter; @@ -205,9 +204,6 @@ struct nfs4_state_maintenance_ops { extern const struct dentry_operations nfs4_dentry_operations; extern const struct inode_operations nfs4_dir_inode_operations; -/* nfs4namespace.c */ -struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *); - /* nfs4proc.c */ extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *); extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *); @@ -216,11 +212,8 @@ extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *); extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *); extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc); extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle); -extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struct qstr *, - struct nfs4_fs_locations *, struct page *); -extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, struct qstr *, - struct nfs_fh *, struct nfs_fattr *); -extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *); +extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, + struct nfs4_fs_locations *fs_locations, struct page *page); extern int nfs4_release_lockowner(struct nfs4_lock_state *); extern const struct xattr_handler *nfs4_xattr_handlers[]; diff --git a/trunk/fs/nfs/nfs4filelayoutdev.c b/trunk/fs/nfs/nfs4filelayoutdev.c index c9cff9adb2d3..a866bbd2890a 100644 --- a/trunk/fs/nfs/nfs4filelayoutdev.c +++ b/trunk/fs/nfs/nfs4filelayoutdev.c @@ -699,7 +699,7 @@ get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_fla * GETDEVICEINFO's maxcount */ max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; - max_pages = nfs_page_array_len(0, max_resp_sz); + max_pages = max_resp_sz >> PAGE_SHIFT; dprintk("%s inode %p max_resp_sz %u max_pages %d\n", __func__, inode, max_resp_sz, max_pages); diff --git a/trunk/fs/nfs/nfs4namespace.c b/trunk/fs/nfs/nfs4namespace.c index a7f3dedc4ec7..9c8eca315f43 100644 --- a/trunk/fs/nfs/nfs4namespace.c +++ b/trunk/fs/nfs/nfs4namespace.c @@ -51,30 +51,6 @@ static inline char *nfs4_pathname_string(const struct nfs4_pathname *pathname, return ERR_PTR(-ENAMETOOLONG); } -/* - * return the path component of ":" - * nfspath - the ":" string - * end - one past the last char that could contain ":" - * returns NULL on failure - */ -static char *nfs_path_component(const char *nfspath, const char *end) -{ - char *p; - - if (*nfspath == '[') { - /* parse [] escaped IPv6 addrs */ - p = strchr(nfspath, ']'); - if (p != NULL && ++p < end && *p == ':') - return p + 1; - } else { - /* otherwise split on first colon */ - p = strchr(nfspath, ':'); - if (p != NULL && p < end) - return p + 1; - } - return NULL; -} - /* * Determine the mount path as a string */ @@ -83,9 +59,9 @@ static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen) char *limit; char *path = nfs_path(&limit, dentry, buffer, buflen); if (!IS_ERR(path)) { - char *path_component = nfs_path_component(path, limit); - if (path_component) - return path_component; + char *colon = strchr(path, ':'); + if (colon && colon < limit) + path = colon + 1; } return path; } @@ -132,58 +108,6 @@ static size_t nfs_parse_server_name(char *string, size_t len, return ret; } -static rpc_authflavor_t nfs4_negotiate_security(struct inode *inode, struct qstr *name) -{ - struct page *page; - struct nfs4_secinfo_flavors *flavors; - rpc_authflavor_t flavor; - int err; - - page = alloc_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - flavors = page_address(page); - - err = nfs4_proc_secinfo(inode, name, flavors); - if (err < 0) { - flavor = err; - goto out; - } - - flavor = nfs_find_best_sec(flavors); - -out: - put_page(page); - return flavor; -} - -/* - * Please call rpc_shutdown_client() when you are done with this client. - */ -struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *clnt, struct inode *inode, - struct qstr *name) -{ - struct rpc_clnt *clone; - struct rpc_auth *auth; - rpc_authflavor_t flavor; - - flavor = nfs4_negotiate_security(inode, name); - if (flavor < 0) - return ERR_PTR(flavor); - - clone = rpc_clone_client(clnt); - if (IS_ERR(clone)) - return clone; - - auth = rpcauth_create(flavor, clone); - if (!auth) { - rpc_shutdown_client(clone); - clone = ERR_PTR(-EIO); - } - - return clone; -} - static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, char *page, char *page2, const struct nfs4_fs_location *location) @@ -300,7 +224,7 @@ static struct vfsmount *nfs_follow_referral(struct dentry *dentry, * @dentry - dentry of referral * */ -struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry) +struct vfsmount *nfs_do_refmount(struct dentry *dentry) { struct vfsmount *mnt = ERR_PTR(-ENOMEM); struct dentry *parent; @@ -326,7 +250,7 @@ struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry) dprintk("%s: getting locations for %s/%s\n", __func__, parent->d_name.name, dentry->d_name.name); - err = nfs4_proc_fs_locations(client, parent->d_inode, &dentry->d_name, fs_locations, page); + err = nfs4_proc_fs_locations(parent->d_inode, &dentry->d_name, fs_locations, page); dput(parent); if (err != 0 || fs_locations->nlocations <= 0 || diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index 99650aaf8937..f82bde005a82 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -838,8 +838,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, p->o_arg.open_flags = flags; p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE); p->o_arg.clientid = server->nfs_client->cl_clientid; - p->o_arg.id.create_time = ktime_to_ns(sp->so_seqid.create_time); - p->o_arg.id.uniquifier = sp->so_seqid.owner_id; + p->o_arg.id = sp->so_seqid.owner_id; p->o_arg.name = &dentry->d_name; p->o_arg.server = server; p->o_arg.bitmask = server->attr_bitmask; @@ -1467,7 +1466,8 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) goto unlock_no_action; rcu_read_unlock(); } - /* Update client id. */ + /* Update sequence id. */ + data->o_arg.id = sp->so_seqid.owner_id; data->o_arg.clientid = sp->so_server->nfs_client->cl_clientid; if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) { task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR]; @@ -1954,19 +1954,10 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, }; int err; do { - err = _nfs4_do_setattr(inode, cred, fattr, sattr, state); - switch (err) { - case -NFS4ERR_OPENMODE: - if (state && !(state->state & FMODE_WRITE)) { - err = -EBADF; - if (sattr->ia_valid & ATTR_OPEN) - err = -EACCES; - goto out; - } - } - err = nfs4_handle_exception(server, err, &exception); + err = nfs4_handle_exception(server, + _nfs4_do_setattr(inode, cred, fattr, sattr, state), + &exception); } while (exception.retry); -out: return err; } @@ -2377,9 +2368,8 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, * Note that we'll actually follow the referral later when * we detect fsid mismatch in inode revalidation */ -static int nfs4_get_referral(struct rpc_clnt *client, struct inode *dir, - const struct qstr *name, struct nfs_fattr *fattr, - struct nfs_fh *fhandle) +static int nfs4_get_referral(struct inode *dir, const struct qstr *name, + struct nfs_fattr *fattr, struct nfs_fh *fhandle) { int status = -ENOMEM; struct page *page = NULL; @@ -2392,7 +2382,7 @@ static int nfs4_get_referral(struct rpc_clnt *client, struct inode *dir, if (locations == NULL) goto out; - status = nfs4_proc_fs_locations(client, dir, name, locations, page); + status = nfs4_proc_fs_locations(dir, name, locations, page); if (status != 0) goto out; /* Make sure server returned a different fsid for the referral */ @@ -2529,84 +2519,39 @@ static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, return status; } -static void nfs_fixup_secinfo_attributes(struct nfs_fattr *fattr) +void nfs_fixup_secinfo_attributes(struct nfs_fattr *fattr, struct nfs_fh *fh) { + memset(fh, 0, sizeof(struct nfs_fh)); + fattr->fsid.major = 1; fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE | - NFS_ATTR_FATTR_NLINK | NFS_ATTR_FATTR_MOUNTPOINT; + NFS_ATTR_FATTR_NLINK | NFS_ATTR_FATTR_FSID | NFS_ATTR_FATTR_MOUNTPOINT; fattr->mode = S_IFDIR | S_IRUGO | S_IXUGO; fattr->nlink = 2; } -static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir, - struct qstr *name, struct nfs_fh *fhandle, - struct nfs_fattr *fattr) +static int nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qstr *name, + struct nfs_fh *fhandle, struct nfs_fattr *fattr) { struct nfs4_exception exception = { }; - struct rpc_clnt *client = *clnt; int err; do { - err = _nfs4_proc_lookup(client, dir, name, fhandle, fattr); - switch (err) { + int status; + + status = _nfs4_proc_lookup(clnt, dir, name, fhandle, fattr); + switch (status) { case -NFS4ERR_BADNAME: - err = -ENOENT; - goto out; + return -ENOENT; case -NFS4ERR_MOVED: - err = nfs4_get_referral(client, dir, name, fattr, fhandle); - goto out; + return nfs4_get_referral(dir, name, fattr, fhandle); case -NFS4ERR_WRONGSEC: - err = -EPERM; - if (client != *clnt) - goto out; - - client = nfs4_create_sec_client(client, dir, name); - if (IS_ERR(client)) - return PTR_ERR(client); - - exception.retry = 1; - break; - default: - err = nfs4_handle_exception(NFS_SERVER(dir), err, &exception); + nfs_fixup_secinfo_attributes(fattr, fhandle); } + err = nfs4_handle_exception(NFS_SERVER(dir), + status, &exception); } while (exception.retry); - -out: - if (err == 0) - *clnt = client; - else if (client != *clnt) - rpc_shutdown_client(client); - return err; } -static int nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qstr *name, - struct nfs_fh *fhandle, struct nfs_fattr *fattr) -{ - int status; - struct rpc_clnt *client = NFS_CLIENT(dir); - - status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr); - if (client != NFS_CLIENT(dir)) { - rpc_shutdown_client(client); - nfs_fixup_secinfo_attributes(fattr); - } - return status; -} - -struct rpc_clnt * -nfs4_proc_lookup_mountpoint(struct inode *dir, struct qstr *name, - struct nfs_fh *fhandle, struct nfs_fattr *fattr) -{ - int status; - struct rpc_clnt *client = rpc_clone_client(NFS_CLIENT(dir)); - - status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr); - if (status < 0) { - rpc_shutdown_client(client); - return ERR_PTR(status); - } - return client; -} - static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry) { struct nfs_server *server = NFS_SERVER(inode); @@ -3674,16 +3619,16 @@ static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_ return ret; } -static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len) +static void nfs4_write_cached_acl(struct inode *inode, const char *buf, size_t acl_len) { struct nfs4_cached_acl *acl; - if (pages && acl_len <= PAGE_SIZE) { + if (buf && acl_len <= PAGE_SIZE) { acl = kmalloc(sizeof(*acl) + acl_len, GFP_KERNEL); if (acl == NULL) goto out; acl->cached = 1; - _copy_from_pages(acl->data, pages, pgbase, acl_len); + memcpy(acl->data, buf, acl_len); } else { acl = kmalloc(sizeof(*acl), GFP_KERNEL); if (acl == NULL) @@ -3716,6 +3661,7 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu struct nfs_getaclres res = { .acl_len = buflen, }; + void *resp_buf; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL], .rpc_argp = &args, @@ -3729,27 +3675,24 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu if (npages == 0) npages = 1; - /* Add an extra page to handle the bitmap returned */ - npages++; - for (i = 0; i < npages; i++) { pages[i] = alloc_page(GFP_KERNEL); if (!pages[i]) goto out_free; } - - /* for decoding across pages */ - res.acl_scratch = alloc_page(GFP_KERNEL); - if (!res.acl_scratch) - goto out_free; - + if (npages > 1) { + /* for decoding across pages */ + res.acl_scratch = alloc_page(GFP_KERNEL); + if (!res.acl_scratch) + goto out_free; + } args.acl_len = npages * PAGE_SIZE; args.acl_pgbase = 0; - /* Let decode_getfacl know not to fail if the ACL data is larger than * the page we send as a guess */ if (buf == NULL) res.acl_flags |= NFS4_ACL_LEN_REQUEST; + resp_buf = page_address(pages[0]); dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", __func__, buf, buflen, npages, args.acl_len); @@ -3760,9 +3703,9 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu acl_len = res.acl_len - res.acl_data_offset; if (acl_len > args.acl_len) - nfs4_write_cached_acl(inode, NULL, 0, acl_len); + nfs4_write_cached_acl(inode, NULL, acl_len); else - nfs4_write_cached_acl(inode, pages, res.acl_data_offset, + nfs4_write_cached_acl(inode, resp_buf + res.acl_data_offset, acl_len); if (buf) { ret = -ERANGE; @@ -4615,9 +4558,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request) { struct nfs_server *server = NFS_SERVER(state->inode); - struct nfs4_exception exception = { - .inode = state->inode, - }; + struct nfs4_exception exception = { }; int err; do { @@ -4635,9 +4576,7 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request) { struct nfs_server *server = NFS_SERVER(state->inode); - struct nfs4_exception exception = { - .inode = state->inode, - }; + struct nfs4_exception exception = { }; int err; err = nfs4_set_lock_state(state, request); @@ -4737,7 +4676,6 @@ static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock * { struct nfs4_exception exception = { .state = state, - .inode = state->inode, }; int err; @@ -4783,20 +4721,6 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request) if (state == NULL) return -ENOLCK; - /* - * Don't rely on the VFS having checked the file open mode, - * since it won't do this for flock() locks. - */ - switch (request->fl_type & (F_RDLCK|F_WRLCK|F_UNLCK)) { - case F_RDLCK: - if (!(filp->f_mode & FMODE_READ)) - return -EBADF; - break; - case F_WRLCK: - if (!(filp->f_mode & FMODE_WRITE)) - return -EBADF; - } - do { status = nfs4_proc_setlk(state, cmd, request); if ((status != -EAGAIN) || IS_SETLK(cmd)) @@ -4967,10 +4891,8 @@ static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr) fattr->nlink = 2; } -static int _nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir, - const struct qstr *name, - struct nfs4_fs_locations *fs_locations, - struct page *page) +int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, + struct nfs4_fs_locations *fs_locations, struct page *page) { struct nfs_server *server = NFS_SERVER(dir); u32 bitmask[2] = { @@ -5004,26 +4926,11 @@ static int _nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir, nfs_fattr_init(&fs_locations->fattr); fs_locations->server = server; fs_locations->nlocations = 0; - status = nfs4_call_sync(client, server, &msg, &args.seq_args, &res.seq_res, 0); + status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); dprintk("%s: returned status = %d\n", __func__, status); return status; } -int nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir, - const struct qstr *name, - struct nfs4_fs_locations *fs_locations, - struct page *page) -{ - struct nfs4_exception exception = { }; - int err; - do { - err = nfs4_handle_exception(NFS_SERVER(dir), - _nfs4_proc_fs_locations(client, dir, name, fs_locations, page), - &exception); - } while (exception.retry); - return err; -} - static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct nfs4_secinfo_flavors *flavors) { int status; @@ -5046,8 +4953,8 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct return status; } -int nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, - struct nfs4_secinfo_flavors *flavors) +static int nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, + struct nfs4_secinfo_flavors *flavors) { struct nfs4_exception exception = { }; int err; @@ -5122,9 +5029,10 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) nfs4_construct_boot_verifier(clp, &verifier); args.id_len = scnprintf(args.id, sizeof(args.id), - "%s/%s/%u", + "%s/%s.%s/%u", clp->cl_ipaddr, - clp->cl_rpcclient->cl_nodename, + init_utsname()->nodename, + init_utsname()->domainname, clp->cl_rpcclient->cl_auth->au_flavor); res.server_scope = kzalloc(sizeof(struct server_scope), GFP_KERNEL); diff --git a/trunk/fs/nfs/nfs4state.c b/trunk/fs/nfs/nfs4state.c index 7f0fcfc1fe9d..0f43414eb25a 100644 --- a/trunk/fs/nfs/nfs4state.c +++ b/trunk/fs/nfs/nfs4state.c @@ -393,7 +393,6 @@ nfs4_remove_state_owner_locked(struct nfs4_state_owner *sp) static void nfs4_init_seqid_counter(struct nfs_seqid_counter *sc) { - sc->create_time = ktime_get(); sc->flags = 0; sc->counter = 0; spin_lock_init(&sc->lock); @@ -435,17 +434,13 @@ nfs4_alloc_state_owner(struct nfs_server *server, static void nfs4_drop_state_owner(struct nfs4_state_owner *sp) { - struct rb_node *rb_node = &sp->so_server_node; - - if (!RB_EMPTY_NODE(rb_node)) { + if (!RB_EMPTY_NODE(&sp->so_server_node)) { struct nfs_server *server = sp->so_server; struct nfs_client *clp = server->nfs_client; spin_lock(&clp->cl_lock); - if (!RB_EMPTY_NODE(rb_node)) { - rb_erase(rb_node, &server->state_owners); - RB_CLEAR_NODE(rb_node); - } + rb_erase(&sp->so_server_node, &server->state_owners); + RB_CLEAR_NODE(&sp->so_server_node); spin_unlock(&clp->cl_lock); } } @@ -521,14 +516,6 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, /** * nfs4_put_state_owner - Release a nfs4_state_owner * @sp: state owner data to release - * - * Note that we keep released state owners on an LRU - * list. - * This caches valid state owners so that they can be - * reused, to avoid the OPEN_CONFIRM on minor version 0. - * It also pins the uniquifier of dropped state owners for - * a while, to ensure that those state owner names are - * never reused. */ void nfs4_put_state_owner(struct nfs4_state_owner *sp) { @@ -538,9 +525,15 @@ void nfs4_put_state_owner(struct nfs4_state_owner *sp) if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock)) return; - sp->so_expires = jiffies; - list_add_tail(&sp->so_lru, &server->state_owners_lru); - spin_unlock(&clp->cl_lock); + if (!RB_EMPTY_NODE(&sp->so_server_node)) { + sp->so_expires = jiffies; + list_add_tail(&sp->so_lru, &server->state_owners_lru); + spin_unlock(&clp->cl_lock); + } else { + nfs4_remove_state_owner_locked(sp); + spin_unlock(&clp->cl_lock); + nfs4_free_state_owner(sp); + } } /** diff --git a/trunk/fs/nfs/nfs4xdr.c b/trunk/fs/nfs/nfs4xdr.c index c54aae364bee..c74fdb114b48 100644 --- a/trunk/fs/nfs/nfs4xdr.c +++ b/trunk/fs/nfs/nfs4xdr.c @@ -74,7 +74,7 @@ static int nfs4_stat_to_errno(int); /* lock,open owner id: * we currently use size 2 (u64) out of (NFS4_OPAQUE_LIMIT >> 2) */ -#define open_owner_id_maxsz (1 + 2 + 1 + 1 + 2) +#define open_owner_id_maxsz (1 + 1 + 4) #define lock_owner_id_maxsz (1 + 1 + 4) #define decode_lockowner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) #define compound_encode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2)) @@ -1340,13 +1340,12 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena */ encode_nfs4_seqid(xdr, arg->seqid); encode_share_access(xdr, arg->fmode); - p = reserve_space(xdr, 36); + p = reserve_space(xdr, 32); p = xdr_encode_hyper(p, arg->clientid); - *p++ = cpu_to_be32(24); + *p++ = cpu_to_be32(20); p = xdr_encode_opaque_fixed(p, "open id:", 8); *p++ = cpu_to_be32(arg->server->s_dev); - *p++ = cpu_to_be32(arg->id.uniquifier); - xdr_encode_hyper(p, arg->id.create_time); + xdr_encode_hyper(p, arg->id); } static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg) @@ -4258,6 +4257,8 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, status = decode_attr_error(xdr, bitmap, &err); if (status < 0) goto xdr_error; + if (err == -NFS4ERR_WRONGSEC) + nfs_fixup_secinfo_attributes(fattr, fh); status = decode_attr_filehandle(xdr, bitmap, fh); if (status < 0) @@ -4900,19 +4901,11 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, bitmap[3] = {0}; struct kvec *iov = req->rq_rcv_buf.head; int status; - size_t page_len = xdr->buf->page_len; res->acl_len = 0; if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) goto out; - bm_p = xdr->p; - res->acl_data_offset = be32_to_cpup(bm_p) + 2; - res->acl_data_offset <<= 2; - /* Check if the acl data starts beyond the allocated buffer */ - if (res->acl_data_offset > page_len) - return -ERANGE; - if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) goto out; if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) @@ -4922,24 +4915,28 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_ACL)) { size_t hdrlen; + u32 recvd; /* The bitmap (xdr len + bitmaps) and the attr xdr len words * are stored with the acl data to handle the problem of * variable length bitmaps.*/ xdr->p = bm_p; + res->acl_data_offset = be32_to_cpup(bm_p) + 2; + res->acl_data_offset <<= 2; /* We ignore &savep and don't do consistency checks on * the attr length. Let userspace figure it out.... */ hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base; attrlen += res->acl_data_offset; - if (attrlen > page_len) { + recvd = req->rq_rcv_buf.len - hdrlen; + if (attrlen > recvd) { if (res->acl_flags & NFS4_ACL_LEN_REQUEST) { /* getxattr interface called with a NULL buf */ res->acl_len = attrlen; goto out; } - dprintk("NFS: acl reply: attrlen %u > page_len %zu\n", - attrlen, page_len); + dprintk("NFS: acl reply: attrlen %u > recvd %u\n", + attrlen, recvd); return -EINVAL; } xdr_read_pages(xdr, attrlen); @@ -5092,13 +5089,16 @@ static int decode_secinfo_gss(struct xdr_stream *xdr, struct nfs4_secinfo_flavor return -EINVAL; } -static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) +static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) { struct nfs4_secinfo_flavor *sec_flavor; int status; __be32 *p; int i, num_flavors; + status = decode_op_hdr(xdr, OP_SECINFO); + if (status) + goto out; p = xdr_inline_decode(xdr, 4); if (unlikely(!p)) goto out_overflow; @@ -5124,7 +5124,6 @@ static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res res->flavors->num_flavors++; } - status = 0; out: return status; out_overflow: @@ -5132,23 +5131,7 @@ static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res return -EIO; } -static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) -{ - int status = decode_op_hdr(xdr, OP_SECINFO); - if (status) - return status; - return decode_secinfo_common(xdr, res); -} - #if defined(CONFIG_NFS_V4_1) -static int decode_secinfo_no_name(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) -{ - int status = decode_op_hdr(xdr, OP_SECINFO_NO_NAME); - if (status) - return status; - return decode_secinfo_common(xdr, res); -} - static int decode_exchange_id(struct xdr_stream *xdr, struct nfs41_exchange_id_res *res) { @@ -6833,7 +6816,7 @@ static int nfs4_xdr_dec_secinfo_no_name(struct rpc_rqst *rqstp, status = decode_putrootfh(xdr); if (status) goto out; - status = decode_secinfo_no_name(xdr, res); + status = decode_secinfo(xdr, res); out: return status; } diff --git a/trunk/fs/nfs/objlayout/objlayout.c b/trunk/fs/nfs/objlayout/objlayout.c index 595c5fc21a19..8d45f1c318ce 100644 --- a/trunk/fs/nfs/objlayout/objlayout.c +++ b/trunk/fs/nfs/objlayout/objlayout.c @@ -604,6 +604,7 @@ int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay, { struct objlayout_deviceinfo *odi; struct pnfs_device pd; + struct super_block *sb; struct page *page, **pages; u32 *p; int err; @@ -622,6 +623,7 @@ int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay, pd.pglen = PAGE_SIZE; pd.mincount = 0; + sb = pnfslay->plh_inode->i_sb; err = nfs4_proc_getdeviceinfo(NFS_SERVER(pnfslay->plh_inode), &pd); dprintk("%s nfs_getdeviceinfo returned %d\n", __func__, err); if (err) diff --git a/trunk/fs/nfs/pnfs.c b/trunk/fs/nfs/pnfs.c index 38512bcd2e98..b5d451586943 100644 --- a/trunk/fs/nfs/pnfs.c +++ b/trunk/fs/nfs/pnfs.c @@ -587,7 +587,7 @@ send_layoutget(struct pnfs_layout_hdr *lo, /* allocate pages for xdr post processing */ max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; - max_pages = nfs_page_array_len(0, max_resp_sz); + max_pages = max_resp_sz >> PAGE_SHIFT; pages = kcalloc(max_pages, sizeof(struct page *), gfp_flags); if (!pages) diff --git a/trunk/fs/nfs/read.c b/trunk/fs/nfs/read.c index 0a4be28c2ea3..9a0e8ef4a409 100644 --- a/trunk/fs/nfs/read.c +++ b/trunk/fs/nfs/read.c @@ -322,7 +322,7 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc, struct list_head while (!list_empty(res)) { data = list_entry(res->next, struct nfs_read_data, list); list_del(&data->list); - nfs_readdata_release(data); + nfs_readdata_free(data); } nfs_readpage_release(req); return -ENOMEM; diff --git a/trunk/fs/nfs/super.c b/trunk/fs/nfs/super.c index 4ac7fca7e4bf..37412f706b32 100644 --- a/trunk/fs/nfs/super.c +++ b/trunk/fs/nfs/super.c @@ -2428,7 +2428,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags, dprintk("--> nfs_xdev_mount()\n"); /* create a new volume representation */ - server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor); + server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr); if (IS_ERR(server)) { error = PTR_ERR(server); goto out_err_noserver; @@ -2767,15 +2767,11 @@ static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type, char *root_devname; size_t len; - len = strlen(hostname) + 5; + len = strlen(hostname) + 3; root_devname = kmalloc(len, GFP_KERNEL); if (root_devname == NULL) return ERR_PTR(-ENOMEM); - /* Does hostname needs to be enclosed in brackets? */ - if (strchr(hostname, ':')) - snprintf(root_devname, len, "[%s]:/", hostname); - else - snprintf(root_devname, len, "%s:/", hostname); + snprintf(root_devname, len, "%s:/", hostname); root_mnt = vfs_kern_mount(fs_type, flags, root_devname, data); kfree(root_devname); return root_mnt; @@ -2955,7 +2951,7 @@ nfs4_xdev_mount(struct file_system_type *fs_type, int flags, dprintk("--> nfs4_xdev_mount()\n"); /* create a new volume representation */ - server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor); + server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr); if (IS_ERR(server)) { error = PTR_ERR(server); goto out_err_noserver; diff --git a/trunk/fs/nfs/write.c b/trunk/fs/nfs/write.c index c07462320f6b..2c68818f68ac 100644 --- a/trunk/fs/nfs/write.c +++ b/trunk/fs/nfs/write.c @@ -682,8 +682,7 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode, req->wb_bytes = rqend - req->wb_offset; out_unlock: spin_unlock(&inode->i_lock); - if (req) - nfs_clear_request_commit(req); + nfs_clear_request_commit(req); return req; out_flushme: spin_unlock(&inode->i_lock); @@ -1019,7 +1018,7 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc, struct list_head while (!list_empty(res)) { data = list_entry(res->next, struct nfs_write_data, list); list_del(&data->list); - nfs_writedata_release(data); + nfs_writedata_free(data); } nfs_redirty_request(req); return -ENOMEM; diff --git a/trunk/fs/nfsd/nfs3xdr.c b/trunk/fs/nfsd/nfs3xdr.c index 43f46cd9edea..08c6e36ab2eb 100644 --- a/trunk/fs/nfsd/nfs3xdr.c +++ b/trunk/fs/nfsd/nfs3xdr.c @@ -803,13 +803,13 @@ encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, return p; } -static __be32 +static int compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, const char *name, int namlen) { struct svc_export *exp; struct dentry *dparent, *dchild; - __be32 rv = nfserr_noent; + int rv = 0; dparent = cd->fh.fh_dentry; exp = cd->fh.fh_export; @@ -817,20 +817,26 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, if (isdotent(name, namlen)) { if (namlen == 2) { dchild = dget_parent(dparent); - /* filesystem root - cannot return filehandle for ".." */ - if (dchild == dparent) - goto out; + if (dchild == dparent) { + /* filesystem root - cannot return filehandle for ".." */ + dput(dchild); + return -ENOENT; + } } else dchild = dget(dparent); } else dchild = lookup_one_len(name, dparent, namlen); if (IS_ERR(dchild)) - return rv; + return -ENOENT; + rv = -ENOENT; if (d_mountpoint(dchild)) goto out; + rv = fh_compose(fhp, exp, dchild, &cd->fh); + if (rv) + goto out; if (!dchild->d_inode) goto out; - rv = fh_compose(fhp, exp, dchild, &cd->fh); + rv = 0; out: dput(dchild); return rv; @@ -839,7 +845,7 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen) { struct svc_fh fh; - __be32 err; + int err; fh_init(&fh, NFS3_FHSIZE); err = compose_entry_fh(cd, &fh, name, namlen); diff --git a/trunk/fs/nfsd/nfs4proc.c b/trunk/fs/nfsd/nfs4proc.c index 987e719fbae8..2ed14dfd00a2 100644 --- a/trunk/fs/nfsd/nfs4proc.c +++ b/trunk/fs/nfsd/nfs4proc.c @@ -235,15 +235,15 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o */ if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0) open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS | - FATTR4_WORD1_TIME_MODIFY); + FATTR4_WORD1_TIME_MODIFY); } else { status = nfsd_lookup(rqstp, current_fh, open->op_fname.data, open->op_fname.len, resfh); fh_unlock(current_fh); + if (status) + goto out; + status = nfsd_check_obj_isreg(resfh); } - if (status) - goto out; - status = nfsd_check_obj_isreg(resfh); if (status) goto out; @@ -841,7 +841,6 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_setattr *setattr) { __be32 status = nfs_ok; - int err; if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { nfs4_lock_state(); @@ -853,9 +852,9 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, return status; } } - err = fh_want_write(&cstate->current_fh); - if (err) - return nfserrno(err); + status = fh_want_write(&cstate->current_fh); + if (status) + return status; status = nfs_ok; status = check_attr_support(rqstp, cstate, setattr->sa_bmval, diff --git a/trunk/fs/nfsd/nfs4recover.c b/trunk/fs/nfsd/nfs4recover.c index ed3f9206a0ee..4767429264a2 100644 --- a/trunk/fs/nfsd/nfs4recover.c +++ b/trunk/fs/nfsd/nfs4recover.c @@ -577,7 +577,7 @@ cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) struct cld_net *cn = nn->cld_net; if (mlen != sizeof(*cmsg)) { - dprintk("%s: got %zu bytes, expected %zu\n", __func__, mlen, + dprintk("%s: got %lu bytes, expected %lu\n", __func__, mlen, sizeof(*cmsg)); return -EINVAL; } diff --git a/trunk/fs/nfsd/nfs4state.c b/trunk/fs/nfsd/nfs4state.c index 7f71c69cdcdf..1841f8bf845e 100644 --- a/trunk/fs/nfsd/nfs4state.c +++ b/trunk/fs/nfsd/nfs4state.c @@ -4211,14 +4211,16 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, * vfs_test_lock. (Arguably perhaps test_lock should be done with an * inode operation.) */ -static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock) +static int nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock) { struct file *file; - __be32 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); - if (!err) { - err = nfserrno(vfs_test_lock(file, lock)); - nfsd_close(file); - } + int err; + + err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); + if (err) + return err; + err = vfs_test_lock(file, lock); + nfsd_close(file); return err; } @@ -4232,6 +4234,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct inode *inode; struct file_lock file_lock; struct nfs4_lockowner *lo; + int error; __be32 status; if (locks_in_grace()) @@ -4277,10 +4280,12 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, nfs4_transform_lock_offset(&file_lock); - status = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock); - if (status) + status = nfs_ok; + error = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock); + if (error) { + status = nfserrno(error); goto out; - + } if (file_lock.fl_type != F_UNLCK) { status = nfserr_denied; nfs4_set_lock_denied(&file_lock, &lockt->lt_denied); diff --git a/trunk/fs/nfsd/nfs4xdr.c b/trunk/fs/nfsd/nfs4xdr.c index 74c00bc92b9a..bcd8904ab1e3 100644 --- a/trunk/fs/nfsd/nfs4xdr.c +++ b/trunk/fs/nfsd/nfs4xdr.c @@ -1392,7 +1392,7 @@ nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_sta for (i = 0; i < test_stateid->ts_num_ids; i++) { stateid = kmalloc(sizeof(struct nfsd4_test_stateid_id), GFP_KERNEL); if (!stateid) { - status = nfserrno(-ENOMEM); + status = PTR_ERR(stateid); goto out; } @@ -3410,7 +3410,7 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr, *p++ = htonl(test_stateid->ts_num_ids); list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) { - *p++ = stateid->ts_id_status; + *p++ = htonl(stateid->ts_id_status); } ADJUST_ARGS(); diff --git a/trunk/fs/nfsd/vfs.c b/trunk/fs/nfsd/vfs.c index 568666156ea4..296d671654d6 100644 --- a/trunk/fs/nfsd/vfs.c +++ b/trunk/fs/nfsd/vfs.c @@ -1458,7 +1458,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, switch (createmode) { case NFS3_CREATE_UNCHECKED: if (! S_ISREG(dchild->d_inode->i_mode)) - goto out; + err = nfserr_exist; else if (truncp) { /* in nfsv4, we need to treat this case a little * differently. we don't want to truncate the diff --git a/trunk/fs/ocfs2/alloc.c b/trunk/fs/ocfs2/alloc.c index 31b9463fba1f..3165aebb43c8 100644 --- a/trunk/fs/ocfs2/alloc.c +++ b/trunk/fs/ocfs2/alloc.c @@ -1134,7 +1134,7 @@ static int ocfs2_adjust_rightmost_branch(handle_t *handle, } el = path_leaf_el(path); - rec = &el->l_recs[le16_to_cpu(el->l_next_free_rec) - 1]; + rec = &el->l_recs[le32_to_cpu(el->l_next_free_rec) - 1]; ocfs2_adjust_rightmost_records(handle, et, path, rec); diff --git a/trunk/fs/ocfs2/ioctl.c b/trunk/fs/ocfs2/ioctl.c index a1a1bfd652c9..a6fda3c188aa 100644 --- a/trunk/fs/ocfs2/ioctl.c +++ b/trunk/fs/ocfs2/ioctl.c @@ -28,6 +28,8 @@ #include "suballoc.h" #include "move_extents.h" +#include + #define o2info_from_user(a, b) \ copy_from_user(&(a), (b), sizeof(a)) #define o2info_to_user(a, b) \ diff --git a/trunk/fs/ocfs2/refcounttree.c b/trunk/fs/ocfs2/refcounttree.c index 9f32d7cbb7a3..cf7823382664 100644 --- a/trunk/fs/ocfs2/refcounttree.c +++ b/trunk/fs/ocfs2/refcounttree.c @@ -1036,14 +1036,14 @@ static int ocfs2_get_refcount_cpos_end(struct ocfs2_caching_info *ci, tmp_el = left_path->p_node[subtree_root].el; blkno = left_path->p_node[subtree_root+1].bh->b_blocknr; - for (i = 0; i < le16_to_cpu(tmp_el->l_next_free_rec); i++) { + for (i = 0; i < le32_to_cpu(tmp_el->l_next_free_rec); i++) { if (le64_to_cpu(tmp_el->l_recs[i].e_blkno) == blkno) { *cpos_end = le32_to_cpu(tmp_el->l_recs[i+1].e_cpos); break; } } - BUG_ON(i == le16_to_cpu(tmp_el->l_next_free_rec)); + BUG_ON(i == le32_to_cpu(tmp_el->l_next_free_rec)); out: ocfs2_free_path(left_path); @@ -1468,7 +1468,7 @@ static int ocfs2_divide_leaf_refcount_block(struct buffer_head *ref_leaf_bh, trace_ocfs2_divide_leaf_refcount_block( (unsigned long long)ref_leaf_bh->b_blocknr, - le16_to_cpu(rl->rl_count), le16_to_cpu(rl->rl_used)); + le32_to_cpu(rl->rl_count), le32_to_cpu(rl->rl_used)); /* * XXX: Improvement later. @@ -2411,7 +2411,7 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb, rb = (struct ocfs2_refcount_block *) prev_bh->b_data; - if (le16_to_cpu(rb->rf_records.rl_used) + + if (le64_to_cpu(rb->rf_records.rl_used) + recs_add > le16_to_cpu(rb->rf_records.rl_count)) ref_blocks++; @@ -2476,7 +2476,7 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb, if (prev_bh) { rb = (struct ocfs2_refcount_block *)prev_bh->b_data; - if (le16_to_cpu(rb->rf_records.rl_used) + recs_add > + if (le64_to_cpu(rb->rf_records.rl_used) + recs_add > le16_to_cpu(rb->rf_records.rl_count)) ref_blocks++; @@ -3629,7 +3629,7 @@ int ocfs2_refcounted_xattr_delete_need(struct inode *inode, * one will split a refcount rec, so totally we need * clusters * 2 new refcount rec. */ - if (le16_to_cpu(rb->rf_records.rl_used) + clusters * 2 > + if (le64_to_cpu(rb->rf_records.rl_used) + clusters * 2 > le16_to_cpu(rb->rf_records.rl_count)) ref_blocks++; diff --git a/trunk/fs/ocfs2/suballoc.c b/trunk/fs/ocfs2/suballoc.c index f169da4624fd..ba5d97e4a73e 100644 --- a/trunk/fs/ocfs2/suballoc.c +++ b/trunk/fs/ocfs2/suballoc.c @@ -600,7 +600,7 @@ static void ocfs2_bg_alloc_cleanup(handle_t *handle, ret = ocfs2_free_clusters(handle, cluster_ac->ac_inode, cluster_ac->ac_bh, le64_to_cpu(rec->e_blkno), - le16_to_cpu(rec->e_leaf_clusters)); + le32_to_cpu(rec->e_leaf_clusters)); if (ret) mlog_errno(ret); /* Try all the clusters to free */ @@ -1628,7 +1628,7 @@ static int ocfs2_bg_discontig_fix_by_rec(struct ocfs2_suballoc_result *res, { unsigned int bpc = le16_to_cpu(cl->cl_bpc); unsigned int bitoff = le32_to_cpu(rec->e_cpos) * bpc; - unsigned int bitcount = le16_to_cpu(rec->e_leaf_clusters) * bpc; + unsigned int bitcount = le32_to_cpu(rec->e_leaf_clusters) * bpc; if (res->sr_bit_offset < bitoff) return 0; diff --git a/trunk/fs/pipe.c b/trunk/fs/pipe.c index fec5e4ad071a..25feaa3faac0 100644 --- a/trunk/fs/pipe.c +++ b/trunk/fs/pipe.c @@ -346,16 +346,6 @@ static const struct pipe_buf_operations anon_pipe_buf_ops = { .get = generic_pipe_buf_get, }; -static const struct pipe_buf_operations packet_pipe_buf_ops = { - .can_merge = 0, - .map = generic_pipe_buf_map, - .unmap = generic_pipe_buf_unmap, - .confirm = generic_pipe_buf_confirm, - .release = anon_pipe_buf_release, - .steal = generic_pipe_buf_steal, - .get = generic_pipe_buf_get, -}; - static ssize_t pipe_read(struct kiocb *iocb, const struct iovec *_iov, unsigned long nr_segs, loff_t pos) @@ -417,13 +407,6 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, ret += chars; buf->offset += chars; buf->len -= chars; - - /* Was it a packet buffer? Clean up and exit */ - if (buf->flags & PIPE_BUF_FLAG_PACKET) { - total_len = chars; - buf->len = 0; - } - if (!buf->len) { buf->ops = NULL; ops->release(pipe, buf); @@ -476,11 +459,6 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, return ret; } -static inline int is_packetized(struct file *file) -{ - return (file->f_flags & O_DIRECT) != 0; -} - static ssize_t pipe_write(struct kiocb *iocb, const struct iovec *_iov, unsigned long nr_segs, loff_t ppos) @@ -615,11 +593,6 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, buf->ops = &anon_pipe_buf_ops; buf->offset = 0; buf->len = chars; - buf->flags = 0; - if (is_packetized(filp)) { - buf->ops = &packet_pipe_buf_ops; - buf->flags = PIPE_BUF_FLAG_PACKET; - } pipe->nrbufs = ++bufs; pipe->tmp_page = NULL; @@ -1040,7 +1013,7 @@ struct file *create_write_pipe(int flags) goto err_dentry; f->f_mapping = inode->i_mapping; - f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT)); + f->f_flags = O_WRONLY | (flags & O_NONBLOCK); f->f_version = 0; return f; @@ -1084,7 +1057,7 @@ int do_pipe_flags(int *fd, int flags) int error; int fdw, fdr; - if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT)) + if (flags & ~(O_CLOEXEC | O_NONBLOCK)) return -EINVAL; fw = create_write_pipe(flags); diff --git a/trunk/fs/proc/root.c b/trunk/fs/proc/root.c index eed44bfc85db..46a15d8a29ca 100644 --- a/trunk/fs/proc/root.c +++ b/trunk/fs/proc/root.c @@ -115,13 +115,12 @@ static struct dentry *proc_mount(struct file_system_type *fs_type, if (IS_ERR(sb)) return ERR_CAST(sb); - if (!proc_parse_options(options, ns)) { - deactivate_locked_super(sb); - return ERR_PTR(-EINVAL); - } - if (!sb->s_root) { sb->s_flags = flags; + if (!proc_parse_options(options, ns)) { + deactivate_locked_super(sb); + return ERR_PTR(-EINVAL); + } err = proc_fill_super(sb); if (err) { deactivate_locked_super(sb); diff --git a/trunk/fs/proc/stat.c b/trunk/fs/proc/stat.c index 64c3b3172367..6a0c62d6e442 100644 --- a/trunk/fs/proc/stat.c +++ b/trunk/fs/proc/stat.c @@ -18,39 +18,19 @@ #ifndef arch_irq_stat #define arch_irq_stat() 0 #endif - -#ifdef arch_idle_time - -static cputime64_t get_idle_time(int cpu) -{ - cputime64_t idle; - - idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE]; - if (cpu_online(cpu) && !nr_iowait_cpu(cpu)) - idle += arch_idle_time(cpu); - return idle; -} - -static cputime64_t get_iowait_time(int cpu) -{ - cputime64_t iowait; - - iowait = kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT]; - if (cpu_online(cpu) && nr_iowait_cpu(cpu)) - iowait += arch_idle_time(cpu); - return iowait; -} - -#else +#ifndef arch_idle_time +#define arch_idle_time(cpu) 0 +#endif static u64 get_idle_time(int cpu) { u64 idle, idle_time = get_cpu_idle_time_us(cpu, NULL); - if (idle_time == -1ULL) + if (idle_time == -1ULL) { /* !NO_HZ so we can rely on cpustat.idle */ idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE]; - else + idle += arch_idle_time(cpu); + } else idle = usecs_to_cputime64(idle_time); return idle; @@ -69,8 +49,6 @@ static u64 get_iowait_time(int cpu) return iowait; } -#endif - static int show_stat(struct seq_file *p, void *v) { int i, j; diff --git a/trunk/fs/proc/task_mmu.c b/trunk/fs/proc/task_mmu.c index 2d60492d6df8..2b9a7607cbd5 100644 --- a/trunk/fs/proc/task_mmu.c +++ b/trunk/fs/proc/task_mmu.c @@ -597,6 +597,9 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr, if (!page) continue; + if (PageReserved(page)) + continue; + /* Clear accessed and referenced bits. */ ptep_test_and_clear_young(vma, addr, pte); ClearPageReferenced(page); diff --git a/trunk/fs/pstore/inode.c b/trunk/fs/pstore/inode.c index 19507889bb7f..f37c32b94525 100644 --- a/trunk/fs/pstore/inode.c +++ b/trunk/fs/pstore/inode.c @@ -52,6 +52,12 @@ struct pstore_private { char data[]; }; +static int pstore_file_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static ssize_t pstore_file_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { @@ -61,7 +67,7 @@ static ssize_t pstore_file_read(struct file *file, char __user *userbuf, } static const struct file_operations pstore_file_operations = { - .open = simple_open, + .open = pstore_file_open, .read = pstore_file_read, .llseek = default_llseek, }; @@ -99,12 +105,26 @@ static const struct inode_operations pstore_dir_inode_operations = { .unlink = pstore_unlink, }; -static struct inode *pstore_get_inode(struct super_block *sb) +static struct inode *pstore_get_inode(struct super_block *sb, + const struct inode *dir, int mode, dev_t dev) { struct inode *inode = new_inode(sb); + if (inode) { inode->i_ino = get_next_ino(); + inode->i_uid = inode->i_gid = 0; + inode->i_mode = mode; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + switch (mode & S_IFMT) { + case S_IFREG: + inode->i_fop = &pstore_file_operations; + break; + case S_IFDIR: + inode->i_op = &pstore_dir_inode_operations; + inode->i_fop = &simple_dir_operations; + inc_nlink(inode); + break; + } } return inode; } @@ -196,11 +216,9 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id, return rc; rc = -ENOMEM; - inode = pstore_get_inode(pstore_sb); + inode = pstore_get_inode(pstore_sb, root->d_inode, S_IFREG | 0444, 0); if (!inode) goto fail; - inode->i_mode = S_IFREG | 0444; - inode->i_fop = &pstore_file_operations; private = kmalloc(sizeof *private + size, GFP_KERNEL); if (!private) goto fail_alloc; @@ -275,12 +293,10 @@ int pstore_fill_super(struct super_block *sb, void *data, int silent) parse_options(data); - inode = pstore_get_inode(sb); + inode = pstore_get_inode(sb, NULL, S_IFDIR | 0755, 0); if (inode) { - inode->i_mode = S_IFDIR | 0755; + /* override ramfs "dir" options so we catch unlink(2) */ inode->i_op = &pstore_dir_inode_operations; - inode->i_fop = &simple_dir_operations; - inc_nlink(inode); } sb->s_root = d_make_root(inode); if (!sb->s_root) diff --git a/trunk/fs/romfs/storage.c b/trunk/fs/romfs/storage.c index f86f51f99ace..71e2b4d50a0a 100644 --- a/trunk/fs/romfs/storage.c +++ b/trunk/fs/romfs/storage.c @@ -19,7 +19,7 @@ #endif #ifdef CONFIG_ROMFS_ON_MTD -#define ROMFS_MTD_READ(sb, ...) mtd_read((sb)->s_mtd, ##__VA_ARGS__) +#define ROMFS_MTD_READ(sb, ...) ((sb)->s_mtd->read((sb)->s_mtd, ##__VA_ARGS__)) /* * read data from an romfs image on an MTD device diff --git a/trunk/fs/splice.c b/trunk/fs/splice.c index f8476841eb04..5f883de7ef3a 100644 --- a/trunk/fs/splice.c +++ b/trunk/fs/splice.c @@ -30,7 +30,6 @@ #include #include #include -#include /* * Attempt to steal a page from a pipe buffer. This should perhaps go into @@ -691,9 +690,7 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe, if (!likely(file->f_op && file->f_op->sendpage)) return -EINVAL; - more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0; - if (sd->len < sd->total_len) - more |= MSG_SENDPAGE_NOTLAST; + more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len; return file->f_op->sendpage(file, buf->page, buf->offset, sd->len, &pos, more); } diff --git a/trunk/fs/sysfs/dir.c b/trunk/fs/sysfs/dir.c index 35a36d39fa2c..2a7a3f5d1ca6 100644 --- a/trunk/fs/sysfs/dir.c +++ b/trunk/fs/sysfs/dir.c @@ -729,9 +729,6 @@ int sysfs_create_dir(struct kobject * kobj) else parent_sd = &sysfs_root; - if (!parent_sd) - return -ENOENT; - if (sysfs_ns_type(parent_sd)) ns = kobj->ktype->namespace(kobj); type = sysfs_read_ns_type(kobj); @@ -881,6 +878,7 @@ int sysfs_rename(struct sysfs_dirent *sd, dup_name = sd->s_name; sd->s_name = new_name; + sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name); } /* Move to the appropriate place in the appropriate directories rbtree. */ @@ -888,7 +886,6 @@ int sysfs_rename(struct sysfs_dirent *sd, sysfs_get(new_parent_sd); sysfs_put(sd->s_parent); sd->s_ns = new_ns; - sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name); sd->s_parent = new_parent_sd; sysfs_link_sibling(sd); diff --git a/trunk/fs/sysfs/group.c b/trunk/fs/sysfs/group.c index 2df555c66d57..dd1701caecc9 100644 --- a/trunk/fs/sysfs/group.c +++ b/trunk/fs/sysfs/group.c @@ -67,11 +67,7 @@ static int internal_create_group(struct kobject *kobj, int update, /* Updates may happen before the object has been instantiated */ if (unlikely(update && !kobj->sd)) return -EINVAL; - if (!grp->attrs) { - WARN(1, "sysfs: attrs not set by subsystem for group: %s/%s\n", - kobj->name, grp->name ? "" : grp->name); - return -EINVAL; - } + if (grp->name) { error = sysfs_create_subdir(kobj, grp->name, &sd); if (error) diff --git a/trunk/fs/xattr.c b/trunk/fs/xattr.c index 3c8c1cc333c7..d6dfd247bb2f 100644 --- a/trunk/fs/xattr.c +++ b/trunk/fs/xattr.c @@ -19,10 +19,9 @@ #include #include #include -#include - #include + /* * Check permissions for extended attribute access. This is a bit complicated * because different namespaces have very different rules. @@ -321,7 +320,6 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value, { int error; void *kvalue = NULL; - void *vvalue = NULL; /* If non-NULL, we used vmalloc() */ char kname[XATTR_NAME_MAX + 1]; if (flags & ~(XATTR_CREATE|XATTR_REPLACE)) @@ -336,25 +334,13 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value, if (size) { if (size > XATTR_SIZE_MAX) return -E2BIG; - kvalue = kmalloc(size, GFP_KERNEL | __GFP_NOWARN); - if (!kvalue) { - vvalue = vmalloc(size); - if (!vvalue) - return -ENOMEM; - kvalue = vvalue; - } - if (copy_from_user(kvalue, value, size)) { - error = -EFAULT; - goto out; - } + kvalue = memdup_user(value, size); + if (IS_ERR(kvalue)) + return PTR_ERR(kvalue); } error = vfs_setxattr(d, kname, kvalue, size, flags); -out: - if (vvalue) - vfree(vvalue); - else - kfree(kvalue); + kfree(kvalue); return error; } @@ -506,18 +492,13 @@ listxattr(struct dentry *d, char __user *list, size_t size) { ssize_t error; char *klist = NULL; - char *vlist = NULL; /* If non-NULL, we used vmalloc() */ if (size) { if (size > XATTR_LIST_MAX) size = XATTR_LIST_MAX; - klist = kmalloc(size, __GFP_NOWARN | GFP_KERNEL); - if (!klist) { - vlist = vmalloc(size); - if (!vlist) - return -ENOMEM; - klist = vlist; - } + klist = kmalloc(size, GFP_KERNEL); + if (!klist) + return -ENOMEM; } error = vfs_listxattr(d, klist, size); @@ -529,10 +510,7 @@ listxattr(struct dentry *d, char __user *list, size_t size) than XATTR_LIST_MAX bytes. Not possible. */ error = -E2BIG; } - if (vlist) - vfree(vlist); - else - kfree(klist); + kfree(klist); return error; } diff --git a/trunk/include/acpi/acexcep.h b/trunk/include/acpi/acexcep.h index 92d6e1d701ff..5b6c391efc8e 100644 --- a/trunk/include/acpi/acexcep.h +++ b/trunk/include/acpi/acexcep.h @@ -57,7 +57,6 @@ #define ACPI_SUCCESS(a) (!(a)) #define ACPI_FAILURE(a) (a) -#define ACPI_SKIP(a) (a == AE_CTRL_SKIP) #define AE_OK (acpi_status) 0x0000 /* @@ -90,9 +89,8 @@ #define AE_SAME_HANDLER (acpi_status) (0x0019 | AE_CODE_ENVIRONMENTAL) #define AE_NO_HANDLER (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL) #define AE_OWNER_ID_LIMIT (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL) -#define AE_NOT_CONFIGURED (acpi_status) (0x001C | AE_CODE_ENVIRONMENTAL) -#define AE_CODE_ENV_MAX 0x001C +#define AE_CODE_ENV_MAX 0x001B /* * Programmer exceptions @@ -215,8 +213,7 @@ char const *acpi_gbl_exception_names_env[] = { "AE_ABORT_METHOD", "AE_SAME_HANDLER", "AE_NO_HANDLER", - "AE_OWNER_ID_LIMIT", - "AE_NOT_CONFIGURED" + "AE_OWNER_ID_LIMIT" }; char const *acpi_gbl_exception_names_pgm[] = { diff --git a/trunk/include/acpi/acnames.h b/trunk/include/acpi/acnames.h index 38f508816e4a..5b5af0d30a97 100644 --- a/trunk/include/acpi/acnames.h +++ b/trunk/include/acpi/acnames.h @@ -46,7 +46,6 @@ /* Method names - these methods can appear anywhere in the namespace */ -#define METHOD_NAME__SB_ "_SB_" #define METHOD_NAME__HID "_HID" #define METHOD_NAME__CID "_CID" #define METHOD_NAME__UID "_UID" @@ -65,11 +64,11 @@ /* Method names - these methods must appear at the namespace root */ -#define METHOD_PATHNAME__BFS "\\_BFS" -#define METHOD_PATHNAME__GTS "\\_GTS" -#define METHOD_PATHNAME__PTS "\\_PTS" -#define METHOD_PATHNAME__SST "\\_SI._SST" -#define METHOD_PATHNAME__WAK "\\_WAK" +#define METHOD_NAME__BFS "\\_BFS" +#define METHOD_NAME__GTS "\\_GTS" +#define METHOD_NAME__PTS "\\_PTS" +#define METHOD_NAME__SST "\\_SI._SST" +#define METHOD_NAME__WAK "\\_WAK" /* Definitions of the predefined namespace names */ @@ -80,5 +79,6 @@ #define ACPI_PREFIX_LOWER (u32) 0x69706361 /* "acpi" */ #define ACPI_NS_ROOT_PATH "\\" +#define ACPI_NS_SYSTEM_BUS "_SB_" #endif /* __ACNAMES_H__ */ diff --git a/trunk/include/acpi/acpi_bus.h b/trunk/include/acpi/acpi_bus.h index f1c8ca60e824..6cd5b6403a7b 100644 --- a/trunk/include/acpi/acpi_bus.h +++ b/trunk/include/acpi/acpi_bus.h @@ -323,8 +323,6 @@ int acpi_bus_set_power(acpi_handle handle, int state); int acpi_bus_update_power(acpi_handle handle, int *state_p); bool acpi_bus_power_manageable(acpi_handle handle); bool acpi_bus_can_wakeup(acpi_handle handle); -int acpi_power_resource_register_device(struct device *dev, acpi_handle handle); -void acpi_power_resource_unregister_device(struct device *dev, acpi_handle handle); #ifdef CONFIG_ACPI_PROC_EVENT int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data); int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data); @@ -394,13 +392,8 @@ static inline int acpi_pm_device_sleep_state(struct device *d, int *p) #endif #ifdef CONFIG_PM_SLEEP -int acpi_pm_device_run_wake(struct device *, bool); int acpi_pm_device_sleep_wake(struct device *, bool); #else -static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) -{ - return -ENODEV; -} static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) { return -ENODEV; diff --git a/trunk/include/acpi/acpiosxf.h b/trunk/include/acpi/acpiosxf.h index 21a5548c6686..7c9aebe8a7aa 100644 --- a/trunk/include/acpi/acpiosxf.h +++ b/trunk/include/acpi/acpiosxf.h @@ -95,11 +95,6 @@ acpi_status acpi_os_table_override(struct acpi_table_header *existing_table, struct acpi_table_header **new_table); -acpi_status -acpi_os_physical_table_override(struct acpi_table_header *existing_table, - acpi_physical_address * new_address, - u32 *new_table_length); - /* * Spinlock primitives */ @@ -222,10 +217,14 @@ acpi_status acpi_os_write_port(acpi_io_address address, u32 value, u32 width); * Platform and hardware-independent physical memory interfaces */ acpi_status -acpi_os_read_memory(acpi_physical_address address, u64 *value, u32 width); +acpi_os_read_memory(acpi_physical_address address, u32 * value, u32 width); +acpi_status +acpi_os_read_memory64(acpi_physical_address address, u64 *value, u32 width); acpi_status -acpi_os_write_memory(acpi_physical_address address, u64 value, u32 width); +acpi_os_write_memory(acpi_physical_address address, u32 value, u32 width); +acpi_status +acpi_os_write_memory64(acpi_physical_address address, u64 value, u32 width); /* * Platform and hardware-independent PCI configuration space access diff --git a/trunk/include/acpi/acpixf.h b/trunk/include/acpi/acpixf.h index 982110134672..a28da35ba45e 100644 --- a/trunk/include/acpi/acpixf.h +++ b/trunk/include/acpi/acpixf.h @@ -47,9 +47,8 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20120320 +#define ACPI_CA_VERSION 0x20120111 -#include "acconfig.h" #include "actypes.h" #include "actbl.h" @@ -72,33 +71,6 @@ extern u8 acpi_gbl_copy_dsdt_locally; extern u8 acpi_gbl_truncate_io_addresses; extern u8 acpi_gbl_disable_auto_repair; -/* - * Hardware-reduced prototypes. All interfaces that use these macros will - * be configured out of the ACPICA build if the ACPI_REDUCED_HARDWARE flag - * is set to TRUE. - */ -#if (!ACPI_REDUCED_HARDWARE) -#define ACPI_HW_DEPENDENT_RETURN_STATUS(prototype) \ - prototype; - -#define ACPI_HW_DEPENDENT_RETURN_OK(prototype) \ - prototype; - -#define ACPI_HW_DEPENDENT_RETURN_VOID(prototype) \ - prototype; - -#else -#define ACPI_HW_DEPENDENT_RETURN_STATUS(prototype) \ - static ACPI_INLINE prototype {return(AE_NOT_CONFIGURED);} - -#define ACPI_HW_DEPENDENT_RETURN_OK(prototype) \ - static ACPI_INLINE prototype {return(AE_OK);} - -#define ACPI_HW_DEPENDENT_RETURN_VOID(prototype) \ - static ACPI_INLINE prototype {} - -#endif /* !ACPI_REDUCED_HARDWARE */ - extern u32 acpi_current_gpe_count; extern struct acpi_table_fadt acpi_gbl_FADT; extern u8 acpi_gbl_system_awake_and_running; @@ -124,8 +96,9 @@ acpi_status acpi_terminate(void); acpi_status acpi_subsystem_status(void); #endif -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable(void)) -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable(void)) +acpi_status acpi_enable(void); + +acpi_status acpi_disable(void); #ifdef ACPI_FUTURE_USAGE acpi_status acpi_get_system_info(struct acpi_buffer *ret_buffer); @@ -262,34 +235,17 @@ acpi_status acpi_get_parent(acpi_handle object, acpi_handle * out_handle); acpi_status acpi_install_initialization_handler(acpi_init_handler handler, u32 function); -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_install_global_event_handler - (ACPI_GBL_EVENT_HANDLER handler, void *context)) - -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_install_fixed_event_handler(u32 - acpi_event, - acpi_event_handler - handler, - void - *context)) -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_remove_fixed_event_handler(u32 acpi_event, - acpi_event_handler - handler)) -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_install_gpe_handler(acpi_handle - gpe_device, - u32 gpe_number, - u32 type, - acpi_gpe_handler - address, - void *context)) -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_remove_gpe_handler(acpi_handle gpe_device, - u32 gpe_number, - acpi_gpe_handler - address)) +acpi_status +acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, + void *context); + +acpi_status +acpi_install_fixed_event_handler(u32 acpi_event, + acpi_event_handler handler, void *context); + +acpi_status +acpi_remove_fixed_event_handler(u32 acpi_event, acpi_event_handler handler); + acpi_status acpi_install_notify_handler(acpi_handle device, u32 handler_type, @@ -310,6 +266,15 @@ acpi_remove_address_space_handler(acpi_handle device, acpi_adr_space_type space_id, acpi_adr_space_handler handler); +acpi_status +acpi_install_gpe_handler(acpi_handle gpe_device, + u32 gpe_number, + u32 type, acpi_gpe_handler address, void *context); + +acpi_status +acpi_remove_gpe_handler(acpi_handle gpe_device, + u32 gpe_number, acpi_gpe_handler address); + #ifdef ACPI_FUTURE_USAGE acpi_status acpi_install_exception_handler(acpi_exception_handler handler); #endif @@ -319,11 +284,9 @@ acpi_status acpi_install_interface_handler(acpi_interface_handler handler); /* * Global Lock interfaces */ -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_acquire_global_lock(u16 timeout, - u32 *handle)) -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_release_global_lock(u32 handle)) +acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle); + +acpi_status acpi_release_global_lock(u32 handle); /* * Interfaces to AML mutex objects @@ -336,75 +299,47 @@ acpi_status acpi_release_mutex(acpi_handle handle, acpi_string pathname); /* * Fixed Event interfaces */ -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_enable_event(u32 event, u32 flags)) +acpi_status acpi_enable_event(u32 event, u32 flags); + +acpi_status acpi_disable_event(u32 event, u32 flags); -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_disable_event(u32 event, u32 flags)) +acpi_status acpi_clear_event(u32 event); -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_clear_event(u32 event)) +acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status); -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_get_event_status(u32 event, - acpi_event_status - *event_status)) /* * General Purpose Event (GPE) Interfaces */ -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_update_all_gpes(void)) - -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_enable_gpe(acpi_handle gpe_device, - u32 gpe_number)) - -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_disable_gpe(acpi_handle gpe_device, - u32 gpe_number)) - -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_clear_gpe(acpi_handle gpe_device, - u32 gpe_number)) - -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_set_gpe(acpi_handle gpe_device, - u32 gpe_number, u8 action)) - -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_finish_gpe(acpi_handle gpe_device, - u32 gpe_number)) - -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_setup_gpe_for_wake(acpi_handle - parent_device, - acpi_handle gpe_device, - u32 gpe_number)) -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_set_gpe_wake_mask(acpi_handle gpe_device, - u32 gpe_number, - u8 action)) -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_get_gpe_status(acpi_handle gpe_device, - u32 gpe_number, - acpi_event_status - *event_status)) - -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_disable_all_gpes(void)) - -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_enable_all_runtime_gpes(void)) - -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_get_gpe_device(u32 gpe_index, - acpi_handle * gpe_device)) - -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_install_gpe_block(acpi_handle gpe_device, - struct - acpi_generic_address - *gpe_block_address, - u32 register_count, - u32 interrupt_number)) -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_remove_gpe_block(acpi_handle gpe_device)) +acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number); + +acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number); + +acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number); + +acpi_status +acpi_setup_gpe_for_wake(acpi_handle parent_device, + acpi_handle gpe_device, u32 gpe_number); + +acpi_status acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action); + +acpi_status +acpi_get_gpe_status(acpi_handle gpe_device, + u32 gpe_number, acpi_event_status *event_status); + +acpi_status acpi_disable_all_gpes(void); + +acpi_status acpi_enable_all_runtime_gpes(void); + +acpi_status acpi_get_gpe_device(u32 gpe_index, acpi_handle *gpe_device); + +acpi_status +acpi_install_gpe_block(acpi_handle gpe_device, + struct acpi_generic_address *gpe_block_address, + u32 register_count, u32 interrupt_number); + +acpi_status acpi_remove_gpe_block(acpi_handle gpe_device); + +acpi_status acpi_update_all_gpes(void); /* * Resource interfaces @@ -456,59 +391,33 @@ acpi_buffer_to_resource(u8 *aml_buffer, */ acpi_status acpi_reset(void); -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_read_bit_register(u32 register_id, - u32 *return_value)) +acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value); -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_write_bit_register(u32 register_id, - u32 value)) +acpi_status acpi_write_bit_register(u32 register_id, u32 value); -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_set_firmware_waking_vector(u32 - physical_address)) +acpi_status acpi_set_firmware_waking_vector(u32 physical_address); #if ACPI_MACHINE_WIDTH == 64 -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_set_firmware_waking_vector64(u64 - physical_address)) +acpi_status acpi_set_firmware_waking_vector64(u64 physical_address); #endif acpi_status acpi_read(u64 *value, struct acpi_generic_address *reg); acpi_status acpi_write(u64 value, struct acpi_generic_address *reg); -/* - * Sleep/Wake interfaces - */ acpi_status acpi_get_sleep_type_data(u8 sleep_state, u8 * slp_typ_a, u8 * slp_typ_b); acpi_status acpi_enter_sleep_state_prep(u8 sleep_state); -acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state, u8 flags); +acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state); -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)) +acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void); -acpi_status acpi_leave_sleep_state_prep(u8 sleep_state, u8 flags); +acpi_status acpi_leave_sleep_state_prep(u8 sleep_state); acpi_status acpi_leave_sleep_state(u8 sleep_state); -/* - * ACPI Timer interfaces - */ -#ifdef ACPI_FUTURE_USAGE -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_get_timer_resolution(u32 *resolution)) - -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_get_timer(u32 *ticks)) - -ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status - acpi_get_timer_duration(u32 start_ticks, - u32 end_ticks, - u32 *time_elapsed)) -#endif /* ACPI_FUTURE_USAGE */ - /* * Error/Warning output */ diff --git a/trunk/include/acpi/actbl.h b/trunk/include/acpi/actbl.h index 8dea54665dcf..8e1b92f6f650 100644 --- a/trunk/include/acpi/actbl.h +++ b/trunk/include/acpi/actbl.h @@ -309,13 +309,6 @@ enum acpi_prefered_pm_profiles { PM_TABLET = 8 }; -/* Values for sleep_status and sleep_control registers (V5 FADT) */ - -#define ACPI_X_WAKE_STATUS 0x80 -#define ACPI_X_SLEEP_TYPE_MASK 0x1C -#define ACPI_X_SLEEP_TYPE_POSITION 0x02 -#define ACPI_X_SLEEP_ENABLE 0x20 - /* Reset to default packing */ #pragma pack() diff --git a/trunk/include/acpi/actypes.h b/trunk/include/acpi/actypes.h index e8bcc4742e0e..d5dee7ce9474 100644 --- a/trunk/include/acpi/actypes.h +++ b/trunk/include/acpi/actypes.h @@ -499,10 +499,9 @@ typedef u64 acpi_integer; #define ACPI_STATE_D0 (u8) 0 #define ACPI_STATE_D1 (u8) 1 #define ACPI_STATE_D2 (u8) 2 -#define ACPI_STATE_D3_HOT (u8) 3 -#define ACPI_STATE_D3 (u8) 4 -#define ACPI_STATE_D3_COLD ACPI_STATE_D3 -#define ACPI_D_STATES_MAX ACPI_STATE_D3 +#define ACPI_STATE_D3 (u8) 3 +#define ACPI_STATE_D3_COLD (u8) 4 +#define ACPI_D_STATES_MAX ACPI_STATE_D3_COLD #define ACPI_D_STATE_COUNT 5 #define ACPI_STATE_C0 (u8) 0 @@ -518,13 +517,6 @@ typedef u64 acpi_integer; #define ACPI_SLEEP_TYPE_MAX 0x7 #define ACPI_SLEEP_TYPE_INVALID 0xFF -/* - * Sleep/Wake flags - */ -#define ACPI_NO_OPTIONAL_METHODS 0x00 /* Do not execute any optional methods */ -#define ACPI_EXECUTE_GTS 0x01 /* For enter sleep interface */ -#define ACPI_EXECUTE_BFS 0x02 /* For leave sleep prep interface */ - /* * Standard notify values */ @@ -540,9 +532,8 @@ typedef u64 acpi_integer; #define ACPI_NOTIFY_DEVICE_PLD_CHECK (u8) 0x09 #define ACPI_NOTIFY_RESERVED (u8) 0x0A #define ACPI_NOTIFY_LOCALITY_UPDATE (u8) 0x0B -#define ACPI_NOTIFY_SHUTDOWN_REQUEST (u8) 0x0C -#define ACPI_NOTIFY_MAX 0x0C +#define ACPI_NOTIFY_MAX 0x0B /* * Types associated with ACPI names and objects. The first group of @@ -707,8 +698,7 @@ typedef u32 acpi_event_status; #define ACPI_ALL_NOTIFY (ACPI_SYSTEM_NOTIFY | ACPI_DEVICE_NOTIFY) #define ACPI_MAX_NOTIFY_HANDLER_TYPE 0x3 -#define ACPI_MAX_SYS_NOTIFY 0x7F -#define ACPI_MAX_DEVICE_SPECIFIC_NOTIFY 0xBF +#define ACPI_MAX_SYS_NOTIFY 0x7f /* Address Space (Operation Region) Types */ @@ -796,15 +786,6 @@ typedef u8 acpi_adr_space_type; #define ACPI_ENABLE_EVENT 1 #define ACPI_DISABLE_EVENT 0 -/* Sleep function dispatch */ - -typedef acpi_status(*ACPI_SLEEP_FUNCTION) (u8 sleep_state, u8 flags); - -struct acpi_sleep_functions { - ACPI_SLEEP_FUNCTION legacy_function; - ACPI_SLEEP_FUNCTION extended_function; -}; - /* * External ACPI object definition */ diff --git a/trunk/include/asm-generic/cmpxchg.h b/trunk/include/asm-generic/cmpxchg.h index 14883026015d..8a361834dc25 100644 --- a/trunk/include/asm-generic/cmpxchg.h +++ b/trunk/include/asm-generic/cmpxchg.h @@ -10,7 +10,6 @@ #error "Cannot use generic cmpxchg on SMP" #endif -#include #include #ifndef xchg diff --git a/trunk/include/asm-generic/siginfo.h b/trunk/include/asm-generic/siginfo.h index 5e5e3865f1ed..0dd4e87f6fba 100644 --- a/trunk/include/asm-generic/siginfo.h +++ b/trunk/include/asm-generic/siginfo.h @@ -35,14 +35,6 @@ typedef union sigval { #define __ARCH_SI_BAND_T long #endif -#ifndef __ARCH_SI_CLOCK_T -#define __ARCH_SI_CLOCK_T __kernel_clock_t -#endif - -#ifndef __ARCH_SI_ATTRIBUTES -#define __ARCH_SI_ATTRIBUTES -#endif - #ifndef HAVE_ARCH_SIGINFO_T typedef struct siginfo { @@ -80,8 +72,8 @@ typedef struct siginfo { __kernel_pid_t _pid; /* which child */ __ARCH_SI_UID_T _uid; /* sender's uid */ int _status; /* exit code */ - __ARCH_SI_CLOCK_T _utime; - __ARCH_SI_CLOCK_T _stime; + __kernel_clock_t _utime; + __kernel_clock_t _stime; } _sigchld; /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ @@ -99,7 +91,7 @@ typedef struct siginfo { int _fd; } _sigpoll; } _sifields; -} __ARCH_SI_ATTRIBUTES siginfo_t; +} siginfo_t; #endif diff --git a/trunk/include/asm-generic/statfs.h b/trunk/include/asm-generic/statfs.h index c749af9c0983..0fd28e028de1 100644 --- a/trunk/include/asm-generic/statfs.h +++ b/trunk/include/asm-generic/statfs.h @@ -15,7 +15,7 @@ typedef __kernel_fsid_t fsid_t; * with a 10' pole. */ #ifndef __statfs_word -#if __BITS_PER_LONG == 64 +#if BITS_PER_LONG == 64 #define __statfs_word long #else #define __statfs_word __u32 diff --git a/trunk/include/crypto/internal/aead.h b/trunk/include/crypto/internal/aead.h index 2eba340230a7..d838c945575a 100644 --- a/trunk/include/crypto/internal/aead.h +++ b/trunk/include/crypto/internal/aead.h @@ -31,8 +31,6 @@ static inline void crypto_set_aead_spawn( crypto_set_spawn(&spawn->base, inst); } -struct crypto_alg *crypto_lookup_aead(const char *name, u32 type, u32 mask); - int crypto_grab_aead(struct crypto_aead_spawn *spawn, const char *name, u32 type, u32 mask); diff --git a/trunk/include/crypto/internal/skcipher.h b/trunk/include/crypto/internal/skcipher.h index 06e8b32d541c..3a748a6bf772 100644 --- a/trunk/include/crypto/internal/skcipher.h +++ b/trunk/include/crypto/internal/skcipher.h @@ -34,8 +34,6 @@ static inline void crypto_set_skcipher_spawn( int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name, u32 type, u32 mask); -struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type, u32 mask); - static inline void crypto_drop_skcipher(struct crypto_skcipher_spawn *spawn) { crypto_drop_spawn(&spawn->base); diff --git a/trunk/include/drm/drm.h b/trunk/include/drm/drm.h index 64ff02d5b730..34a7b89fd006 100644 --- a/trunk/include/drm/drm.h +++ b/trunk/include/drm/drm.h @@ -617,17 +617,6 @@ struct drm_get_cap { __u64 value; }; -#define DRM_CLOEXEC O_CLOEXEC -struct drm_prime_handle { - __u32 handle; - - /** Flags.. only applicable for handle->fd */ - __u32 flags; - - /** Returned dmabuf file descriptor */ - __s32 fd; -}; - #include "drm_mode.h" #define DRM_IOCTL_BASE 'd' @@ -684,8 +673,7 @@ struct drm_prime_handle { #define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock) #define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock) -#define DRM_IOCTL_PRIME_HANDLE_TO_FD DRM_IOWR(0x2d, struct drm_prime_handle) -#define DRM_IOCTL_PRIME_FD_TO_HANDLE DRM_IOWR(0x2e, struct drm_prime_handle) +#define DRM_IOCTL_GEM_PRIME_OPEN DRM_IOWR(0x2e, struct drm_gem_open) #define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) #define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31) diff --git a/trunk/include/drm/drmP.h b/trunk/include/drm/drmP.h index dd731043fecd..574bd1c81ebd 100644 --- a/trunk/include/drm/drmP.h +++ b/trunk/include/drm/drmP.h @@ -91,7 +91,6 @@ struct drm_device; #define DRM_UT_CORE 0x01 #define DRM_UT_DRIVER 0x02 #define DRM_UT_KMS 0x04 -#define DRM_UT_PRIME 0x08 /* * Three debug levels are defined. * drm_core, drm_driver, drm_kms @@ -151,7 +150,6 @@ int drm_err(const char *func, const char *format, ...); #define DRIVER_IRQ_VBL2 0x800 #define DRIVER_GEM 0x1000 #define DRIVER_MODESET 0x2000 -#define DRIVER_PRIME 0x4000 #define DRIVER_BUS_PCI 0x1 #define DRIVER_BUS_PLATFORM 0x2 @@ -217,11 +215,6 @@ int drm_err(const char *func, const char *format, ...); drm_ut_debug_printk(DRM_UT_KMS, DRM_NAME, \ __func__, fmt, ##args); \ } while (0) -#define DRM_DEBUG_PRIME(fmt, args...) \ - do { \ - drm_ut_debug_printk(DRM_UT_PRIME, DRM_NAME, \ - __func__, fmt, ##args); \ - } while (0) #define DRM_LOG(fmt, args...) \ do { \ drm_ut_debug_printk(DRM_UT_CORE, NULL, \ @@ -245,7 +238,6 @@ int drm_err(const char *func, const char *format, ...); #else #define DRM_DEBUG_DRIVER(fmt, args...) do { } while (0) #define DRM_DEBUG_KMS(fmt, args...) do { } while (0) -#define DRM_DEBUG_PRIME(fmt, args...) do { } while (0) #define DRM_DEBUG(fmt, arg...) do { } while (0) #define DRM_LOG(fmt, arg...) do { } while (0) #define DRM_LOG_KMS(fmt, args...) do { } while (0) @@ -418,12 +410,6 @@ struct drm_pending_event { void (*destroy)(struct drm_pending_event *event); }; -/* initial implementaton using a linked list - todo hashtab */ -struct drm_prime_file_private { - struct list_head head; - struct mutex lock; -}; - /** File private data */ struct drm_file { int authenticated; @@ -451,8 +437,6 @@ struct drm_file { wait_queue_head_t event_wait; struct list_head event_list; int event_space; - - struct drm_prime_file_private prime; }; /** Wait queue */ @@ -668,12 +652,6 @@ struct drm_gem_object { uint32_t pending_write_domain; void *driver_private; - - /* dma buf exported from this GEM object */ - struct dma_buf *export_dma_buf; - - /* dma buf attachment backing this object */ - struct dma_buf_attachment *import_attach; }; #include "drm_crtc.h" @@ -912,20 +890,6 @@ struct drm_driver { int (*gem_open_object) (struct drm_gem_object *, struct drm_file *); void (*gem_close_object) (struct drm_gem_object *, struct drm_file *); - /* prime: */ - /* export handle -> fd (see drm_gem_prime_handle_to_fd() helper) */ - int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file *file_priv, - uint32_t handle, uint32_t flags, int *prime_fd); - /* import fd -> handle (see drm_gem_prime_fd_to_handle() helper) */ - int (*prime_fd_to_handle)(struct drm_device *dev, struct drm_file *file_priv, - int prime_fd, uint32_t *handle); - /* export GEM -> dmabuf */ - struct dma_buf * (*gem_prime_export)(struct drm_device *dev, - struct drm_gem_object *obj, int flags); - /* import dmabuf -> GEM */ - struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev, - struct dma_buf *dma_buf); - /* vga arb irq handler */ void (*vgaarb_irq)(struct drm_device *dev, bool state); @@ -1545,32 +1509,6 @@ extern int drm_vblank_info(struct seq_file *m, void *data); extern int drm_clients_info(struct seq_file *m, void* data); extern int drm_gem_name_info(struct seq_file *m, void *data); - -extern int drm_gem_prime_handle_to_fd(struct drm_device *dev, - struct drm_file *file_priv, uint32_t handle, uint32_t flags, - int *prime_fd); -extern int drm_gem_prime_fd_to_handle(struct drm_device *dev, - struct drm_file *file_priv, int prime_fd, uint32_t *handle); - -extern int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - -extern struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages); -extern void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg); - - -void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv); -void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv); -int drm_prime_add_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle); -int drm_prime_lookup_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t *handle); -void drm_prime_remove_imported_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf); - -int drm_prime_add_dma_buf(struct drm_device *dev, struct drm_gem_object *obj); -int drm_prime_lookup_obj(struct drm_device *dev, struct dma_buf *buf, - struct drm_gem_object **obj); - #if DRM_DEBUG_CODE extern int drm_vma_info(struct seq_file *m, void *data); #endif diff --git a/trunk/include/drm/exynos_drm.h b/trunk/include/drm/exynos_drm.h index e478de4e5d56..3963116083ae 100644 --- a/trunk/include/drm/exynos_drm.h +++ b/trunk/include/drm/exynos_drm.h @@ -85,7 +85,7 @@ struct drm_exynos_gem_mmap { struct drm_exynos_vidi_connection { unsigned int connection; unsigned int extensions; - uint64_t edid; + uint64_t *edid; }; struct drm_exynos_plane_set_zpos { @@ -96,8 +96,7 @@ struct drm_exynos_plane_set_zpos { /* memory type definitions. */ enum e_drm_exynos_gem_mem_type { /* Physically Non-Continuous memory. */ - EXYNOS_BO_NONCONTIG = 1 << 0, - EXYNOS_BO_MASK = EXYNOS_BO_NONCONTIG + EXYNOS_BO_NONCONTIG = 1 << 0 }; #define DRM_EXYNOS_GEM_CREATE 0x00 diff --git a/trunk/include/drm/intel-gtt.h b/trunk/include/drm/intel-gtt.h index 923afb5dcf0c..0a0001b9dc78 100644 --- a/trunk/include/drm/intel-gtt.h +++ b/trunk/include/drm/intel-gtt.h @@ -44,8 +44,4 @@ void intel_gtt_insert_pages(unsigned int first_entry, unsigned int num_entries, /* flag for GFDT type */ #define AGP_USER_CACHED_MEMORY_GFDT (1 << 3) -#ifdef CONFIG_INTEL_IOMMU -extern int intel_iommu_gfx_mapped; -#endif - #endif diff --git a/trunk/include/linux/Kbuild b/trunk/include/linux/Kbuild index 3c9b616c834a..a4b5da2b83f5 100644 --- a/trunk/include/linux/Kbuild +++ b/trunk/include/linux/Kbuild @@ -3,7 +3,6 @@ header-y += can/ header-y += caif/ header-y += dvb/ header-y += hdlc/ -header-y += hsi/ header-y += isdn/ header-y += mmc/ header-y += nfsd/ @@ -121,6 +120,7 @@ header-y += errno.h header-y += errqueue.h header-y += ethtool.h header-y += eventpoll.h +header-y += ext2_fs.h header-y += fadvise.h header-y += falloc.h header-y += fanotify.h diff --git a/trunk/include/linux/acpi.h b/trunk/include/linux/acpi.h index f421dd84f29d..f53fea61f40a 100644 --- a/trunk/include/linux/acpi.h +++ b/trunk/include/linux/acpi.h @@ -372,14 +372,4 @@ static inline int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *), #endif /* !CONFIG_ACPI */ -#ifdef CONFIG_ACPI -void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state, - u32 pm1a_ctrl, u32 pm1b_ctrl)); - -acpi_status acpi_os_prepare_sleep(u8 sleep_state, - u32 pm1a_control, u32 pm1b_control); -#else -#define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0) -#endif - #endif /*_LINUX_ACPI_H*/ diff --git a/trunk/include/linux/amba/bus.h b/trunk/include/linux/amba/bus.h index 8d54f79457ba..7847e197730a 100644 --- a/trunk/include/linux/amba/bus.h +++ b/trunk/include/linux/amba/bus.h @@ -30,6 +30,7 @@ struct amba_device { struct device dev; struct resource res; struct clk *pclk; + struct regulator *vcore; u64 dma_mask; unsigned int periphid; unsigned int irq[AMBA_NR_IRQS]; @@ -74,6 +75,12 @@ void amba_release_regions(struct amba_device *); #define amba_pclk_disable(d) \ do { if (!IS_ERR((d)->pclk)) clk_disable((d)->pclk); } while (0) +#define amba_vcore_enable(d) \ + (IS_ERR((d)->vcore) ? 0 : regulator_enable((d)->vcore)) + +#define amba_vcore_disable(d) \ + do { if (!IS_ERR((d)->vcore)) regulator_disable((d)->vcore); } while (0) + /* Some drivers don't use the struct amba_device */ #define AMBA_CONFIG_BITS(a) (((a) >> 24) & 0xff) #define AMBA_REV_BITS(a) (((a) >> 20) & 0x0f) diff --git a/trunk/include/linux/amba/pl022.h b/trunk/include/linux/amba/pl022.h index 76dd1b199a1b..b8c51124ed19 100644 --- a/trunk/include/linux/amba/pl022.h +++ b/trunk/include/linux/amba/pl022.h @@ -25,8 +25,6 @@ #ifndef _SSP_PL022_H #define _SSP_PL022_H -#include - /** * whether SSP is in loopback mode or not */ diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h index 2aa24664a5b5..606cf339bb56 100644 --- a/trunk/include/linux/blkdev.h +++ b/trunk/include/linux/blkdev.h @@ -426,10 +426,14 @@ struct request_queue { (1 << QUEUE_FLAG_SAME_COMP) | \ (1 << QUEUE_FLAG_ADD_RANDOM)) -static inline void queue_lockdep_assert_held(struct request_queue *q) +static inline int queue_is_locked(struct request_queue *q) { - if (q->queue_lock) - lockdep_assert_held(q->queue_lock); +#ifdef CONFIG_SMP + spinlock_t *lock = q->queue_lock; + return lock && spin_is_locked(lock); +#else + return 1; +#endif } static inline void queue_flag_set_unlocked(unsigned int flag, @@ -441,7 +445,7 @@ static inline void queue_flag_set_unlocked(unsigned int flag, static inline int queue_flag_test_and_clear(unsigned int flag, struct request_queue *q) { - queue_lockdep_assert_held(q); + WARN_ON_ONCE(!queue_is_locked(q)); if (test_bit(flag, &q->queue_flags)) { __clear_bit(flag, &q->queue_flags); @@ -454,7 +458,7 @@ static inline int queue_flag_test_and_clear(unsigned int flag, static inline int queue_flag_test_and_set(unsigned int flag, struct request_queue *q) { - queue_lockdep_assert_held(q); + WARN_ON_ONCE(!queue_is_locked(q)); if (!test_bit(flag, &q->queue_flags)) { __set_bit(flag, &q->queue_flags); @@ -466,7 +470,7 @@ static inline int queue_flag_test_and_set(unsigned int flag, static inline void queue_flag_set(unsigned int flag, struct request_queue *q) { - queue_lockdep_assert_held(q); + WARN_ON_ONCE(!queue_is_locked(q)); __set_bit(flag, &q->queue_flags); } @@ -483,7 +487,7 @@ static inline int queue_in_flight(struct request_queue *q) static inline void queue_flag_clear(unsigned int flag, struct request_queue *q) { - queue_lockdep_assert_held(q); + WARN_ON_ONCE(!queue_is_locked(q)); __clear_bit(flag, &q->queue_flags); } diff --git a/trunk/include/linux/cpuidle.h b/trunk/include/linux/cpuidle.h index 6c26a3da0e03..712abcc205ae 100644 --- a/trunk/include/linux/cpuidle.h +++ b/trunk/include/linux/cpuidle.h @@ -15,7 +15,6 @@ #include #include #include -#include #define CPUIDLE_STATE_MAX 8 #define CPUIDLE_NAME_LEN 16 @@ -44,15 +43,12 @@ struct cpuidle_state { unsigned int flags; unsigned int exit_latency; /* in US */ - int power_usage; /* in mW */ + unsigned int power_usage; /* in mW */ unsigned int target_residency; /* in US */ - unsigned int disable; int (*enter) (struct cpuidle_device *dev, struct cpuidle_driver *drv, int index); - - int (*enter_dead) (struct cpuidle_device *dev, int index); }; /* Idle State Flags */ @@ -100,6 +96,7 @@ struct cpuidle_device { struct list_head device_list; struct kobject kobj; struct completion kobj_unregister; + void *governor_data; }; DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices); @@ -121,12 +118,10 @@ static inline int cpuidle_get_last_residency(struct cpuidle_device *dev) ****************************/ struct cpuidle_driver { - const char *name; + char name[CPUIDLE_NAME_LEN]; struct module *owner; unsigned int power_specified:1; - /* set to 1 to use the core cpuidle time keeping (for all states). */ - unsigned int en_core_tk_irqen:1; struct cpuidle_state states[CPUIDLE_STATE_MAX]; int state_count; int safe_state_index; @@ -145,11 +140,6 @@ extern void cpuidle_pause_and_lock(void); extern void cpuidle_resume_and_unlock(void); extern int cpuidle_enable_device(struct cpuidle_device *dev); extern void cpuidle_disable_device(struct cpuidle_device *dev); -extern int cpuidle_wrap_enter(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index, - int (*enter)(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index)); -extern int cpuidle_play_dead(void); #else static inline void disable_cpuidle(void) { } @@ -167,12 +157,6 @@ static inline void cpuidle_resume_and_unlock(void) { } static inline int cpuidle_enable_device(struct cpuidle_device *dev) {return -ENODEV; } static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } -static inline int cpuidle_wrap_enter(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index, - int (*enter)(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index)) -{ return -ENODEV; } -static inline int cpuidle_play_dead(void) {return -ENODEV; } #endif diff --git a/trunk/include/linux/cpumask.h b/trunk/include/linux/cpumask.h index a2c819d3c96e..1ffdb9856bb9 100644 --- a/trunk/include/linux/cpumask.h +++ b/trunk/include/linux/cpumask.h @@ -764,6 +764,12 @@ static inline const struct cpumask *get_cpu_mask(unsigned int cpu) * */ #ifndef CONFIG_DISABLE_OBSOLETE_CPUMASK_FUNCTIONS +/* These strip const, as traditionally they weren't const. */ +#define cpu_possible_map (*(cpumask_t *)cpu_possible_mask) +#define cpu_online_map (*(cpumask_t *)cpu_online_mask) +#define cpu_present_map (*(cpumask_t *)cpu_present_mask) +#define cpu_active_map (*(cpumask_t *)cpu_active_mask) + #define cpumask_of_cpu(cpu) (*get_cpu_mask(cpu)) #define CPU_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(NR_CPUS) diff --git a/trunk/include/linux/cryptouser.h b/trunk/include/linux/cryptouser.h index 4abf2ea6a887..532fb58f16bf 100644 --- a/trunk/include/linux/cryptouser.h +++ b/trunk/include/linux/cryptouser.h @@ -100,6 +100,3 @@ struct crypto_report_rng { char type[CRYPTO_MAX_NAME]; unsigned int seedsize; }; - -#define CRYPTO_REPORT_MAXSIZE (sizeof(struct crypto_user_alg) + \ - sizeof(struct crypto_report_blkcipher)) diff --git a/trunk/include/linux/dma-attrs.h b/trunk/include/linux/dma-attrs.h index 547ab568d3ae..71ad34eca6e3 100644 --- a/trunk/include/linux/dma-attrs.h +++ b/trunk/include/linux/dma-attrs.h @@ -13,8 +13,6 @@ enum dma_attr { DMA_ATTR_WRITE_BARRIER, DMA_ATTR_WEAK_ORDERING, - DMA_ATTR_WRITE_COMBINE, - DMA_ATTR_NON_CONSISTENT, DMA_ATTR_MAX, }; diff --git a/trunk/include/linux/dma-mapping.h b/trunk/include/linux/dma-mapping.h index dfc099e56a66..5a736af3cc7a 100644 --- a/trunk/include/linux/dma-mapping.h +++ b/trunk/include/linux/dma-mapping.h @@ -9,15 +9,10 @@ #include struct dma_map_ops { - void* (*alloc)(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp, - struct dma_attrs *attrs); - void (*free)(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, - struct dma_attrs *attrs); - int (*mmap)(struct device *, struct vm_area_struct *, - void *, dma_addr_t, size_t, struct dma_attrs *attrs); - + void* (*alloc_coherent)(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp); + void (*free_coherent)(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle); dma_addr_t (*map_page)(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction dir, diff --git a/trunk/include/linux/dmaengine.h b/trunk/include/linux/dmaengine.h index f9a2e5e67a54..676f967390ae 100644 --- a/trunk/include/linux/dmaengine.h +++ b/trunk/include/linux/dmaengine.h @@ -974,7 +974,6 @@ int dma_async_device_register(struct dma_device *device); void dma_async_device_unregister(struct dma_device *device); void dma_run_dependencies(struct dma_async_tx_descriptor *tx); struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type); -struct dma_chan *net_dma_find_channel(void); #define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y) /* --- Helper iov-locking functions --- */ diff --git a/trunk/include/linux/efi.h b/trunk/include/linux/efi.h index ec45ccd8708a..88ec80670d5f 100644 --- a/trunk/include/linux/efi.h +++ b/trunk/include/linux/efi.h @@ -554,18 +554,7 @@ extern int __init efi_setup_pcdp_console(char *); #define EFI_VARIABLE_NON_VOLATILE 0x0000000000000001 #define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002 #define EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004 -#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x0000000000000008 -#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x0000000000000010 -#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x0000000000000020 -#define EFI_VARIABLE_APPEND_WRITE 0x0000000000000040 - -#define EFI_VARIABLE_MASK (EFI_VARIABLE_NON_VOLATILE | \ - EFI_VARIABLE_BOOTSERVICE_ACCESS | \ - EFI_VARIABLE_RUNTIME_ACCESS | \ - EFI_VARIABLE_HARDWARE_ERROR_RECORD | \ - EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | \ - EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \ - EFI_VARIABLE_APPEND_WRITE) + /* * The type of search to perform when calling boottime->locate_handle */ diff --git a/trunk/include/linux/ethtool.h b/trunk/include/linux/ethtool.h index f5647b59a90e..e1d9e0ede309 100644 --- a/trunk/include/linux/ethtool.h +++ b/trunk/include/linux/ethtool.h @@ -896,7 +896,8 @@ static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings) * * All operations are optional (i.e. the function pointer may be set * to %NULL) and callers must take this into account. Callers must - * hold the RTNL lock. + * hold the RTNL, except that for @get_drvinfo the caller may or may + * not hold the RTNL. * * See the structures used by these operations for further documentation. * diff --git a/trunk/include/linux/ext2_fs.h b/trunk/include/linux/ext2_fs.h index 2723e715f67a..ce1b719e8bd4 100644 --- a/trunk/include/linux/ext2_fs.h +++ b/trunk/include/linux/ext2_fs.h @@ -18,25 +18,574 @@ #include #include +#include -#define EXT2_NAME_LEN 255 +/* + * The second extended filesystem constants/structures + */ + +/* + * Define EXT2FS_DEBUG to produce debug messages + */ +#undef EXT2FS_DEBUG + +/* + * Define EXT2_RESERVATION to reserve data blocks for expanding files + */ +#define EXT2_DEFAULT_RESERVE_BLOCKS 8 +/*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */ +#define EXT2_MAX_RESERVE_BLOCKS 1027 +#define EXT2_RESERVE_WINDOW_NOT_ALLOCATED 0 +/* + * The second extended file system version + */ +#define EXT2FS_DATE "95/08/09" +#define EXT2FS_VERSION "0.5b" + +/* + * Debug code + */ +#ifdef EXT2FS_DEBUG +# define ext2_debug(f, a...) { \ + printk ("EXT2-fs DEBUG (%s, %d): %s:", \ + __FILE__, __LINE__, __func__); \ + printk (f, ## a); \ + } +#else +# define ext2_debug(f, a...) /**/ +#endif + +/* + * Special inode numbers + */ +#define EXT2_BAD_INO 1 /* Bad blocks inode */ +#define EXT2_ROOT_INO 2 /* Root inode */ +#define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */ +#define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */ + +/* First non-reserved inode for old ext2 filesystems */ +#define EXT2_GOOD_OLD_FIRST_INO 11 + +#ifdef __KERNEL__ +#include +static inline struct ext2_sb_info *EXT2_SB(struct super_block *sb) +{ + return sb->s_fs_info; +} +#else +/* Assume that user mode programs are passing in an ext2fs superblock, not + * a kernel struct super_block. This will allow us to call the feature-test + * macros from user land. */ +#define EXT2_SB(sb) (sb) +#endif /* * Maximal count of links to a file */ #define EXT2_LINK_MAX 32000 -#define EXT2_SB_MAGIC_OFFSET 0x38 -#define EXT2_SB_BLOCKS_OFFSET 0x04 -#define EXT2_SB_BSIZE_OFFSET 0x18 +/* + * Macro-instructions used to manage several block sizes + */ +#define EXT2_MIN_BLOCK_SIZE 1024 +#define EXT2_MAX_BLOCK_SIZE 4096 +#define EXT2_MIN_BLOCK_LOG_SIZE 10 +#ifdef __KERNEL__ +# define EXT2_BLOCK_SIZE(s) ((s)->s_blocksize) +#else +# define EXT2_BLOCK_SIZE(s) (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size) +#endif +#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32)) +#ifdef __KERNEL__ +# define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) +#else +# define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) +#endif +#ifdef __KERNEL__ +#define EXT2_ADDR_PER_BLOCK_BITS(s) (EXT2_SB(s)->s_addr_per_block_bits) +#define EXT2_INODE_SIZE(s) (EXT2_SB(s)->s_inode_size) +#define EXT2_FIRST_INO(s) (EXT2_SB(s)->s_first_ino) +#else +#define EXT2_INODE_SIZE(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \ + EXT2_GOOD_OLD_INODE_SIZE : \ + (s)->s_inode_size) +#define EXT2_FIRST_INO(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \ + EXT2_GOOD_OLD_FIRST_INO : \ + (s)->s_first_ino) +#endif -static inline u64 ext2_image_size(void *ext2_sb) +/* + * Macro-instructions used to manage fragments + */ +#define EXT2_MIN_FRAG_SIZE 1024 +#define EXT2_MAX_FRAG_SIZE 4096 +#define EXT2_MIN_FRAG_LOG_SIZE 10 +#ifdef __KERNEL__ +# define EXT2_FRAG_SIZE(s) (EXT2_SB(s)->s_frag_size) +# define EXT2_FRAGS_PER_BLOCK(s) (EXT2_SB(s)->s_frags_per_block) +#else +# define EXT2_FRAG_SIZE(s) (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size) +# define EXT2_FRAGS_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s)) +#endif + +/* + * Structure of a blocks group descriptor + */ +struct ext2_group_desc { - __u8 *p = ext2_sb; - if (*(__le16 *)(p + EXT2_SB_MAGIC_OFFSET) != cpu_to_le16(EXT2_SUPER_MAGIC)) - return 0; - return (u64)le32_to_cpup((__le32 *)(p + EXT2_SB_BLOCKS_OFFSET)) << - le32_to_cpup((__le32 *)(p + EXT2_SB_BSIZE_OFFSET)); + __le32 bg_block_bitmap; /* Blocks bitmap block */ + __le32 bg_inode_bitmap; /* Inodes bitmap block */ + __le32 bg_inode_table; /* Inodes table block */ + __le16 bg_free_blocks_count; /* Free blocks count */ + __le16 bg_free_inodes_count; /* Free inodes count */ + __le16 bg_used_dirs_count; /* Directories count */ + __le16 bg_pad; + __le32 bg_reserved[3]; +}; + +/* + * Macro-instructions used to manage group descriptors + */ +#ifdef __KERNEL__ +# define EXT2_BLOCKS_PER_GROUP(s) (EXT2_SB(s)->s_blocks_per_group) +# define EXT2_DESC_PER_BLOCK(s) (EXT2_SB(s)->s_desc_per_block) +# define EXT2_INODES_PER_GROUP(s) (EXT2_SB(s)->s_inodes_per_group) +# define EXT2_DESC_PER_BLOCK_BITS(s) (EXT2_SB(s)->s_desc_per_block_bits) +#else +# define EXT2_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group) +# define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc)) +# define EXT2_INODES_PER_GROUP(s) ((s)->s_inodes_per_group) +#endif + +/* + * Constants relative to the data blocks + */ +#define EXT2_NDIR_BLOCKS 12 +#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS +#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1) +#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1) +#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1) + +/* + * Inode flags (GETFLAGS/SETFLAGS) + */ +#define EXT2_SECRM_FL FS_SECRM_FL /* Secure deletion */ +#define EXT2_UNRM_FL FS_UNRM_FL /* Undelete */ +#define EXT2_COMPR_FL FS_COMPR_FL /* Compress file */ +#define EXT2_SYNC_FL FS_SYNC_FL /* Synchronous updates */ +#define EXT2_IMMUTABLE_FL FS_IMMUTABLE_FL /* Immutable file */ +#define EXT2_APPEND_FL FS_APPEND_FL /* writes to file may only append */ +#define EXT2_NODUMP_FL FS_NODUMP_FL /* do not dump file */ +#define EXT2_NOATIME_FL FS_NOATIME_FL /* do not update atime */ +/* Reserved for compression usage... */ +#define EXT2_DIRTY_FL FS_DIRTY_FL +#define EXT2_COMPRBLK_FL FS_COMPRBLK_FL /* One or more compressed clusters */ +#define EXT2_NOCOMP_FL FS_NOCOMP_FL /* Don't compress */ +#define EXT2_ECOMPR_FL FS_ECOMPR_FL /* Compression error */ +/* End compression flags --- maybe not all used */ +#define EXT2_BTREE_FL FS_BTREE_FL /* btree format dir */ +#define EXT2_INDEX_FL FS_INDEX_FL /* hash-indexed directory */ +#define EXT2_IMAGIC_FL FS_IMAGIC_FL /* AFS directory */ +#define EXT2_JOURNAL_DATA_FL FS_JOURNAL_DATA_FL /* Reserved for ext3 */ +#define EXT2_NOTAIL_FL FS_NOTAIL_FL /* file tail should not be merged */ +#define EXT2_DIRSYNC_FL FS_DIRSYNC_FL /* dirsync behaviour (directories only) */ +#define EXT2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/ +#define EXT2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */ + +#define EXT2_FL_USER_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */ +#define EXT2_FL_USER_MODIFIABLE FS_FL_USER_MODIFIABLE /* User modifiable flags */ + +/* Flags that should be inherited by new inodes from their parent. */ +#define EXT2_FL_INHERITED (EXT2_SECRM_FL | EXT2_UNRM_FL | EXT2_COMPR_FL |\ + EXT2_SYNC_FL | EXT2_NODUMP_FL |\ + EXT2_NOATIME_FL | EXT2_COMPRBLK_FL |\ + EXT2_NOCOMP_FL | EXT2_JOURNAL_DATA_FL |\ + EXT2_NOTAIL_FL | EXT2_DIRSYNC_FL) + +/* Flags that are appropriate for regular files (all but dir-specific ones). */ +#define EXT2_REG_FLMASK (~(EXT2_DIRSYNC_FL | EXT2_TOPDIR_FL)) + +/* Flags that are appropriate for non-directories/regular files. */ +#define EXT2_OTHER_FLMASK (EXT2_NODUMP_FL | EXT2_NOATIME_FL) + +/* Mask out flags that are inappropriate for the given type of inode. */ +static inline __u32 ext2_mask_flags(umode_t mode, __u32 flags) +{ + if (S_ISDIR(mode)) + return flags; + else if (S_ISREG(mode)) + return flags & EXT2_REG_FLMASK; + else + return flags & EXT2_OTHER_FLMASK; } +/* + * ioctl commands + */ +#define EXT2_IOC_GETFLAGS FS_IOC_GETFLAGS +#define EXT2_IOC_SETFLAGS FS_IOC_SETFLAGS +#define EXT2_IOC_GETVERSION FS_IOC_GETVERSION +#define EXT2_IOC_SETVERSION FS_IOC_SETVERSION +#define EXT2_IOC_GETRSVSZ _IOR('f', 5, long) +#define EXT2_IOC_SETRSVSZ _IOW('f', 6, long) + +/* + * ioctl commands in 32 bit emulation + */ +#define EXT2_IOC32_GETFLAGS FS_IOC32_GETFLAGS +#define EXT2_IOC32_SETFLAGS FS_IOC32_SETFLAGS +#define EXT2_IOC32_GETVERSION FS_IOC32_GETVERSION +#define EXT2_IOC32_SETVERSION FS_IOC32_SETVERSION + +/* + * Structure of an inode on the disk + */ +struct ext2_inode { + __le16 i_mode; /* File mode */ + __le16 i_uid; /* Low 16 bits of Owner Uid */ + __le32 i_size; /* Size in bytes */ + __le32 i_atime; /* Access time */ + __le32 i_ctime; /* Creation time */ + __le32 i_mtime; /* Modification time */ + __le32 i_dtime; /* Deletion Time */ + __le16 i_gid; /* Low 16 bits of Group Id */ + __le16 i_links_count; /* Links count */ + __le32 i_blocks; /* Blocks count */ + __le32 i_flags; /* File flags */ + union { + struct { + __le32 l_i_reserved1; + } linux1; + struct { + __le32 h_i_translator; + } hurd1; + struct { + __le32 m_i_reserved1; + } masix1; + } osd1; /* OS dependent 1 */ + __le32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */ + __le32 i_generation; /* File version (for NFS) */ + __le32 i_file_acl; /* File ACL */ + __le32 i_dir_acl; /* Directory ACL */ + __le32 i_faddr; /* Fragment address */ + union { + struct { + __u8 l_i_frag; /* Fragment number */ + __u8 l_i_fsize; /* Fragment size */ + __u16 i_pad1; + __le16 l_i_uid_high; /* these 2 fields */ + __le16 l_i_gid_high; /* were reserved2[0] */ + __u32 l_i_reserved2; + } linux2; + struct { + __u8 h_i_frag; /* Fragment number */ + __u8 h_i_fsize; /* Fragment size */ + __le16 h_i_mode_high; + __le16 h_i_uid_high; + __le16 h_i_gid_high; + __le32 h_i_author; + } hurd2; + struct { + __u8 m_i_frag; /* Fragment number */ + __u8 m_i_fsize; /* Fragment size */ + __u16 m_pad1; + __u32 m_i_reserved2[2]; + } masix2; + } osd2; /* OS dependent 2 */ +}; + +#define i_size_high i_dir_acl + +#if defined(__KERNEL__) || defined(__linux__) +#define i_reserved1 osd1.linux1.l_i_reserved1 +#define i_frag osd2.linux2.l_i_frag +#define i_fsize osd2.linux2.l_i_fsize +#define i_uid_low i_uid +#define i_gid_low i_gid +#define i_uid_high osd2.linux2.l_i_uid_high +#define i_gid_high osd2.linux2.l_i_gid_high +#define i_reserved2 osd2.linux2.l_i_reserved2 +#endif + +#ifdef __hurd__ +#define i_translator osd1.hurd1.h_i_translator +#define i_frag osd2.hurd2.h_i_frag +#define i_fsize osd2.hurd2.h_i_fsize +#define i_uid_high osd2.hurd2.h_i_uid_high +#define i_gid_high osd2.hurd2.h_i_gid_high +#define i_author osd2.hurd2.h_i_author +#endif + +#ifdef __masix__ +#define i_reserved1 osd1.masix1.m_i_reserved1 +#define i_frag osd2.masix2.m_i_frag +#define i_fsize osd2.masix2.m_i_fsize +#define i_reserved2 osd2.masix2.m_i_reserved2 +#endif + +/* + * File system states + */ +#define EXT2_VALID_FS 0x0001 /* Unmounted cleanly */ +#define EXT2_ERROR_FS 0x0002 /* Errors detected */ + +/* + * Mount flags + */ +#define EXT2_MOUNT_CHECK 0x000001 /* Do mount-time checks */ +#define EXT2_MOUNT_OLDALLOC 0x000002 /* Don't use the new Orlov allocator */ +#define EXT2_MOUNT_GRPID 0x000004 /* Create files with directory's group */ +#define EXT2_MOUNT_DEBUG 0x000008 /* Some debugging messages */ +#define EXT2_MOUNT_ERRORS_CONT 0x000010 /* Continue on errors */ +#define EXT2_MOUNT_ERRORS_RO 0x000020 /* Remount fs ro on errors */ +#define EXT2_MOUNT_ERRORS_PANIC 0x000040 /* Panic on errors */ +#define EXT2_MOUNT_MINIX_DF 0x000080 /* Mimics the Minix statfs */ +#define EXT2_MOUNT_NOBH 0x000100 /* No buffer_heads */ +#define EXT2_MOUNT_NO_UID32 0x000200 /* Disable 32-bit UIDs */ +#define EXT2_MOUNT_XATTR_USER 0x004000 /* Extended user attributes */ +#define EXT2_MOUNT_POSIX_ACL 0x008000 /* POSIX Access Control Lists */ +#define EXT2_MOUNT_XIP 0x010000 /* Execute in place */ +#define EXT2_MOUNT_USRQUOTA 0x020000 /* user quota */ +#define EXT2_MOUNT_GRPQUOTA 0x040000 /* group quota */ +#define EXT2_MOUNT_RESERVATION 0x080000 /* Preallocation */ + + +#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt +#define set_opt(o, opt) o |= EXT2_MOUNT_##opt +#define test_opt(sb, opt) (EXT2_SB(sb)->s_mount_opt & \ + EXT2_MOUNT_##opt) +/* + * Maximal mount counts between two filesystem checks + */ +#define EXT2_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */ +#define EXT2_DFL_CHECKINTERVAL 0 /* Don't use interval check */ + +/* + * Behaviour when detecting errors + */ +#define EXT2_ERRORS_CONTINUE 1 /* Continue execution */ +#define EXT2_ERRORS_RO 2 /* Remount fs read-only */ +#define EXT2_ERRORS_PANIC 3 /* Panic */ +#define EXT2_ERRORS_DEFAULT EXT2_ERRORS_CONTINUE + +/* + * Structure of the super block + */ +struct ext2_super_block { + __le32 s_inodes_count; /* Inodes count */ + __le32 s_blocks_count; /* Blocks count */ + __le32 s_r_blocks_count; /* Reserved blocks count */ + __le32 s_free_blocks_count; /* Free blocks count */ + __le32 s_free_inodes_count; /* Free inodes count */ + __le32 s_first_data_block; /* First Data Block */ + __le32 s_log_block_size; /* Block size */ + __le32 s_log_frag_size; /* Fragment size */ + __le32 s_blocks_per_group; /* # Blocks per group */ + __le32 s_frags_per_group; /* # Fragments per group */ + __le32 s_inodes_per_group; /* # Inodes per group */ + __le32 s_mtime; /* Mount time */ + __le32 s_wtime; /* Write time */ + __le16 s_mnt_count; /* Mount count */ + __le16 s_max_mnt_count; /* Maximal mount count */ + __le16 s_magic; /* Magic signature */ + __le16 s_state; /* File system state */ + __le16 s_errors; /* Behaviour when detecting errors */ + __le16 s_minor_rev_level; /* minor revision level */ + __le32 s_lastcheck; /* time of last check */ + __le32 s_checkinterval; /* max. time between checks */ + __le32 s_creator_os; /* OS */ + __le32 s_rev_level; /* Revision level */ + __le16 s_def_resuid; /* Default uid for reserved blocks */ + __le16 s_def_resgid; /* Default gid for reserved blocks */ + /* + * These fields are for EXT2_DYNAMIC_REV superblocks only. + * + * Note: the difference between the compatible feature set and + * the incompatible feature set is that if there is a bit set + * in the incompatible feature set that the kernel doesn't + * know about, it should refuse to mount the filesystem. + * + * e2fsck's requirements are more strict; if it doesn't know + * about a feature in either the compatible or incompatible + * feature set, it must abort and not try to meddle with + * things it doesn't understand... + */ + __le32 s_first_ino; /* First non-reserved inode */ + __le16 s_inode_size; /* size of inode structure */ + __le16 s_block_group_nr; /* block group # of this superblock */ + __le32 s_feature_compat; /* compatible feature set */ + __le32 s_feature_incompat; /* incompatible feature set */ + __le32 s_feature_ro_compat; /* readonly-compatible feature set */ + __u8 s_uuid[16]; /* 128-bit uuid for volume */ + char s_volume_name[16]; /* volume name */ + char s_last_mounted[64]; /* directory where last mounted */ + __le32 s_algorithm_usage_bitmap; /* For compression */ + /* + * Performance hints. Directory preallocation should only + * happen if the EXT2_COMPAT_PREALLOC flag is on. + */ + __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ + __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ + __u16 s_padding1; + /* + * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set. + */ + __u8 s_journal_uuid[16]; /* uuid of journal superblock */ + __u32 s_journal_inum; /* inode number of journal file */ + __u32 s_journal_dev; /* device number of journal file */ + __u32 s_last_orphan; /* start of list of inodes to delete */ + __u32 s_hash_seed[4]; /* HTREE hash seed */ + __u8 s_def_hash_version; /* Default hash version to use */ + __u8 s_reserved_char_pad; + __u16 s_reserved_word_pad; + __le32 s_default_mount_opts; + __le32 s_first_meta_bg; /* First metablock block group */ + __u32 s_reserved[190]; /* Padding to the end of the block */ +}; + +/* + * Codes for operating systems + */ +#define EXT2_OS_LINUX 0 +#define EXT2_OS_HURD 1 +#define EXT2_OS_MASIX 2 +#define EXT2_OS_FREEBSD 3 +#define EXT2_OS_LITES 4 + +/* + * Revision levels + */ +#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */ +#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */ + +#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV +#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV + +#define EXT2_GOOD_OLD_INODE_SIZE 128 + +/* + * Feature set definitions + */ + +#define EXT2_HAS_COMPAT_FEATURE(sb,mask) \ + ( EXT2_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) ) +#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask) \ + ( EXT2_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) ) +#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask) \ + ( EXT2_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) ) +#define EXT2_SET_COMPAT_FEATURE(sb,mask) \ + EXT2_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask) +#define EXT2_SET_RO_COMPAT_FEATURE(sb,mask) \ + EXT2_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask) +#define EXT2_SET_INCOMPAT_FEATURE(sb,mask) \ + EXT2_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask) +#define EXT2_CLEAR_COMPAT_FEATURE(sb,mask) \ + EXT2_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask) +#define EXT2_CLEAR_RO_COMPAT_FEATURE(sb,mask) \ + EXT2_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask) +#define EXT2_CLEAR_INCOMPAT_FEATURE(sb,mask) \ + EXT2_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask) + +#define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001 +#define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002 +#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 +#define EXT2_FEATURE_COMPAT_EXT_ATTR 0x0008 +#define EXT2_FEATURE_COMPAT_RESIZE_INO 0x0010 +#define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020 +#define EXT2_FEATURE_COMPAT_ANY 0xffffffff + +#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 +#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 +#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 +#define EXT2_FEATURE_RO_COMPAT_ANY 0xffffffff + +#define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001 +#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 +#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 +#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 +#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010 +#define EXT2_FEATURE_INCOMPAT_ANY 0xffffffff + +#define EXT2_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR +#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ + EXT2_FEATURE_INCOMPAT_META_BG) +#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ + EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ + EXT2_FEATURE_RO_COMPAT_BTREE_DIR) +#define EXT2_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT2_FEATURE_RO_COMPAT_SUPP +#define EXT2_FEATURE_INCOMPAT_UNSUPPORTED ~EXT2_FEATURE_INCOMPAT_SUPP + +/* + * Default values for user and/or group using reserved blocks + */ +#define EXT2_DEF_RESUID 0 +#define EXT2_DEF_RESGID 0 + +/* + * Default mount options + */ +#define EXT2_DEFM_DEBUG 0x0001 +#define EXT2_DEFM_BSDGROUPS 0x0002 +#define EXT2_DEFM_XATTR_USER 0x0004 +#define EXT2_DEFM_ACL 0x0008 +#define EXT2_DEFM_UID16 0x0010 + /* Not used by ext2, but reserved for use by ext3 */ +#define EXT3_DEFM_JMODE 0x0060 +#define EXT3_DEFM_JMODE_DATA 0x0020 +#define EXT3_DEFM_JMODE_ORDERED 0x0040 +#define EXT3_DEFM_JMODE_WBACK 0x0060 + +/* + * Structure of a directory entry + */ +#define EXT2_NAME_LEN 255 + +struct ext2_dir_entry { + __le32 inode; /* Inode number */ + __le16 rec_len; /* Directory entry length */ + __le16 name_len; /* Name length */ + char name[EXT2_NAME_LEN]; /* File name */ +}; + +/* + * The new version of the directory entry. Since EXT2 structures are + * stored in intel byte order, and the name_len field could never be + * bigger than 255 chars, it's safe to reclaim the extra byte for the + * file_type field. + */ +struct ext2_dir_entry_2 { + __le32 inode; /* Inode number */ + __le16 rec_len; /* Directory entry length */ + __u8 name_len; /* Name length */ + __u8 file_type; + char name[EXT2_NAME_LEN]; /* File name */ +}; + +/* + * Ext2 directory file types. Only the low 3 bits are used. The + * other bits are reserved for now. + */ +enum { + EXT2_FT_UNKNOWN = 0, + EXT2_FT_REG_FILE = 1, + EXT2_FT_DIR = 2, + EXT2_FT_CHRDEV = 3, + EXT2_FT_BLKDEV = 4, + EXT2_FT_FIFO = 5, + EXT2_FT_SOCK = 6, + EXT2_FT_SYMLINK = 7, + EXT2_FT_MAX +}; + +/* + * EXT2_DIR_PAD defines the directory entries boundaries + * + * NOTE: It must be a multiple of 4 + */ +#define EXT2_DIR_PAD 4 +#define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1) +#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \ + ~EXT2_DIR_ROUND) +#define EXT2_MAX_REC_LEN ((1<<16)-1) + #endif /* _LINUX_EXT2_FS_H */ diff --git a/trunk/include/linux/ext2_fs_sb.h b/trunk/include/linux/ext2_fs_sb.h new file mode 100644 index 000000000000..db4d9f586bb6 --- /dev/null +++ b/trunk/include/linux/ext2_fs_sb.h @@ -0,0 +1,126 @@ +/* + * linux/include/linux/ext2_fs_sb.h + * + * Copyright (C) 1992, 1993, 1994, 1995 + * Remy Card (card@masi.ibp.fr) + * Laboratoire MASI - Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) + * + * from + * + * linux/include/linux/minix_fs_sb.h + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +#ifndef _LINUX_EXT2_FS_SB +#define _LINUX_EXT2_FS_SB + +#include +#include +#include + +/* XXX Here for now... not interested in restructing headers JUST now */ + +/* data type for block offset of block group */ +typedef int ext2_grpblk_t; + +/* data type for filesystem-wide blocks number */ +typedef unsigned long ext2_fsblk_t; + +#define E2FSBLK "%lu" + +struct ext2_reserve_window { + ext2_fsblk_t _rsv_start; /* First byte reserved */ + ext2_fsblk_t _rsv_end; /* Last byte reserved or 0 */ +}; + +struct ext2_reserve_window_node { + struct rb_node rsv_node; + __u32 rsv_goal_size; + __u32 rsv_alloc_hit; + struct ext2_reserve_window rsv_window; +}; + +struct ext2_block_alloc_info { + /* information about reservation window */ + struct ext2_reserve_window_node rsv_window_node; + /* + * was i_next_alloc_block in ext2_inode_info + * is the logical (file-relative) number of the + * most-recently-allocated block in this file. + * We use this for detecting linearly ascending allocation requests. + */ + __u32 last_alloc_logical_block; + /* + * Was i_next_alloc_goal in ext2_inode_info + * is the *physical* companion to i_next_alloc_block. + * it the the physical block number of the block which was most-recentl + * allocated to this file. This give us the goal (target) for the next + * allocation when we detect linearly ascending requests. + */ + ext2_fsblk_t last_alloc_physical_block; +}; + +#define rsv_start rsv_window._rsv_start +#define rsv_end rsv_window._rsv_end + +/* + * second extended-fs super-block data in memory + */ +struct ext2_sb_info { + unsigned long s_frag_size; /* Size of a fragment in bytes */ + unsigned long s_frags_per_block;/* Number of fragments per block */ + unsigned long s_inodes_per_block;/* Number of inodes per block */ + unsigned long s_frags_per_group;/* Number of fragments in a group */ + unsigned long s_blocks_per_group;/* Number of blocks in a group */ + unsigned long s_inodes_per_group;/* Number of inodes in a group */ + unsigned long s_itb_per_group; /* Number of inode table blocks per group */ + unsigned long s_gdb_count; /* Number of group descriptor blocks */ + unsigned long s_desc_per_block; /* Number of group descriptors per block */ + unsigned long s_groups_count; /* Number of groups in the fs */ + unsigned long s_overhead_last; /* Last calculated overhead */ + unsigned long s_blocks_last; /* Last seen block count */ + struct buffer_head * s_sbh; /* Buffer containing the super block */ + struct ext2_super_block * s_es; /* Pointer to the super block in the buffer */ + struct buffer_head ** s_group_desc; + unsigned long s_mount_opt; + unsigned long s_sb_block; + uid_t s_resuid; + gid_t s_resgid; + unsigned short s_mount_state; + unsigned short s_pad; + int s_addr_per_block_bits; + int s_desc_per_block_bits; + int s_inode_size; + int s_first_ino; + spinlock_t s_next_gen_lock; + u32 s_next_generation; + unsigned long s_dir_count; + u8 *s_debts; + struct percpu_counter s_freeblocks_counter; + struct percpu_counter s_freeinodes_counter; + struct percpu_counter s_dirs_counter; + struct blockgroup_lock *s_blockgroup_lock; + /* root of the per fs reservation window tree */ + spinlock_t s_rsv_window_lock; + struct rb_root s_rsv_window_root; + struct ext2_reserve_window_node s_rsv_window_head; + /* + * s_lock protects against concurrent modifications of s_mount_state, + * s_blocks_last, s_overhead_last and the content of superblock's + * buffer pointed to by sbi->s_es. + * + * Note: It is used in ext2_show_options() to provide a consistent view + * of the mount options. + */ + spinlock_t s_lock; +}; + +static inline spinlock_t * +sb_bgl_lock(struct ext2_sb_info *sbi, unsigned int block_group) +{ + return bgl_lock_ptr(sbi->s_blockgroup_lock, block_group); +} + +#endif /* _LINUX_EXT2_FS_SB */ diff --git a/trunk/fs/ext3/ext3.h b/trunk/include/linux/ext3_fs.h similarity index 67% rename from trunk/fs/ext3/ext3.h rename to trunk/include/linux/ext3_fs.h index b6515fd7e56c..f5a84eef6ed2 100644 --- a/trunk/fs/ext3/ext3.h +++ b/trunk/include/linux/ext3_fs.h @@ -1,11 +1,5 @@ /* - * Written by Stephen C. Tweedie , 1999 - * - * Copyright 1998--1999 Red Hat corp --- All Rights Reserved - * - * This file is part of the Linux kernel and is made available under - * the terms of the GNU General Public License, version 2, or at your - * option, any later version, incorporated herein by reference. + * linux/include/linux/ext3_fs.h * * Copyright (C) 1992, 1993, 1994, 1995 * Remy Card (card@masi.ibp.fr) @@ -19,11 +13,12 @@ * Copyright (C) 1991, 1992 Linus Torvalds */ -#include -#include +#ifndef _LINUX_EXT3_FS_H +#define _LINUX_EXT3_FS_H + +#include #include #include -#include /* * The second extended filesystem constants/structures @@ -80,12 +75,29 @@ #define EXT3_MIN_BLOCK_SIZE 1024 #define EXT3_MAX_BLOCK_SIZE 65536 #define EXT3_MIN_BLOCK_LOG_SIZE 10 -#define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) +#ifdef __KERNEL__ +# define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) +#else +# define EXT3_BLOCK_SIZE(s) (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size) +#endif #define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) -#define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) +#ifdef __KERNEL__ +# define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) +#else +# define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) +#endif +#ifdef __KERNEL__ #define EXT3_ADDR_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_addr_per_block_bits) #define EXT3_INODE_SIZE(s) (EXT3_SB(s)->s_inode_size) #define EXT3_FIRST_INO(s) (EXT3_SB(s)->s_first_ino) +#else +#define EXT3_INODE_SIZE(s) (((s)->s_rev_level == EXT3_GOOD_OLD_REV) ? \ + EXT3_GOOD_OLD_INODE_SIZE : \ + (s)->s_inode_size) +#define EXT3_FIRST_INO(s) (((s)->s_rev_level == EXT3_GOOD_OLD_REV) ? \ + EXT3_GOOD_OLD_FIRST_INO : \ + (s)->s_first_ino) +#endif /* * Macro-instructions used to manage fragments @@ -93,8 +105,13 @@ #define EXT3_MIN_FRAG_SIZE 1024 #define EXT3_MAX_FRAG_SIZE 4096 #define EXT3_MIN_FRAG_LOG_SIZE 10 -#define EXT3_FRAG_SIZE(s) (EXT3_SB(s)->s_frag_size) -#define EXT3_FRAGS_PER_BLOCK(s) (EXT3_SB(s)->s_frags_per_block) +#ifdef __KERNEL__ +# define EXT3_FRAG_SIZE(s) (EXT3_SB(s)->s_frag_size) +# define EXT3_FRAGS_PER_BLOCK(s) (EXT3_SB(s)->s_frags_per_block) +#else +# define EXT3_FRAG_SIZE(s) (EXT3_MIN_FRAG_SIZE << (s)->s_log_frag_size) +# define EXT3_FRAGS_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / EXT3_FRAG_SIZE(s)) +#endif /* * Structure of a blocks group descriptor @@ -114,10 +131,16 @@ struct ext3_group_desc /* * Macro-instructions used to manage group descriptors */ -#define EXT3_BLOCKS_PER_GROUP(s) (EXT3_SB(s)->s_blocks_per_group) -#define EXT3_DESC_PER_BLOCK(s) (EXT3_SB(s)->s_desc_per_block) -#define EXT3_INODES_PER_GROUP(s) (EXT3_SB(s)->s_inodes_per_group) -#define EXT3_DESC_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_desc_per_block_bits) +#ifdef __KERNEL__ +# define EXT3_BLOCKS_PER_GROUP(s) (EXT3_SB(s)->s_blocks_per_group) +# define EXT3_DESC_PER_BLOCK(s) (EXT3_SB(s)->s_desc_per_block) +# define EXT3_INODES_PER_GROUP(s) (EXT3_SB(s)->s_inodes_per_group) +# define EXT3_DESC_PER_BLOCK_BITS(s) (EXT3_SB(s)->s_desc_per_block_bits) +#else +# define EXT3_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group) +# define EXT3_DESC_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_group_desc)) +# define EXT3_INODES_PER_GROUP(s) ((s)->s_inodes_per_group) +#endif /* * Constants relative to the data blocks @@ -313,6 +336,7 @@ struct ext3_inode { #define i_size_high i_dir_acl +#if defined(__KERNEL__) || defined(__linux__) #define i_reserved1 osd1.linux1.l_i_reserved1 #define i_frag osd2.linux2.l_i_frag #define i_fsize osd2.linux2.l_i_fsize @@ -322,6 +346,24 @@ struct ext3_inode { #define i_gid_high osd2.linux2.l_i_gid_high #define i_reserved2 osd2.linux2.l_i_reserved2 +#elif defined(__GNU__) + +#define i_translator osd1.hurd1.h_i_translator +#define i_frag osd2.hurd2.h_i_frag; +#define i_fsize osd2.hurd2.h_i_fsize; +#define i_uid_high osd2.hurd2.h_i_uid_high +#define i_gid_high osd2.hurd2.h_i_gid_high +#define i_author osd2.hurd2.h_i_author + +#elif defined(__masix__) + +#define i_reserved1 osd1.masix1.m_i_reserved1 +#define i_frag osd2.masix2.m_i_frag +#define i_fsize osd2.masix2.m_i_fsize +#define i_reserved2 osd2.masix2.m_i_reserved2 + +#endif /* defined(__KERNEL__) || defined(__linux__) */ + /* * File system states */ @@ -489,197 +531,9 @@ struct ext3_super_block { __u32 s_reserved[162]; /* Padding to the end of the block */ }; -/* data type for block offset of block group */ -typedef int ext3_grpblk_t; - -/* data type for filesystem-wide blocks number */ -typedef unsigned long ext3_fsblk_t; - -#define E3FSBLK "%lu" - -struct ext3_reserve_window { - ext3_fsblk_t _rsv_start; /* First byte reserved */ - ext3_fsblk_t _rsv_end; /* Last byte reserved or 0 */ -}; - -struct ext3_reserve_window_node { - struct rb_node rsv_node; - __u32 rsv_goal_size; - __u32 rsv_alloc_hit; - struct ext3_reserve_window rsv_window; -}; - -struct ext3_block_alloc_info { - /* information about reservation window */ - struct ext3_reserve_window_node rsv_window_node; - /* - * was i_next_alloc_block in ext3_inode_info - * is the logical (file-relative) number of the - * most-recently-allocated block in this file. - * We use this for detecting linearly ascending allocation requests. - */ - __u32 last_alloc_logical_block; - /* - * Was i_next_alloc_goal in ext3_inode_info - * is the *physical* companion to i_next_alloc_block. - * it the physical block number of the block which was most-recentl - * allocated to this file. This give us the goal (target) for the next - * allocation when we detect linearly ascending requests. - */ - ext3_fsblk_t last_alloc_physical_block; -}; - -#define rsv_start rsv_window._rsv_start -#define rsv_end rsv_window._rsv_end - -/* - * third extended file system inode data in memory - */ -struct ext3_inode_info { - __le32 i_data[15]; /* unconverted */ - __u32 i_flags; -#ifdef EXT3_FRAGMENTS - __u32 i_faddr; - __u8 i_frag_no; - __u8 i_frag_size; -#endif - ext3_fsblk_t i_file_acl; - __u32 i_dir_acl; - __u32 i_dtime; - - /* - * i_block_group is the number of the block group which contains - * this file's inode. Constant across the lifetime of the inode, - * it is ued for making block allocation decisions - we try to - * place a file's data blocks near its inode block, and new inodes - * near to their parent directory's inode. - */ - __u32 i_block_group; - unsigned long i_state_flags; /* Dynamic state flags for ext3 */ - - /* block reservation info */ - struct ext3_block_alloc_info *i_block_alloc_info; - - __u32 i_dir_start_lookup; -#ifdef CONFIG_EXT3_FS_XATTR - /* - * Extended attributes can be read independently of the main file - * data. Taking i_mutex even when reading would cause contention - * between readers of EAs and writers of regular file data, so - * instead we synchronize on xattr_sem when reading or changing - * EAs. - */ - struct rw_semaphore xattr_sem; -#endif - - struct list_head i_orphan; /* unlinked but open inodes */ - - /* - * i_disksize keeps track of what the inode size is ON DISK, not - * in memory. During truncate, i_size is set to the new size by - * the VFS prior to calling ext3_truncate(), but the filesystem won't - * set i_disksize to 0 until the truncate is actually under way. - * - * The intent is that i_disksize always represents the blocks which - * are used by this file. This allows recovery to restart truncate - * on orphans if we crash during truncate. We actually write i_disksize - * into the on-disk inode when writing inodes out, instead of i_size. - * - * The only time when i_disksize and i_size may be different is when - * a truncate is in progress. The only things which change i_disksize - * are ext3_get_block (growth) and ext3_truncate (shrinkth). - */ - loff_t i_disksize; - - /* on-disk additional length */ - __u16 i_extra_isize; - - /* - * truncate_mutex is for serialising ext3_truncate() against - * ext3_getblock(). In the 2.4 ext2 design, great chunks of inode's - * data tree are chopped off during truncate. We can't do that in - * ext3 because whenever we perform intermediate commits during - * truncate, the inode and all the metadata blocks *must* be in a - * consistent state which allows truncation of the orphans to restart - * during recovery. Hence we must fix the get_block-vs-truncate race - * by other means, so we have truncate_mutex. - */ - struct mutex truncate_mutex; - - /* - * Transactions that contain inode's metadata needed to complete - * fsync and fdatasync, respectively. - */ - atomic_t i_sync_tid; - atomic_t i_datasync_tid; - - struct inode vfs_inode; -}; - -/* - * third extended-fs super-block data in memory - */ -struct ext3_sb_info { - unsigned long s_frag_size; /* Size of a fragment in bytes */ - unsigned long s_frags_per_block;/* Number of fragments per block */ - unsigned long s_inodes_per_block;/* Number of inodes per block */ - unsigned long s_frags_per_group;/* Number of fragments in a group */ - unsigned long s_blocks_per_group;/* Number of blocks in a group */ - unsigned long s_inodes_per_group;/* Number of inodes in a group */ - unsigned long s_itb_per_group; /* Number of inode table blocks per group */ - unsigned long s_gdb_count; /* Number of group descriptor blocks */ - unsigned long s_desc_per_block; /* Number of group descriptors per block */ - unsigned long s_groups_count; /* Number of groups in the fs */ - unsigned long s_overhead_last; /* Last calculated overhead */ - unsigned long s_blocks_last; /* Last seen block count */ - struct buffer_head * s_sbh; /* Buffer containing the super block */ - struct ext3_super_block * s_es; /* Pointer to the super block in the buffer */ - struct buffer_head ** s_group_desc; - unsigned long s_mount_opt; - ext3_fsblk_t s_sb_block; - uid_t s_resuid; - gid_t s_resgid; - unsigned short s_mount_state; - unsigned short s_pad; - int s_addr_per_block_bits; - int s_desc_per_block_bits; - int s_inode_size; - int s_first_ino; - spinlock_t s_next_gen_lock; - u32 s_next_generation; - u32 s_hash_seed[4]; - int s_def_hash_version; - int s_hash_unsigned; /* 3 if hash should be signed, 0 if not */ - struct percpu_counter s_freeblocks_counter; - struct percpu_counter s_freeinodes_counter; - struct percpu_counter s_dirs_counter; - struct blockgroup_lock *s_blockgroup_lock; - - /* root of the per fs reservation window tree */ - spinlock_t s_rsv_window_lock; - struct rb_root s_rsv_window_root; - struct ext3_reserve_window_node s_rsv_window_head; - - /* Journaling */ - struct inode * s_journal_inode; - struct journal_s * s_journal; - struct list_head s_orphan; - struct mutex s_orphan_lock; - struct mutex s_resize_lock; - unsigned long s_commit_interval; - struct block_device *journal_bdev; -#ifdef CONFIG_QUOTA - char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */ - int s_jquota_fmt; /* Format of quota to use */ -#endif -}; - -static inline spinlock_t * -sb_bgl_lock(struct ext3_sb_info *sbi, unsigned int block_group) -{ - return bgl_lock_ptr(sbi->s_blockgroup_lock, block_group); -} - +#ifdef __KERNEL__ +#include +#include static inline struct ext3_sb_info * EXT3_SB(struct super_block *sb) { return sb->s_fs_info; @@ -722,6 +576,12 @@ static inline void ext3_clear_inode_state(struct inode *inode, int bit) { clear_bit(bit, &EXT3_I(inode)->i_state_flags); } +#else +/* Assume that user mode programs are passing in an ext3fs superblock, not + * a kernel struct super_block. This will allow us to call the feature-test + * macros from user land. */ +#define EXT3_SB(sb) (sb) +#endif #define NEXT_ORPHAN(inode) EXT3_I(inode)->i_dtime @@ -911,6 +771,8 @@ static inline __le16 ext3_rec_len_to_disk(unsigned len) #define DX_HASH_HALF_MD4_UNSIGNED 4 #define DX_HASH_TEA_UNSIGNED 5 +#ifdef __KERNEL__ + /* hash info structure used by the directory hash */ struct dx_hash_info { @@ -1112,211 +974,7 @@ extern const struct inode_operations ext3_special_inode_operations; extern const struct inode_operations ext3_symlink_inode_operations; extern const struct inode_operations ext3_fast_symlink_inode_operations; -#define EXT3_JOURNAL(inode) (EXT3_SB((inode)->i_sb)->s_journal) - -/* Define the number of blocks we need to account to a transaction to - * modify one block of data. - * - * We may have to touch one inode, one bitmap buffer, up to three - * indirection blocks, the group and superblock summaries, and the data - * block to complete the transaction. */ - -#define EXT3_SINGLEDATA_TRANS_BLOCKS 8U - -/* Extended attribute operations touch at most two data buffers, - * two bitmap buffers, and two group summaries, in addition to the inode - * and the superblock, which are already accounted for. */ - -#define EXT3_XATTR_TRANS_BLOCKS 6U - -/* Define the minimum size for a transaction which modifies data. This - * needs to take into account the fact that we may end up modifying two - * quota files too (one for the group, one for the user quota). The - * superblock only gets updated once, of course, so don't bother - * counting that again for the quota updates. */ - -#define EXT3_DATA_TRANS_BLOCKS(sb) (EXT3_SINGLEDATA_TRANS_BLOCKS + \ - EXT3_XATTR_TRANS_BLOCKS - 2 + \ - EXT3_MAXQUOTAS_TRANS_BLOCKS(sb)) - -/* Delete operations potentially hit one directory's namespace plus an - * entire inode, plus arbitrary amounts of bitmap/indirection data. Be - * generous. We can grow the delete transaction later if necessary. */ - -#define EXT3_DELETE_TRANS_BLOCKS(sb) (EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) + 64) - -/* Define an arbitrary limit for the amount of data we will anticipate - * writing to any given transaction. For unbounded transactions such as - * write(2) and truncate(2) we can write more than this, but we always - * start off at the maximum transaction size and grow the transaction - * optimistically as we go. */ - -#define EXT3_MAX_TRANS_DATA 64U - -/* We break up a large truncate or write transaction once the handle's - * buffer credits gets this low, we need either to extend the - * transaction or to start a new one. Reserve enough space here for - * inode, bitmap, superblock, group and indirection updates for at least - * one block, plus two quota updates. Quota allocations are not - * needed. */ - -#define EXT3_RESERVE_TRANS_BLOCKS 12U - -#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 - -#ifdef CONFIG_QUOTA -/* Amount of blocks needed for quota update - we know that the structure was - * allocated so we need to update only inode+data */ -#define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0) -/* Amount of blocks needed for quota insert/delete - we do some block writes - * but inode, sb and group updates are done only once */ -#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\ - (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0) -#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\ - (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0) -#else -#define EXT3_QUOTA_TRANS_BLOCKS(sb) 0 -#define EXT3_QUOTA_INIT_BLOCKS(sb) 0 -#define EXT3_QUOTA_DEL_BLOCKS(sb) 0 -#endif -#define EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_TRANS_BLOCKS(sb)) -#define EXT3_MAXQUOTAS_INIT_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_INIT_BLOCKS(sb)) -#define EXT3_MAXQUOTAS_DEL_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_DEL_BLOCKS(sb)) - -int -ext3_mark_iloc_dirty(handle_t *handle, - struct inode *inode, - struct ext3_iloc *iloc); - -/* - * On success, We end up with an outstanding reference count against - * iloc->bh. This _must_ be cleaned up later. - */ - -int ext3_reserve_inode_write(handle_t *handle, struct inode *inode, - struct ext3_iloc *iloc); - -int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode); - -/* - * Wrapper functions with which ext3 calls into JBD. The intent here is - * to allow these to be turned into appropriate stubs so ext3 can control - * ext2 filesystems, so ext2+ext3 systems only nee one fs. This work hasn't - * been done yet. - */ - -static inline void ext3_journal_release_buffer(handle_t *handle, - struct buffer_head *bh) -{ - journal_release_buffer(handle, bh); -} - -void ext3_journal_abort_handle(const char *caller, const char *err_fn, - struct buffer_head *bh, handle_t *handle, int err); - -int __ext3_journal_get_undo_access(const char *where, handle_t *handle, - struct buffer_head *bh); - -int __ext3_journal_get_write_access(const char *where, handle_t *handle, - struct buffer_head *bh); - -int __ext3_journal_forget(const char *where, handle_t *handle, - struct buffer_head *bh); -int __ext3_journal_revoke(const char *where, handle_t *handle, - unsigned long blocknr, struct buffer_head *bh); - -int __ext3_journal_get_create_access(const char *where, - handle_t *handle, struct buffer_head *bh); - -int __ext3_journal_dirty_metadata(const char *where, - handle_t *handle, struct buffer_head *bh); - -#define ext3_journal_get_undo_access(handle, bh) \ - __ext3_journal_get_undo_access(__func__, (handle), (bh)) -#define ext3_journal_get_write_access(handle, bh) \ - __ext3_journal_get_write_access(__func__, (handle), (bh)) -#define ext3_journal_revoke(handle, blocknr, bh) \ - __ext3_journal_revoke(__func__, (handle), (blocknr), (bh)) -#define ext3_journal_get_create_access(handle, bh) \ - __ext3_journal_get_create_access(__func__, (handle), (bh)) -#define ext3_journal_dirty_metadata(handle, bh) \ - __ext3_journal_dirty_metadata(__func__, (handle), (bh)) -#define ext3_journal_forget(handle, bh) \ - __ext3_journal_forget(__func__, (handle), (bh)) - -int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh); - -handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks); -int __ext3_journal_stop(const char *where, handle_t *handle); - -static inline handle_t *ext3_journal_start(struct inode *inode, int nblocks) -{ - return ext3_journal_start_sb(inode->i_sb, nblocks); -} - -#define ext3_journal_stop(handle) \ - __ext3_journal_stop(__func__, (handle)) - -static inline handle_t *ext3_journal_current_handle(void) -{ - return journal_current_handle(); -} - -static inline int ext3_journal_extend(handle_t *handle, int nblocks) -{ - return journal_extend(handle, nblocks); -} - -static inline int ext3_journal_restart(handle_t *handle, int nblocks) -{ - return journal_restart(handle, nblocks); -} - -static inline int ext3_journal_blocks_per_page(struct inode *inode) -{ - return journal_blocks_per_page(inode); -} - -static inline int ext3_journal_force_commit(journal_t *journal) -{ - return journal_force_commit(journal); -} - -/* super.c */ -int ext3_force_commit(struct super_block *sb); - -static inline int ext3_should_journal_data(struct inode *inode) -{ - if (!S_ISREG(inode->i_mode)) - return 1; - if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA) - return 1; - if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) - return 1; - return 0; -} - -static inline int ext3_should_order_data(struct inode *inode) -{ - if (!S_ISREG(inode->i_mode)) - return 0; - if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) - return 0; - if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA) - return 1; - return 0; -} - -static inline int ext3_should_writeback_data(struct inode *inode) -{ - if (!S_ISREG(inode->i_mode)) - return 0; - if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) - return 0; - if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) - return 1; - return 0; -} +#endif /* __KERNEL__ */ -#include +#endif /* _LINUX_EXT3_FS_H */ diff --git a/trunk/include/linux/ext3_fs_i.h b/trunk/include/linux/ext3_fs_i.h new file mode 100644 index 000000000000..f42c098aed8d --- /dev/null +++ b/trunk/include/linux/ext3_fs_i.h @@ -0,0 +1,151 @@ +/* + * linux/include/linux/ext3_fs_i.h + * + * Copyright (C) 1992, 1993, 1994, 1995 + * Remy Card (card@masi.ibp.fr) + * Laboratoire MASI - Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) + * + * from + * + * linux/include/linux/minix_fs_i.h + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +#ifndef _LINUX_EXT3_FS_I +#define _LINUX_EXT3_FS_I + +#include +#include +#include +#include + +/* data type for block offset of block group */ +typedef int ext3_grpblk_t; + +/* data type for filesystem-wide blocks number */ +typedef unsigned long ext3_fsblk_t; + +#define E3FSBLK "%lu" + +struct ext3_reserve_window { + ext3_fsblk_t _rsv_start; /* First byte reserved */ + ext3_fsblk_t _rsv_end; /* Last byte reserved or 0 */ +}; + +struct ext3_reserve_window_node { + struct rb_node rsv_node; + __u32 rsv_goal_size; + __u32 rsv_alloc_hit; + struct ext3_reserve_window rsv_window; +}; + +struct ext3_block_alloc_info { + /* information about reservation window */ + struct ext3_reserve_window_node rsv_window_node; + /* + * was i_next_alloc_block in ext3_inode_info + * is the logical (file-relative) number of the + * most-recently-allocated block in this file. + * We use this for detecting linearly ascending allocation requests. + */ + __u32 last_alloc_logical_block; + /* + * Was i_next_alloc_goal in ext3_inode_info + * is the *physical* companion to i_next_alloc_block. + * it the physical block number of the block which was most-recentl + * allocated to this file. This give us the goal (target) for the next + * allocation when we detect linearly ascending requests. + */ + ext3_fsblk_t last_alloc_physical_block; +}; + +#define rsv_start rsv_window._rsv_start +#define rsv_end rsv_window._rsv_end + +/* + * third extended file system inode data in memory + */ +struct ext3_inode_info { + __le32 i_data[15]; /* unconverted */ + __u32 i_flags; +#ifdef EXT3_FRAGMENTS + __u32 i_faddr; + __u8 i_frag_no; + __u8 i_frag_size; +#endif + ext3_fsblk_t i_file_acl; + __u32 i_dir_acl; + __u32 i_dtime; + + /* + * i_block_group is the number of the block group which contains + * this file's inode. Constant across the lifetime of the inode, + * it is ued for making block allocation decisions - we try to + * place a file's data blocks near its inode block, and new inodes + * near to their parent directory's inode. + */ + __u32 i_block_group; + unsigned long i_state_flags; /* Dynamic state flags for ext3 */ + + /* block reservation info */ + struct ext3_block_alloc_info *i_block_alloc_info; + + __u32 i_dir_start_lookup; +#ifdef CONFIG_EXT3_FS_XATTR + /* + * Extended attributes can be read independently of the main file + * data. Taking i_mutex even when reading would cause contention + * between readers of EAs and writers of regular file data, so + * instead we synchronize on xattr_sem when reading or changing + * EAs. + */ + struct rw_semaphore xattr_sem; +#endif + + struct list_head i_orphan; /* unlinked but open inodes */ + + /* + * i_disksize keeps track of what the inode size is ON DISK, not + * in memory. During truncate, i_size is set to the new size by + * the VFS prior to calling ext3_truncate(), but the filesystem won't + * set i_disksize to 0 until the truncate is actually under way. + * + * The intent is that i_disksize always represents the blocks which + * are used by this file. This allows recovery to restart truncate + * on orphans if we crash during truncate. We actually write i_disksize + * into the on-disk inode when writing inodes out, instead of i_size. + * + * The only time when i_disksize and i_size may be different is when + * a truncate is in progress. The only things which change i_disksize + * are ext3_get_block (growth) and ext3_truncate (shrinkth). + */ + loff_t i_disksize; + + /* on-disk additional length */ + __u16 i_extra_isize; + + /* + * truncate_mutex is for serialising ext3_truncate() against + * ext3_getblock(). In the 2.4 ext2 design, great chunks of inode's + * data tree are chopped off during truncate. We can't do that in + * ext3 because whenever we perform intermediate commits during + * truncate, the inode and all the metadata blocks *must* be in a + * consistent state which allows truncation of the orphans to restart + * during recovery. Hence we must fix the get_block-vs-truncate race + * by other means, so we have truncate_mutex. + */ + struct mutex truncate_mutex; + + /* + * Transactions that contain inode's metadata needed to complete + * fsync and fdatasync, respectively. + */ + atomic_t i_sync_tid; + atomic_t i_datasync_tid; + + struct inode vfs_inode; +}; + +#endif /* _LINUX_EXT3_FS_I */ diff --git a/trunk/include/linux/ext3_fs_sb.h b/trunk/include/linux/ext3_fs_sb.h new file mode 100644 index 000000000000..64365252f1b0 --- /dev/null +++ b/trunk/include/linux/ext3_fs_sb.h @@ -0,0 +1,91 @@ +/* + * linux/include/linux/ext3_fs_sb.h + * + * Copyright (C) 1992, 1993, 1994, 1995 + * Remy Card (card@masi.ibp.fr) + * Laboratoire MASI - Institut Blaise Pascal + * Universite Pierre et Marie Curie (Paris VI) + * + * from + * + * linux/include/linux/minix_fs_sb.h + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +#ifndef _LINUX_EXT3_FS_SB +#define _LINUX_EXT3_FS_SB + +#ifdef __KERNEL__ +#include +#include +#include +#include +#endif +#include + +/* + * third extended-fs super-block data in memory + */ +struct ext3_sb_info { + unsigned long s_frag_size; /* Size of a fragment in bytes */ + unsigned long s_frags_per_block;/* Number of fragments per block */ + unsigned long s_inodes_per_block;/* Number of inodes per block */ + unsigned long s_frags_per_group;/* Number of fragments in a group */ + unsigned long s_blocks_per_group;/* Number of blocks in a group */ + unsigned long s_inodes_per_group;/* Number of inodes in a group */ + unsigned long s_itb_per_group; /* Number of inode table blocks per group */ + unsigned long s_gdb_count; /* Number of group descriptor blocks */ + unsigned long s_desc_per_block; /* Number of group descriptors per block */ + unsigned long s_groups_count; /* Number of groups in the fs */ + unsigned long s_overhead_last; /* Last calculated overhead */ + unsigned long s_blocks_last; /* Last seen block count */ + struct buffer_head * s_sbh; /* Buffer containing the super block */ + struct ext3_super_block * s_es; /* Pointer to the super block in the buffer */ + struct buffer_head ** s_group_desc; + unsigned long s_mount_opt; + ext3_fsblk_t s_sb_block; + uid_t s_resuid; + gid_t s_resgid; + unsigned short s_mount_state; + unsigned short s_pad; + int s_addr_per_block_bits; + int s_desc_per_block_bits; + int s_inode_size; + int s_first_ino; + spinlock_t s_next_gen_lock; + u32 s_next_generation; + u32 s_hash_seed[4]; + int s_def_hash_version; + int s_hash_unsigned; /* 3 if hash should be signed, 0 if not */ + struct percpu_counter s_freeblocks_counter; + struct percpu_counter s_freeinodes_counter; + struct percpu_counter s_dirs_counter; + struct blockgroup_lock *s_blockgroup_lock; + + /* root of the per fs reservation window tree */ + spinlock_t s_rsv_window_lock; + struct rb_root s_rsv_window_root; + struct ext3_reserve_window_node s_rsv_window_head; + + /* Journaling */ + struct inode * s_journal_inode; + struct journal_s * s_journal; + struct list_head s_orphan; + struct mutex s_orphan_lock; + struct mutex s_resize_lock; + unsigned long s_commit_interval; + struct block_device *journal_bdev; +#ifdef CONFIG_QUOTA + char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */ + int s_jquota_fmt; /* Format of quota to use */ +#endif +}; + +static inline spinlock_t * +sb_bgl_lock(struct ext3_sb_info *sbi, unsigned int block_group) +{ + return bgl_lock_ptr(sbi->s_blockgroup_lock, block_group); +} + +#endif /* _LINUX_EXT3_FS_SB */ diff --git a/trunk/include/linux/ext3_jbd.h b/trunk/include/linux/ext3_jbd.h new file mode 100644 index 000000000000..d7b5ddca99c2 --- /dev/null +++ b/trunk/include/linux/ext3_jbd.h @@ -0,0 +1,229 @@ +/* + * linux/include/linux/ext3_jbd.h + * + * Written by Stephen C. Tweedie , 1999 + * + * Copyright 1998--1999 Red Hat corp --- All Rights Reserved + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + * + * Ext3-specific journaling extensions. + */ + +#ifndef _LINUX_EXT3_JBD_H +#define _LINUX_EXT3_JBD_H + +#include +#include +#include + +#define EXT3_JOURNAL(inode) (EXT3_SB((inode)->i_sb)->s_journal) + +/* Define the number of blocks we need to account to a transaction to + * modify one block of data. + * + * We may have to touch one inode, one bitmap buffer, up to three + * indirection blocks, the group and superblock summaries, and the data + * block to complete the transaction. */ + +#define EXT3_SINGLEDATA_TRANS_BLOCKS 8U + +/* Extended attribute operations touch at most two data buffers, + * two bitmap buffers, and two group summaries, in addition to the inode + * and the superblock, which are already accounted for. */ + +#define EXT3_XATTR_TRANS_BLOCKS 6U + +/* Define the minimum size for a transaction which modifies data. This + * needs to take into account the fact that we may end up modifying two + * quota files too (one for the group, one for the user quota). The + * superblock only gets updated once, of course, so don't bother + * counting that again for the quota updates. */ + +#define EXT3_DATA_TRANS_BLOCKS(sb) (EXT3_SINGLEDATA_TRANS_BLOCKS + \ + EXT3_XATTR_TRANS_BLOCKS - 2 + \ + EXT3_MAXQUOTAS_TRANS_BLOCKS(sb)) + +/* Delete operations potentially hit one directory's namespace plus an + * entire inode, plus arbitrary amounts of bitmap/indirection data. Be + * generous. We can grow the delete transaction later if necessary. */ + +#define EXT3_DELETE_TRANS_BLOCKS(sb) (EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) + 64) + +/* Define an arbitrary limit for the amount of data we will anticipate + * writing to any given transaction. For unbounded transactions such as + * write(2) and truncate(2) we can write more than this, but we always + * start off at the maximum transaction size and grow the transaction + * optimistically as we go. */ + +#define EXT3_MAX_TRANS_DATA 64U + +/* We break up a large truncate or write transaction once the handle's + * buffer credits gets this low, we need either to extend the + * transaction or to start a new one. Reserve enough space here for + * inode, bitmap, superblock, group and indirection updates for at least + * one block, plus two quota updates. Quota allocations are not + * needed. */ + +#define EXT3_RESERVE_TRANS_BLOCKS 12U + +#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 + +#ifdef CONFIG_QUOTA +/* Amount of blocks needed for quota update - we know that the structure was + * allocated so we need to update only inode+data */ +#define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0) +/* Amount of blocks needed for quota insert/delete - we do some block writes + * but inode, sb and group updates are done only once */ +#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\ + (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0) +#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\ + (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0) +#else +#define EXT3_QUOTA_TRANS_BLOCKS(sb) 0 +#define EXT3_QUOTA_INIT_BLOCKS(sb) 0 +#define EXT3_QUOTA_DEL_BLOCKS(sb) 0 +#endif +#define EXT3_MAXQUOTAS_TRANS_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_TRANS_BLOCKS(sb)) +#define EXT3_MAXQUOTAS_INIT_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_INIT_BLOCKS(sb)) +#define EXT3_MAXQUOTAS_DEL_BLOCKS(sb) (MAXQUOTAS*EXT3_QUOTA_DEL_BLOCKS(sb)) + +int +ext3_mark_iloc_dirty(handle_t *handle, + struct inode *inode, + struct ext3_iloc *iloc); + +/* + * On success, We end up with an outstanding reference count against + * iloc->bh. This _must_ be cleaned up later. + */ + +int ext3_reserve_inode_write(handle_t *handle, struct inode *inode, + struct ext3_iloc *iloc); + +int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode); + +/* + * Wrapper functions with which ext3 calls into JBD. The intent here is + * to allow these to be turned into appropriate stubs so ext3 can control + * ext2 filesystems, so ext2+ext3 systems only nee one fs. This work hasn't + * been done yet. + */ + +static inline void ext3_journal_release_buffer(handle_t *handle, + struct buffer_head *bh) +{ + journal_release_buffer(handle, bh); +} + +void ext3_journal_abort_handle(const char *caller, const char *err_fn, + struct buffer_head *bh, handle_t *handle, int err); + +int __ext3_journal_get_undo_access(const char *where, handle_t *handle, + struct buffer_head *bh); + +int __ext3_journal_get_write_access(const char *where, handle_t *handle, + struct buffer_head *bh); + +int __ext3_journal_forget(const char *where, handle_t *handle, + struct buffer_head *bh); + +int __ext3_journal_revoke(const char *where, handle_t *handle, + unsigned long blocknr, struct buffer_head *bh); + +int __ext3_journal_get_create_access(const char *where, + handle_t *handle, struct buffer_head *bh); + +int __ext3_journal_dirty_metadata(const char *where, + handle_t *handle, struct buffer_head *bh); + +#define ext3_journal_get_undo_access(handle, bh) \ + __ext3_journal_get_undo_access(__func__, (handle), (bh)) +#define ext3_journal_get_write_access(handle, bh) \ + __ext3_journal_get_write_access(__func__, (handle), (bh)) +#define ext3_journal_revoke(handle, blocknr, bh) \ + __ext3_journal_revoke(__func__, (handle), (blocknr), (bh)) +#define ext3_journal_get_create_access(handle, bh) \ + __ext3_journal_get_create_access(__func__, (handle), (bh)) +#define ext3_journal_dirty_metadata(handle, bh) \ + __ext3_journal_dirty_metadata(__func__, (handle), (bh)) +#define ext3_journal_forget(handle, bh) \ + __ext3_journal_forget(__func__, (handle), (bh)) + +int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh); + +handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks); +int __ext3_journal_stop(const char *where, handle_t *handle); + +static inline handle_t *ext3_journal_start(struct inode *inode, int nblocks) +{ + return ext3_journal_start_sb(inode->i_sb, nblocks); +} + +#define ext3_journal_stop(handle) \ + __ext3_journal_stop(__func__, (handle)) + +static inline handle_t *ext3_journal_current_handle(void) +{ + return journal_current_handle(); +} + +static inline int ext3_journal_extend(handle_t *handle, int nblocks) +{ + return journal_extend(handle, nblocks); +} + +static inline int ext3_journal_restart(handle_t *handle, int nblocks) +{ + return journal_restart(handle, nblocks); +} + +static inline int ext3_journal_blocks_per_page(struct inode *inode) +{ + return journal_blocks_per_page(inode); +} + +static inline int ext3_journal_force_commit(journal_t *journal) +{ + return journal_force_commit(journal); +} + +/* super.c */ +int ext3_force_commit(struct super_block *sb); + +static inline int ext3_should_journal_data(struct inode *inode) +{ + if (!S_ISREG(inode->i_mode)) + return 1; + if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA) + return 1; + if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) + return 1; + return 0; +} + +static inline int ext3_should_order_data(struct inode *inode) +{ + if (!S_ISREG(inode->i_mode)) + return 0; + if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) + return 0; + if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA) + return 1; + return 0; +} + +static inline int ext3_should_writeback_data(struct inode *inode) +{ + if (!S_ISREG(inode->i_mode)) + return 0; + if (EXT3_I(inode)->i_flags & EXT3_JOURNAL_DATA_FL) + return 0; + if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA) + return 1; + return 0; +} + +#endif /* _LINUX_EXT3_JBD_H */ diff --git a/trunk/include/linux/firewire.h b/trunk/include/linux/firewire.h index cdc9b719e9c7..4db7b68f0582 100644 --- a/trunk/include/linux/firewire.h +++ b/trunk/include/linux/firewire.h @@ -2,7 +2,6 @@ #define _LINUX_FIREWIRE_H #include -#include #include #include #include @@ -65,6 +64,8 @@ #define CSR_MODEL 0x17 #define CSR_DIRECTORY_ID 0x20 +struct device; + struct fw_csr_iterator { const u32 *p; const u32 *end; diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 8de675523e46..135693e79f2b 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -1215,7 +1215,6 @@ extern int vfs_setlease(struct file *, long, struct file_lock **); extern int lease_modify(struct file_lock **, int); extern int lock_may_read(struct inode *, loff_t start, unsigned long count); extern int lock_may_write(struct inode *, loff_t start, unsigned long count); -extern void locks_delete_block(struct file_lock *waiter); extern void lock_flocks(void); extern void unlock_flocks(void); #else /* !CONFIG_FILE_LOCKING */ @@ -1360,10 +1359,6 @@ static inline int lock_may_write(struct inode *inode, loff_t start, return 1; } -static inline void locks_delete_block(struct file_lock *waiter) -{ -} - static inline void lock_flocks(void) { } @@ -2511,7 +2506,6 @@ extern int dcache_readdir(struct file *, void *, filldir_t); extern int simple_setattr(struct dentry *, struct iattr *); extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *); extern int simple_statfs(struct dentry *, struct kstatfs *); -extern int simple_open(struct inode *inode, struct file *file); extern int simple_link(struct dentry *, struct inode *, struct dentry *); extern int simple_unlink(struct inode *, struct dentry *); extern int simple_rmdir(struct inode *, struct dentry *); diff --git a/trunk/include/linux/ftrace_event.h b/trunk/include/linux/ftrace_event.h index 5f3f3be5af09..dd478fc8f9f5 100644 --- a/trunk/include/linux/ftrace_event.h +++ b/trunk/include/linux/ftrace_event.h @@ -144,14 +144,12 @@ struct event_filter; enum trace_reg { TRACE_REG_REGISTER, TRACE_REG_UNREGISTER, -#ifdef CONFIG_PERF_EVENTS TRACE_REG_PERF_REGISTER, TRACE_REG_PERF_UNREGISTER, TRACE_REG_PERF_OPEN, TRACE_REG_PERF_CLOSE, TRACE_REG_PERF_ADD, TRACE_REG_PERF_DEL, -#endif }; struct ftrace_event_call; diff --git a/trunk/include/linux/fuse.h b/trunk/include/linux/fuse.h index 8f2ab8fef929..8ba2c9460b28 100644 --- a/trunk/include/linux/fuse.h +++ b/trunk/include/linux/fuse.h @@ -593,7 +593,7 @@ struct fuse_dirent { __u64 off; __u32 namelen; __u32 type; - char name[]; + char name[0]; }; #define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name) diff --git a/trunk/include/linux/gpio-pxa.h b/trunk/include/linux/gpio-pxa.h index d755b28ba635..05071ee34c3f 100644 --- a/trunk/include/linux/gpio-pxa.h +++ b/trunk/include/linux/gpio-pxa.h @@ -13,8 +13,4 @@ extern int pxa_last_gpio; extern int pxa_irq_to_gpio(int irq); -struct pxa_gpio_platform_data { - int (*gpio_set_wake)(unsigned int gpio, unsigned int on); -}; - #endif /* __GPIO_PXA_H */ diff --git a/trunk/include/linux/hsi/Kbuild b/trunk/include/linux/hsi/Kbuild deleted file mode 100644 index 271a770b4784..000000000000 --- a/trunk/include/linux/hsi/Kbuild +++ /dev/null @@ -1 +0,0 @@ -header-y += hsi_char.h diff --git a/trunk/include/linux/hsi/hsi.h b/trunk/include/linux/hsi/hsi.h deleted file mode 100644 index 56fae865e272..000000000000 --- a/trunk/include/linux/hsi/hsi.h +++ /dev/null @@ -1,413 +0,0 @@ -/* - * HSI core header file. - * - * Copyright (C) 2010 Nokia Corporation. All rights reserved. - * - * Contact: Carlos Chinea - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - -#ifndef __LINUX_HSI_H__ -#define __LINUX_HSI_H__ - -#include -#include -#include -#include -#include -#include - -/* HSI message ttype */ -#define HSI_MSG_READ 0 -#define HSI_MSG_WRITE 1 - -/* HSI configuration values */ -enum { - HSI_MODE_STREAM = 1, - HSI_MODE_FRAME, -}; - -enum { - HSI_FLOW_SYNC, /* Synchronized flow */ - HSI_FLOW_PIPE, /* Pipelined flow */ -}; - -enum { - HSI_ARB_RR, /* Round-robin arbitration */ - HSI_ARB_PRIO, /* Channel priority arbitration */ -}; - -#define HSI_MAX_CHANNELS 16 - -/* HSI message status codes */ -enum { - HSI_STATUS_COMPLETED, /* Message transfer is completed */ - HSI_STATUS_PENDING, /* Message pending to be read/write (POLL) */ - HSI_STATUS_PROCEEDING, /* Message transfer is ongoing */ - HSI_STATUS_QUEUED, /* Message waiting to be served */ - HSI_STATUS_ERROR, /* Error when message transfer was ongoing */ -}; - -/* HSI port event codes */ -enum { - HSI_EVENT_START_RX, - HSI_EVENT_STOP_RX, -}; - -/** - * struct hsi_config - Configuration for RX/TX HSI modules - * @mode: Bit transmission mode (STREAM or FRAME) - * @channels: Number of channels to use [1..16] - * @speed: Max bit transmission speed (Kbit/s) - * @flow: RX flow type (SYNCHRONIZED or PIPELINE) - * @arb_mode: Arbitration mode for TX frame (Round robin, priority) - */ -struct hsi_config { - unsigned int mode; - unsigned int channels; - unsigned int speed; - union { - unsigned int flow; /* RX only */ - unsigned int arb_mode; /* TX only */ - }; -}; - -/** - * struct hsi_board_info - HSI client board info - * @name: Name for the HSI device - * @hsi_id: HSI controller id where the client sits - * @port: Port number in the controller where the client sits - * @tx_cfg: HSI TX configuration - * @rx_cfg: HSI RX configuration - * @platform_data: Platform related data - * @archdata: Architecture-dependent device data - */ -struct hsi_board_info { - const char *name; - unsigned int hsi_id; - unsigned int port; - struct hsi_config tx_cfg; - struct hsi_config rx_cfg; - void *platform_data; - struct dev_archdata *archdata; -}; - -#ifdef CONFIG_HSI_BOARDINFO -extern int hsi_register_board_info(struct hsi_board_info const *info, - unsigned int len); -#else -static inline int hsi_register_board_info(struct hsi_board_info const *info, - unsigned int len) -{ - return 0; -} -#endif /* CONFIG_HSI_BOARDINFO */ - -/** - * struct hsi_client - HSI client attached to an HSI port - * @device: Driver model representation of the device - * @tx_cfg: HSI TX configuration - * @rx_cfg: HSI RX configuration - * @e_handler: Callback for handling port events (RX Wake High/Low) - * @pclaimed: Keeps tracks if the clients claimed its associated HSI port - * @nb: Notifier block for port events - */ -struct hsi_client { - struct device device; - struct hsi_config tx_cfg; - struct hsi_config rx_cfg; - /* private: */ - void (*ehandler)(struct hsi_client *, unsigned long); - unsigned int pclaimed:1; - struct notifier_block nb; -}; - -#define to_hsi_client(dev) container_of(dev, struct hsi_client, device) - -static inline void hsi_client_set_drvdata(struct hsi_client *cl, void *data) -{ - dev_set_drvdata(&cl->device, data); -} - -static inline void *hsi_client_drvdata(struct hsi_client *cl) -{ - return dev_get_drvdata(&cl->device); -} - -int hsi_register_port_event(struct hsi_client *cl, - void (*handler)(struct hsi_client *, unsigned long)); -int hsi_unregister_port_event(struct hsi_client *cl); - -/** - * struct hsi_client_driver - Driver associated to an HSI client - * @driver: Driver model representation of the driver - */ -struct hsi_client_driver { - struct device_driver driver; -}; - -#define to_hsi_client_driver(drv) container_of(drv, struct hsi_client_driver,\ - driver) - -int hsi_register_client_driver(struct hsi_client_driver *drv); - -static inline void hsi_unregister_client_driver(struct hsi_client_driver *drv) -{ - driver_unregister(&drv->driver); -} - -/** - * struct hsi_msg - HSI message descriptor - * @link: Free to use by the current descriptor owner - * @cl: HSI device client that issues the transfer - * @sgt: Head of the scatterlist array - * @context: Client context data associated to the transfer - * @complete: Transfer completion callback - * @destructor: Destructor to free resources when flushing - * @status: Status of the transfer when completed - * @actual_len: Actual length of data transfered on completion - * @channel: Channel were to TX/RX the message - * @ttype: Transfer type (TX if set, RX otherwise) - * @break_frame: if true HSI will send/receive a break frame. Data buffers are - * ignored in the request. - */ -struct hsi_msg { - struct list_head link; - struct hsi_client *cl; - struct sg_table sgt; - void *context; - - void (*complete)(struct hsi_msg *msg); - void (*destructor)(struct hsi_msg *msg); - - int status; - unsigned int actual_len; - unsigned int channel; - unsigned int ttype:1; - unsigned int break_frame:1; -}; - -struct hsi_msg *hsi_alloc_msg(unsigned int n_frag, gfp_t flags); -void hsi_free_msg(struct hsi_msg *msg); - -/** - * struct hsi_port - HSI port device - * @device: Driver model representation of the device - * @tx_cfg: Current TX path configuration - * @rx_cfg: Current RX path configuration - * @num: Port number - * @shared: Set when port can be shared by different clients - * @claimed: Reference count of clients which claimed the port - * @lock: Serialize port claim - * @async: Asynchronous transfer callback - * @setup: Callback to set the HSI client configuration - * @flush: Callback to clean the HW state and destroy all pending transfers - * @start_tx: Callback to inform that a client wants to TX data - * @stop_tx: Callback to inform that a client no longer wishes to TX data - * @release: Callback to inform that a client no longer uses the port - * @n_head: Notifier chain for signaling port events to the clients. - */ -struct hsi_port { - struct device device; - struct hsi_config tx_cfg; - struct hsi_config rx_cfg; - unsigned int num; - unsigned int shared:1; - int claimed; - struct mutex lock; - int (*async)(struct hsi_msg *msg); - int (*setup)(struct hsi_client *cl); - int (*flush)(struct hsi_client *cl); - int (*start_tx)(struct hsi_client *cl); - int (*stop_tx)(struct hsi_client *cl); - int (*release)(struct hsi_client *cl); - /* private */ - struct atomic_notifier_head n_head; -}; - -#define to_hsi_port(dev) container_of(dev, struct hsi_port, device) -#define hsi_get_port(cl) to_hsi_port((cl)->device.parent) - -int hsi_event(struct hsi_port *port, unsigned long event); -int hsi_claim_port(struct hsi_client *cl, unsigned int share); -void hsi_release_port(struct hsi_client *cl); - -static inline int hsi_port_claimed(struct hsi_client *cl) -{ - return cl->pclaimed; -} - -static inline void hsi_port_set_drvdata(struct hsi_port *port, void *data) -{ - dev_set_drvdata(&port->device, data); -} - -static inline void *hsi_port_drvdata(struct hsi_port *port) -{ - return dev_get_drvdata(&port->device); -} - -/** - * struct hsi_controller - HSI controller device - * @device: Driver model representation of the device - * @owner: Pointer to the module owning the controller - * @id: HSI controller ID - * @num_ports: Number of ports in the HSI controller - * @port: Array of HSI ports - */ -struct hsi_controller { - struct device device; - struct module *owner; - unsigned int id; - unsigned int num_ports; - struct hsi_port **port; -}; - -#define to_hsi_controller(dev) container_of(dev, struct hsi_controller, device) - -struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags); -void hsi_put_controller(struct hsi_controller *hsi); -int hsi_register_controller(struct hsi_controller *hsi); -void hsi_unregister_controller(struct hsi_controller *hsi); - -static inline void hsi_controller_set_drvdata(struct hsi_controller *hsi, - void *data) -{ - dev_set_drvdata(&hsi->device, data); -} - -static inline void *hsi_controller_drvdata(struct hsi_controller *hsi) -{ - return dev_get_drvdata(&hsi->device); -} - -static inline struct hsi_port *hsi_find_port_num(struct hsi_controller *hsi, - unsigned int num) -{ - return (num < hsi->num_ports) ? hsi->port[num] : NULL; -} - -/* - * API for HSI clients - */ -int hsi_async(struct hsi_client *cl, struct hsi_msg *msg); - -/** - * hsi_id - Get HSI controller ID associated to a client - * @cl: Pointer to a HSI client - * - * Return the controller id where the client is attached to - */ -static inline unsigned int hsi_id(struct hsi_client *cl) -{ - return to_hsi_controller(cl->device.parent->parent)->id; -} - -/** - * hsi_port_id - Gets the port number a client is attached to - * @cl: Pointer to HSI client - * - * Return the port number associated to the client - */ -static inline unsigned int hsi_port_id(struct hsi_client *cl) -{ - return to_hsi_port(cl->device.parent)->num; -} - -/** - * hsi_setup - Configure the client's port - * @cl: Pointer to the HSI client - * - * When sharing ports, clients should either relay on a single - * client setup or have the same setup for all of them. - * - * Return -errno on failure, 0 on success - */ -static inline int hsi_setup(struct hsi_client *cl) -{ - if (!hsi_port_claimed(cl)) - return -EACCES; - return hsi_get_port(cl)->setup(cl); -} - -/** - * hsi_flush - Flush all pending transactions on the client's port - * @cl: Pointer to the HSI client - * - * This function will destroy all pending hsi_msg in the port and reset - * the HW port so it is ready to receive and transmit from a clean state. - * - * Return -errno on failure, 0 on success - */ -static inline int hsi_flush(struct hsi_client *cl) -{ - if (!hsi_port_claimed(cl)) - return -EACCES; - return hsi_get_port(cl)->flush(cl); -} - -/** - * hsi_async_read - Submit a read transfer - * @cl: Pointer to the HSI client - * @msg: HSI message descriptor of the transfer - * - * Return -errno on failure, 0 on success - */ -static inline int hsi_async_read(struct hsi_client *cl, struct hsi_msg *msg) -{ - msg->ttype = HSI_MSG_READ; - return hsi_async(cl, msg); -} - -/** - * hsi_async_write - Submit a write transfer - * @cl: Pointer to the HSI client - * @msg: HSI message descriptor of the transfer - * - * Return -errno on failure, 0 on success - */ -static inline int hsi_async_write(struct hsi_client *cl, struct hsi_msg *msg) -{ - msg->ttype = HSI_MSG_WRITE; - return hsi_async(cl, msg); -} - -/** - * hsi_start_tx - Signal the port that the client wants to start a TX - * @cl: Pointer to the HSI client - * - * Return -errno on failure, 0 on success - */ -static inline int hsi_start_tx(struct hsi_client *cl) -{ - if (!hsi_port_claimed(cl)) - return -EACCES; - return hsi_get_port(cl)->start_tx(cl); -} - -/** - * hsi_stop_tx - Signal the port that the client no longer wants to transmit - * @cl: Pointer to the HSI client - * - * Return -errno on failure, 0 on success - */ -static inline int hsi_stop_tx(struct hsi_client *cl) -{ - if (!hsi_port_claimed(cl)) - return -EACCES; - return hsi_get_port(cl)->stop_tx(cl); -} -#endif /* __LINUX_HSI_H__ */ diff --git a/trunk/include/linux/hsi/hsi_char.h b/trunk/include/linux/hsi/hsi_char.h deleted file mode 100644 index 76160b4f455d..000000000000 --- a/trunk/include/linux/hsi/hsi_char.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Part of the HSI character device driver. - * - * Copyright (C) 2010 Nokia Corporation. All rights reserved. - * - * Contact: Andras Domokos - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ - - -#ifndef __HSI_CHAR_H -#define __HSI_CHAR_H - -#define HSI_CHAR_MAGIC 'k' -#define HSC_IOW(num, dtype) _IOW(HSI_CHAR_MAGIC, num, dtype) -#define HSC_IOR(num, dtype) _IOR(HSI_CHAR_MAGIC, num, dtype) -#define HSC_IOWR(num, dtype) _IOWR(HSI_CHAR_MAGIC, num, dtype) -#define HSC_IO(num) _IO(HSI_CHAR_MAGIC, num) - -#define HSC_RESET HSC_IO(16) -#define HSC_SET_PM HSC_IO(17) -#define HSC_SEND_BREAK HSC_IO(18) -#define HSC_SET_RX HSC_IOW(19, struct hsc_rx_config) -#define HSC_GET_RX HSC_IOW(20, struct hsc_rx_config) -#define HSC_SET_TX HSC_IOW(21, struct hsc_tx_config) -#define HSC_GET_TX HSC_IOW(22, struct hsc_tx_config) - -#define HSC_PM_DISABLE 0 -#define HSC_PM_ENABLE 1 - -#define HSC_MODE_STREAM 1 -#define HSC_MODE_FRAME 2 -#define HSC_FLOW_SYNC 0 -#define HSC_ARB_RR 0 -#define HSC_ARB_PRIO 1 - -struct hsc_rx_config { - uint32_t mode; - uint32_t flow; - uint32_t channels; -}; - -struct hsc_tx_config { - uint32_t mode; - uint32_t channels; - uint32_t speed; - uint32_t arb_mode; -}; - -#endif /* __HSI_CHAR_H */ diff --git a/trunk/include/linux/i2c/twl.h b/trunk/include/linux/i2c/twl.h index 1f90de0cfdbe..2463b6100333 100644 --- a/trunk/include/linux/i2c/twl.h +++ b/trunk/include/linux/i2c/twl.h @@ -666,11 +666,23 @@ struct twl4030_codec_data { unsigned int check_defaults:1; unsigned int reset_registers:1; unsigned int hs_extmute:1; + u16 hs_left_step; + u16 hs_right_step; + u16 hf_left_step; + u16 hf_right_step; void (*set_hs_extmute)(int mute); }; struct twl4030_vibra_data { unsigned int coexist; + + /* twl6040 */ + unsigned int vibldrv_res; /* left driver resistance */ + unsigned int vibrdrv_res; /* right driver resistance */ + unsigned int viblmotor_res; /* left motor resistance */ + unsigned int vibrmotor_res; /* right motor resistance */ + int vddvibl_uV; /* VDDVIBL volt, set 0 for fixed reg */ + int vddvibr_uV; /* VDDVIBR volt, set 0 for fixed reg */ }; struct twl4030_audio_data { diff --git a/trunk/include/linux/if_eql.h b/trunk/include/linux/if_eql.h index 18a5d02a8644..79c4f268410d 100644 --- a/trunk/include/linux/if_eql.h +++ b/trunk/include/linux/if_eql.h @@ -22,7 +22,7 @@ #define EQL_DEFAULT_SLAVE_PRIORITY 28800 #define EQL_DEFAULT_MAX_SLAVES 4 #define EQL_DEFAULT_MTU 576 -#define EQL_DEFAULT_RESCHED_IVAL HZ +#define EQL_DEFAULT_RESCHED_IVAL 100 #define EQL_ENSLAVE (SIOCDEVPRIVATE) #define EQL_EMANCIPATE (SIOCDEVPRIVATE + 1) diff --git a/trunk/include/linux/irq.h b/trunk/include/linux/irq.h index b27cfcfd3a59..bff29c58da23 100644 --- a/trunk/include/linux/irq.h +++ b/trunk/include/linux/irq.h @@ -49,12 +49,6 @@ typedef void (*irq_preflow_handler_t)(struct irq_data *data); * IRQ_TYPE_LEVEL_LOW - low level triggered * IRQ_TYPE_LEVEL_MASK - Mask to filter out the level bits * IRQ_TYPE_SENSE_MASK - Mask for all the above bits - * IRQ_TYPE_DEFAULT - For use by some PICs to ask irq_set_type - * to setup the HW to a sane default (used - * by irqdomain map() callbacks to synchronize - * the HW state and SW flags for a newly - * allocated descriptor). - * * IRQ_TYPE_PROBE - Special flag for probing in progress * * Bits which can be modified via irq_set/clear/modify_status_flags() @@ -83,7 +77,6 @@ enum { IRQ_TYPE_LEVEL_LOW = 0x00000008, IRQ_TYPE_LEVEL_MASK = (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH), IRQ_TYPE_SENSE_MASK = 0x0000000f, - IRQ_TYPE_DEFAULT = IRQ_TYPE_SENSE_MASK, IRQ_TYPE_PROBE = 0x00000010, @@ -270,11 +263,6 @@ static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) d->state_use_accessors &= ~IRQD_IRQ_INPROGRESS; } -static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d) -{ - return d->hwirq; -} - /** * struct irq_chip - hardware interrupt chip descriptor * diff --git a/trunk/include/linux/irqdomain.h b/trunk/include/linux/irqdomain.h index c65740d76e66..ead4a4215797 100644 --- a/trunk/include/linux/irqdomain.h +++ b/trunk/include/linux/irqdomain.h @@ -42,6 +42,12 @@ struct of_device_id; /* Number of irqs reserved for a legacy isa controller */ #define NUM_ISA_INTERRUPTS 16 +/* This type is the placeholder for a hardware interrupt number. It has to + * be big enough to enclose whatever representation is used by a given + * platform. + */ +typedef unsigned long irq_hw_number_t; + /** * struct irq_domain_ops - Methods for irq_domain objects * @match: Match an interrupt controller device node to a host, returns @@ -98,9 +104,6 @@ struct irq_domain { unsigned int size; unsigned int *revmap; } linear; - struct { - unsigned int max_irq; - } nomap; struct radix_tree_root tree; } revmap_data; const struct irq_domain_ops *ops; @@ -123,7 +126,6 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node, const struct irq_domain_ops *ops, void *host_data); struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, - unsigned int max_irq, const struct irq_domain_ops *ops, void *host_data); struct irq_domain *irq_domain_add_tree(struct device_node *of_node, @@ -132,6 +134,7 @@ struct irq_domain *irq_domain_add_tree(struct device_node *of_node, extern struct irq_domain *irq_find_host(struct device_node *node); extern void irq_set_default_host(struct irq_domain *host); +extern void irq_set_virq_count(unsigned int count); static inline struct irq_domain *irq_domain_add_legacy_isa( struct device_node *of_node, @@ -143,6 +146,7 @@ static inline struct irq_domain *irq_domain_add_legacy_isa( } extern struct irq_domain *irq_find_host(struct device_node *node); extern void irq_set_default_host(struct irq_domain *host); +extern void irq_set_virq_count(unsigned int count); extern unsigned int irq_create_mapping(struct irq_domain *host, diff --git a/trunk/include/linux/kconfig.h b/trunk/include/linux/kconfig.h index be342b94c640..067eda0e4b32 100644 --- a/trunk/include/linux/kconfig.h +++ b/trunk/include/linux/kconfig.h @@ -4,43 +4,29 @@ #include /* - * Helper macros to use CONFIG_ options in C/CPP expressions. Note that + * Helper macros to use CONFIG_ options in C expressions. Note that * these only work with boolean and tristate options. */ -/* - * Getting something that works in C and CPP for an arg that may or may - * not be defined is tricky. Here, if we have "#define CONFIG_BOOGER 1" - * we match on the placeholder define, insert the "0," for arg1 and generate - * the triplet (0, 1, 0). Then the last step cherry picks the 2nd arg (a one). - * When CONFIG_BOOGER is not defined, we generate a (... 1, 0) pair, and when - * the last step cherry picks the 2nd arg, we get a zero. - */ -#define __ARG_PLACEHOLDER_1 0, -#define config_enabled(cfg) _config_enabled(cfg) -#define _config_enabled(value) __config_enabled(__ARG_PLACEHOLDER_##value) -#define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0) -#define ___config_enabled(__ignored, val, ...) val - /* * IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y' or 'm', * 0 otherwise. * */ #define IS_ENABLED(option) \ - (config_enabled(option) || config_enabled(option##_MODULE)) + (__enabled_ ## option || __enabled_ ## option ## _MODULE) /* * IS_BUILTIN(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y', 0 * otherwise. For boolean options, this is equivalent to * IS_ENABLED(CONFIG_FOO). */ -#define IS_BUILTIN(option) config_enabled(option) +#define IS_BUILTIN(option) __enabled_ ## option /* * IS_MODULE(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'm', 0 * otherwise. */ -#define IS_MODULE(option) config_enabled(option##_MODULE) +#define IS_MODULE(option) __enabled_ ## option ## _MODULE #endif /* __LINUX_KCONFIG_H */ diff --git a/trunk/include/linux/kernel.h b/trunk/include/linux/kernel.h index 645231c373c8..a5375e7f3fea 100644 --- a/trunk/include/linux/kernel.h +++ b/trunk/include/linux/kernel.h @@ -430,10 +430,16 @@ extern int __must_check hex2bin(u8 *dst, const char *src, size_t count); * Most likely, you want to use tracing_on/tracing_off. */ #ifdef CONFIG_RING_BUFFER +void tracing_on(void); +void tracing_off(void); /* trace_off_permanent stops recording with no way to bring it back */ void tracing_off_permanent(void); +int tracing_is_on(void); #else +static inline void tracing_on(void) { } +static inline void tracing_off(void) { } static inline void tracing_off_permanent(void) { } +static inline int tracing_is_on(void) { return 0; } #endif enum ftrace_dump_mode { @@ -443,10 +449,6 @@ enum ftrace_dump_mode { }; #ifdef CONFIG_TRACING -void tracing_on(void); -void tracing_off(void); -int tracing_is_on(void); - extern void tracing_start(void); extern void tracing_stop(void); extern void ftrace_off_permanent(void); @@ -531,11 +533,6 @@ static inline void tracing_start(void) { } static inline void tracing_stop(void) { } static inline void ftrace_off_permanent(void) { } static inline void trace_dump_stack(void) { } - -static inline void tracing_on(void) { } -static inline void tracing_off(void) { } -static inline int tracing_is_on(void) { return 0; } - static inline int trace_printk(const char *fmt, ...) { diff --git a/trunk/include/linux/kgdb.h b/trunk/include/linux/kgdb.h index c4d2fc194ede..fa391835508d 100644 --- a/trunk/include/linux/kgdb.h +++ b/trunk/include/linux/kgdb.h @@ -63,8 +63,7 @@ enum kgdb_bptype { BP_HARDWARE_BREAKPOINT, BP_WRITE_WATCHPOINT, BP_READ_WATCHPOINT, - BP_ACCESS_WATCHPOINT, - BP_POKE_BREAKPOINT, + BP_ACCESS_WATCHPOINT }; enum kgdb_bpstate { @@ -208,8 +207,8 @@ extern void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc); /* Optional functions. */ extern int kgdb_validate_break_address(unsigned long addr); -extern int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt); -extern int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt); +extern int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr); +extern int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle); /** * kgdb_arch_late - Perform any architecture specific initalization. diff --git a/trunk/include/linux/kmod.h b/trunk/include/linux/kmod.h index dd99c329e161..9efeae679106 100644 --- a/trunk/include/linux/kmod.h +++ b/trunk/include/linux/kmod.h @@ -110,29 +110,12 @@ call_usermodehelper(char *path, char **argv, char **envp, int wait) extern struct ctl_table usermodehelper_table[]; -enum umh_disable_depth { - UMH_ENABLED = 0, - UMH_FREEZING, - UMH_DISABLED, -}; - extern void usermodehelper_init(void); -extern int __usermodehelper_disable(enum umh_disable_depth depth); -extern void __usermodehelper_set_disable_depth(enum umh_disable_depth depth); - -static inline int usermodehelper_disable(void) -{ - return __usermodehelper_disable(UMH_DISABLED); -} - -static inline void usermodehelper_enable(void) -{ - __usermodehelper_set_disable_depth(UMH_ENABLED); -} - -extern int usermodehelper_read_trylock(void); -extern long usermodehelper_read_lock_wait(long timeout); -extern void usermodehelper_read_unlock(void); +extern int usermodehelper_disable(void); +extern void usermodehelper_enable(void); +extern bool usermodehelper_is_disabled(void); +extern void read_lock_usermodehelper(void); +extern void read_unlock_usermodehelper(void); #endif /* __LINUX_KMOD_H__ */ diff --git a/trunk/include/linux/kvm_host.h b/trunk/include/linux/kvm_host.h index 72cbf08d45fb..665a260c7e09 100644 --- a/trunk/include/linux/kvm_host.h +++ b/trunk/include/linux/kvm_host.h @@ -596,7 +596,6 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id); #ifdef CONFIG_IOMMU_API int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot); -void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot); int kvm_iommu_map_guest(struct kvm *kvm); int kvm_iommu_unmap_guest(struct kvm *kvm); int kvm_assign_device(struct kvm *kvm, @@ -610,11 +609,6 @@ static inline int kvm_iommu_map_pages(struct kvm *kvm, return 0; } -static inline void kvm_iommu_unmap_pages(struct kvm *kvm, - struct kvm_memory_slot *slot) -{ -} - static inline int kvm_iommu_map_guest(struct kvm *kvm) { return -ENODEV; diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index e926df7b54c9..42378d637ffb 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -996,8 +996,7 @@ extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev, extern void ata_sas_port_destroy(struct ata_port *); extern struct ata_port *ata_sas_port_alloc(struct ata_host *, struct ata_port_info *, struct Scsi_Host *); -extern void ata_sas_async_probe(struct ata_port *ap); -extern int ata_sas_sync_probe(struct ata_port *ap); +extern int ata_sas_async_port_init(struct ata_port *); extern int ata_sas_port_init(struct ata_port *); extern int ata_sas_port_start(struct ata_port *ap); extern void ata_sas_port_stop(struct ata_port *ap); diff --git a/trunk/include/linux/lp8727.h b/trunk/include/linux/lp8727.h index ea98c6133d32..d21fa2865bf4 100644 --- a/trunk/include/linux/lp8727.h +++ b/trunk/include/linux/lp8727.h @@ -1,7 +1,4 @@ /* - * LP8727 Micro/Mini USB IC with integrated charger - * - * Copyright (C) 2011 Texas Instruments * Copyright (C) 2011 National Semiconductor * * This program is free software; you can redistribute it and/or modify @@ -35,24 +32,13 @@ enum lp8727_ichg { ICHG_1000mA, }; -/** - * struct lp8727_chg_param - * @eoc_level : end of charge level setting - * @ichg : charging current - */ struct lp8727_chg_param { + /* end of charge level setting */ enum lp8727_eoc_level eoc_level; + /* charging current */ enum lp8727_ichg ichg; }; -/** - * struct lp8727_platform_data - * @get_batt_present : check battery status - exists or not - * @get_batt_level : get battery voltage (mV) - * @get_batt_capacity : get battery capacity (%) - * @get_batt_temp : get battery temperature - * @ac, @usb : charging parameters each charger type - */ struct lp8727_platform_data { u8 (*get_batt_present)(void); u16 (*get_batt_level)(void); diff --git a/trunk/include/linux/lsm_audit.h b/trunk/include/linux/lsm_audit.h index fad48aab893b..eab507f2b1cb 100644 --- a/trunk/include/linux/lsm_audit.h +++ b/trunk/include/linux/lsm_audit.h @@ -22,23 +22,6 @@ #include #include -struct lsm_network_audit { - int netif; - struct sock *sk; - u16 family; - __be16 dport; - __be16 sport; - union { - struct { - __be32 daddr; - __be32 saddr; - } v4; - struct { - struct in6_addr daddr; - struct in6_addr saddr; - } v6; - } fam; -}; /* Auxiliary data to use in generating the audit record. */ struct common_audit_data { @@ -58,7 +41,23 @@ struct common_audit_data { struct path path; struct dentry *dentry; struct inode *inode; - struct lsm_network_audit *net; + struct { + int netif; + struct sock *sk; + u16 family; + __be16 dport; + __be16 sport; + union { + struct { + __be32 daddr; + __be32 saddr; + } v4; + struct { + struct in6_addr daddr; + struct in6_addr saddr; + } v6; + } fam; + } net; int cap; int ipc_id; struct task_struct *tsk; @@ -73,15 +72,64 @@ struct common_audit_data { /* this union contains LSM specific data */ union { #ifdef CONFIG_SECURITY_SMACK - struct smack_audit_data *smack_audit_data; + /* SMACK data */ + struct smack_audit_data { + const char *function; + char *subject; + char *object; + char *request; + int result; + } smack_audit_data; #endif #ifdef CONFIG_SECURITY_SELINUX - struct selinux_audit_data *selinux_audit_data; + /* SELinux data */ + struct { + u32 ssid; + u32 tsid; + u16 tclass; + u32 requested; + u32 audited; + u32 denied; + /* + * auditdeny is a bit tricky and unintuitive. See the + * comments in avc.c for it's meaning and usage. + */ + u32 auditdeny; + struct av_decision *avd; + int result; + } selinux_audit_data; #endif #ifdef CONFIG_SECURITY_APPARMOR - struct apparmor_audit_data *apparmor_audit_data; + struct { + int error; + int op; + int type; + void *profile; + const char *name; + const char *info; + union { + void *target; + struct { + long pos; + void *target; + } iface; + struct { + int rlim; + unsigned long max; + } rlim; + struct { + const char *target; + u32 request; + u32 denied; + uid_t ouid; + } fs; + }; + } apparmor_audit_data; #endif - }; /* per LSM data pointer union */ + }; + /* these callback will be implemented by a specific LSM */ + void (*lsm_pre_audit)(struct audit_buffer *, void *); + void (*lsm_post_audit)(struct audit_buffer *, void *); }; #define v4info fam.v4 @@ -98,8 +146,6 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, { memset((_d), 0, sizeof(struct common_audit_data)); \ (_d)->type = LSM_AUDIT_DATA_##_t; } -void common_lsm_audit(struct common_audit_data *a, - void (*pre_audit)(struct audit_buffer *, void *), - void (*post_audit)(struct audit_buffer *, void *)); +void common_lsm_audit(struct common_audit_data *a); #endif diff --git a/trunk/include/linux/mfd/abx500.h b/trunk/include/linux/mfd/abx500.h index ee96cd51d8b2..5fa697477b71 100644 --- a/trunk/include/linux/mfd/abx500.h +++ b/trunk/include/linux/mfd/abx500.h @@ -146,279 +146,6 @@ struct abx500_init_settings { u8 setting; }; -/* Battery driver related data */ -/* - * ADC for the battery thermistor. - * When using the ABx500_ADC_THERM_BATCTRL the battery ID resistor is combined - * with a NTC resistor to both identify the battery and to measure its - * temperature. Different phone manufactures uses different techniques to both - * identify the battery and to read its temperature. - */ -enum abx500_adc_therm { - ABx500_ADC_THERM_BATCTRL, - ABx500_ADC_THERM_BATTEMP, -}; - -/** - * struct abx500_res_to_temp - defines one point in a temp to res curve. To - * be used in battery packs that combines the identification resistor with a - * NTC resistor. - * @temp: battery pack temperature in Celcius - * @resist: NTC resistor net total resistance - */ -struct abx500_res_to_temp { - int temp; - int resist; -}; - -/** - * struct abx500_v_to_cap - Table for translating voltage to capacity - * @voltage: Voltage in mV - * @capacity: Capacity in percent - */ -struct abx500_v_to_cap { - int voltage; - int capacity; -}; - -/* Forward declaration */ -struct abx500_fg; - -/** - * struct abx500_fg_parameters - Fuel gauge algorithm parameters, in seconds - * if not specified - * @recovery_sleep_timer: Time between measurements while recovering - * @recovery_total_time: Total recovery time - * @init_timer: Measurement interval during startup - * @init_discard_time: Time we discard voltage measurement at startup - * @init_total_time: Total init time during startup - * @high_curr_time: Time current has to be high to go to recovery - * @accu_charging: FG accumulation time while charging - * @accu_high_curr: FG accumulation time in high current mode - * @high_curr_threshold: High current threshold, in mA - * @lowbat_threshold: Low battery threshold, in mV - * @overbat_threshold: Over battery threshold, in mV - * @battok_falling_th_sel0 Threshold in mV for battOk signal sel0 - * Resolution in 50 mV step. - * @battok_raising_th_sel1 Threshold in mV for battOk signal sel1 - * Resolution in 50 mV step. - * @user_cap_limit Capacity reported from user must be within this - * limit to be considered as sane, in percentage - * points. - * @maint_thres This is the threshold where we stop reporting - * battery full while in maintenance, in per cent - */ -struct abx500_fg_parameters { - int recovery_sleep_timer; - int recovery_total_time; - int init_timer; - int init_discard_time; - int init_total_time; - int high_curr_time; - int accu_charging; - int accu_high_curr; - int high_curr_threshold; - int lowbat_threshold; - int overbat_threshold; - int battok_falling_th_sel0; - int battok_raising_th_sel1; - int user_cap_limit; - int maint_thres; -}; - -/** - * struct abx500_charger_maximization - struct used by the board config. - * @use_maxi: Enable maximization for this battery type - * @maxi_chg_curr: Maximum charger current allowed - * @maxi_wait_cycles: cycles to wait before setting charger current - * @charger_curr_step delta between two charger current settings (mA) - */ -struct abx500_maxim_parameters { - bool ena_maxi; - int chg_curr; - int wait_cycles; - int charger_curr_step; -}; - -/** - * struct abx500_battery_type - different batteries supported - * @name: battery technology - * @resis_high: battery upper resistance limit - * @resis_low: battery lower resistance limit - * @charge_full_design: Maximum battery capacity in mAh - * @nominal_voltage: Nominal voltage of the battery in mV - * @termination_vol: max voltage upto which battery can be charged - * @termination_curr battery charging termination current in mA - * @recharge_vol battery voltage limit that will trigger a new - * full charging cycle in the case where maintenan- - * -ce charging has been disabled - * @normal_cur_lvl: charger current in normal state in mA - * @normal_vol_lvl: charger voltage in normal state in mV - * @maint_a_cur_lvl: charger current in maintenance A state in mA - * @maint_a_vol_lvl: charger voltage in maintenance A state in mV - * @maint_a_chg_timer_h: charge time in maintenance A state - * @maint_b_cur_lvl: charger current in maintenance B state in mA - * @maint_b_vol_lvl: charger voltage in maintenance B state in mV - * @maint_b_chg_timer_h: charge time in maintenance B state - * @low_high_cur_lvl: charger current in temp low/high state in mA - * @low_high_vol_lvl: charger voltage in temp low/high state in mV' - * @battery_resistance: battery inner resistance in mOhm. - * @n_r_t_tbl_elements: number of elements in r_to_t_tbl - * @r_to_t_tbl: table containing resistance to temp points - * @n_v_cap_tbl_elements: number of elements in v_to_cap_tbl - * @v_to_cap_tbl: Voltage to capacity (in %) table - * @n_batres_tbl_elements number of elements in the batres_tbl - * @batres_tbl battery internal resistance vs temperature table - */ -struct abx500_battery_type { - int name; - int resis_high; - int resis_low; - int charge_full_design; - int nominal_voltage; - int termination_vol; - int termination_curr; - int recharge_vol; - int normal_cur_lvl; - int normal_vol_lvl; - int maint_a_cur_lvl; - int maint_a_vol_lvl; - int maint_a_chg_timer_h; - int maint_b_cur_lvl; - int maint_b_vol_lvl; - int maint_b_chg_timer_h; - int low_high_cur_lvl; - int low_high_vol_lvl; - int battery_resistance; - int n_temp_tbl_elements; - struct abx500_res_to_temp *r_to_t_tbl; - int n_v_cap_tbl_elements; - struct abx500_v_to_cap *v_to_cap_tbl; - int n_batres_tbl_elements; - struct batres_vs_temp *batres_tbl; -}; - -/** - * struct abx500_bm_capacity_levels - abx500 capacity level data - * @critical: critical capacity level in percent - * @low: low capacity level in percent - * @normal: normal capacity level in percent - * @high: high capacity level in percent - * @full: full capacity level in percent - */ -struct abx500_bm_capacity_levels { - int critical; - int low; - int normal; - int high; - int full; -}; - -/** - * struct abx500_bm_charger_parameters - Charger specific parameters - * @usb_volt_max: maximum allowed USB charger voltage in mV - * @usb_curr_max: maximum allowed USB charger current in mA - * @ac_volt_max: maximum allowed AC charger voltage in mV - * @ac_curr_max: maximum allowed AC charger current in mA - */ -struct abx500_bm_charger_parameters { - int usb_volt_max; - int usb_curr_max; - int ac_volt_max; - int ac_curr_max; -}; - -/** - * struct abx500_bm_data - abx500 battery management data - * @temp_under under this temp, charging is stopped - * @temp_low between this temp and temp_under charging is reduced - * @temp_high between this temp and temp_over charging is reduced - * @temp_over over this temp, charging is stopped - * @temp_now present battery temperature - * @temp_interval_chg temperature measurement interval in s when charging - * @temp_interval_nochg temperature measurement interval in s when not charging - * @main_safety_tmr_h safety timer for main charger - * @usb_safety_tmr_h safety timer for usb charger - * @bkup_bat_v voltage which we charge the backup battery with - * @bkup_bat_i current which we charge the backup battery with - * @no_maintenance indicates that maintenance charging is disabled - * @abx500_adc_therm placement of thermistor, batctrl or battemp adc - * @chg_unknown_bat flag to enable charging of unknown batteries - * @enable_overshoot flag to enable VBAT overshoot control - * @auto_trig flag to enable auto adc trigger - * @fg_res resistance of FG resistor in 0.1mOhm - * @n_btypes number of elements in array bat_type - * @batt_id index of the identified battery in array bat_type - * @interval_charging charge alg cycle period time when charging (sec) - * @interval_not_charging charge alg cycle period time when not charging (sec) - * @temp_hysteresis temperature hysteresis - * @gnd_lift_resistance Battery ground to phone ground resistance (mOhm) - * @maxi: maximization parameters - * @cap_levels capacity in percent for the different capacity levels - * @bat_type table of supported battery types - * @chg_params charger parameters - * @fg_params fuel gauge parameters - */ -struct abx500_bm_data { - int temp_under; - int temp_low; - int temp_high; - int temp_over; - int temp_now; - int temp_interval_chg; - int temp_interval_nochg; - int main_safety_tmr_h; - int usb_safety_tmr_h; - int bkup_bat_v; - int bkup_bat_i; - bool no_maintenance; - bool chg_unknown_bat; - bool enable_overshoot; - bool auto_trig; - enum abx500_adc_therm adc_therm; - int fg_res; - int n_btypes; - int batt_id; - int interval_charging; - int interval_not_charging; - int temp_hysteresis; - int gnd_lift_resistance; - const struct abx500_maxim_parameters *maxi; - const struct abx500_bm_capacity_levels *cap_levels; - const struct abx500_battery_type *bat_type; - const struct abx500_bm_charger_parameters *chg_params; - const struct abx500_fg_parameters *fg_params; -}; - -struct abx500_chargalg_platform_data { - char **supplied_to; - size_t num_supplicants; -}; - -struct abx500_charger_platform_data { - char **supplied_to; - size_t num_supplicants; - bool autopower_cfg; -}; - -struct abx500_btemp_platform_data { - char **supplied_to; - size_t num_supplicants; -}; - -struct abx500_fg_platform_data { - char **supplied_to; - size_t num_supplicants; -}; - -struct abx500_bm_plat_data { - struct abx500_bm_data *battery; - struct abx500_charger_platform_data *charger; - struct abx500_btemp_platform_data *btemp; - struct abx500_fg_platform_data *fg; - struct abx500_chargalg_platform_data *chargalg; -}; - int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg, u8 value); int abx500_get_register_interruptible(struct device *dev, u8 bank, u8 reg, diff --git a/trunk/include/linux/mfd/abx500/ab8500-bm.h b/trunk/include/linux/mfd/abx500/ab8500-bm.h deleted file mode 100644 index 44310c98ee6e..000000000000 --- a/trunk/include/linux/mfd/abx500/ab8500-bm.h +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Copyright ST-Ericsson 2012. - * - * Author: Arun Murthy - * Licensed under GPLv2. - */ - -#ifndef _AB8500_BM_H -#define _AB8500_BM_H - -#include -#include - -/* - * System control 2 register offsets. - * bank = 0x02 - */ -#define AB8500_MAIN_WDOG_CTRL_REG 0x01 -#define AB8500_LOW_BAT_REG 0x03 -#define AB8500_BATT_OK_REG 0x04 -/* - * USB/ULPI register offsets - * Bank : 0x5 - */ -#define AB8500_USB_LINE_STAT_REG 0x80 - -/* - * Charger / status register offfsets - * Bank : 0x0B - */ -#define AB8500_CH_STATUS1_REG 0x00 -#define AB8500_CH_STATUS2_REG 0x01 -#define AB8500_CH_USBCH_STAT1_REG 0x02 -#define AB8500_CH_USBCH_STAT2_REG 0x03 -#define AB8500_CH_FSM_STAT_REG 0x04 -#define AB8500_CH_STAT_REG 0x05 - -/* - * Charger / control register offfsets - * Bank : 0x0B - */ -#define AB8500_CH_VOLT_LVL_REG 0x40 -#define AB8500_CH_VOLT_LVL_MAX_REG 0x41 /*Only in Cut2.0*/ -#define AB8500_CH_OPT_CRNTLVL_REG 0x42 -#define AB8500_CH_OPT_CRNTLVL_MAX_REG 0x43 /*Only in Cut2.0*/ -#define AB8500_CH_WD_TIMER_REG 0x50 -#define AB8500_CHARG_WD_CTRL 0x51 -#define AB8500_BTEMP_HIGH_TH 0x52 -#define AB8500_LED_INDICATOR_PWM_CTRL 0x53 -#define AB8500_LED_INDICATOR_PWM_DUTY 0x54 -#define AB8500_BATT_OVV 0x55 -#define AB8500_CHARGER_CTRL 0x56 -#define AB8500_BAT_CTRL_CURRENT_SOURCE 0x60 /*Only in Cut2.0*/ - -/* - * Charger / main control register offsets - * Bank : 0x0B - */ -#define AB8500_MCH_CTRL1 0x80 -#define AB8500_MCH_CTRL2 0x81 -#define AB8500_MCH_IPT_CURLVL_REG 0x82 -#define AB8500_CH_WD_REG 0x83 - -/* - * Charger / USB control register offsets - * Bank : 0x0B - */ -#define AB8500_USBCH_CTRL1_REG 0xC0 -#define AB8500_USBCH_CTRL2_REG 0xC1 -#define AB8500_USBCH_IPT_CRNTLVL_REG 0xC2 - -/* - * Gas Gauge register offsets - * Bank : 0x0C - */ -#define AB8500_GASG_CC_CTRL_REG 0x00 -#define AB8500_GASG_CC_ACCU1_REG 0x01 -#define AB8500_GASG_CC_ACCU2_REG 0x02 -#define AB8500_GASG_CC_ACCU3_REG 0x03 -#define AB8500_GASG_CC_ACCU4_REG 0x04 -#define AB8500_GASG_CC_SMPL_CNTRL_REG 0x05 -#define AB8500_GASG_CC_SMPL_CNTRH_REG 0x06 -#define AB8500_GASG_CC_SMPL_CNVL_REG 0x07 -#define AB8500_GASG_CC_SMPL_CNVH_REG 0x08 -#define AB8500_GASG_CC_CNTR_AVGOFF_REG 0x09 -#define AB8500_GASG_CC_OFFSET_REG 0x0A -#define AB8500_GASG_CC_NCOV_ACCU 0x10 -#define AB8500_GASG_CC_NCOV_ACCU_CTRL 0x11 -#define AB8500_GASG_CC_NCOV_ACCU_LOW 0x12 -#define AB8500_GASG_CC_NCOV_ACCU_MED 0x13 -#define AB8500_GASG_CC_NCOV_ACCU_HIGH 0x14 - -/* - * Interrupt register offsets - * Bank : 0x0E - */ -#define AB8500_IT_SOURCE2_REG 0x01 -#define AB8500_IT_SOURCE21_REG 0x14 - -/* - * RTC register offsets - * Bank: 0x0F - */ -#define AB8500_RTC_BACKUP_CHG_REG 0x0C -#define AB8500_RTC_CC_CONF_REG 0x01 -#define AB8500_RTC_CTRL_REG 0x0B - -/* - * OTP register offsets - * Bank : 0x15 - */ -#define AB8500_OTP_CONF_15 0x0E - -/* GPADC constants from AB8500 spec, UM0836 */ -#define ADC_RESOLUTION 1024 -#define ADC_CH_MAIN_MIN 0 -#define ADC_CH_MAIN_MAX 20030 -#define ADC_CH_VBUS_MIN 0 -#define ADC_CH_VBUS_MAX 20030 -#define ADC_CH_VBAT_MIN 2300 -#define ADC_CH_VBAT_MAX 4800 -#define ADC_CH_BKBAT_MIN 0 -#define ADC_CH_BKBAT_MAX 3200 - -/* Main charge i/p current */ -#define MAIN_CH_IP_CUR_0P9A 0x80 -#define MAIN_CH_IP_CUR_1P0A 0x90 -#define MAIN_CH_IP_CUR_1P1A 0xA0 -#define MAIN_CH_IP_CUR_1P2A 0xB0 -#define MAIN_CH_IP_CUR_1P3A 0xC0 -#define MAIN_CH_IP_CUR_1P4A 0xD0 -#define MAIN_CH_IP_CUR_1P5A 0xE0 - -/* ChVoltLevel */ -#define CH_VOL_LVL_3P5 0x00 -#define CH_VOL_LVL_4P0 0x14 -#define CH_VOL_LVL_4P05 0x16 -#define CH_VOL_LVL_4P1 0x1B -#define CH_VOL_LVL_4P15 0x20 -#define CH_VOL_LVL_4P2 0x25 -#define CH_VOL_LVL_4P6 0x4D - -/* ChOutputCurrentLevel */ -#define CH_OP_CUR_LVL_0P1 0x00 -#define CH_OP_CUR_LVL_0P2 0x01 -#define CH_OP_CUR_LVL_0P3 0x02 -#define CH_OP_CUR_LVL_0P4 0x03 -#define CH_OP_CUR_LVL_0P5 0x04 -#define CH_OP_CUR_LVL_0P6 0x05 -#define CH_OP_CUR_LVL_0P7 0x06 -#define CH_OP_CUR_LVL_0P8 0x07 -#define CH_OP_CUR_LVL_0P9 0x08 -#define CH_OP_CUR_LVL_1P4 0x0D -#define CH_OP_CUR_LVL_1P5 0x0E -#define CH_OP_CUR_LVL_1P6 0x0F - -/* BTEMP High thermal limits */ -#define BTEMP_HIGH_TH_57_0 0x00 -#define BTEMP_HIGH_TH_52 0x01 -#define BTEMP_HIGH_TH_57_1 0x02 -#define BTEMP_HIGH_TH_62 0x03 - -/* current is mA */ -#define USB_0P1A 100 -#define USB_0P2A 200 -#define USB_0P3A 300 -#define USB_0P4A 400 -#define USB_0P5A 500 - -#define LOW_BAT_3P1V 0x20 -#define LOW_BAT_2P3V 0x00 -#define LOW_BAT_RESET 0x01 -#define LOW_BAT_ENABLE 0x01 - -/* Backup battery constants */ -#define BUP_ICH_SEL_50UA 0x00 -#define BUP_ICH_SEL_150UA 0x04 -#define BUP_ICH_SEL_300UA 0x08 -#define BUP_ICH_SEL_700UA 0x0C - -#define BUP_VCH_SEL_2P5V 0x00 -#define BUP_VCH_SEL_2P6V 0x01 -#define BUP_VCH_SEL_2P8V 0x02 -#define BUP_VCH_SEL_3P1V 0x03 - -/* Battery OVV constants */ -#define BATT_OVV_ENA 0x02 -#define BATT_OVV_TH_3P7 0x00 -#define BATT_OVV_TH_4P75 0x01 - -/* A value to indicate over voltage */ -#define BATT_OVV_VALUE 4750 - -/* VBUS OVV constants */ -#define VBUS_OVV_SELECT_MASK 0x78 -#define VBUS_OVV_SELECT_5P6V 0x00 -#define VBUS_OVV_SELECT_5P7V 0x08 -#define VBUS_OVV_SELECT_5P8V 0x10 -#define VBUS_OVV_SELECT_5P9V 0x18 -#define VBUS_OVV_SELECT_6P0V 0x20 -#define VBUS_OVV_SELECT_6P1V 0x28 -#define VBUS_OVV_SELECT_6P2V 0x30 -#define VBUS_OVV_SELECT_6P3V 0x38 - -#define VBUS_AUTO_IN_CURR_LIM_ENA 0x04 - -/* Fuel Gauge constants */ -#define RESET_ACCU 0x02 -#define READ_REQ 0x01 -#define CC_DEEP_SLEEP_ENA 0x02 -#define CC_PWR_UP_ENA 0x01 -#define CC_SAMPLES_40 0x28 -#define RD_NCONV_ACCU_REQ 0x01 -#define CC_CALIB 0x08 -#define CC_INTAVGOFFSET_ENA 0x10 -#define CC_MUXOFFSET 0x80 -#define CC_INT_CAL_N_AVG_MASK 0x60 -#define CC_INT_CAL_SAMPLES_16 0x40 -#define CC_INT_CAL_SAMPLES_8 0x20 -#define CC_INT_CAL_SAMPLES_4 0x00 - -/* RTC constants */ -#define RTC_BUP_CH_ENA 0x10 - -/* BatCtrl Current Source Constants */ -#define BAT_CTRL_7U_ENA 0x01 -#define BAT_CTRL_20U_ENA 0x02 -#define BAT_CTRL_CMP_ENA 0x04 -#define FORCE_BAT_CTRL_CMP_HIGH 0x08 -#define BAT_CTRL_PULL_UP_ENA 0x10 - -/* Battery type */ -#define BATTERY_UNKNOWN 00 - -/** - * struct res_to_temp - defines one point in a temp to res curve. To - * be used in battery packs that combines the identification resistor with a - * NTC resistor. - * @temp: battery pack temperature in Celcius - * @resist: NTC resistor net total resistance - */ -struct res_to_temp { - int temp; - int resist; -}; - -/** - * struct batres_vs_temp - defines one point in a temp vs battery internal - * resistance curve. - * @temp: battery pack temperature in Celcius - * @resist: battery internal reistance in mOhm - */ -struct batres_vs_temp { - int temp; - int resist; -}; - -/* Forward declaration */ -struct ab8500_fg; - -/** - * struct ab8500_fg_parameters - Fuel gauge algorithm parameters, in seconds - * if not specified - * @recovery_sleep_timer: Time between measurements while recovering - * @recovery_total_time: Total recovery time - * @init_timer: Measurement interval during startup - * @init_discard_time: Time we discard voltage measurement at startup - * @init_total_time: Total init time during startup - * @high_curr_time: Time current has to be high to go to recovery - * @accu_charging: FG accumulation time while charging - * @accu_high_curr: FG accumulation time in high current mode - * @high_curr_threshold: High current threshold, in mA - * @lowbat_threshold: Low battery threshold, in mV - * @battok_falling_th_sel0 Threshold in mV for battOk signal sel0 - * Resolution in 50 mV step. - * @battok_raising_th_sel1 Threshold in mV for battOk signal sel1 - * Resolution in 50 mV step. - * @user_cap_limit Capacity reported from user must be within this - * limit to be considered as sane, in percentage - * points. - * @maint_thres This is the threshold where we stop reporting - * battery full while in maintenance, in per cent - */ -struct ab8500_fg_parameters { - int recovery_sleep_timer; - int recovery_total_time; - int init_timer; - int init_discard_time; - int init_total_time; - int high_curr_time; - int accu_charging; - int accu_high_curr; - int high_curr_threshold; - int lowbat_threshold; - int battok_falling_th_sel0; - int battok_raising_th_sel1; - int user_cap_limit; - int maint_thres; -}; - -/** - * struct ab8500_charger_maximization - struct used by the board config. - * @use_maxi: Enable maximization for this battery type - * @maxi_chg_curr: Maximum charger current allowed - * @maxi_wait_cycles: cycles to wait before setting charger current - * @charger_curr_step delta between two charger current settings (mA) - */ -struct ab8500_maxim_parameters { - bool ena_maxi; - int chg_curr; - int wait_cycles; - int charger_curr_step; -}; - -/** - * struct ab8500_bm_capacity_levels - ab8500 capacity level data - * @critical: critical capacity level in percent - * @low: low capacity level in percent - * @normal: normal capacity level in percent - * @high: high capacity level in percent - * @full: full capacity level in percent - */ -struct ab8500_bm_capacity_levels { - int critical; - int low; - int normal; - int high; - int full; -}; - -/** - * struct ab8500_bm_charger_parameters - Charger specific parameters - * @usb_volt_max: maximum allowed USB charger voltage in mV - * @usb_curr_max: maximum allowed USB charger current in mA - * @ac_volt_max: maximum allowed AC charger voltage in mV - * @ac_curr_max: maximum allowed AC charger current in mA - */ -struct ab8500_bm_charger_parameters { - int usb_volt_max; - int usb_curr_max; - int ac_volt_max; - int ac_curr_max; -}; - -/** - * struct ab8500_bm_data - ab8500 battery management data - * @temp_under under this temp, charging is stopped - * @temp_low between this temp and temp_under charging is reduced - * @temp_high between this temp and temp_over charging is reduced - * @temp_over over this temp, charging is stopped - * @temp_interval_chg temperature measurement interval in s when charging - * @temp_interval_nochg temperature measurement interval in s when not charging - * @main_safety_tmr_h safety timer for main charger - * @usb_safety_tmr_h safety timer for usb charger - * @bkup_bat_v voltage which we charge the backup battery with - * @bkup_bat_i current which we charge the backup battery with - * @no_maintenance indicates that maintenance charging is disabled - * @adc_therm placement of thermistor, batctrl or battemp adc - * @chg_unknown_bat flag to enable charging of unknown batteries - * @enable_overshoot flag to enable VBAT overshoot control - * @fg_res resistance of FG resistor in 0.1mOhm - * @n_btypes number of elements in array bat_type - * @batt_id index of the identified battery in array bat_type - * @interval_charging charge alg cycle period time when charging (sec) - * @interval_not_charging charge alg cycle period time when not charging (sec) - * @temp_hysteresis temperature hysteresis - * @gnd_lift_resistance Battery ground to phone ground resistance (mOhm) - * @maxi: maximization parameters - * @cap_levels capacity in percent for the different capacity levels - * @bat_type table of supported battery types - * @chg_params charger parameters - * @fg_params fuel gauge parameters - */ -struct ab8500_bm_data { - int temp_under; - int temp_low; - int temp_high; - int temp_over; - int temp_interval_chg; - int temp_interval_nochg; - int main_safety_tmr_h; - int usb_safety_tmr_h; - int bkup_bat_v; - int bkup_bat_i; - bool no_maintenance; - bool chg_unknown_bat; - bool enable_overshoot; - enum abx500_adc_therm adc_therm; - int fg_res; - int n_btypes; - int batt_id; - int interval_charging; - int interval_not_charging; - int temp_hysteresis; - int gnd_lift_resistance; - const struct ab8500_maxim_parameters *maxi; - const struct ab8500_bm_capacity_levels *cap_levels; - const struct ab8500_bm_charger_parameters *chg_params; - const struct ab8500_fg_parameters *fg_params; -}; - -struct ab8500_charger_platform_data { - char **supplied_to; - size_t num_supplicants; - bool autopower_cfg; -}; - -struct ab8500_btemp_platform_data { - char **supplied_to; - size_t num_supplicants; -}; - -struct ab8500_fg_platform_data { - char **supplied_to; - size_t num_supplicants; -}; - -struct ab8500_chargalg_platform_data { - char **supplied_to; - size_t num_supplicants; -}; -struct ab8500_btemp; -struct ab8500_gpadc; -struct ab8500_fg; -#ifdef CONFIG_AB8500_BM -void ab8500_fg_reinit(void); -void ab8500_charger_usb_state_changed(u8 bm_usb_state, u16 mA); -struct ab8500_btemp *ab8500_btemp_get(void); -int ab8500_btemp_get_batctrl_temp(struct ab8500_btemp *btemp); -struct ab8500_fg *ab8500_fg_get(void); -int ab8500_fg_inst_curr_blocking(struct ab8500_fg *dev); -int ab8500_fg_inst_curr_start(struct ab8500_fg *di); -int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res); -int ab8500_fg_inst_curr_done(struct ab8500_fg *di); - -#else -int ab8500_fg_inst_curr_done(struct ab8500_fg *di) -{ -} -static void ab8500_fg_reinit(void) -{ -} -static void ab8500_charger_usb_state_changed(u8 bm_usb_state, u16 mA) -{ -} -static struct ab8500_btemp *ab8500_btemp_get(void) -{ - return NULL; -} -static int ab8500_btemp_get_batctrl_temp(struct ab8500_btemp *btemp) -{ - return 0; -} -struct ab8500_fg *ab8500_fg_get(void) -{ - return NULL; -} -static int ab8500_fg_inst_curr_blocking(struct ab8500_fg *dev) -{ - return -ENODEV; -} - -static inline int ab8500_fg_inst_curr_start(struct ab8500_fg *di) -{ - return -ENODEV; -} - -static inline int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res) -{ - return -ENODEV; -} - -#endif -#endif /* _AB8500_BM_H */ diff --git a/trunk/include/linux/mfd/abx500/ux500_chargalg.h b/trunk/include/linux/mfd/abx500/ux500_chargalg.h deleted file mode 100644 index 9b07725750c9..000000000000 --- a/trunk/include/linux/mfd/abx500/ux500_chargalg.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2012 - * Author: Johan Gardsmark for ST-Ericsson. - * License terms: GNU General Public License (GPL), version 2 - */ - -#ifndef _UX500_CHARGALG_H -#define _UX500_CHARGALG_H - -#include - -#define psy_to_ux500_charger(x) container_of((x), \ - struct ux500_charger, psy) - -/* Forward declaration */ -struct ux500_charger; - -struct ux500_charger_ops { - int (*enable) (struct ux500_charger *, int, int, int); - int (*kick_wd) (struct ux500_charger *); - int (*update_curr) (struct ux500_charger *, int); -}; - -/** - * struct ux500_charger - power supply ux500 charger sub class - * @psy power supply base class - * @ops ux500 charger operations - * @max_out_volt maximum output charger voltage in mV - * @max_out_curr maximum output charger current in mA - */ -struct ux500_charger { - struct power_supply psy; - struct ux500_charger_ops ops; - int max_out_volt; - int max_out_curr; -}; - -#endif diff --git a/trunk/include/linux/mfd/db5500-prcmu.h b/trunk/include/linux/mfd/db5500-prcmu.h index 5a049dfaf153..9890687f582d 100644 --- a/trunk/include/linux/mfd/db5500-prcmu.h +++ b/trunk/include/linux/mfd/db5500-prcmu.h @@ -8,14 +8,41 @@ #ifndef __MFD_DB5500_PRCMU_H #define __MFD_DB5500_PRCMU_H -static inline int prcmu_resetout(u8 resoutn, u8 state) +#ifdef CONFIG_MFD_DB5500_PRCMU + +void db5500_prcmu_early_init(void); +int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state); +int db5500_prcmu_set_display_clocks(void); +int db5500_prcmu_disable_dsipll(void); +int db5500_prcmu_enable_dsipll(void); +int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); +int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); +void db5500_prcmu_enable_wakeups(u32 wakeups); +int db5500_prcmu_request_clock(u8 clock, bool enable); +void db5500_prcmu_config_abb_event_readout(u32 abb_events); +void db5500_prcmu_get_abb_event_buffer(void __iomem **buf); +int prcmu_resetout(u8 resoutn, u8 state); +int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, + bool keep_ap_pll); +int db5500_prcmu_config_esram0_deep_sleep(u8 state); +void db5500_prcmu_system_reset(u16 reset_code); +u16 db5500_prcmu_get_reset_code(void); +bool db5500_prcmu_is_ac_wake_requested(void); +int db5500_prcmu_set_arm_opp(u8 opp); +int db5500_prcmu_get_arm_opp(void); + +#else /* !CONFIG_UX500_SOC_DB5500 */ + +static inline void db5500_prcmu_early_init(void) {} + +static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) { - return 0; + return -ENOSYS; } -static inline int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state) +static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) { - return 0; + return -ENOSYS; } static inline int db5500_prcmu_request_clock(u8 clock, bool enable) @@ -23,83 +50,70 @@ static inline int db5500_prcmu_request_clock(u8 clock, bool enable) return 0; } -static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, - bool keep_ap_pll) +static inline int db5500_prcmu_set_display_clocks(void) { return 0; } -static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state) +static inline int db5500_prcmu_disable_dsipll(void) { return 0; } -static inline u16 db5500_prcmu_get_reset_code(void) +static inline int db5500_prcmu_enable_dsipll(void) { return 0; } -static inline bool db5500_prcmu_is_ac_wake_requested(void) +static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state) { return 0; } -static inline int db5500_prcmu_set_arm_opp(u8 opp) +static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {} + +static inline int prcmu_resetout(u8 resoutn, u8 state) { return 0; } -static inline int db5500_prcmu_get_arm_opp(void) +static inline int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state) { return 0; } -static inline void db5500_prcmu_config_abb_event_readout(u32 abb_events) {} - static inline void db5500_prcmu_get_abb_event_buffer(void __iomem **buf) {} +static inline void db5500_prcmu_config_abb_event_readout(u32 abb_events) {} -static inline void db5500_prcmu_system_reset(u16 reset_code) {} - -static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {} - -#ifdef CONFIG_MFD_DB5500_PRCMU - -void db5500_prcmu_early_init(void); -int db5500_prcmu_set_display_clocks(void); -int db5500_prcmu_disable_dsipll(void); -int db5500_prcmu_enable_dsipll(void); -int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); -int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); - -#else /* !CONFIG_UX500_SOC_DB5500 */ - -static inline void db5500_prcmu_early_init(void) {} - -static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) +static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, + bool keep_ap_pll) { - return -ENOSYS; + return 0; } -static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) +static inline void db5500_prcmu_system_reset(u16 reset_code) {} + +static inline u16 db5500_prcmu_get_reset_code(void) { - return -ENOSYS; + return 0; } -static inline int db5500_prcmu_set_display_clocks(void) +static inline bool db5500_prcmu_is_ac_wake_requested(void) { return 0; } -static inline int db5500_prcmu_disable_dsipll(void) +static inline int db5500_prcmu_set_arm_opp(u8 opp) { return 0; } -static inline int db5500_prcmu_enable_dsipll(void) +static inline int db5500_prcmu_get_arm_opp(void) { return 0; } + #endif /* CONFIG_MFD_DB5500_PRCMU */ #endif /* __MFD_DB5500_PRCMU_H */ diff --git a/trunk/include/linux/mfd/rc5t583.h b/trunk/include/linux/mfd/rc5t583.h index 0b64b19d81ab..a2c61609d21d 100644 --- a/trunk/include/linux/mfd/rc5t583.h +++ b/trunk/include/linux/mfd/rc5t583.h @@ -26,7 +26,6 @@ #include #include -#include #define RC5T583_MAX_REGS 0xF8 @@ -280,44 +279,14 @@ struct rc5t583_platform_data { bool enable_shutdown; }; -static inline int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - return regmap_write(rc5t583->regmap, reg, val); -} - -static inline int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - unsigned int ival; - int ret; - ret = regmap_read(rc5t583->regmap, reg, &ival); - if (!ret) - *val = (uint8_t)ival; - return ret; -} - -static inline int rc5t583_set_bits(struct device *dev, unsigned int reg, - unsigned int bit_mask) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask); -} - -static inline int rc5t583_clear_bits(struct device *dev, unsigned int reg, - unsigned int bit_mask) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0); -} - -static inline int rc5t583_update(struct device *dev, unsigned int reg, - unsigned int val, unsigned int mask) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - return regmap_update_bits(rc5t583->regmap, reg, mask, val); -} - +int rc5t583_write(struct device *dev, u8 reg, uint8_t val); +int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val); +int rc5t583_set_bits(struct device *dev, unsigned int reg, + unsigned int bit_mask); +int rc5t583_clear_bits(struct device *dev, unsigned int reg, + unsigned int bit_mask); +int rc5t583_update(struct device *dev, unsigned int reg, + unsigned int val, unsigned int mask); int rc5t583_ext_power_req_config(struct device *dev, int deepsleep_id, int ext_pwr_req, int deepsleep_slot_nr); int rc5t583_irq_init(struct rc5t583 *rc5t583, int irq, int irq_base); diff --git a/trunk/include/linux/mfd/twl6040.h b/trunk/include/linux/mfd/twl6040.h index b15b5f03f5c4..9bc9ac651dad 100644 --- a/trunk/include/linux/mfd/twl6040.h +++ b/trunk/include/linux/mfd/twl6040.h @@ -174,35 +174,8 @@ #define TWL6040_SYSCLK_SEL_LPPLL 0 #define TWL6040_SYSCLK_SEL_HPPLL 1 -struct twl6040_codec_data { - u16 hs_left_step; - u16 hs_right_step; - u16 hf_left_step; - u16 hf_right_step; -}; - -struct twl6040_vibra_data { - unsigned int vibldrv_res; /* left driver resistance */ - unsigned int vibrdrv_res; /* right driver resistance */ - unsigned int viblmotor_res; /* left motor resistance */ - unsigned int vibrmotor_res; /* right motor resistance */ - int vddvibl_uV; /* VDDVIBL volt, set 0 for fixed reg */ - int vddvibr_uV; /* VDDVIBR volt, set 0 for fixed reg */ -}; - -struct twl6040_platform_data { - int audpwron_gpio; /* audio power-on gpio */ - unsigned int irq_base; - - struct twl6040_codec_data *codec; - struct twl6040_vibra_data *vibra; -}; - -struct regmap; - struct twl6040 { struct device *dev; - struct regmap *regmap; struct mutex mutex; struct mutex io_mutex; struct mutex irq_mutex; diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index 74aa71bea1e4..d8738a464b94 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -1393,20 +1393,29 @@ extern int install_special_mapping(struct mm_struct *mm, extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); +extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, + unsigned long len, unsigned long prot, + unsigned long flag, unsigned long pgoff); extern unsigned long mmap_region(struct file *file, unsigned long addr, unsigned long len, unsigned long flags, vm_flags_t vm_flags, unsigned long pgoff); -extern unsigned long do_mmap(struct file *, unsigned long, - unsigned long, unsigned long, - unsigned long, unsigned long); + +static inline unsigned long do_mmap(struct file *file, unsigned long addr, + unsigned long len, unsigned long prot, + unsigned long flag, unsigned long offset) +{ + unsigned long ret = -EINVAL; + if ((offset + PAGE_ALIGN(len)) < offset) + goto out; + if (!(offset & ~PAGE_MASK)) + ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); +out: + return ret; +} + extern int do_munmap(struct mm_struct *, unsigned long, size_t); -/* These take the mm semaphore themselves */ -extern unsigned long vm_brk(unsigned long, unsigned long); -extern int vm_munmap(unsigned long, size_t); -extern unsigned long vm_mmap(struct file *, unsigned long, - unsigned long, unsigned long, - unsigned long, unsigned long); +extern unsigned long do_brk(unsigned long, unsigned long); /* truncate.c */ extern void truncate_inode_pages(struct address_space *, loff_t); diff --git a/trunk/include/linux/mmc/card.h b/trunk/include/linux/mmc/card.h index 629b823f8836..01beae78f079 100644 --- a/trunk/include/linux/mmc/card.h +++ b/trunk/include/linux/mmc/card.h @@ -481,7 +481,7 @@ struct mmc_driver { struct device_driver drv; int (*probe)(struct mmc_card *); void (*remove)(struct mmc_card *); - int (*suspend)(struct mmc_card *); + int (*suspend)(struct mmc_card *, pm_message_t); int (*resume)(struct mmc_card *); }; diff --git a/trunk/include/linux/mtd/bbm.h b/trunk/include/linux/mtd/bbm.h index 650ef352f045..c4eec228eef9 100644 --- a/trunk/include/linux/mtd/bbm.h +++ b/trunk/include/linux/mtd/bbm.h @@ -112,11 +112,6 @@ struct nand_bbt_descr { #define NAND_BBT_USE_FLASH 0x00020000 /* Do not store flash based bad block table in OOB area; store it in-band */ #define NAND_BBT_NO_OOB 0x00040000 -/* - * Do not write new bad block markers to OOB; useful, e.g., when ECC covers - * entire spare area. Must be used with NAND_BBT_USE_FLASH. - */ -#define NAND_BBT_NO_OOB_BBM 0x00080000 /* * Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr diff --git a/trunk/include/linux/mtd/blktrans.h b/trunk/include/linux/mtd/blktrans.h index ed270bd2e4df..1bbd9f289245 100644 --- a/trunk/include/linux/mtd/blktrans.h +++ b/trunk/include/linux/mtd/blktrans.h @@ -47,7 +47,6 @@ struct mtd_blktrans_dev { struct request_queue *rq; spinlock_t queue_lock; void *priv; - fmode_t file_mode; }; struct mtd_blktrans_ops { diff --git a/trunk/include/linux/mtd/fsmc.h b/trunk/include/linux/mtd/fsmc.h index b20029221fb1..6987995ad3cf 100644 --- a/trunk/include/linux/mtd/fsmc.h +++ b/trunk/include/linux/mtd/fsmc.h @@ -26,83 +26,95 @@ #define FSMC_NAND_BW8 1 #define FSMC_NAND_BW16 2 +/* + * The placement of the Command Latch Enable (CLE) and + * Address Latch Enable (ALE) is twisted around in the + * SPEAR310 implementation. + */ +#if defined(CONFIG_MACH_SPEAR310) +#define PLAT_NAND_CLE (1 << 17) +#define PLAT_NAND_ALE (1 << 16) +#else +#define PLAT_NAND_CLE (1 << 16) +#define PLAT_NAND_ALE (1 << 17) +#endif + #define FSMC_MAX_NOR_BANKS 4 #define FSMC_MAX_NAND_BANKS 4 #define FSMC_FLASH_WIDTH8 1 #define FSMC_FLASH_WIDTH16 2 -/* fsmc controller registers for NOR flash */ -#define CTRL 0x0 - /* ctrl register definitions */ - #define BANK_ENABLE (1 << 0) - #define MUXED (1 << 1) - #define NOR_DEV (2 << 2) - #define WIDTH_8 (0 << 4) - #define WIDTH_16 (1 << 4) - #define RSTPWRDWN (1 << 6) - #define WPROT (1 << 7) - #define WRT_ENABLE (1 << 12) - #define WAIT_ENB (1 << 13) - -#define CTRL_TIM 0x4 - /* ctrl_tim register definitions */ - -#define FSMC_NOR_BANK_SZ 0x8 +struct fsmc_nor_bank_regs { + uint32_t ctrl; + uint32_t ctrl_tim; +}; + +/* ctrl register definitions */ +#define BANK_ENABLE (1 << 0) +#define MUXED (1 << 1) +#define NOR_DEV (2 << 2) +#define WIDTH_8 (0 << 4) +#define WIDTH_16 (1 << 4) +#define RSTPWRDWN (1 << 6) +#define WPROT (1 << 7) +#define WRT_ENABLE (1 << 12) +#define WAIT_ENB (1 << 13) + +/* ctrl_tim register definitions */ + +struct fsmc_nand_bank_regs { + uint32_t pc; + uint32_t sts; + uint32_t comm; + uint32_t attrib; + uint32_t ioata; + uint32_t ecc1; + uint32_t ecc2; + uint32_t ecc3; +}; + #define FSMC_NOR_REG_SIZE 0x40 -#define FSMC_NOR_REG(base, bank, reg) (base + \ - FSMC_NOR_BANK_SZ * (bank) + \ - reg) - -/* fsmc controller registers for NAND flash */ -#define PC 0x00 - /* pc register definitions */ - #define FSMC_RESET (1 << 0) - #define FSMC_WAITON (1 << 1) - #define FSMC_ENABLE (1 << 2) - #define FSMC_DEVTYPE_NAND (1 << 3) - #define FSMC_DEVWID_8 (0 << 4) - #define FSMC_DEVWID_16 (1 << 4) - #define FSMC_ECCEN (1 << 6) - #define FSMC_ECCPLEN_512 (0 << 7) - #define FSMC_ECCPLEN_256 (1 << 7) - #define FSMC_TCLR_1 (1) - #define FSMC_TCLR_SHIFT (9) - #define FSMC_TCLR_MASK (0xF) - #define FSMC_TAR_1 (1) - #define FSMC_TAR_SHIFT (13) - #define FSMC_TAR_MASK (0xF) -#define STS 0x04 - /* sts register definitions */ - #define FSMC_CODE_RDY (1 << 15) -#define COMM 0x08 - /* comm register definitions */ - #define FSMC_TSET_0 0 - #define FSMC_TSET_SHIFT 0 - #define FSMC_TSET_MASK 0xFF - #define FSMC_TWAIT_6 6 - #define FSMC_TWAIT_SHIFT 8 - #define FSMC_TWAIT_MASK 0xFF - #define FSMC_THOLD_4 4 - #define FSMC_THOLD_SHIFT 16 - #define FSMC_THOLD_MASK 0xFF - #define FSMC_THIZ_1 1 - #define FSMC_THIZ_SHIFT 24 - #define FSMC_THIZ_MASK 0xFF -#define ATTRIB 0x0C -#define IOATA 0x10 -#define ECC1 0x14 -#define ECC2 0x18 -#define ECC3 0x1C -#define FSMC_NAND_BANK_SZ 0x20 - -#define FSMC_NAND_REG(base, bank, reg) (base + FSMC_NOR_REG_SIZE + \ - (FSMC_NAND_BANK_SZ * (bank)) + \ - reg) +struct fsmc_regs { + struct fsmc_nor_bank_regs nor_bank_regs[FSMC_MAX_NOR_BANKS]; + uint8_t reserved_1[0x40 - 0x20]; + struct fsmc_nand_bank_regs bank_regs[FSMC_MAX_NAND_BANKS]; + uint8_t reserved_2[0xfe0 - 0xc0]; + uint32_t peripid0; /* 0xfe0 */ + uint32_t peripid1; /* 0xfe4 */ + uint32_t peripid2; /* 0xfe8 */ + uint32_t peripid3; /* 0xfec */ + uint32_t pcellid0; /* 0xff0 */ + uint32_t pcellid1; /* 0xff4 */ + uint32_t pcellid2; /* 0xff8 */ + uint32_t pcellid3; /* 0xffc */ +}; #define FSMC_BUSY_WAIT_TIMEOUT (1 * HZ) +/* pc register definitions */ +#define FSMC_RESET (1 << 0) +#define FSMC_WAITON (1 << 1) +#define FSMC_ENABLE (1 << 2) +#define FSMC_DEVTYPE_NAND (1 << 3) +#define FSMC_DEVWID_8 (0 << 4) +#define FSMC_DEVWID_16 (1 << 4) +#define FSMC_ECCEN (1 << 6) +#define FSMC_ECCPLEN_512 (0 << 7) +#define FSMC_ECCPLEN_256 (1 << 7) +#define FSMC_TCLR_1 (1 << 9) +#define FSMC_TAR_1 (1 << 13) + +/* sts register definitions */ +#define FSMC_CODE_RDY (1 << 15) + +/* comm register definitions */ +#define FSMC_TSET_0 (0 << 0) +#define FSMC_TWAIT_6 (6 << 8) +#define FSMC_THOLD_4 (4 << 16) +#define FSMC_THIZ_1 (1 << 24) + /* * There are 13 bytes of ecc for every 512 byte block in FSMC version 8 * and it has to be read consecutively and immediately after the 512 @@ -121,20 +133,6 @@ struct fsmc_eccplace { struct fsmc_nand_eccplace eccplace[MAX_ECCPLACE_ENTRIES]; }; -struct fsmc_nand_timings { - uint8_t tclr; - uint8_t tar; - uint8_t thiz; - uint8_t thold; - uint8_t twait; - uint8_t tset; -}; - -enum access_mode { - USE_DMA_ACCESS = 1, - USE_WORD_ACCESS, -}; - /** * fsmc_nand_platform_data - platform specific NAND controller config * @partitions: partition table for the platform, use a default fallback @@ -148,23 +146,12 @@ enum access_mode { * this may be set to NULL */ struct fsmc_nand_platform_data { - struct fsmc_nand_timings *nand_timings; struct mtd_partition *partitions; unsigned int nr_partitions; unsigned int options; unsigned int width; unsigned int bank; - - /* CLE, ALE offsets */ - unsigned int cle_off; - unsigned int ale_off; - enum access_mode mode; - void (*select_bank)(uint32_t bank, uint32_t busw); - - /* priv structures for dma accesses */ - void *read_dma_priv; - void *write_dma_priv; }; extern int __init fsmc_nor_init(struct platform_device *pdev, diff --git a/trunk/include/linux/mtd/mtd.h b/trunk/include/linux/mtd/mtd.h index cf5ea8cdcf8e..d43dc25af82e 100644 --- a/trunk/include/linux/mtd/mtd.h +++ b/trunk/include/linux/mtd/mtd.h @@ -164,9 +164,6 @@ struct mtd_info { /* ECC layout structure pointer - read only! */ struct nand_ecclayout *ecclayout; - /* max number of correctible bit errors per writesize */ - unsigned int ecc_strength; - /* Data for variable erase regions. If numeraseregions is zero, * it means that the whole device has erasesize as given above. */ @@ -177,52 +174,52 @@ struct mtd_info { * Do not call via these pointers, use corresponding mtd_*() * wrappers instead. */ - int (*_erase) (struct mtd_info *mtd, struct erase_info *instr); - int (*_point) (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, void **virt, resource_size_t *phys); - int (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len); - unsigned long (*_get_unmapped_area) (struct mtd_info *mtd, - unsigned long len, - unsigned long offset, - unsigned long flags); - int (*_read) (struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf); - int (*_write) (struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf); - int (*_panic_write) (struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf); - int (*_read_oob) (struct mtd_info *mtd, loff_t from, + int (*erase) (struct mtd_info *mtd, struct erase_info *instr); + int (*point) (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, void **virt, resource_size_t *phys); + void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len); + unsigned long (*get_unmapped_area) (struct mtd_info *mtd, + unsigned long len, + unsigned long offset, + unsigned long flags); + int (*read) (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf); + int (*write) (struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf); + int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf); + int (*read_oob) (struct mtd_info *mtd, loff_t from, + struct mtd_oob_ops *ops); + int (*write_oob) (struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops); - int (*_write_oob) (struct mtd_info *mtd, loff_t to, - struct mtd_oob_ops *ops); - int (*_get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, - size_t len); - int (*_read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, - size_t len, size_t *retlen, u_char *buf); - int (*_get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, - size_t len); - int (*_read_user_prot_reg) (struct mtd_info *mtd, loff_t from, - size_t len, size_t *retlen, u_char *buf); - int (*_write_user_prot_reg) (struct mtd_info *mtd, loff_t to, - size_t len, size_t *retlen, u_char *buf); - int (*_lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, - size_t len); - int (*_writev) (struct mtd_info *mtd, const struct kvec *vecs, + int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, + size_t len); + int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, + size_t len, size_t *retlen, u_char *buf); + int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, + size_t len); + int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, + size_t len, size_t *retlen, u_char *buf); + int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, u_char *buf); + int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, + size_t len); + int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); - void (*_sync) (struct mtd_info *mtd); - int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); - int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); - int (*_is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len); - int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs); - int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs); - int (*_suspend) (struct mtd_info *mtd); - void (*_resume) (struct mtd_info *mtd); + void (*sync) (struct mtd_info *mtd); + int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); + int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); + int (*is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len); + int (*block_isbad) (struct mtd_info *mtd, loff_t ofs); + int (*block_markbad) (struct mtd_info *mtd, loff_t ofs); + int (*suspend) (struct mtd_info *mtd); + void (*resume) (struct mtd_info *mtd); /* * If the driver is something smart, like UBI, it may need to maintain * its own reference counting. The below functions are only for driver. */ - int (*_get_device) (struct mtd_info *mtd); - void (*_put_device) (struct mtd_info *mtd); + int (*get_device) (struct mtd_info *mtd); + void (*put_device) (struct mtd_info *mtd); /* Backing device capabilities for this device * - provides mmap capabilities @@ -243,75 +240,214 @@ struct mtd_info { int usecount; }; -int mtd_erase(struct mtd_info *mtd, struct erase_info *instr); -int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, - void **virt, resource_size_t *phys); -int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len); -unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, unsigned long len, - unsigned long offset, unsigned long flags); -int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, - u_char *buf); -int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, - const u_char *buf); -int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, - const u_char *buf); +/* + * Erase is an asynchronous operation. Device drivers are supposed + * to call instr->callback() whenever the operation completes, even + * if it completes with a failure. + * Callers are supposed to pass a callback function and wait for it + * to be called before writing to the block. + */ +static inline int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) +{ + return mtd->erase(mtd, instr); +} + +/* + * This stuff for eXecute-In-Place. phys is optional and may be set to NULL. + */ +static inline int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, void **virt, resource_size_t *phys) +{ + *retlen = 0; + if (!mtd->point) + return -EOPNOTSUPP; + return mtd->point(mtd, from, len, retlen, virt, phys); +} + +/* We probably shouldn't allow XIP if the unpoint isn't a NULL */ +static inline void mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len) +{ + return mtd->unpoint(mtd, from, len); +} + +/* + * Allow NOMMU mmap() to directly map the device (if not NULL) + * - return the address to which the offset maps + * - return -ENOSYS to indicate refusal to do the mapping + */ +static inline unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, + unsigned long len, + unsigned long offset, + unsigned long flags) +{ + if (!mtd->get_unmapped_area) + return -EOPNOTSUPP; + return mtd->get_unmapped_area(mtd, len, offset, flags); +} + +static inline int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) +{ + return mtd->read(mtd, from, len, retlen, buf); +} + +static inline int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) +{ + *retlen = 0; + if (!mtd->write) + return -EROFS; + return mtd->write(mtd, to, len, retlen, buf); +} + +/* + * In blackbox flight recorder like scenarios we want to make successful writes + * in interrupt context. panic_write() is only intended to be called when its + * known the kernel is about to panic and we need the write to succeed. Since + * the kernel is not going to be running for much longer, this function can + * break locks and delay to ensure the write succeeds (but not sleep). + */ +static inline int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) +{ + *retlen = 0; + if (!mtd->panic_write) + return -EOPNOTSUPP; + return mtd->panic_write(mtd, to, len, retlen, buf); +} static inline int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) { ops->retlen = ops->oobretlen = 0; - if (!mtd->_read_oob) + if (!mtd->read_oob) return -EOPNOTSUPP; - return mtd->_read_oob(mtd, from, ops); + return mtd->read_oob(mtd, from, ops); } static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) { ops->retlen = ops->oobretlen = 0; - if (!mtd->_write_oob) + if (!mtd->write_oob) return -EOPNOTSUPP; - if (!(mtd->flags & MTD_WRITEABLE)) - return -EROFS; - return mtd->_write_oob(mtd, to, ops); + return mtd->write_oob(mtd, to, ops); } -int mtd_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf, - size_t len); -int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf); -int mtd_get_user_prot_info(struct mtd_info *mtd, struct otp_info *buf, - size_t len); -int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf); -int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, u_char *buf); -int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len); +/* + * Method to access the protection register area, present in some flash + * devices. The user data is one time programmable but the factory data is read + * only. + */ +static inline int mtd_get_fact_prot_info(struct mtd_info *mtd, + struct otp_info *buf, size_t len) +{ + if (!mtd->get_fact_prot_info) + return -EOPNOTSUPP; + return mtd->get_fact_prot_info(mtd, buf, len); +} + +static inline int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, + size_t len, size_t *retlen, + u_char *buf) +{ + *retlen = 0; + if (!mtd->read_fact_prot_reg) + return -EOPNOTSUPP; + return mtd->read_fact_prot_reg(mtd, from, len, retlen, buf); +} + +static inline int mtd_get_user_prot_info(struct mtd_info *mtd, + struct otp_info *buf, + size_t len) +{ + if (!mtd->get_user_prot_info) + return -EOPNOTSUPP; + return mtd->get_user_prot_info(mtd, buf, len); +} + +static inline int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, + size_t len, size_t *retlen, + u_char *buf) +{ + *retlen = 0; + if (!mtd->read_user_prot_reg) + return -EOPNOTSUPP; + return mtd->read_user_prot_reg(mtd, from, len, retlen, buf); +} + +static inline int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, + size_t len, size_t *retlen, + u_char *buf) +{ + *retlen = 0; + if (!mtd->write_user_prot_reg) + return -EOPNOTSUPP; + return mtd->write_user_prot_reg(mtd, to, len, retlen, buf); +} + +static inline int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, + size_t len) +{ + if (!mtd->lock_user_prot_reg) + return -EOPNOTSUPP; + return mtd->lock_user_prot_reg(mtd, from, len); +} int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); static inline void mtd_sync(struct mtd_info *mtd) { - if (mtd->_sync) - mtd->_sync(mtd); + if (mtd->sync) + mtd->sync(mtd); +} + +/* Chip-supported device locking */ +static inline int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) +{ + if (!mtd->lock) + return -EOPNOTSUPP; + return mtd->lock(mtd, ofs, len); } -int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len); -int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); -int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len); -int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs); -int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs); +static inline int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) +{ + if (!mtd->unlock) + return -EOPNOTSUPP; + return mtd->unlock(mtd, ofs, len); +} + +static inline int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) +{ + if (!mtd->is_locked) + return -EOPNOTSUPP; + return mtd->is_locked(mtd, ofs, len); +} static inline int mtd_suspend(struct mtd_info *mtd) { - return mtd->_suspend ? mtd->_suspend(mtd) : 0; + return mtd->suspend ? mtd->suspend(mtd) : 0; } static inline void mtd_resume(struct mtd_info *mtd) { - if (mtd->_resume) - mtd->_resume(mtd); + if (mtd->resume) + mtd->resume(mtd); +} + +static inline int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) +{ + if (!mtd->block_isbad) + return 0; + return mtd->block_isbad(mtd, ofs); +} + +static inline int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs) +{ + if (!mtd->block_markbad) + return -EOPNOTSUPP; + return mtd->block_markbad(mtd, ofs); } static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd) @@ -346,12 +482,12 @@ static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd) static inline int mtd_has_oob(const struct mtd_info *mtd) { - return mtd->_read_oob && mtd->_write_oob; + return mtd->read_oob && mtd->write_oob; } static inline int mtd_can_have_bb(const struct mtd_info *mtd) { - return !!mtd->_block_isbad; + return !!mtd->block_isbad; } /* Kernel-side ioctl definitions */ diff --git a/trunk/include/linux/mtd/nand.h b/trunk/include/linux/mtd/nand.h index 1482340d3d9f..63b5a8b6dfbd 100644 --- a/trunk/include/linux/mtd/nand.h +++ b/trunk/include/linux/mtd/nand.h @@ -324,7 +324,6 @@ struct nand_hw_control { * @steps: number of ECC steps per page * @size: data bytes per ECC step * @bytes: ECC bytes per step - * @strength: max number of correctible bits per ECC step * @total: total number of ECC bytes per page * @prepad: padding information for syndrome based ECC generators * @postpad: padding information for syndrome based ECC generators @@ -352,7 +351,6 @@ struct nand_ecc_ctrl { int size; int bytes; int total; - int strength; int prepad; int postpad; struct nand_ecclayout *layout; @@ -450,9 +448,8 @@ struct nand_buffers { * will be copied to the appropriate nand_bbt_descr's. * @badblockpos: [INTERN] position of the bad block marker in the oob * area. - * @badblockbits: [INTERN] minimum number of set bits in a good block's - * bad block marker position; i.e., BBM == 11110111b is - * not bad when badblockbits == 7 + * @badblockbits: [INTERN] number of bits to left-shift the bad block + * number * @cellinfo: [INTERN] MLC/multichip data from chip ident * @numchips: [INTERN] number of physical chips * @chipsize: [INTERN] the size of one chip for multichip arrays diff --git a/trunk/include/linux/mtd/pmc551.h b/trunk/include/linux/mtd/pmc551.h new file mode 100644 index 000000000000..27ad40aed19f --- /dev/null +++ b/trunk/include/linux/mtd/pmc551.h @@ -0,0 +1,78 @@ +/* + * PMC551 PCI Mezzanine Ram Device + * + * Author: + * Mark Ferrell + * Copyright 1999,2000 Nortel Networks + * + * License: + * As part of this driver was derrived from the slram.c driver it falls + * under the same license, which is GNU General Public License v2 + */ + +#ifndef __MTD_PMC551_H__ +#define __MTD_PMC551_H__ + +#include + +#define PMC551_VERSION \ + "Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n" + +/* + * Our personal and private information + */ +struct mypriv { + struct pci_dev *dev; + u_char *start; + u32 base_map0; + u32 curr_map0; + u32 asize; + struct mtd_info *nextpmc551; +}; + +/* + * Function Prototypes + */ +static int pmc551_erase(struct mtd_info *, struct erase_info *); +static void pmc551_unpoint(struct mtd_info *, loff_t, size_t); +static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, void **virt, resource_size_t *phys); +static int pmc551_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); +static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); + + +/* + * Define the PCI ID's if the kernel doesn't define them for us + */ +#ifndef PCI_VENDOR_ID_V3_SEMI +#define PCI_VENDOR_ID_V3_SEMI 0x11b0 +#endif + +#ifndef PCI_DEVICE_ID_V3_SEMI_V370PDC +#define PCI_DEVICE_ID_V3_SEMI_V370PDC 0x0200 +#endif + + +#define PMC551_PCI_MEM_MAP0 0x50 +#define PMC551_PCI_MEM_MAP1 0x54 +#define PMC551_PCI_MEM_MAP_MAP_ADDR_MASK 0x3ff00000 +#define PMC551_PCI_MEM_MAP_APERTURE_MASK 0x000000f0 +#define PMC551_PCI_MEM_MAP_REG_EN 0x00000002 +#define PMC551_PCI_MEM_MAP_ENABLE 0x00000001 + +#define PMC551_SDRAM_MA 0x60 +#define PMC551_SDRAM_CMD 0x62 +#define PMC551_DRAM_CFG 0x64 +#define PMC551_SYS_CTRL_REG 0x78 + +#define PMC551_DRAM_BLK0 0x68 +#define PMC551_DRAM_BLK1 0x6c +#define PMC551_DRAM_BLK2 0x70 +#define PMC551_DRAM_BLK3 0x74 +#define PMC551_DRAM_BLK_GET_SIZE(x) (524288<<((x>>4)&0x0f)) +#define PMC551_DRAM_BLK_SET_COL_MUX(x,v) (((x) & ~0x00007000) | (((v) & 0x7) << 12)) +#define PMC551_DRAM_BLK_SET_ROW_MUX(x,v) (((x) & ~0x00000f00) | (((v) & 0xf) << 8)) + + +#endif /* __MTD_PMC551_H__ */ + diff --git a/trunk/include/linux/mtd/sh_flctl.h b/trunk/include/linux/mtd/sh_flctl.h index a38e1fa8af01..9cf4c4c79555 100644 --- a/trunk/include/linux/mtd/sh_flctl.h +++ b/trunk/include/linux/mtd/sh_flctl.h @@ -23,7 +23,6 @@ #include #include #include -#include /* FLCTL registers */ #define FLCMNCR(f) (f->reg + 0x0) @@ -39,7 +38,6 @@ #define FLDTFIFO(f) (f->reg + 0x24) #define FLECFIFO(f) (f->reg + 0x28) #define FLTRCR(f) (f->reg + 0x2C) -#define FLHOLDCR(f) (f->reg + 0x38) #define FL4ECCRESULT0(f) (f->reg + 0x80) #define FL4ECCRESULT1(f) (f->reg + 0x84) #define FL4ECCRESULT2(f) (f->reg + 0x88) @@ -69,30 +67,6 @@ #define CE0_ENABLE (0x1 << 3) /* Chip Enable 0 */ #define TYPESEL_SET (0x1 << 0) -/* - * Clock settings using the PULSEx registers from FLCMNCR - * - * Some hardware uses bits called PULSEx instead of FCKSEL_E and QTSEL_E - * to control the clock divider used between the High-Speed Peripheral Clock - * and the FLCTL internal clock. If so, use CLK_8_BIT_xxx for connecting 8 bit - * and CLK_16_BIT_xxx for connecting 16 bit bus bandwith NAND chips. For the 16 - * bit version the divider is seperate for the pulse width of high and low - * signals. - */ -#define PULSE3 (0x1 << 27) -#define PULSE2 (0x1 << 17) -#define PULSE1 (0x1 << 15) -#define PULSE0 (0x1 << 9) -#define CLK_8B_0_5 PULSE1 -#define CLK_8B_1 0x0 -#define CLK_8B_1_5 (PULSE1 | PULSE2) -#define CLK_8B_2 PULSE0 -#define CLK_8B_3 (PULSE0 | PULSE1 | PULSE2) -#define CLK_8B_4 (PULSE0 | PULSE2) -#define CLK_16B_6L_2H PULSE0 -#define CLK_16B_9L_3H (PULSE0 | PULSE1 | PULSE2) -#define CLK_16B_12L_4H (PULSE0 | PULSE2) - /* FLCMDCR control bits */ #define ADRCNT2_E (0x1 << 31) /* 5byte address enable */ #define ADRMD_E (0x1 << 26) /* Sector address access */ @@ -111,15 +85,6 @@ #define TRSTRT (0x1 << 0) /* translation start */ #define TREND (0x1 << 1) /* translation end */ -/* - * FLHOLDCR control bits - * - * HOLDEN: Bus Occupancy Enable (inverted) - * Enable this bit when the external bus might be used in between transfers. - * If not set and the bus gets used by other modules, a deadlock occurs. - */ -#define HOLDEN (0x1 << 0) - /* FL4ECCCR control bits */ #define _4ECCFA (0x1 << 2) /* 4 symbols correct fault */ #define _4ECCEND (0x1 << 1) /* 4 symbols end */ @@ -132,7 +97,6 @@ struct sh_flctl { struct mtd_info mtd; struct nand_chip chip; struct platform_device *pdev; - struct dev_pm_qos_request pm_qos; void __iomem *reg; uint8_t done_buff[2048 + 64]; /* max size 2048 + 64 */ @@ -144,14 +108,11 @@ struct sh_flctl { int erase1_page_addr; /* page_addr in ERASE1 cmd */ uint32_t erase_ADRCNT; /* bits of FLCMDCR in ERASE1 cmd */ uint32_t rw_ADRCNT; /* bits of FLCMDCR in READ WRITE cmd */ - uint32_t flcmncr_base; /* base value of FLCMNCR */ int hwecc_cant_correct[4]; unsigned page_size:1; /* NAND page size (0 = 512, 1 = 2048) */ unsigned hwecc:1; /* Hardware ECC (0 = disabled, 1 = enabled) */ - unsigned holden:1; /* Hardware has FLHOLDCR and HOLDEN is set */ - unsigned qos_request:1; /* QoS request to prevent deep power shutdown */ }; struct sh_flctl_platform_data { @@ -160,7 +121,6 @@ struct sh_flctl_platform_data { unsigned long flcmncr_val; unsigned has_hwecc:1; - unsigned use_holden:1; }; static inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo) diff --git a/trunk/include/linux/mtd/spear_smi.h b/trunk/include/linux/mtd/spear_smi.h deleted file mode 100644 index 8ae1726044c3..000000000000 --- a/trunk/include/linux/mtd/spear_smi.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright © 2010 ST Microelectronics - * Shiraz Hashim - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __MTD_SPEAR_SMI_H -#define __MTD_SPEAR_SMI_H - -#include -#include -#include -#include -#include - -/* max possible slots for serial-nor flash chip in the SMI controller */ -#define MAX_NUM_FLASH_CHIP 4 - -/* macro to define partitions for flash devices */ -#define DEFINE_PARTS(n, of, s) \ -{ \ - .name = n, \ - .offset = of, \ - .size = s, \ -} - -/** - * struct spear_smi_flash_info - platform structure for passing flash - * information - * - * name: name of the serial nor flash for identification - * mem_base: the memory base on which the flash is mapped - * size: size of the flash in bytes - * partitions: parition details - * nr_partitions: number of partitions - * fast_mode: whether flash supports fast mode - */ - -struct spear_smi_flash_info { - char *name; - unsigned long mem_base; - unsigned long size; - struct mtd_partition *partitions; - int nr_partitions; - u8 fast_mode; -}; - -/** - * struct spear_smi_plat_data - platform structure for configuring smi - * - * clk_rate: clk rate at which SMI must operate - * num_flashes: number of flashes present on board - * board_flash_info: specific details of each flash present on board - */ -struct spear_smi_plat_data { - unsigned long clk_rate; - int num_flashes; - struct spear_smi_flash_info *board_flash_info; - struct device_node *np[MAX_NUM_FLASH_CHIP]; -}; - -#endif /* __MTD_SPEAR_SMI_H */ diff --git a/trunk/include/linux/mtio.h b/trunk/include/linux/mtio.h index 18543e2db06f..8f825756c459 100644 --- a/trunk/include/linux/mtio.h +++ b/trunk/include/linux/mtio.h @@ -194,7 +194,6 @@ struct mtpos { #define MT_ST_SYSV 0x1000 #define MT_ST_NOWAIT 0x2000 #define MT_ST_SILI 0x4000 -#define MT_ST_NOWAIT_EOF 0x8000 /* The mode parameters to be controlled. Parameter chosen with bits 20-28 */ #define MT_ST_CLEAR_DEFAULT 0xfffff diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 5cbaa20f1659..1f77540bdc95 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -2604,6 +2604,8 @@ extern void net_disable_timestamp(void); extern void *dev_seq_start(struct seq_file *seq, loff_t *pos); extern void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos); extern void dev_seq_stop(struct seq_file *seq, void *v); +extern int dev_seq_open_ops(struct inode *inode, struct file *file, + const struct seq_operations *ops); #endif extern int netdev_class_create_file(struct class_attribute *class_attr); diff --git a/trunk/include/linux/netfilter/xt_set.h b/trunk/include/linux/netfilter/xt_set.h index e3a9978f259f..c0405ac92870 100644 --- a/trunk/include/linux/netfilter/xt_set.h +++ b/trunk/include/linux/netfilter/xt_set.h @@ -58,8 +58,8 @@ struct xt_set_info_target_v1 { struct xt_set_info_target_v2 { struct xt_set_info add_set; struct xt_set_info del_set; - __u32 flags; - __u32 timeout; + u32 flags; + u32 timeout; }; #endif /*_XT_SET_H*/ diff --git a/trunk/include/linux/netfilter_bridge.h b/trunk/include/linux/netfilter_bridge.h index 31d2844e6572..0ddd161f3b06 100644 --- a/trunk/include/linux/netfilter_bridge.h +++ b/trunk/include/linux/netfilter_bridge.h @@ -104,18 +104,9 @@ struct bridge_skb_cb { } daddr; }; -static inline void br_drop_fake_rtable(struct sk_buff *skb) -{ - struct dst_entry *dst = skb_dst(skb); - - if (dst && (dst->flags & DST_FAKE_RTABLE)) - skb_dst_drop(skb); -} - #else #define nf_bridge_maybe_copy_header(skb) (0) #define nf_bridge_pad(skb) (0) -#define br_drop_fake_rtable(skb) do { } while (0) #endif /* CONFIG_BRIDGE_NETFILTER */ #endif /* __KERNEL__ */ diff --git a/trunk/include/linux/netfilter_ipv6/ip6_tables.h b/trunk/include/linux/netfilter_ipv6/ip6_tables.h index 1bc898b14a80..f549adccc94c 100644 --- a/trunk/include/linux/netfilter_ipv6/ip6_tables.h +++ b/trunk/include/linux/netfilter_ipv6/ip6_tables.h @@ -287,17 +287,7 @@ extern unsigned int ip6t_do_table(struct sk_buff *skb, struct xt_table *table); /* Check for an extension */ -static inline int -ip6t_ext_hdr(u8 nexthdr) -{ return (nexthdr == IPPROTO_HOPOPTS) || - (nexthdr == IPPROTO_ROUTING) || - (nexthdr == IPPROTO_FRAGMENT) || - (nexthdr == IPPROTO_ESP) || - (nexthdr == IPPROTO_AH) || - (nexthdr == IPPROTO_NONE) || - (nexthdr == IPPROTO_DSTOPTS); -} - +extern int ip6t_ext_hdr(u8 nexthdr); /* find specified header and get offset to it */ extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, int target, unsigned short *fragoff); diff --git a/trunk/include/linux/nfs_xdr.h b/trunk/include/linux/nfs_xdr.h index 7ba3551a0414..bfd0d1bf6707 100644 --- a/trunk/include/linux/nfs_xdr.h +++ b/trunk/include/linux/nfs_xdr.h @@ -312,11 +312,6 @@ struct nfs4_layoutreturn { int rpc_status; }; -struct stateowner_id { - __u64 create_time; - __u32 uniquifier; -}; - /* * Arguments to the open call. */ @@ -326,7 +321,7 @@ struct nfs_openargs { int open_flags; fmode_t fmode; __u64 clientid; - struct stateowner_id id; + __u64 id; union { struct { struct iattr * attrs; /* UNCHECKED, GUARDED */ diff --git a/trunk/include/linux/nfsd/Kbuild b/trunk/include/linux/nfsd/Kbuild index 5b7d84ac954a..b8d4001212b3 100644 --- a/trunk/include/linux/nfsd/Kbuild +++ b/trunk/include/linux/nfsd/Kbuild @@ -1,4 +1,3 @@ -header-y += cld.h header-y += debug.h header-y += export.h header-y += nfsfh.h diff --git a/trunk/include/linux/perf_event.h b/trunk/include/linux/perf_event.h index ddbb6a901f65..bd9f55a5958d 100644 --- a/trunk/include/linux/perf_event.h +++ b/trunk/include/linux/perf_event.h @@ -299,31 +299,18 @@ struct perf_event_mmap_page { /* * Bits needed to read the hw events in user-space. * - * u32 seq, time_mult, time_shift, idx, width; - * u64 count, enabled, running; - * u64 cyc, time_offset; - * s64 pmc = 0; + * u32 seq; + * s64 count; * * do { * seq = pc->lock; - * barrier() - * - * enabled = pc->time_enabled; - * running = pc->time_running; - * - * if (pc->cap_usr_time && enabled != running) { - * cyc = rdtsc(); - * time_offset = pc->time_offset; - * time_mult = pc->time_mult; - * time_shift = pc->time_shift; - * } * - * idx = pc->index; - * count = pc->offset; - * if (pc->cap_usr_rdpmc && idx) { - * width = pc->pmc_width; - * pmc = rdpmc(idx - 1); - * } + * barrier() + * if (pc->index) { + * count = pmc_read(pc->index - 1); + * count += pc->offset; + * } else + * goto regular_read; * * barrier(); * } while (pc->lock != seq); @@ -336,57 +323,14 @@ struct perf_event_mmap_page { __s64 offset; /* add to hardware event value */ __u64 time_enabled; /* time event active */ __u64 time_running; /* time event on cpu */ - union { - __u64 capabilities; - __u64 cap_usr_time : 1, - cap_usr_rdpmc : 1, - cap_____res : 62; - }; - - /* - * If cap_usr_rdpmc this field provides the bit-width of the value - * read using the rdpmc() or equivalent instruction. This can be used - * to sign extend the result like: - * - * pmc <<= 64 - width; - * pmc >>= 64 - width; // signed shift right - * count += pmc; - */ - __u16 pmc_width; - - /* - * If cap_usr_time the below fields can be used to compute the time - * delta since time_enabled (in ns) using rdtsc or similar. - * - * u64 quot, rem; - * u64 delta; - * - * quot = (cyc >> time_shift); - * rem = cyc & ((1 << time_shift) - 1); - * delta = time_offset + quot * time_mult + - * ((rem * time_mult) >> time_shift); - * - * Where time_offset,time_mult,time_shift and cyc are read in the - * seqcount loop described above. This delta can then be added to - * enabled and possible running (if idx), improving the scaling: - * - * enabled += delta; - * if (idx) - * running += delta; - * - * quot = count / running; - * rem = count % running; - * count = quot * enabled + (rem * enabled) / running; - */ - __u16 time_shift; - __u32 time_mult; + __u32 time_mult, time_shift; __u64 time_offset; /* * Hole for extension of the self monitor capabilities */ - __u64 __reserved[120]; /* align to 1k */ + __u64 __reserved[121]; /* align to 1k */ /* * Control data for the mmap() data buffer. @@ -606,7 +550,6 @@ struct perf_guest_info_callbacks { #include #include #include -#include #include #define PERF_MAX_STACK_DEPTH 255 @@ -1348,18 +1291,5 @@ do { \ register_cpu_notifier(&fn##_nb); \ } while (0) - -#define PMU_FORMAT_ATTR(_name, _format) \ -static ssize_t \ -_name##_show(struct device *dev, \ - struct device_attribute *attr, \ - char *page) \ -{ \ - BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ - return sprintf(page, _format "\n"); \ -} \ - \ -static struct device_attribute format_attr_##_name = __ATTR_RO(_name) - #endif /* __KERNEL__ */ #endif /* _LINUX_PERF_EVENT_H */ diff --git a/trunk/include/linux/pinctrl/machine.h b/trunk/include/linux/pinctrl/machine.h index e4d1de742502..fee4349364f7 100644 --- a/trunk/include/linux/pinctrl/machine.h +++ b/trunk/include/linux/pinctrl/machine.h @@ -12,8 +12,6 @@ #ifndef __LINUX_PINCTRL_MACHINE_H #define __LINUX_PINCTRL_MACHINE_H -#include - #include "pinctrl-state.h" enum pinctrl_map_type { @@ -150,7 +148,7 @@ struct pinctrl_map { #define PIN_MAP_CONFIGS_GROUP_HOG_DEFAULT(dev, grp, cfgs) \ PIN_MAP_CONFIGS_GROUP(dev, PINCTRL_STATE_DEFAULT, dev, grp, cfgs) -#ifdef CONFIG_PINCTRL +#ifdef CONFIG_PINMUX extern int pinctrl_register_mappings(struct pinctrl_map const *map, unsigned num_maps); diff --git a/trunk/include/linux/pipe_fs_i.h b/trunk/include/linux/pipe_fs_i.h index e1ac1ce16fb0..6d626ff0cfd0 100644 --- a/trunk/include/linux/pipe_fs_i.h +++ b/trunk/include/linux/pipe_fs_i.h @@ -6,7 +6,6 @@ #define PIPE_BUF_FLAG_LRU 0x01 /* page is on the LRU */ #define PIPE_BUF_FLAG_ATOMIC 0x02 /* was atomically mapped */ #define PIPE_BUF_FLAG_GIFT 0x04 /* page is a gift */ -#define PIPE_BUF_FLAG_PACKET 0x08 /* read() as a packet */ /** * struct pipe_buffer - a linux kernel pipe buffer diff --git a/trunk/include/linux/platform_data/atmel.h b/trunk/include/linux/platform_data/atmel.h index b0f2c56a8ea2..d056263545b1 100644 --- a/trunk/include/linux/platform_data/atmel.h +++ b/trunk/include/linux/platform_data/atmel.h @@ -4,8 +4,8 @@ * GPL v2 Only */ -#ifndef __ATMEL_H__ -#define __ATMEL_H__ +#ifndef __ATMEL_NAND_H__ +#define __ATMEL_NAND_H__ #include @@ -24,4 +24,4 @@ struct atmel_nand_data { unsigned int num_parts; }; -#endif /* __ATMEL_H__ */ +#endif /* __ATMEL_NAND_H__ */ diff --git a/trunk/include/linux/platform_data/spear_thermal.h b/trunk/include/linux/platform_data/spear_thermal.h deleted file mode 100644 index 724f2e1cbbcb..000000000000 --- a/trunk/include/linux/platform_data/spear_thermal.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * SPEAr thermal driver platform data. - * - * Copyright (C) 2011-2012 ST Microelectronics - * Author: Vincenzo Frascino - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - * - */ -#ifndef SPEAR_THERMAL_H -#define SPEAR_THERMAL_H - -/* SPEAr Thermal Sensor Platform Data */ -struct spear_thermal_pdata { - /* flags used to enable thermal sensor */ - unsigned int thermal_flags; -}; - -#endif /* SPEAR_THERMAL_H */ diff --git a/trunk/include/linux/pm_qos.h b/trunk/include/linux/pm_qos.h index 233149cb19f4..2e9191a712f3 100644 --- a/trunk/include/linux/pm_qos.h +++ b/trunk/include/linux/pm_qos.h @@ -8,7 +8,6 @@ #include #include #include -#include enum { PM_QOS_RESERVED = 0, @@ -30,7 +29,6 @@ enum { struct pm_qos_request { struct plist_node node; int pm_qos_class; - struct delayed_work work; /* for pm_qos_update_request_timeout */ }; struct dev_pm_qos_request { @@ -75,8 +73,6 @@ void pm_qos_add_request(struct pm_qos_request *req, int pm_qos_class, s32 value); void pm_qos_update_request(struct pm_qos_request *req, s32 new_value); -void pm_qos_update_request_timeout(struct pm_qos_request *req, - s32 new_value, unsigned long timeout_us); void pm_qos_remove_request(struct pm_qos_request *req); int pm_qos_request(int pm_qos_class); diff --git a/trunk/include/linux/power/max17042_battery.h b/trunk/include/linux/power/max17042_battery.h index e01b167e66f0..fe99211fb2b8 100644 --- a/trunk/include/linux/power/max17042_battery.h +++ b/trunk/include/linux/power/max17042_battery.h @@ -27,8 +27,6 @@ #define MAX17042_BATTERY_FULL (100) #define MAX17042_DEFAULT_SNS_RESISTOR (10000) -#define MAX17042_CHARACTERIZATION_DATA_SIZE 48 - enum max17042_register { MAX17042_STATUS = 0x00, MAX17042_VALRT_Th = 0x01, @@ -42,11 +40,11 @@ enum max17042_register { MAX17042_VCELL = 0x09, MAX17042_Current = 0x0A, MAX17042_AvgCurrent = 0x0B, - + MAX17042_Qresidual = 0x0C, MAX17042_SOC = 0x0D, MAX17042_AvSOC = 0x0E, MAX17042_RemCap = 0x0F, - MAX17042_FullCAP = 0x10, + MAX17402_FullCAP = 0x10, MAX17042_TTE = 0x11, MAX17042_V_empty = 0x12, @@ -64,14 +62,14 @@ enum max17042_register { MAX17042_AvCap = 0x1F, MAX17042_ManName = 0x20, MAX17042_DevName = 0x21, + MAX17042_DevChem = 0x22, - MAX17042_FullCAPNom = 0x23, MAX17042_TempNom = 0x24, - MAX17042_TempLim = 0x25, + MAX17042_TempCold = 0x25, MAX17042_TempHot = 0x26, MAX17042_AIN = 0x27, MAX17042_LearnCFG = 0x28, - MAX17042_FilterCFG = 0x29, + MAX17042_SHFTCFG = 0x29, MAX17042_RelaxCFG = 0x2A, MAX17042_MiscCFG = 0x2B, MAX17042_TGAIN = 0x2C, @@ -79,41 +77,22 @@ enum max17042_register { MAX17042_CGAIN = 0x2E, MAX17042_COFF = 0x2F, - MAX17042_MaskSOC = 0x32, - MAX17042_SOC_empty = 0x33, + MAX17042_Q_empty = 0x33, MAX17042_T_empty = 0x34, - MAX17042_FullCAP0 = 0x35, - MAX17042_LAvg_empty = 0x36, - MAX17042_FCTC = 0x37, MAX17042_RCOMP0 = 0x38, MAX17042_TempCo = 0x39, - MAX17042_EmptyTempCo = 0x3A, - MAX17042_K_empty0 = 0x3B, + MAX17042_Rx = 0x3A, + MAX17042_T_empty0 = 0x3B, MAX17042_TaskPeriod = 0x3C, MAX17042_FSTAT = 0x3D, MAX17042_SHDNTIMER = 0x3F, - MAX17042_dQacc = 0x45, - MAX17042_dPacc = 0x46, - - MAX17042_VFSOC0 = 0x48, + MAX17042_VFRemCap = 0x4A, MAX17042_QH = 0x4D, MAX17042_QL = 0x4E, - - MAX17042_VFSOC0Enable = 0x60, - MAX17042_MLOCKReg1 = 0x62, - MAX17042_MLOCKReg2 = 0x63, - - MAX17042_MODELChrTbl = 0x80, - - MAX17042_OCV = 0xEE, - - MAX17042_OCVInternal = 0xFB, - - MAX17042_VFSOC = 0xFF, }; /* @@ -126,64 +105,10 @@ struct max17042_reg_data { u16 data; }; -struct max17042_config_data { - /* External current sense resistor value in milli-ohms */ - u32 cur_sense_val; - - /* A/D measurement */ - u16 tgain; /* 0x2C */ - u16 toff; /* 0x2D */ - u16 cgain; /* 0x2E */ - u16 coff; /* 0x2F */ - - /* Alert / Status */ - u16 valrt_thresh; /* 0x01 */ - u16 talrt_thresh; /* 0x02 */ - u16 soc_alrt_thresh; /* 0x03 */ - u16 config; /* 0x01D */ - u16 shdntimer; /* 0x03F */ - - /* App data */ - u16 design_cap; /* 0x18 */ - u16 ichgt_term; /* 0x1E */ - - /* MG3 config */ - u16 at_rate; /* 0x04 */ - u16 learn_cfg; /* 0x28 */ - u16 filter_cfg; /* 0x29 */ - u16 relax_cfg; /* 0x2A */ - u16 misc_cfg; /* 0x2B */ - u16 masksoc; /* 0x32 */ - - /* MG3 save and restore */ - u16 fullcap; /* 0x10 */ - u16 fullcapnom; /* 0x23 */ - u16 socempty; /* 0x33 */ - u16 lavg_empty; /* 0x36 */ - u16 dqacc; /* 0x45 */ - u16 dpacc; /* 0x46 */ - - /* Cell technology from power_supply.h */ - u16 cell_technology; - - /* Cell Data */ - u16 vempty; /* 0x12 */ - u16 temp_nom; /* 0x24 */ - u16 temp_lim; /* 0x25 */ - u16 fctc; /* 0x37 */ - u16 rcomp0; /* 0x38 */ - u16 tcompc0; /* 0x39 */ - u16 empty_tempco; /* 0x3A */ - u16 kempty0; /* 0x3B */ - u16 cell_char_tbl[MAX17042_CHARACTERIZATION_DATA_SIZE]; -} __packed; - struct max17042_platform_data { struct max17042_reg_data *init_data; - struct max17042_config_data *config_data; int num_init_data; /* Number of enties in init_data array */ bool enable_current_sense; - bool enable_por_init; /* Use POR init from Maxim appnote */ /* * R_sns in micro-ohms. diff --git a/trunk/include/linux/power/smb347-charger.h b/trunk/include/linux/power/smb347-charger.h deleted file mode 100644 index b3cb20dab55f..000000000000 --- a/trunk/include/linux/power/smb347-charger.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Summit Microelectronics SMB347 Battery Charger Driver - * - * Copyright (C) 2011, Intel Corporation - * - * Authors: Bruce E. Robertson - * Mika Westerberg - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef SMB347_CHARGER_H -#define SMB347_CHARGER_H - -#include -#include - -enum { - /* use the default compensation method */ - SMB347_SOFT_TEMP_COMPENSATE_DEFAULT = -1, - - SMB347_SOFT_TEMP_COMPENSATE_NONE, - SMB347_SOFT_TEMP_COMPENSATE_CURRENT, - SMB347_SOFT_TEMP_COMPENSATE_VOLTAGE, -}; - -/* Use default factory programmed value for hard/soft temperature limit */ -#define SMB347_TEMP_USE_DEFAULT -273 - -/* - * Charging enable can be controlled by software (via i2c) by - * smb347-charger driver or by EN pin (active low/high). - */ -enum smb347_chg_enable { - SMB347_CHG_ENABLE_SW, - SMB347_CHG_ENABLE_PIN_ACTIVE_LOW, - SMB347_CHG_ENABLE_PIN_ACTIVE_HIGH, -}; - -/** - * struct smb347_charger_platform_data - platform data for SMB347 charger - * @battery_info: Information about the battery - * @max_charge_current: maximum current (in uA) the battery can be charged - * @max_charge_voltage: maximum voltage (in uV) the battery can be charged - * @pre_charge_current: current (in uA) to use in pre-charging phase - * @termination_current: current (in uA) used to determine when the - * charging cycle terminates - * @pre_to_fast_voltage: voltage (in uV) treshold used for transitioning to - * pre-charge to fast charge mode - * @mains_current_limit: maximum input current drawn from AC/DC input (in uA) - * @usb_hc_current_limit: maximum input high current (in uA) drawn from USB - * input - * @chip_temp_threshold: die temperature where device starts limiting charge - * current [%100 - %130] (in degree C) - * @soft_cold_temp_limit: soft cold temperature limit [%0 - %15] (in degree C), - * granularity is 5 deg C. - * @soft_hot_temp_limit: soft hot temperature limit [%40 - %55] (in degree C), - * granularity is 5 deg C. - * @hard_cold_temp_limit: hard cold temperature limit [%-5 - %10] (in degree C), - * granularity is 5 deg C. - * @hard_hot_temp_limit: hard hot temperature limit [%50 - %65] (in degree C), - * granularity is 5 deg C. - * @suspend_on_hard_temp_limit: suspend charging when hard limit is hit - * @soft_temp_limit_compensation: compensation method when soft temperature - * limit is hit - * @charge_current_compensation: current (in uA) for charging compensation - * current when temperature hits soft limits - * @use_mains: AC/DC input can be used - * @use_usb: USB input can be used - * @use_usb_otg: USB OTG output can be used (not implemented yet) - * @irq_gpio: GPIO number used for interrupts (%-1 if not used) - * @enable_control: how charging enable/disable is controlled - * (driver/pin controls) - * - * @use_main, @use_usb, and @use_usb_otg are means to enable/disable - * hardware support for these. This is useful when we want to have for - * example OTG charging controlled via OTG transceiver driver and not by - * the SMB347 hardware. - * - * Hard and soft temperature limit values are given as described in the - * device data sheet and assuming NTC beta value is %3750. Even if this is - * not the case, these values should be used. They can be mapped to the - * corresponding NTC beta values with the help of table %2 in the data - * sheet. So for example if NTC beta is %3375 and we want to program hard - * hot limit to be %53 deg C, @hard_hot_temp_limit should be set to %50. - * - * If zero value is given in any of the current and voltage values, the - * factory programmed default will be used. For soft/hard temperature - * values, pass in %SMB347_TEMP_USE_DEFAULT instead. - */ -struct smb347_charger_platform_data { - struct power_supply_info battery_info; - unsigned int max_charge_current; - unsigned int max_charge_voltage; - unsigned int pre_charge_current; - unsigned int termination_current; - unsigned int pre_to_fast_voltage; - unsigned int mains_current_limit; - unsigned int usb_hc_current_limit; - unsigned int chip_temp_threshold; - int soft_cold_temp_limit; - int soft_hot_temp_limit; - int hard_cold_temp_limit; - int hard_hot_temp_limit; - bool suspend_on_hard_temp_limit; - unsigned int soft_temp_limit_compensation; - unsigned int charge_current_compensation; - bool use_mains; - bool use_usb; - bool use_usb_otg; - int irq_gpio; - enum smb347_chg_enable enable_control; -}; - -#endif /* SMB347_CHARGER_H */ diff --git a/trunk/include/linux/regulator/machine.h b/trunk/include/linux/regulator/machine.h index b02108446be7..7abb16093312 100644 --- a/trunk/include/linux/regulator/machine.h +++ b/trunk/include/linux/regulator/machine.h @@ -71,7 +71,7 @@ struct regulator_state { * @uV_offset: Offset applied to voltages from consumer to compensate for * voltage drops. * - * @min_uA: Smallest current consumers may set. + * @min_uA: Smallest consumers consumers may set. * @max_uA: Largest current consumers may set. * * @valid_modes_mask: Mask of modes which may be configured by consumers. @@ -134,8 +134,10 @@ struct regulation_constraints { /** * struct regulator_consumer_supply - supply -> device mapping * - * This maps a supply name to a device. Use of dev_name allows support for - * buses which make struct device available late such as I2C. + * This maps a supply name to a device. Only one of dev or dev_name + * can be specified. Use of dev_name allows support for buses which + * make struct device available late such as I2C and is the preferred + * form. * * @dev_name: Result of dev_name() for the consumer. * @supply: Name for the supply. diff --git a/trunk/include/linux/ring_buffer.h b/trunk/include/linux/ring_buffer.h index 7be2e88f23fd..67be0376d8e3 100644 --- a/trunk/include/linux/ring_buffer.h +++ b/trunk/include/linux/ring_buffer.h @@ -151,9 +151,6 @@ int ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu); void ring_buffer_record_disable(struct ring_buffer *buffer); void ring_buffer_record_enable(struct ring_buffer *buffer); -void ring_buffer_record_off(struct ring_buffer *buffer); -void ring_buffer_record_on(struct ring_buffer *buffer); -int ring_buffer_record_is_on(struct ring_buffer *buffer); void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu); void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu); diff --git a/trunk/include/linux/seqlock.h b/trunk/include/linux/seqlock.h index 600060e25ec6..c6db9fb33c44 100644 --- a/trunk/include/linux/seqlock.h +++ b/trunk/include/linux/seqlock.h @@ -141,7 +141,7 @@ static inline unsigned __read_seqcount_begin(const seqcount_t *s) unsigned ret; repeat: - ret = ACCESS_ONCE(s->sequence); + ret = s->sequence; if (unlikely(ret & 1)) { cpu_relax(); goto repeat; @@ -165,27 +165,6 @@ static inline unsigned read_seqcount_begin(const seqcount_t *s) return ret; } -/** - * raw_seqcount_begin - begin a seq-read critical section - * @s: pointer to seqcount_t - * Returns: count to be passed to read_seqcount_retry - * - * raw_seqcount_begin opens a read critical section of the given seqcount. - * Validity of the critical section is tested by checking read_seqcount_retry - * function. - * - * Unlike read_seqcount_begin(), this function will not wait for the count - * to stabilize. If a writer is active when we begin, we will fail the - * read_seqcount_retry() instead of stabilizing at the beginning of the - * critical section. - */ -static inline unsigned raw_seqcount_begin(const seqcount_t *s) -{ - unsigned ret = ACCESS_ONCE(s->sequence); - smp_rmb(); - return ret & ~1; -} - /** * __read_seqcount_retry - end a seq-read critical section (without barrier) * @s: pointer to seqcount_t diff --git a/trunk/include/linux/serial_core.h b/trunk/include/linux/serial_core.h index 2db407a40051..f51bf2e70c69 100644 --- a/trunk/include/linux/serial_core.h +++ b/trunk/include/linux/serial_core.h @@ -357,7 +357,7 @@ struct uart_port { #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) #define UPF_EXAR_EFR ((__force upf_t) (1 << 25)) -#define UPF_BUG_THRE ((__force upf_t) (1 << 26)) +#define UPF_IIR_ONCE ((__force upf_t) (1 << 26)) /* The exact UART type is known and should not be probed. */ #define UPF_FIXED_TYPE ((__force upf_t) (1 << 27)) #define UPF_BOOT_AUTOCONF ((__force upf_t) (1 << 28)) diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index 111f26b6e28b..33370271b8b2 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -238,12 +238,11 @@ enum { /* * The callback notifies userspace to release buffers when skb DMA is done in * lower device, the skb last reference should be 0 when calling this. - * The ctx field is used to track device context. - * The desc field is used to track userspace buffer index. + * The desc is used to track userspace buffer index. */ struct ubuf_info { - void (*callback)(struct ubuf_info *); - void *ctx; + void (*callback)(void *); + void *arg; unsigned long desc; }; @@ -482,7 +481,6 @@ struct sk_buff { union { __u32 mark; __u32 dropcount; - __u32 avail_size; }; sk_buff_data_t transport_header; @@ -1020,7 +1018,7 @@ static inline void skb_queue_splice(const struct sk_buff_head *list, } /** - * skb_queue_splice_init - join two skb lists and reinitialise the emptied list + * skb_queue_splice - join two skb lists and reinitialise the emptied list * @list: the new list to add * @head: the place to add it in the first list * @@ -1051,7 +1049,7 @@ static inline void skb_queue_splice_tail(const struct sk_buff_head *list, } /** - * skb_queue_splice_tail_init - join two skb lists and reinitialise the emptied list + * skb_queue_splice_tail - join two skb lists and reinitialise the emptied list * @list: the new list to add * @head: the place to add it in the first list * @@ -1367,18 +1365,6 @@ static inline int skb_tailroom(const struct sk_buff *skb) return skb_is_nonlinear(skb) ? 0 : skb->end - skb->tail; } -/** - * skb_availroom - bytes at buffer end - * @skb: buffer to check - * - * Return the number of bytes of free space at the tail of an sk_buff - * allocated by sk_stream_alloc() - */ -static inline int skb_availroom(const struct sk_buff *skb) -{ - return skb_is_nonlinear(skb) ? 0 : skb->avail_size - skb->len; -} - /** * skb_reserve - adjust headroom * @skb: buffer to alter diff --git a/trunk/include/linux/socket.h b/trunk/include/linux/socket.h index b84bbd48b874..da2d3e2543f3 100644 --- a/trunk/include/linux/socket.h +++ b/trunk/include/linux/socket.h @@ -265,7 +265,7 @@ struct ucred { #define MSG_NOSIGNAL 0x4000 /* Do not generate SIGPIPE */ #define MSG_MORE 0x8000 /* Sender will send more */ #define MSG_WAITFORONE 0x10000 /* recvmmsg(): block until 1+ packets avail */ -#define MSG_SENDPAGE_NOTLAST 0x20000 /* sendpage() internal : not the last page */ + #define MSG_EOF MSG_FIN #define MSG_CMSG_CLOEXEC 0x40000000 /* Set close_on_exit for file diff --git a/trunk/include/linux/spi/spi.h b/trunk/include/linux/spi/spi.h index fa702aeb5038..98679b061b63 100644 --- a/trunk/include/linux/spi/spi.h +++ b/trunk/include/linux/spi/spi.h @@ -254,7 +254,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * driver is finished with this message, it must call * spi_finalize_current_message() so the subsystem can issue the next * transfer - * @unprepare_transfer_hardware: there are currently no more messages on the + * @prepare_transfer_hardware: there are currently no more messages on the * queue so the subsystem notifies the driver that it may relax the * hardware by issuing this call * diff --git a/trunk/include/linux/stddef.h b/trunk/include/linux/stddef.h index 1747b6787b9e..6a40c76bdcf1 100644 --- a/trunk/include/linux/stddef.h +++ b/trunk/include/linux/stddef.h @@ -3,10 +3,14 @@ #include -#ifdef __KERNEL__ - #undef NULL +#if defined(__cplusplus) +#define NULL 0 +#else #define NULL ((void *)0) +#endif + +#ifdef __KERNEL__ enum { false = 0, diff --git a/trunk/include/linux/swap.h b/trunk/include/linux/swap.h index b1fd5c7925fe..8dc0ea7caf02 100644 --- a/trunk/include/linux/swap.h +++ b/trunk/include/linux/swap.h @@ -305,13 +305,6 @@ static inline int mem_cgroup_swappiness(struct mem_cgroup *mem) return vm_swappiness; } #endif -#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP -extern void mem_cgroup_uncharge_swap(swp_entry_t ent); -#else -static inline void mem_cgroup_uncharge_swap(swp_entry_t ent) -{ -} -#endif #ifdef CONFIG_SWAP /* linux/mm/page_io.c */ extern int swap_readpage(struct page *); @@ -382,6 +375,13 @@ mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent, bool swapout) { } #endif +#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP +extern void mem_cgroup_uncharge_swap(swp_entry_t ent); +#else +static inline void mem_cgroup_uncharge_swap(swp_entry_t ent) +{ +} +#endif #else /* CONFIG_SWAP */ diff --git a/trunk/include/linux/tboot.h b/trunk/include/linux/tboot.h index c75128bed5fa..1dba6ee55203 100644 --- a/trunk/include/linux/tboot.h +++ b/trunk/include/linux/tboot.h @@ -143,6 +143,7 @@ static inline int tboot_enabled(void) extern void tboot_probe(void); extern void tboot_shutdown(u32 shutdown_type); +extern void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control); extern struct acpi_table_header *tboot_get_dmar_table( struct acpi_table_header *dmar_tbl); extern int tboot_force_iommu(void); diff --git a/trunk/include/linux/types.h b/trunk/include/linux/types.h index 7f480db60231..e5fa50345516 100644 --- a/trunk/include/linux/types.h +++ b/trunk/include/linux/types.h @@ -210,12 +210,6 @@ typedef u32 phys_addr_t; typedef phys_addr_t resource_size_t; -/* - * This type is the placeholder for a hardware interrupt number. It has to be - * big enough to enclose whatever representation is used by a given platform. - */ -typedef unsigned long irq_hw_number_t; - typedef struct { int counter; } atomic_t; diff --git a/trunk/include/linux/usb/hcd.h b/trunk/include/linux/usb/hcd.h index d28cc78a38e4..5de415707c23 100644 --- a/trunk/include/linux/usb/hcd.h +++ b/trunk/include/linux/usb/hcd.h @@ -126,8 +126,6 @@ struct usb_hcd { unsigned wireless:1; /* Wireless USB HCD */ unsigned authorized_default:1; unsigned has_tt:1; /* Integrated TT in root hub */ - unsigned broken_pci_sleep:1; /* Don't put the - controller in PCI-D3 for system sleep */ unsigned int irq; /* irq allocated */ void __iomem *regs; /* device memory/io */ diff --git a/trunk/include/linux/usb/otg.h b/trunk/include/linux/usb/otg.h index 38ab3f46346f..f67810f8f21b 100644 --- a/trunk/include/linux/usb/otg.h +++ b/trunk/include/linux/usb/otg.h @@ -94,7 +94,6 @@ struct usb_phy { struct usb_otg *otg; - struct device *io_dev; struct usb_phy_io_ops *io_ops; void __iomem *io_priv; diff --git a/trunk/include/linux/usb/serial.h b/trunk/include/linux/usb/serial.h index 474283888233..fbb666b1b670 100644 --- a/trunk/include/linux/usb/serial.h +++ b/trunk/include/linux/usb/serial.h @@ -28,6 +28,13 @@ /* parity check flag */ #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) +enum port_dev_state { + PORT_UNREGISTERED, + PORT_REGISTERING, + PORT_REGISTERED, + PORT_UNREGISTERING, +}; + /* USB serial flags */ #define USB_SERIAL_WRITE_BUSY 0 @@ -117,6 +124,7 @@ struct usb_serial_port { char throttle_req; unsigned long sysrq; /* sysrq timeout */ struct device dev; + enum port_dev_state dev_state; }; #define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev) diff --git a/trunk/include/linux/vgaarb.h b/trunk/include/linux/vgaarb.h index b572f80bdfd5..9c3120dca294 100644 --- a/trunk/include/linux/vgaarb.h +++ b/trunk/include/linux/vgaarb.h @@ -47,8 +47,6 @@ */ #define VGA_DEFAULT_DEVICE (NULL) -struct pci_dev; - /* For use by clients */ /** diff --git a/trunk/include/linux/virtio.h b/trunk/include/linux/virtio.h index 8efd28ae5597..d0018d27c281 100644 --- a/trunk/include/linux/virtio.h +++ b/trunk/include/linux/virtio.h @@ -96,6 +96,7 @@ struct virtio_driver { void (*config_changed)(struct virtio_device *dev); #ifdef CONFIG_PM int (*freeze)(struct virtio_device *dev); + int (*thaw)(struct virtio_device *dev); int (*restore)(struct virtio_device *dev); #endif }; diff --git a/trunk/include/linux/vm_event_item.h b/trunk/include/linux/vm_event_item.h index 06f8e3858251..03b90cdc1921 100644 --- a/trunk/include/linux/vm_event_item.h +++ b/trunk/include/linux/vm_event_item.h @@ -26,14 +26,13 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, PGFREE, PGACTIVATE, PGDEACTIVATE, PGFAULT, PGMAJFAULT, FOR_ALL_ZONES(PGREFILL), - FOR_ALL_ZONES(PGSTEAL_KSWAPD), - FOR_ALL_ZONES(PGSTEAL_DIRECT), + FOR_ALL_ZONES(PGSTEAL), FOR_ALL_ZONES(PGSCAN_KSWAPD), FOR_ALL_ZONES(PGSCAN_DIRECT), #ifdef CONFIG_NUMA PGSCAN_ZONE_RECLAIM_FAILED, #endif - PGINODESTEAL, SLABS_SCANNED, KSWAPD_INODESTEAL, + PGINODESTEAL, SLABS_SCANNED, KSWAPD_STEAL, KSWAPD_INODESTEAL, KSWAPD_LOW_WMARK_HIT_QUICKLY, KSWAPD_HIGH_WMARK_HIT_QUICKLY, KSWAPD_SKIP_CONGESTION_WAIT, PAGEOUTRUN, ALLOCSTALL, PGROTATED, diff --git a/trunk/include/net/bluetooth/hci.h b/trunk/include/net/bluetooth/hci.h index d47e523c9d83..344b0f972828 100644 --- a/trunk/include/net/bluetooth/hci.h +++ b/trunk/include/net/bluetooth/hci.h @@ -92,7 +92,6 @@ enum { HCI_SERVICE_CACHE, HCI_LINK_KEYS, HCI_DEBUG_KEYS, - HCI_UNREGISTER, HCI_LE_SCAN, HCI_SSP_ENABLED, @@ -1328,8 +1327,8 @@ struct sockaddr_hci { #define HCI_DEV_NONE 0xffff #define HCI_CHANNEL_RAW 0 +#define HCI_CHANNEL_CONTROL 1 #define HCI_CHANNEL_MONITOR 2 -#define HCI_CHANNEL_CONTROL 3 struct hci_filter { unsigned long type_mask; diff --git a/trunk/include/net/bluetooth/hci_core.h b/trunk/include/net/bluetooth/hci_core.h index db1c5df45224..daefaac51131 100644 --- a/trunk/include/net/bluetooth/hci_core.h +++ b/trunk/include/net/bluetooth/hci_core.h @@ -314,7 +314,6 @@ struct hci_conn { __u8 remote_cap; __u8 remote_auth; - bool flush_key; unsigned int sent; @@ -428,7 +427,7 @@ enum { static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - return (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && + return (test_bit(HCI_SSP_ENABLED, &hdev->flags) && test_bit(HCI_CONN_SSP_ENABLED, &conn->flags)); } @@ -908,13 +907,11 @@ static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type) { - size_t parsed = 0; + u8 field_len; + size_t parsed; - if (data_len < 2) - return false; - - while (parsed < data_len - 1) { - u8 field_len = data[0]; + for (parsed = 0; parsed < data_len - 1; parsed += field_len) { + field_len = data[0]; if (field_len == 0) break; @@ -981,7 +978,7 @@ int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); int mgmt_connectable(struct hci_dev *hdev, u8 connectable); int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status); int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, - bool persistent); + u8 persistent); int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u32 flags, u8 *name, u8 name_len, u8 *dev_class); diff --git a/trunk/include/net/bluetooth/mgmt.h b/trunk/include/net/bluetooth/mgmt.h index ebfd91fc20f8..ffc1377e092e 100644 --- a/trunk/include/net/bluetooth/mgmt.h +++ b/trunk/include/net/bluetooth/mgmt.h @@ -117,7 +117,7 @@ struct mgmt_mode { #define MGMT_OP_SET_DISCOVERABLE 0x0006 struct mgmt_cp_set_discoverable { __u8 val; - __le16 timeout; + __u16 timeout; } __packed; #define MGMT_SET_DISCOVERABLE_SIZE 3 diff --git a/trunk/include/net/cfg80211.h b/trunk/include/net/cfg80211.h index 83d800c31e3c..248fb05feb63 100644 --- a/trunk/include/net/cfg80211.h +++ b/trunk/include/net/cfg80211.h @@ -620,10 +620,8 @@ struct sta_bss_parameters { * @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state - * @signal: the signal strength, type depends on the wiphy's signal_type - NOTE: For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. - * @signal_avg: avg signal strength, type depends on the wiphy's signal_type - NOTE: For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. + * @signal: signal strength of last received packet in dBm + * @signal_avg: signal strength average in dBm * @txrate: current unicast bitrate from this station * @rxrate: current unicast bitrate to this station * @rx_packets: packets received from this station diff --git a/trunk/include/net/dst.h b/trunk/include/net/dst.h index bed833d9796a..59c5d18cc385 100644 --- a/trunk/include/net/dst.h +++ b/trunk/include/net/dst.h @@ -36,11 +36,7 @@ struct dst_entry { struct net_device *dev; struct dst_ops *ops; unsigned long _metrics; - union { - unsigned long expires; - /* point to where the dst_entry copied from */ - struct dst_entry *from; - }; + unsigned long expires; struct dst_entry *path; struct neighbour __rcu *_neighbour; #ifdef CONFIG_XFRM @@ -59,7 +55,6 @@ struct dst_entry { #define DST_NOCACHE 0x0010 #define DST_NOCOUNT 0x0020 #define DST_NOPEER 0x0040 -#define DST_FAKE_RTABLE 0x0080 short error; short obsolete; diff --git a/trunk/include/net/ip6_fib.h b/trunk/include/net/ip6_fib.h index 0ae759a6c76e..b26bb8101981 100644 --- a/trunk/include/net/ip6_fib.h +++ b/trunk/include/net/ip6_fib.h @@ -123,54 +123,6 @@ static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst) return ((struct rt6_info *)dst)->rt6i_idev; } -static inline void rt6_clean_expires(struct rt6_info *rt) -{ - if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) - dst_release(rt->dst.from); - - rt->rt6i_flags &= ~RTF_EXPIRES; - rt->dst.from = NULL; -} - -static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires) -{ - if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) - dst_release(rt->dst.from); - - rt->rt6i_flags |= RTF_EXPIRES; - rt->dst.expires = expires; -} - -static inline void rt6_update_expires(struct rt6_info *rt, int timeout) -{ - if (!(rt->rt6i_flags & RTF_EXPIRES)) { - if (rt->dst.from) - dst_release(rt->dst.from); - /* dst_set_expires relies on expires == 0 - * if it has not been set previously. - */ - rt->dst.expires = 0; - } - - dst_set_expires(&rt->dst, timeout); - rt->rt6i_flags |= RTF_EXPIRES; -} - -static inline void rt6_set_from(struct rt6_info *rt, struct rt6_info *from) -{ - struct dst_entry *new = (struct dst_entry *) from; - - if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) { - if (new == rt->dst.from) - return; - dst_release(rt->dst.from); - } - - rt->rt6i_flags &= ~RTF_EXPIRES; - rt->dst.from = new; - dst_hold(new); -} - struct fib6_walker_t { struct list_head lh; struct fib6_node *root, *node; diff --git a/trunk/include/net/ip_vs.h b/trunk/include/net/ip_vs.h index 72522f087375..2bdee51ba30d 100644 --- a/trunk/include/net/ip_vs.h +++ b/trunk/include/net/ip_vs.h @@ -393,7 +393,7 @@ struct ip_vs_protocol { void (*exit)(struct ip_vs_protocol *pp); - int (*init_netns)(struct net *net, struct ip_vs_proto_data *pd); + void (*init_netns)(struct net *net, struct ip_vs_proto_data *pd); void (*exit_netns)(struct net *net, struct ip_vs_proto_data *pd); @@ -1203,8 +1203,6 @@ ip_vs_lookup_real_service(struct net *net, int af, __u16 protocol, extern int ip_vs_use_count_inc(void); extern void ip_vs_use_count_dec(void); -extern int ip_vs_register_nl_ioctl(void); -extern void ip_vs_unregister_nl_ioctl(void); extern int ip_vs_control_init(void); extern void ip_vs_control_cleanup(void); extern struct ip_vs_dest * diff --git a/trunk/include/net/mac80211.h b/trunk/include/net/mac80211.h index 9210bdc7bd8d..87d203ff7a8a 100644 --- a/trunk/include/net/mac80211.h +++ b/trunk/include/net/mac80211.h @@ -1327,7 +1327,7 @@ static inline struct ieee80211_rate * ieee80211_get_tx_rate(const struct ieee80211_hw *hw, const struct ieee80211_tx_info *c) { - if (WARN_ON_ONCE(c->control.rates[0].idx < 0)) + if (WARN_ON(c->control.rates[0].idx < 0)) return NULL; return &hw->wiphy->bands[c->band]->bitrates[c->control.rates[0].idx]; } diff --git a/trunk/include/net/netfilter/xt_log.h b/trunk/include/net/netfilter/xt_log.h index 9d9756cca013..7e1544e8f70d 100644 --- a/trunk/include/net/netfilter/xt_log.h +++ b/trunk/include/net/netfilter/xt_log.h @@ -47,7 +47,7 @@ static void sb_close(struct sbuff *m) if (likely(m != &emergency)) kfree(m); else { - emergency_ptr = m; + xchg(&emergency_ptr, m); local_bh_enable(); } } diff --git a/trunk/include/net/red.h b/trunk/include/net/red.h index ef46058d35bf..77d4c3745cb5 100644 --- a/trunk/include/net/red.h +++ b/trunk/include/net/red.h @@ -245,7 +245,7 @@ static inline unsigned long red_calc_qavg_from_idle_time(const struct red_parms * * dummy packets as a burst after idle time, i.e. * - * v->qavg *= (1-W)^m + * p->qavg *= (1-W)^m * * This is an apparently overcomplicated solution (f.e. we have to * precompute a table to make this calculation in reasonable time) @@ -279,7 +279,7 @@ static inline unsigned long red_calc_qavg_no_idle_time(const struct red_parms *p unsigned int backlog) { /* - * NOTE: v->qavg is fixed point number with point at Wlog. + * NOTE: p->qavg is fixed point number with point at Wlog. * The formula below is equvalent to floating point * version: * @@ -390,7 +390,7 @@ static inline void red_adaptative_algo(struct red_parms *p, struct red_vars *v) if (red_is_idling(v)) qavg = red_calc_qavg_from_idle_time(p, v); - /* v->qavg is fixed point number with point at Wlog */ + /* p->qavg is fixed point number with point at Wlog */ qavg >>= p->Wlog; if (qavg > p->target_max && p->max_P <= MAX_P_MAX) diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index 5a0a58ac4126..a6ba1f8871fd 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -246,7 +246,6 @@ struct cg_proto; * @sk_user_data: RPC layer private data * @sk_sndmsg_page: cached page for sendmsg * @sk_sndmsg_off: cached offset for sendmsg - * @sk_peek_off: current peek_offset value * @sk_send_head: front of stuff to transmit * @sk_security: used by security modules * @sk_mark: generic packet mark @@ -1129,9 +1128,9 @@ sk_sockets_allocated_read_positive(struct sock *sk) struct proto *prot = sk->sk_prot; if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - return percpu_counter_read_positive(sk->sk_cgrp->sockets_allocated); + return percpu_counter_sum_positive(sk->sk_cgrp->sockets_allocated); - return percpu_counter_read_positive(prot->sockets_allocated); + return percpu_counter_sum_positive(prot->sockets_allocated); } static inline int diff --git a/trunk/include/scsi/iscsi_if.h b/trunk/include/scsi/iscsi_if.h index 917741bb8e11..9c23ee8fd2d3 100644 --- a/trunk/include/scsi/iscsi_if.h +++ b/trunk/include/scsi/iscsi_if.h @@ -261,8 +261,7 @@ struct iscsi_uevent { } host_event; struct msg_ping_comp { uint32_t host_no; - uint32_t status; /* enum - * iscsi_ping_status_code */ + uint32_t status; uint32_t pid; /* unique ping id associated with each ping request */ uint32_t data_size; @@ -484,20 +483,6 @@ enum iscsi_port_state { ISCSI_PORT_STATE_UP = 0x2, }; -/* iSCSI PING status/error code */ -enum iscsi_ping_status_code { - ISCSI_PING_SUCCESS = 0, - ISCSI_PING_FW_DISABLED = 0x1, - ISCSI_PING_IPADDR_INVALID = 0x2, - ISCSI_PING_LINKLOCAL_IPV6_ADDR_INVALID = 0x3, - ISCSI_PING_TIMEOUT = 0x4, - ISCSI_PING_INVALID_DEST_ADDR = 0x5, - ISCSI_PING_OVERSIZE_PACKET = 0x6, - ISCSI_PING_ICMP_ERROR = 0x7, - ISCSI_PING_MAX_REQ_EXCEEDED = 0x8, - ISCSI_PING_NO_ARP_RECEIVED = 0x9, -}; - #define iscsi_ptr(_handle) ((void*)(unsigned long)_handle) #define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr) @@ -593,6 +578,6 @@ struct iscsi_chap_rec { char username[ISCSI_CHAP_AUTH_NAME_MAX_LEN]; uint8_t password[ISCSI_CHAP_AUTH_SECRET_MAX_LEN]; uint8_t password_length; -}; +} __packed; #endif diff --git a/trunk/include/scsi/libfcoe.h b/trunk/include/scsi/libfcoe.h index cfdb55f0937e..5a35a2a2d3c5 100644 --- a/trunk/include/scsi/libfcoe.h +++ b/trunk/include/scsi/libfcoe.h @@ -165,8 +165,7 @@ struct fcoe_ctlr { * @switch_name: WWN of switch from advertisement * @fabric_name: WWN of fabric from advertisement * @fc_map: FC_MAP value from advertisement - * @fcf_mac: Ethernet address of the FCF for FIP traffic - * @fcoe_mac: Ethernet address of the FCF for FCoE traffic + * @fcf_mac: Ethernet address of the FCF * @vfid: virtual fabric ID * @pri: selection priority, smaller values are better * @flogi_sent: current FLOGI sent to this FCF @@ -189,7 +188,6 @@ struct fcoe_fcf { u32 fc_map; u16 vfid; u8 fcf_mac[ETH_ALEN]; - u8 fcoe_mac[ETH_ALEN]; u8 pri; u8 flogi_sent; diff --git a/trunk/include/scsi/libsas.h b/trunk/include/scsi/libsas.h index f4f1c96dca72..5f5ed1b8b41b 100644 --- a/trunk/include/scsi/libsas.h +++ b/trunk/include/scsi/libsas.h @@ -217,29 +217,11 @@ struct domain_device { struct kref kref; }; -struct sas_work { - struct list_head drain_node; - struct work_struct work; -}; - -static inline void INIT_SAS_WORK(struct sas_work *sw, void (*fn)(struct work_struct *)) -{ - INIT_WORK(&sw->work, fn); - INIT_LIST_HEAD(&sw->drain_node); -} - struct sas_discovery_event { - struct sas_work work; + struct work_struct work; struct asd_sas_port *port; }; -static inline struct sas_discovery_event *to_sas_discovery_event(struct work_struct *work) -{ - struct sas_discovery_event *ev = container_of(work, typeof(*ev), work.work); - - return ev; -} - struct sas_discovery { struct sas_discovery_event disc_work[DISC_NUM_EVENTS]; unsigned long pending; @@ -262,7 +244,7 @@ struct asd_sas_port { struct list_head destroy_list; enum sas_linkrate linkrate; - struct sas_work work; + struct work_struct work; /* public: */ int id; @@ -288,17 +270,10 @@ struct asd_sas_port { }; struct asd_sas_event { - struct sas_work work; + struct work_struct work; struct asd_sas_phy *phy; }; -static inline struct asd_sas_event *to_asd_sas_event(struct work_struct *work) -{ - struct asd_sas_event *ev = container_of(work, typeof(*ev), work.work); - - return ev; -} - /* The phy pretty much is controlled by the LLDD. * The class only reads those fields. */ @@ -358,17 +333,10 @@ struct scsi_core { }; struct sas_ha_event { - struct sas_work work; + struct work_struct work; struct sas_ha_struct *ha; }; -static inline struct sas_ha_event *to_sas_ha_event(struct work_struct *work) -{ - struct sas_ha_event *ev = container_of(work, typeof(*ev), work.work); - - return ev; -} - enum sas_ha_state { SAS_HA_REGISTERED, SAS_HA_DRAINING, diff --git a/trunk/include/scsi/sas_ata.h b/trunk/include/scsi/sas_ata.h index 77670e823ed8..cdccd2eb7b6c 100644 --- a/trunk/include/scsi/sas_ata.h +++ b/trunk/include/scsi/sas_ata.h @@ -37,7 +37,7 @@ static inline int dev_is_sata(struct domain_device *dev) } int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy); -int sas_ata_init(struct domain_device *dev); +int sas_ata_init_host_and_port(struct domain_device *found_dev); void sas_ata_task_abort(struct sas_task *task); void sas_ata_strategy_handler(struct Scsi_Host *shost); void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, @@ -52,7 +52,7 @@ static inline int dev_is_sata(struct domain_device *dev) { return 0; } -static inline int sas_ata_init(struct domain_device *dev) +static inline int sas_ata_init_host_and_port(struct domain_device *found_dev) { return 0; } diff --git a/trunk/include/scsi/scsi_cmnd.h b/trunk/include/scsi/scsi_cmnd.h index 1e1198546c72..377df4a28512 100644 --- a/trunk/include/scsi/scsi_cmnd.h +++ b/trunk/include/scsi/scsi_cmnd.h @@ -134,9 +134,6 @@ struct scsi_cmnd { static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) { - if (!cmd->request->rq_disk) - return NULL; - return *(struct scsi_driver **)cmd->request->rq_disk->private_data; } diff --git a/trunk/include/sound/core.h b/trunk/include/sound/core.h index bc056687f647..b6e0f57d451d 100644 --- a/trunk/include/sound/core.h +++ b/trunk/include/sound/core.h @@ -325,13 +325,6 @@ void release_and_free_resource(struct resource *res); /* --- */ -/* sound printk debug levels */ -enum { - SND_PR_ALWAYS, - SND_PR_DEBUG, - SND_PR_VERBOSE, -}; - #if defined(CONFIG_SND_DEBUG) || defined(CONFIG_SND_VERBOSE_PRINTK) __printf(4, 5) void __snd_printk(unsigned int level, const char *file, int line, @@ -361,8 +354,6 @@ void __snd_printk(unsigned int level, const char *file, int line, */ #define snd_printd(fmt, args...) \ __snd_printk(1, __FILE__, __LINE__, fmt, ##args) -#define _snd_printd(level, fmt, args...) \ - __snd_printk(level, __FILE__, __LINE__, fmt, ##args) /** * snd_BUG - give a BUG warning message and stack trace @@ -392,7 +383,6 @@ void __snd_printk(unsigned int level, const char *file, int line, #else /* !CONFIG_SND_DEBUG */ #define snd_printd(fmt, args...) do { } while (0) -#define _snd_printd(level, fmt, args...) do { } while (0) #define snd_BUG() do { } while (0) static inline int __snd_bug_on(int cond) { diff --git a/trunk/include/trace/events/btrfs.h b/trunk/include/trace/events/btrfs.h index 91b91e805673..84f3001a568d 100644 --- a/trunk/include/trace/events/btrfs.h +++ b/trunk/include/trace/events/btrfs.h @@ -6,7 +6,6 @@ #include #include -#include struct btrfs_root; struct btrfs_fs_info; @@ -863,49 +862,6 @@ TRACE_EVENT(btrfs_setup_cluster, __entry->size, __entry->max_size, __entry->bitmap) ); -struct extent_state; -TRACE_EVENT(alloc_extent_state, - - TP_PROTO(struct extent_state *state, gfp_t mask, unsigned long IP), - - TP_ARGS(state, mask, IP), - - TP_STRUCT__entry( - __field(struct extent_state *, state) - __field(gfp_t, mask) - __field(unsigned long, ip) - ), - - TP_fast_assign( - __entry->state = state, - __entry->mask = mask, - __entry->ip = IP - ), - - TP_printk("state=%p; mask = %s; caller = %pF", __entry->state, - show_gfp_flags(__entry->mask), (void *)__entry->ip) -); - -TRACE_EVENT(free_extent_state, - - TP_PROTO(struct extent_state *state, unsigned long IP), - - TP_ARGS(state, IP), - - TP_STRUCT__entry( - __field(struct extent_state *, state) - __field(unsigned long, ip) - ), - - TP_fast_assign( - __entry->state = state, - __entry->ip = IP - ), - - TP_printk(" state=%p; caller = %pF", __entry->state, - (void *)__entry->ip) -); - #endif /* _TRACE_BTRFS_H */ /* This part must be outside protection */ diff --git a/trunk/include/trace/events/sched.h b/trunk/include/trace/events/sched.h index ea7a2035456d..fbc7b1ad929b 100644 --- a/trunk/include/trace/events/sched.h +++ b/trunk/include/trace/events/sched.h @@ -295,7 +295,7 @@ TRACE_EVENT(sched_process_exec, TP_fast_assign( __assign_str(filename, bprm->filename); __entry->pid = p->pid; - __entry->old_pid = old_pid; + __entry->old_pid = p->pid; ), TP_printk("filename=%s pid=%d old_pid=%d", __get_str(filename), diff --git a/trunk/include/xen/swiotlb-xen.h b/trunk/include/xen/swiotlb-xen.h index 4f4d449f00f6..2ea2fdc79c16 100644 --- a/trunk/include/xen/swiotlb-xen.h +++ b/trunk/include/xen/swiotlb-xen.h @@ -7,13 +7,11 @@ extern void xen_swiotlb_init(int verbose); extern void *xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size, - dma_addr_t *dma_handle, gfp_t flags, - struct dma_attrs *attrs); + dma_addr_t *dma_handle, gfp_t flags); extern void xen_swiotlb_free_coherent(struct device *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle, - struct dma_attrs *attrs); + void *vaddr, dma_addr_t dma_handle); extern dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, diff --git a/trunk/init/Kconfig b/trunk/init/Kconfig index 6cfd71d06463..72f33faca44f 100644 --- a/trunk/init/Kconfig +++ b/trunk/init/Kconfig @@ -1414,8 +1414,8 @@ endif # MODULES config INIT_ALL_POSSIBLE bool help - Back when each arch used to define their own cpu_online_mask and - cpu_possible_mask, some of them chose to initialize cpu_possible_mask + Back when each arch used to define their own cpu_online_map and + cpu_possible_map, some of them chose to initialize cpu_possible_map with all 1s, and others with all 0s. When they were centralised, it was better to provide this option than to break all the archs and have several arch maintainers pursuing me down dark alleys. diff --git a/trunk/init/do_mounts.c b/trunk/init/do_mounts.c index 42b0707c3481..0e93f92a0345 100644 --- a/trunk/init/do_mounts.c +++ b/trunk/init/do_mounts.c @@ -472,7 +472,7 @@ void __init change_floppy(char *fmt, ...) void __init mount_root(void) { #ifdef CONFIG_ROOT_NFS - if (ROOT_DEV == Root_NFS) { + if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) { if (mount_nfs_root()) return; diff --git a/trunk/init/do_mounts_initrd.c b/trunk/init/do_mounts_initrd.c index 9047330c73e9..3098a38f3ae1 100644 --- a/trunk/init/do_mounts_initrd.c +++ b/trunk/init/do_mounts_initrd.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/init/do_mounts_rd.c b/trunk/init/do_mounts_rd.c index 6212586df29a..01f1306aa26e 100644 --- a/trunk/init/do_mounts_rd.c +++ b/trunk/init/do_mounts_rd.c @@ -54,19 +54,20 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) { const int size = 512; struct minix_super_block *minixsb; + struct ext2_super_block *ext2sb; struct romfs_super_block *romfsb; struct cramfs_super *cramfsb; struct squashfs_super_block *squashfsb; int nblocks = -1; unsigned char *buf; const char *compress_name; - unsigned long n; buf = kmalloc(size, GFP_KERNEL); if (!buf) return -ENOMEM; minixsb = (struct minix_super_block *) buf; + ext2sb = (struct ext2_super_block *) buf; romfsb = (struct romfs_super_block *) buf; cramfsb = (struct cramfs_super *) buf; squashfsb = (struct squashfs_super_block *) buf; @@ -149,12 +150,12 @@ identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) } /* Try ext2 */ - n = ext2_image_size(buf); - if (n) { + if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) { printk(KERN_NOTICE "RAMDISK: ext2 filesystem found at block %d\n", start_block); - nblocks = n; + nblocks = le32_to_cpu(ext2sb->s_blocks_count) << + le32_to_cpu(ext2sb->s_log_block_size); goto done; } diff --git a/trunk/init/main.c b/trunk/init/main.c index 44b2433334c7..9d454f09f3b1 100644 --- a/trunk/init/main.c +++ b/trunk/init/main.c @@ -225,9 +225,13 @@ static int __init loglevel(char *str) early_param("loglevel", loglevel); -/* Change NUL term back to "=", to make "param" the whole string. */ -static int __init repair_env_string(char *param, char *val) +/* + * Unknown boot options get handed to init, unless they look like + * unused parameters (modprobe will find them in /proc/cmdline). + */ +static int __init unknown_bootoption(char *param, char *val) { + /* Change NUL term back to "=", to make "param" the whole string. */ if (val) { /* param=val or param="val"? */ if (val == param+strlen(param)+1) @@ -239,16 +243,6 @@ static int __init repair_env_string(char *param, char *val) } else BUG(); } - return 0; -} - -/* - * Unknown boot options get handed to init, unless they look like - * unused parameters (modprobe will find them in /proc/cmdline). - */ -static int __init unknown_bootoption(char *param, char *val) -{ - repair_env_string(param, val); /* Handle obsolete-style parameters */ if (obsolete_checksetup(param)) @@ -738,6 +732,11 @@ static char *initcall_level_names[] __initdata = { "late parameters", }; +static int __init ignore_unknown_bootoption(char *param, char *val) +{ + return 0; +} + static void __init do_initcall_level(int level) { extern const struct kernel_param __start___param[], __stop___param[]; @@ -748,7 +747,7 @@ static void __init do_initcall_level(int level) static_command_line, __start___param, __stop___param - __start___param, level, level, - repair_env_string); + ignore_unknown_bootoption); for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) do_one_initcall(*fn); diff --git a/trunk/kernel/cpuset.c b/trunk/kernel/cpuset.c index 14f7070b4ba2..b96ad75b7e64 100644 --- a/trunk/kernel/cpuset.c +++ b/trunk/kernel/cpuset.c @@ -270,11 +270,11 @@ static struct file_system_type cpuset_fs_type = { * are online. If none are online, walk up the cpuset hierarchy * until we find one that does have some online cpus. If we get * all the way to the top and still haven't found any online cpus, - * return cpu_online_mask. Or if passed a NULL cs from an exit'ing - * task, return cpu_online_mask. + * return cpu_online_map. Or if passed a NULL cs from an exit'ing + * task, return cpu_online_map. * * One way or another, we guarantee to return some non-empty subset - * of cpu_online_mask. + * of cpu_online_map. * * Call with callback_mutex held. */ @@ -867,7 +867,7 @@ static int update_cpumask(struct cpuset *cs, struct cpuset *trialcs, int retval; int is_load_balanced; - /* top_cpuset.cpus_allowed tracks cpu_online_mask; it's read-only */ + /* top_cpuset.cpus_allowed tracks cpu_online_map; it's read-only */ if (cs == &top_cpuset) return -EACCES; @@ -2149,7 +2149,7 @@ void __init cpuset_init_smp(void) * * Description: Returns the cpumask_var_t cpus_allowed of the cpuset * attached to the specified @tsk. Guaranteed to return some non-empty - * subset of cpu_online_mask, even if this means going outside the + * subset of cpu_online_map, even if this means going outside the * tasks cpuset. **/ diff --git a/trunk/kernel/cred.c b/trunk/kernel/cred.c index e70683d9ec32..97b36eeca4c9 100644 --- a/trunk/kernel/cred.c +++ b/trunk/kernel/cred.c @@ -386,8 +386,6 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) struct cred *new; int ret; - p->replacement_session_keyring = NULL; - if ( #ifdef CONFIG_KEYS !p->cred->thread_keyring && diff --git a/trunk/kernel/debug/debug_core.c b/trunk/kernel/debug/debug_core.c index 0557f24c6bca..1dc53bae56e1 100644 --- a/trunk/kernel/debug/debug_core.c +++ b/trunk/kernel/debug/debug_core.c @@ -160,39 +160,37 @@ early_param("nokgdbroundup", opt_nokgdbroundup); * Weak aliases for breakpoint management, * can be overriden by architectures when needed: */ -int __weak kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) +int __weak kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr) { int err; - err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, - BREAK_INSTR_SIZE); + err = probe_kernel_read(saved_instr, (char *)addr, BREAK_INSTR_SIZE); if (err) return err; - err = probe_kernel_write((char *)bpt->bpt_addr, - arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE); - return err; + + return probe_kernel_write((char *)addr, arch_kgdb_ops.gdb_bpt_instr, + BREAK_INSTR_SIZE); } -int __weak kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) +int __weak kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle) { - return probe_kernel_write((char *)bpt->bpt_addr, - (char *)bpt->saved_instr, BREAK_INSTR_SIZE); + return probe_kernel_write((char *)addr, + (char *)bundle, BREAK_INSTR_SIZE); } int __weak kgdb_validate_break_address(unsigned long addr) { - struct kgdb_bkpt tmp; + char tmp_variable[BREAK_INSTR_SIZE]; int err; - /* Validate setting the breakpoint and then removing it. If the + /* Validate setting the breakpoint and then removing it. In the * remove fails, the kernel needs to emit a bad message because we * are deep trouble not being able to put things back the way we * found them. */ - tmp.bpt_addr = addr; - err = kgdb_arch_set_breakpoint(&tmp); + err = kgdb_arch_set_breakpoint(addr, tmp_variable); if (err) return err; - err = kgdb_arch_remove_breakpoint(&tmp); + err = kgdb_arch_remove_breakpoint(addr, tmp_variable); if (err) printk(KERN_ERR "KGDB: Critical breakpoint error, kernel " "memory destroyed at: %lx", addr); @@ -236,6 +234,7 @@ static void kgdb_flush_swbreak_addr(unsigned long addr) */ int dbg_activate_sw_breakpoints(void) { + unsigned long addr; int error; int ret = 0; int i; @@ -244,15 +243,16 @@ int dbg_activate_sw_breakpoints(void) if (kgdb_break[i].state != BP_SET) continue; - error = kgdb_arch_set_breakpoint(&kgdb_break[i]); + addr = kgdb_break[i].bpt_addr; + error = kgdb_arch_set_breakpoint(addr, + kgdb_break[i].saved_instr); if (error) { ret = error; - printk(KERN_INFO "KGDB: BP install failed: %lx", - kgdb_break[i].bpt_addr); + printk(KERN_INFO "KGDB: BP install failed: %lx", addr); continue; } - kgdb_flush_swbreak_addr(kgdb_break[i].bpt_addr); + kgdb_flush_swbreak_addr(addr); kgdb_break[i].state = BP_ACTIVE; } return ret; @@ -301,6 +301,7 @@ int dbg_set_sw_break(unsigned long addr) int dbg_deactivate_sw_breakpoints(void) { + unsigned long addr; int error; int ret = 0; int i; @@ -308,14 +309,15 @@ int dbg_deactivate_sw_breakpoints(void) for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { if (kgdb_break[i].state != BP_ACTIVE) continue; - error = kgdb_arch_remove_breakpoint(&kgdb_break[i]); + addr = kgdb_break[i].bpt_addr; + error = kgdb_arch_remove_breakpoint(addr, + kgdb_break[i].saved_instr); if (error) { - printk(KERN_INFO "KGDB: BP remove failed: %lx\n", - kgdb_break[i].bpt_addr); + printk(KERN_INFO "KGDB: BP remove failed: %lx\n", addr); ret = error; } - kgdb_flush_swbreak_addr(kgdb_break[i].bpt_addr); + kgdb_flush_swbreak_addr(addr); kgdb_break[i].state = BP_SET; } return ret; @@ -349,6 +351,7 @@ int kgdb_isremovedbreak(unsigned long addr) int dbg_remove_all_break(void) { + unsigned long addr; int error; int i; @@ -356,10 +359,12 @@ int dbg_remove_all_break(void) for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) { if (kgdb_break[i].state != BP_ACTIVE) goto setundefined; - error = kgdb_arch_remove_breakpoint(&kgdb_break[i]); + addr = kgdb_break[i].bpt_addr; + error = kgdb_arch_remove_breakpoint(addr, + kgdb_break[i].saved_instr); if (error) printk(KERN_ERR "KGDB: breakpoint remove failed: %lx\n", - kgdb_break[i].bpt_addr); + addr); setundefined: kgdb_break[i].state = BP_UNDEFINED; } diff --git a/trunk/kernel/debug/kdb/kdb_io.c b/trunk/kernel/debug/kdb/kdb_io.c index bb9520f0f6ff..9b5f17da1c56 100644 --- a/trunk/kernel/debug/kdb/kdb_io.c +++ b/trunk/kernel/debug/kdb/kdb_io.c @@ -743,7 +743,7 @@ int vkdb_printf(const char *fmt, va_list ap) kdb_input_flush(); c = console_drivers; - if (dbg_io_ops && !dbg_io_ops->is_console) { + if (!dbg_io_ops->is_console) { len = strlen(moreprompt); cp = moreprompt; while (len--) { diff --git a/trunk/kernel/events/core.c b/trunk/kernel/events/core.c index fd126f82b57c..4b50357914fb 100644 --- a/trunk/kernel/events/core.c +++ b/trunk/kernel/events/core.c @@ -3183,7 +3183,7 @@ static void perf_event_for_each(struct perf_event *event, perf_event_for_each_child(event, func); func(event); list_for_each_entry(sibling, &event->sibling_list, group_entry) - perf_event_for_each_child(sibling, func); + perf_event_for_each_child(event, func); mutex_unlock(&ctx->mutex); } @@ -3348,7 +3348,7 @@ static void calc_timer_values(struct perf_event *event, *running = ctx_time - event->tstamp_running; } -void __weak arch_perf_update_userpage(struct perf_event_mmap_page *userpg, u64 now) +void __weak perf_update_user_clock(struct perf_event_mmap_page *userpg, u64 now) { } @@ -3398,7 +3398,7 @@ void perf_event_update_userpage(struct perf_event *event) userpg->time_running = running + atomic64_read(&event->child_total_time_running); - arch_perf_update_userpage(userpg, now); + perf_update_user_clock(userpg, now); barrier(); ++userpg->lock; @@ -7116,13 +7116,6 @@ void __init perf_event_init(void) /* do not patch jump label more than once per second */ jump_label_rate_limit(&perf_sched_events, HZ); - - /* - * Build time assertion that we keep the data_head at the intended - * location. IOW, validation we got the __reserved[] size right. - */ - BUILD_BUG_ON((offsetof(struct perf_event_mmap_page, data_head)) - != 1024); } static int __init perf_event_sysfs_init(void) diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index e2b0fb9a0b3b..72efa1e4359a 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -59,7 +59,6 @@ #include #include #include -#include #include @@ -2444,31 +2443,40 @@ SYSCALL_DEFINE3(get_robust_list, int, pid, { struct robust_list_head __user *head; unsigned long ret; - struct task_struct *p; + const struct cred *cred = current_cred(), *pcred; if (!futex_cmpxchg_enabled) return -ENOSYS; - WARN_ONCE(1, "deprecated: get_robust_list will be deleted in 2013.\n"); - - rcu_read_lock(); - - ret = -ESRCH; if (!pid) - p = current; + head = current->robust_list; else { + struct task_struct *p; + + ret = -ESRCH; + rcu_read_lock(); p = find_task_by_vpid(pid); if (!p) goto err_unlock; + ret = -EPERM; + pcred = __task_cred(p); + /* If victim is in different user_ns, then uids are not + comparable, so we must have CAP_SYS_PTRACE */ + if (cred->user->user_ns != pcred->user->user_ns) { + if (!ns_capable(pcred->user->user_ns, CAP_SYS_PTRACE)) + goto err_unlock; + goto ok; + } + /* If victim is in same user_ns, then uids are comparable */ + if (cred->euid != pcred->euid && + cred->euid != pcred->uid && + !ns_capable(pcred->user->user_ns, CAP_SYS_PTRACE)) + goto err_unlock; +ok: + head = p->robust_list; + rcu_read_unlock(); } - ret = -EPERM; - if (!ptrace_may_access(p, PTRACE_MODE_READ)) - goto err_unlock; - - head = p->robust_list; - rcu_read_unlock(); - if (put_user(sizeof(*head), len_ptr)) return -EFAULT; return put_user(head, head_ptr); diff --git a/trunk/kernel/futex_compat.c b/trunk/kernel/futex_compat.c index 83e368b005fc..5f9e689dc8f0 100644 --- a/trunk/kernel/futex_compat.c +++ b/trunk/kernel/futex_compat.c @@ -10,7 +10,6 @@ #include #include #include -#include #include @@ -137,31 +136,40 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, { struct compat_robust_list_head __user *head; unsigned long ret; - struct task_struct *p; + const struct cred *cred = current_cred(), *pcred; if (!futex_cmpxchg_enabled) return -ENOSYS; - WARN_ONCE(1, "deprecated: get_robust_list will be deleted in 2013.\n"); - - rcu_read_lock(); - - ret = -ESRCH; if (!pid) - p = current; + head = current->compat_robust_list; else { + struct task_struct *p; + + ret = -ESRCH; + rcu_read_lock(); p = find_task_by_vpid(pid); if (!p) goto err_unlock; + ret = -EPERM; + pcred = __task_cred(p); + /* If victim is in different user_ns, then uids are not + comparable, so we must have CAP_SYS_PTRACE */ + if (cred->user->user_ns != pcred->user->user_ns) { + if (!ns_capable(pcred->user->user_ns, CAP_SYS_PTRACE)) + goto err_unlock; + goto ok; + } + /* If victim is in same user_ns, then uids are comparable */ + if (cred->euid != pcred->euid && + cred->euid != pcred->uid && + !ns_capable(pcred->user->user_ns, CAP_SYS_PTRACE)) + goto err_unlock; +ok: + head = p->compat_robust_list; + rcu_read_unlock(); } - ret = -EPERM; - if (!ptrace_may_access(p, PTRACE_MODE_READ)) - goto err_unlock; - - head = p->compat_robust_list; - rcu_read_unlock(); - if (put_user(sizeof(*head), len_ptr)) return -EFAULT; return put_user(ptr_to_compat(head), head_ptr); diff --git a/trunk/kernel/irq/Kconfig b/trunk/kernel/irq/Kconfig index d1a758bc972a..cf1a4a68ce44 100644 --- a/trunk/kernel/irq/Kconfig +++ b/trunk/kernel/irq/Kconfig @@ -62,7 +62,7 @@ config IRQ_DOMAIN_DEBUG help This option will show the mapping relationship between hardware irq numbers and Linux irq numbers. The mapping is exposed via debugfs - in the file "irq_domain_mapping". + in the file "virq_mapping". If you don't know what this means you don't need it. diff --git a/trunk/kernel/irq/debug.h b/trunk/kernel/irq/debug.h index e75e29e4434a..97a8bfadc88a 100644 --- a/trunk/kernel/irq/debug.h +++ b/trunk/kernel/irq/debug.h @@ -4,10 +4,10 @@ #include -#define ___P(f) if (desc->status_use_accessors & f) printk("%14s set\n", #f) -#define ___PS(f) if (desc->istate & f) printk("%14s set\n", #f) +#define P(f) if (desc->status_use_accessors & f) printk("%14s set\n", #f) +#define PS(f) if (desc->istate & f) printk("%14s set\n", #f) /* FIXME */ -#define ___PD(f) do { } while (0) +#define PD(f) do { } while (0) static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc) { @@ -23,23 +23,23 @@ static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc) print_symbol("%s\n", (unsigned long)desc->action->handler); } - ___P(IRQ_LEVEL); - ___P(IRQ_PER_CPU); - ___P(IRQ_NOPROBE); - ___P(IRQ_NOREQUEST); - ___P(IRQ_NOTHREAD); - ___P(IRQ_NOAUTOEN); + P(IRQ_LEVEL); + P(IRQ_PER_CPU); + P(IRQ_NOPROBE); + P(IRQ_NOREQUEST); + P(IRQ_NOTHREAD); + P(IRQ_NOAUTOEN); - ___PS(IRQS_AUTODETECT); - ___PS(IRQS_REPLAY); - ___PS(IRQS_WAITING); - ___PS(IRQS_PENDING); + PS(IRQS_AUTODETECT); + PS(IRQS_REPLAY); + PS(IRQS_WAITING); + PS(IRQS_PENDING); - ___PD(IRQS_INPROGRESS); - ___PD(IRQS_DISABLED); - ___PD(IRQS_MASKED); + PD(IRQS_INPROGRESS); + PD(IRQS_DISABLED); + PD(IRQS_MASKED); } -#undef ___P -#undef ___PS -#undef ___PD +#undef P +#undef PS +#undef PD diff --git a/trunk/kernel/irq/handle.c b/trunk/kernel/irq/handle.c index bdb180325551..6ff84e6a954c 100644 --- a/trunk/kernel/irq/handle.c +++ b/trunk/kernel/irq/handle.c @@ -54,18 +54,14 @@ static void warn_no_thread(unsigned int irq, struct irqaction *action) static void irq_wake_thread(struct irq_desc *desc, struct irqaction *action) { /* - * In case the thread crashed and was killed we just pretend that - * we handled the interrupt. The hardirq handler has disabled the - * device interrupt, so no irq storm is lurking. - */ - if (action->thread->flags & PF_EXITING) - return; - - /* - * Wake up the handler thread for this action. If the + * Wake up the handler thread for this action. In case the + * thread crashed and was killed we just pretend that we + * handled the interrupt. The hardirq handler has disabled the + * device interrupt, so no irq storm is lurking. If the * RUNTHREAD bit is already set, nothing to do. */ - if (test_and_set_bit(IRQTF_RUNTHREAD, &action->thread_flags)) + if ((action->thread->flags & PF_EXITING) || + test_and_set_bit(IRQTF_RUNTHREAD, &action->thread_flags)) return; /* diff --git a/trunk/kernel/irq/irqdomain.c b/trunk/kernel/irq/irqdomain.c index 0e0ba5f840b2..3601f3fbf67c 100644 --- a/trunk/kernel/irq/irqdomain.c +++ b/trunk/kernel/irq/irqdomain.c @@ -23,6 +23,7 @@ static LIST_HEAD(irq_domain_list); static DEFINE_MUTEX(irq_domain_mutex); static DEFINE_MUTEX(revmap_trees_mutex); +static unsigned int irq_virq_count = NR_IRQS; static struct irq_domain *irq_default_domain; /** @@ -183,16 +184,13 @@ struct irq_domain *irq_domain_add_linear(struct device_node *of_node, } struct irq_domain *irq_domain_add_nomap(struct device_node *of_node, - unsigned int max_irq, const struct irq_domain_ops *ops, void *host_data) { struct irq_domain *domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_NOMAP, ops, host_data); - if (domain) { - domain->revmap_data.nomap.max_irq = max_irq ? max_irq : ~0; + if (domain) irq_domain_add(domain); - } return domain; } @@ -264,6 +262,22 @@ void irq_set_default_host(struct irq_domain *domain) irq_default_domain = domain; } +/** + * irq_set_virq_count() - Set the maximum number of linux irqs + * @count: number of linux irqs, capped with NR_IRQS + * + * This is mainly for use by platforms like iSeries who want to program + * the virtual irq number in the controller to avoid the reverse mapping + */ +void irq_set_virq_count(unsigned int count) +{ + pr_debug("irq: Trying to set virq count to %d\n", count); + + BUG_ON(count < NUM_ISA_INTERRUPTS); + if (count < NR_IRQS) + irq_virq_count = count; +} + static int irq_setup_virq(struct irq_domain *domain, unsigned int virq, irq_hw_number_t hwirq) { @@ -306,12 +320,13 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain) pr_debug("irq: create_direct virq allocation failed\n"); return 0; } - if (virq >= domain->revmap_data.nomap.max_irq) { + if (virq >= irq_virq_count) { pr_err("ERROR: no free irqs available below %i maximum\n", - domain->revmap_data.nomap.max_irq); + irq_virq_count); irq_free_desc(virq); return 0; } + pr_debug("irq: create_direct obtained virq %d\n", virq); if (irq_setup_virq(domain, virq, virq)) { @@ -335,8 +350,7 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain) unsigned int irq_create_mapping(struct irq_domain *domain, irq_hw_number_t hwirq) { - unsigned int hint; - int virq; + unsigned int virq, hint; pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq); @@ -363,13 +377,13 @@ unsigned int irq_create_mapping(struct irq_domain *domain, return irq_domain_legacy_revmap(domain, hwirq); /* Allocate a virtual interrupt number */ - hint = hwirq % nr_irqs; + hint = hwirq % irq_virq_count; if (hint == 0) hint++; virq = irq_alloc_desc_from(hint, 0); - if (virq <= 0) + if (!virq) virq = irq_alloc_desc_from(1, 0); - if (virq <= 0) { + if (!virq) { pr_debug("irq: -> virq allocation failed\n"); return 0; } @@ -501,7 +515,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain, irq_hw_number_t hwirq) { unsigned int i; - unsigned int hint = hwirq % nr_irqs; + unsigned int hint = hwirq % irq_virq_count; /* Look for default domain if nececssary */ if (domain == NULL) @@ -522,7 +536,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain, if (data && (data->domain == domain) && (data->hwirq == hwirq)) return i; i++; - if (i >= nr_irqs) + if (i >= irq_virq_count) i = 1; } while(i != hint); return 0; @@ -628,9 +642,8 @@ static int virq_debug_show(struct seq_file *m, void *private) void *data; int i; - seq_printf(m, "%-5s %-7s %-15s %-*s %s\n", "irq", "hwirq", - "chip name", (int)(2 * sizeof(void *) + 2), "chip data", - "domain name"); + seq_printf(m, "%-5s %-7s %-15s %-18s %s\n", "virq", "hwirq", + "chip name", "chip data", "domain name"); for (i = 1; i < nr_irqs; i++) { desc = irq_to_desc(i); @@ -653,7 +666,7 @@ static int virq_debug_show(struct seq_file *m, void *private) seq_printf(m, "%-15s ", p); data = irq_desc_get_chip_data(desc); - seq_printf(m, data ? "0x%p " : " %p ", data); + seq_printf(m, "0x%16p ", data); if (desc->irq_data.domain && desc->irq_data.domain->of_node) p = desc->irq_data.domain->of_node->full_name; diff --git a/trunk/kernel/irq/manage.c b/trunk/kernel/irq/manage.c index 89a3ea82569b..b0ccd1ac2d6a 100644 --- a/trunk/kernel/irq/manage.c +++ b/trunk/kernel/irq/manage.c @@ -282,7 +282,7 @@ setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask) { struct irq_chip *chip = irq_desc_get_chip(desc); struct cpumask *set = irq_default_affinity; - int ret, node = desc->irq_data.node; + int ret; /* Excludes PER_CPU and NO_BALANCE interrupts */ if (!irq_can_set_affinity(irq)) @@ -301,13 +301,6 @@ setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask) } cpumask_and(mask, cpu_online_mask, set); - if (node != NUMA_NO_NODE) { - const struct cpumask *nodemask = cpumask_of_node(node); - - /* make sure at least one of the cpus in nodemask is online */ - if (cpumask_intersects(mask, nodemask)) - cpumask_and(mask, mask, nodemask); - } ret = chip->irq_set_affinity(&desc->irq_data, mask, false); switch (ret) { case IRQ_SET_MASK_OK: @@ -652,7 +645,7 @@ static int irq_wait_for_interrupt(struct irqaction *action) * is marked MASKED. */ static void irq_finalize_oneshot(struct irq_desc *desc, - struct irqaction *action) + struct irqaction *action, bool force) { if (!(desc->istate & IRQS_ONESHOT)) return; @@ -686,7 +679,7 @@ static void irq_finalize_oneshot(struct irq_desc *desc, * we would clear the threads_oneshot bit of this thread which * was just set. */ - if (test_bit(IRQTF_RUNTHREAD, &action->thread_flags)) + if (!force && test_bit(IRQTF_RUNTHREAD, &action->thread_flags)) goto out_unlock; desc->threads_oneshot &= ~action->thread_mask; @@ -746,7 +739,7 @@ irq_forced_thread_fn(struct irq_desc *desc, struct irqaction *action) local_bh_disable(); ret = action->thread_fn(action->irq, action->dev_id); - irq_finalize_oneshot(desc, action); + irq_finalize_oneshot(desc, action, false); local_bh_enable(); return ret; } @@ -762,7 +755,7 @@ static irqreturn_t irq_thread_fn(struct irq_desc *desc, irqreturn_t ret; ret = action->thread_fn(action->irq, action->dev_id); - irq_finalize_oneshot(desc, action); + irq_finalize_oneshot(desc, action, false); return ret; } @@ -851,7 +844,7 @@ void exit_irq_thread(void) wake_threads_waitq(desc); /* Prevent a stale desc->threads_oneshot */ - irq_finalize_oneshot(desc, action); + irq_finalize_oneshot(desc, action, true); } static void irq_setup_forced_threading(struct irqaction *new) diff --git a/trunk/kernel/irq/migration.c b/trunk/kernel/irq/migration.c index c3c89751b327..47420908fba0 100644 --- a/trunk/kernel/irq/migration.c +++ b/trunk/kernel/irq/migration.c @@ -43,16 +43,12 @@ void irq_move_masked_irq(struct irq_data *idata) * masking the irqs. */ if (likely(cpumask_any_and(desc->pending_mask, cpu_online_mask) - < nr_cpu_ids)) { - int ret = chip->irq_set_affinity(&desc->irq_data, - desc->pending_mask, false); - switch (ret) { - case IRQ_SET_MASK_OK: + < nr_cpu_ids)) + if (!chip->irq_set_affinity(&desc->irq_data, + desc->pending_mask, false)) { cpumask_copy(desc->irq_data.affinity, desc->pending_mask); - case IRQ_SET_MASK_OK_NOCOPY: irq_set_thread_affinity(desc); } - } cpumask_clear(desc->pending_mask); } diff --git a/trunk/kernel/irq_work.c b/trunk/kernel/irq_work.c index 1588e3b2871b..c3c46c72046e 100644 --- a/trunk/kernel/irq_work.c +++ b/trunk/kernel/irq_work.c @@ -5,13 +5,11 @@ * context. The enqueueing is NMI-safe. */ -#include #include #include #include #include #include -#include #include /* diff --git a/trunk/kernel/itimer.c b/trunk/kernel/itimer.c index 8d262b467573..22000c3db0dd 100644 --- a/trunk/kernel/itimer.c +++ b/trunk/kernel/itimer.c @@ -284,12 +284,8 @@ SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value, if (value) { if(copy_from_user(&set_buffer, value, sizeof(set_buffer))) return -EFAULT; - } else { - memset(&set_buffer, 0, sizeof(set_buffer)); - printk_once(KERN_WARNING "%s calls setitimer() with new_value NULL pointer." - " Misfeature support will be removed\n", - current->comm); - } + } else + memset((char *) &set_buffer, 0, sizeof(set_buffer)); error = do_setitimer(which, &set_buffer, ovalue ? &get_buffer : NULL); if (error || !ovalue) diff --git a/trunk/kernel/kmod.c b/trunk/kernel/kmod.c index 05698a7415fe..957a7aab8ebc 100644 --- a/trunk/kernel/kmod.c +++ b/trunk/kernel/kmod.c @@ -322,7 +322,7 @@ static void __call_usermodehelper(struct work_struct *work) * land has been frozen during a system-wide hibernation or suspend operation). * Should always be manipulated under umhelper_sem acquired for write. */ -static enum umh_disable_depth usermodehelper_disabled = UMH_DISABLED; +static int usermodehelper_disabled = 1; /* Number of helpers running */ static atomic_t running_helpers = ATOMIC_INIT(0); @@ -333,111 +333,33 @@ static atomic_t running_helpers = ATOMIC_INIT(0); */ static DECLARE_WAIT_QUEUE_HEAD(running_helpers_waitq); -/* - * Used by usermodehelper_read_lock_wait() to wait for usermodehelper_disabled - * to become 'false'. - */ -static DECLARE_WAIT_QUEUE_HEAD(usermodehelper_disabled_waitq); - /* * Time to wait for running_helpers to become zero before the setting of * usermodehelper_disabled in usermodehelper_disable() fails */ #define RUNNING_HELPERS_TIMEOUT (5 * HZ) -int usermodehelper_read_trylock(void) +void read_lock_usermodehelper(void) { - DEFINE_WAIT(wait); - int ret = 0; - down_read(&umhelper_sem); - for (;;) { - prepare_to_wait(&usermodehelper_disabled_waitq, &wait, - TASK_INTERRUPTIBLE); - if (!usermodehelper_disabled) - break; - - if (usermodehelper_disabled == UMH_DISABLED) - ret = -EAGAIN; - - up_read(&umhelper_sem); - - if (ret) - break; - - schedule(); - try_to_freeze(); - - down_read(&umhelper_sem); - } - finish_wait(&usermodehelper_disabled_waitq, &wait); - return ret; -} -EXPORT_SYMBOL_GPL(usermodehelper_read_trylock); - -long usermodehelper_read_lock_wait(long timeout) -{ - DEFINE_WAIT(wait); - - if (timeout < 0) - return -EINVAL; - - down_read(&umhelper_sem); - for (;;) { - prepare_to_wait(&usermodehelper_disabled_waitq, &wait, - TASK_UNINTERRUPTIBLE); - if (!usermodehelper_disabled) - break; - - up_read(&umhelper_sem); - - timeout = schedule_timeout(timeout); - if (!timeout) - break; - - down_read(&umhelper_sem); - } - finish_wait(&usermodehelper_disabled_waitq, &wait); - return timeout; } -EXPORT_SYMBOL_GPL(usermodehelper_read_lock_wait); +EXPORT_SYMBOL_GPL(read_lock_usermodehelper); -void usermodehelper_read_unlock(void) +void read_unlock_usermodehelper(void) { up_read(&umhelper_sem); } -EXPORT_SYMBOL_GPL(usermodehelper_read_unlock); +EXPORT_SYMBOL_GPL(read_unlock_usermodehelper); /** - * __usermodehelper_set_disable_depth - Modify usermodehelper_disabled. - * depth: New value to assign to usermodehelper_disabled. - * - * Change the value of usermodehelper_disabled (under umhelper_sem locked for - * writing) and wakeup tasks waiting for it to change. + * usermodehelper_disable - prevent new helpers from being started */ -void __usermodehelper_set_disable_depth(enum umh_disable_depth depth) -{ - down_write(&umhelper_sem); - usermodehelper_disabled = depth; - wake_up(&usermodehelper_disabled_waitq); - up_write(&umhelper_sem); -} - -/** - * __usermodehelper_disable - Prevent new helpers from being started. - * @depth: New value to assign to usermodehelper_disabled. - * - * Set usermodehelper_disabled to @depth and wait for running helpers to exit. - */ -int __usermodehelper_disable(enum umh_disable_depth depth) +int usermodehelper_disable(void) { long retval; - if (!depth) - return -EINVAL; - down_write(&umhelper_sem); - usermodehelper_disabled = depth; + usermodehelper_disabled = 1; up_write(&umhelper_sem); /* @@ -452,10 +374,31 @@ int __usermodehelper_disable(enum umh_disable_depth depth) if (retval) return 0; - __usermodehelper_set_disable_depth(UMH_ENABLED); + down_write(&umhelper_sem); + usermodehelper_disabled = 0; + up_write(&umhelper_sem); return -EAGAIN; } +/** + * usermodehelper_enable - allow new helpers to be started again + */ +void usermodehelper_enable(void) +{ + down_write(&umhelper_sem); + usermodehelper_disabled = 0; + up_write(&umhelper_sem); +} + +/** + * usermodehelper_is_disabled - check if new helpers are allowed to be started + */ +bool usermodehelper_is_disabled(void) +{ + return usermodehelper_disabled; +} +EXPORT_SYMBOL_GPL(usermodehelper_is_disabled); + static void helper_lock(void) { atomic_inc(&running_helpers); diff --git a/trunk/kernel/padata.c b/trunk/kernel/padata.c index 89fe3d1b9efb..6f10eb285ece 100644 --- a/trunk/kernel/padata.c +++ b/trunk/kernel/padata.c @@ -1,8 +1,6 @@ /* * padata.c - generic interface to process data streams in parallel * - * See Documentation/padata.txt for an api documentation. - * * Copyright (C) 2008, 2009 secunet Security Networks AG * Copyright (C) 2008, 2009 Steffen Klassert * @@ -356,13 +354,13 @@ static int padata_setup_cpumasks(struct parallel_data *pd, if (!alloc_cpumask_var(&pd->cpumask.pcpu, GFP_KERNEL)) return -ENOMEM; - cpumask_and(pd->cpumask.pcpu, pcpumask, cpu_online_mask); + cpumask_and(pd->cpumask.pcpu, pcpumask, cpu_active_mask); if (!alloc_cpumask_var(&pd->cpumask.cbcpu, GFP_KERNEL)) { free_cpumask_var(pd->cpumask.cbcpu); return -ENOMEM; } - cpumask_and(pd->cpumask.cbcpu, cbcpumask, cpu_online_mask); + cpumask_and(pd->cpumask.cbcpu, cbcpumask, cpu_active_mask); return 0; } @@ -566,7 +564,7 @@ EXPORT_SYMBOL(padata_unregister_cpumask_notifier); static bool padata_validate_cpumask(struct padata_instance *pinst, const struct cpumask *cpumask) { - if (!cpumask_intersects(cpumask, cpu_online_mask)) { + if (!cpumask_intersects(cpumask, cpu_active_mask)) { pinst->flags |= PADATA_INVALID; return false; } @@ -680,7 +678,7 @@ static int __padata_add_cpu(struct padata_instance *pinst, int cpu) { struct parallel_data *pd; - if (cpumask_test_cpu(cpu, cpu_online_mask)) { + if (cpumask_test_cpu(cpu, cpu_active_mask)) { pd = padata_alloc_pd(pinst, pinst->cpumask.pcpu, pinst->cpumask.cbcpu); if (!pd) @@ -748,9 +746,6 @@ static int __padata_remove_cpu(struct padata_instance *pinst, int cpu) return -ENOMEM; padata_replace(pinst, pd); - - cpumask_clear_cpu(cpu, pd->cpumask.cbcpu); - cpumask_clear_cpu(cpu, pd->cpumask.pcpu); } return 0; diff --git a/trunk/kernel/panic.c b/trunk/kernel/panic.c index 8ed89a175d79..80aed44e345a 100644 --- a/trunk/kernel/panic.c +++ b/trunk/kernel/panic.c @@ -97,7 +97,7 @@ void panic(const char *fmt, ...) /* * Avoid nested stack-dumping if a panic occurs during oops processing */ - if (!test_taint(TAINT_DIE) && oops_in_progress <= 1) + if (!oops_in_progress) dump_stack(); #endif diff --git a/trunk/kernel/power/hibernate.c b/trunk/kernel/power/hibernate.c index e09dfbfeecee..0a186cfde788 100644 --- a/trunk/kernel/power/hibernate.c +++ b/trunk/kernel/power/hibernate.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -610,10 +611,14 @@ int hibernate(void) if (error) goto Exit; + error = usermodehelper_disable(); + if (error) + goto Exit; + /* Allocate memory management structures */ error = create_basic_memory_bitmaps(); if (error) - goto Exit; + goto Enable_umh; printk(KERN_INFO "PM: Syncing filesystems ... "); sys_sync(); @@ -656,6 +661,8 @@ int hibernate(void) Free_bitmaps: free_basic_memory_bitmaps(); + Enable_umh: + usermodehelper_enable(); Exit: pm_notifier_call_chain(PM_POST_HIBERNATION); pm_restore_console(); @@ -770,10 +777,16 @@ static int software_resume(void) if (error) goto close_finish; - error = create_basic_memory_bitmaps(); + error = usermodehelper_disable(); if (error) goto close_finish; + error = create_basic_memory_bitmaps(); + if (error) { + usermodehelper_enable(); + goto close_finish; + } + pr_debug("PM: Preparing processes for restore.\n"); error = freeze_processes(); if (error) { @@ -793,6 +806,7 @@ static int software_resume(void) thaw_processes(); Done: free_basic_memory_bitmaps(); + usermodehelper_enable(); Finish: pm_notifier_call_chain(PM_POST_RESTORE); pm_restore_console(); diff --git a/trunk/kernel/power/process.c b/trunk/kernel/power/process.c index 19db29f67558..0d2aeb226108 100644 --- a/trunk/kernel/power/process.c +++ b/trunk/kernel/power/process.c @@ -16,7 +16,6 @@ #include #include #include -#include /* * Timeout for stopping processes @@ -123,10 +122,6 @@ int freeze_processes(void) { int error; - error = __usermodehelper_disable(UMH_FREEZING); - if (error) - return error; - if (!pm_freezing) atomic_inc(&system_freezing_cnt); @@ -135,7 +130,6 @@ int freeze_processes(void) error = try_to_freeze_tasks(true); if (!error) { printk("done."); - __usermodehelper_set_disable_depth(UMH_DISABLED); oom_killer_disable(); } printk("\n"); @@ -193,8 +187,6 @@ void thaw_processes(void) } while_each_thread(g, p); read_unlock(&tasklist_lock); - usermodehelper_enable(); - schedule(); printk("done.\n"); } diff --git a/trunk/kernel/power/qos.c b/trunk/kernel/power/qos.c index 6a031e684026..d6d6dbd1ecc0 100644 --- a/trunk/kernel/power/qos.c +++ b/trunk/kernel/power/qos.c @@ -229,21 +229,6 @@ int pm_qos_request_active(struct pm_qos_request *req) } EXPORT_SYMBOL_GPL(pm_qos_request_active); -/** - * pm_qos_work_fn - the timeout handler of pm_qos_update_request_timeout - * @work: work struct for the delayed work (timeout) - * - * This cancels the timeout request by falling back to the default at timeout. - */ -static void pm_qos_work_fn(struct work_struct *work) -{ - struct pm_qos_request *req = container_of(to_delayed_work(work), - struct pm_qos_request, - work); - - pm_qos_update_request(req, PM_QOS_DEFAULT_VALUE); -} - /** * pm_qos_add_request - inserts new qos request into the list * @req: pointer to a preallocated handle @@ -268,7 +253,6 @@ void pm_qos_add_request(struct pm_qos_request *req, return; } req->pm_qos_class = pm_qos_class; - INIT_DELAYED_WORK(&req->work, pm_qos_work_fn); pm_qos_update_target(pm_qos_array[pm_qos_class]->constraints, &req->node, PM_QOS_ADD_REQ, value); } @@ -295,9 +279,6 @@ void pm_qos_update_request(struct pm_qos_request *req, return; } - if (delayed_work_pending(&req->work)) - cancel_delayed_work_sync(&req->work); - if (new_value != req->node.prio) pm_qos_update_target( pm_qos_array[req->pm_qos_class]->constraints, @@ -305,34 +286,6 @@ void pm_qos_update_request(struct pm_qos_request *req, } EXPORT_SYMBOL_GPL(pm_qos_update_request); -/** - * pm_qos_update_request_timeout - modifies an existing qos request temporarily. - * @req : handle to list element holding a pm_qos request to use - * @new_value: defines the temporal qos request - * @timeout_us: the effective duration of this qos request in usecs. - * - * After timeout_us, this qos request is cancelled automatically. - */ -void pm_qos_update_request_timeout(struct pm_qos_request *req, s32 new_value, - unsigned long timeout_us) -{ - if (!req) - return; - if (WARN(!pm_qos_request_active(req), - "%s called for unknown object.", __func__)) - return; - - if (delayed_work_pending(&req->work)) - cancel_delayed_work_sync(&req->work); - - if (new_value != req->node.prio) - pm_qos_update_target( - pm_qos_array[req->pm_qos_class]->constraints, - &req->node, PM_QOS_UPDATE_REQ, new_value); - - schedule_delayed_work(&req->work, usecs_to_jiffies(timeout_us)); -} - /** * pm_qos_remove_request - modifies an existing qos request * @req: handle to request list element @@ -352,9 +305,6 @@ void pm_qos_remove_request(struct pm_qos_request *req) return; } - if (delayed_work_pending(&req->work)) - cancel_delayed_work_sync(&req->work); - pm_qos_update_target(pm_qos_array[req->pm_qos_class]->constraints, &req->node, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); diff --git a/trunk/kernel/power/suspend.c b/trunk/kernel/power/suspend.c index 396d262b8fd0..88e5c967370d 100644 --- a/trunk/kernel/power/suspend.c +++ b/trunk/kernel/power/suspend.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -101,12 +102,17 @@ static int suspend_prepare(void) if (error) goto Finish; + error = usermodehelper_disable(); + if (error) + goto Finish; + error = suspend_freeze_processes(); if (!error) return 0; suspend_stats.failed_freeze++; dpm_save_failed_step(SUSPEND_FREEZE); + usermodehelper_enable(); Finish: pm_notifier_call_chain(PM_POST_SUSPEND); pm_restore_console(); @@ -253,6 +259,7 @@ int suspend_devices_and_enter(suspend_state_t state) static void suspend_finish(void) { suspend_thaw_processes(); + usermodehelper_enable(); pm_notifier_call_chain(PM_POST_SUSPEND); pm_restore_console(); } diff --git a/trunk/kernel/power/swap.c b/trunk/kernel/power/swap.c index eef311a58a64..8742fd013a94 100644 --- a/trunk/kernel/power/swap.c +++ b/trunk/kernel/power/swap.c @@ -51,23 +51,6 @@ #define MAP_PAGE_ENTRIES (PAGE_SIZE / sizeof(sector_t) - 1) -/* - * Number of free pages that are not high. - */ -static inline unsigned long low_free_pages(void) -{ - return nr_free_pages() - nr_free_highpages(); -} - -/* - * Number of pages required to be kept free while writing the image. Always - * half of all available low pages before the writing starts. - */ -static inline unsigned long reqd_free_pages(void) -{ - return low_free_pages() / 2; -} - struct swap_map_page { sector_t entries[MAP_PAGE_ENTRIES]; sector_t next_swap; @@ -89,7 +72,7 @@ struct swap_map_handle { sector_t cur_swap; sector_t first_sector; unsigned int k; - unsigned long reqd_free_pages; + unsigned long nr_free_pages, written; u32 crc32; }; @@ -333,7 +316,8 @@ static int get_swap_writer(struct swap_map_handle *handle) goto err_rel; } handle->k = 0; - handle->reqd_free_pages = reqd_free_pages(); + handle->nr_free_pages = nr_free_pages() >> 1; + handle->written = 0; handle->first_sector = handle->cur_swap; return 0; err_rel: @@ -368,11 +352,11 @@ static int swap_write_page(struct swap_map_handle *handle, void *buf, handle->cur_swap = offset; handle->k = 0; } - if (bio_chain && low_free_pages() <= handle->reqd_free_pages) { + if (bio_chain && ++handle->written > handle->nr_free_pages) { error = hib_wait_on_bio_chain(bio_chain); if (error) goto out; - handle->reqd_free_pages = reqd_free_pages(); + handle->written = 0; } out: return error; @@ -634,7 +618,7 @@ static int save_image_lzo(struct swap_map_handle *handle, * Adjust number of free pages after all allocations have been done. * We don't want to run out of pages when writing. */ - handle->reqd_free_pages = reqd_free_pages(); + handle->nr_free_pages = nr_free_pages() >> 1; /* * Start the CRC32 thread. diff --git a/trunk/kernel/power/user.c b/trunk/kernel/power/user.c index 91b0fd021a95..33c4329205af 100644 --- a/trunk/kernel/power/user.c +++ b/trunk/kernel/power/user.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -221,8 +222,14 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, sys_sync(); printk("done.\n"); + error = usermodehelper_disable(); + if (error) + break; + error = freeze_processes(); - if (!error) + if (error) + usermodehelper_enable(); + else data->frozen = 1; break; @@ -231,6 +238,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, break; pm_restore_gfp_mask(); thaw_processes(); + usermodehelper_enable(); data->frozen = 0; break; diff --git a/trunk/kernel/rcutree.c b/trunk/kernel/rcutree.c index d0c5baf1ab18..1050d6d3922c 100644 --- a/trunk/kernel/rcutree.c +++ b/trunk/kernel/rcutree.c @@ -1820,6 +1820,7 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu), * a quiescent state betweentimes. */ local_irq_save(flags); + WARN_ON_ONCE(cpu_is_offline(smp_processor_id())); rdp = this_cpu_ptr(rsp->rda); /* Add the callback to our list. */ diff --git a/trunk/kernel/sched/core.c b/trunk/kernel/sched/core.c index 0533a688ce22..e3ed0ecee7c7 100644 --- a/trunk/kernel/sched/core.c +++ b/trunk/kernel/sched/core.c @@ -1270,7 +1270,7 @@ static int select_fallback_rq(int cpu, struct task_struct *p) int dest_cpu; /* Look for allowed, online CPU in same node. */ - for_each_cpu(dest_cpu, nodemask) { + for_each_cpu_mask(dest_cpu, *nodemask) { if (!cpu_online(dest_cpu)) continue; if (!cpu_active(dest_cpu)) @@ -1281,7 +1281,7 @@ static int select_fallback_rq(int cpu, struct task_struct *p) for (;;) { /* Any allowed, online CPU? */ - for_each_cpu(dest_cpu, tsk_cpus_allowed(p)) { + for_each_cpu_mask(dest_cpu, *tsk_cpus_allowed(p)) { if (!cpu_online(dest_cpu)) continue; if (!cpu_active(dest_cpu)) @@ -1964,7 +1964,6 @@ static void finish_task_switch(struct rq *rq, struct task_struct *prev) local_irq_enable(); #endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */ finish_lock_switch(rq, prev); - finish_arch_post_lock_switch(); fire_sched_in_preempt_notifiers(current); if (mm) @@ -3102,6 +3101,8 @@ EXPORT_SYMBOL(sub_preempt_count); */ static noinline void __schedule_bug(struct task_struct *prev) { + struct pt_regs *regs = get_irq_regs(); + if (oops_in_progress) return; @@ -3112,7 +3113,11 @@ static noinline void __schedule_bug(struct task_struct *prev) print_modules(); if (irqs_disabled()) print_irqtrace_events(prev); - dump_stack(); + + if (regs) + show_regs(regs); + else + dump_stack(); } /* @@ -6405,26 +6410,16 @@ static void __sdt_free(const struct cpumask *cpu_map) struct sd_data *sdd = &tl->data; for_each_cpu(j, cpu_map) { - struct sched_domain *sd; - - if (sdd->sd) { - sd = *per_cpu_ptr(sdd->sd, j); - if (sd && (sd->flags & SD_OVERLAP)) - free_sched_groups(sd->groups, 0); - kfree(*per_cpu_ptr(sdd->sd, j)); - } - - if (sdd->sg) - kfree(*per_cpu_ptr(sdd->sg, j)); - if (sdd->sgp) - kfree(*per_cpu_ptr(sdd->sgp, j)); + struct sched_domain *sd = *per_cpu_ptr(sdd->sd, j); + if (sd && (sd->flags & SD_OVERLAP)) + free_sched_groups(sd->groups, 0); + kfree(*per_cpu_ptr(sdd->sd, j)); + kfree(*per_cpu_ptr(sdd->sg, j)); + kfree(*per_cpu_ptr(sdd->sgp, j)); } free_percpu(sdd->sd); - sdd->sd = NULL; free_percpu(sdd->sg); - sdd->sg = NULL; free_percpu(sdd->sgp); - sdd->sgp = NULL; } } diff --git a/trunk/kernel/sched/fair.c b/trunk/kernel/sched/fair.c index e9553640c1c3..0d97ebdc58f0 100644 --- a/trunk/kernel/sched/fair.c +++ b/trunk/kernel/sched/fair.c @@ -784,7 +784,7 @@ account_entity_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se) update_load_add(&rq_of(cfs_rq)->load, se->load.weight); #ifdef CONFIG_SMP if (entity_is_task(se)) - list_add(&se->group_node, &rq_of(cfs_rq)->cfs_tasks); + list_add_tail(&se->group_node, &rq_of(cfs_rq)->cfs_tasks); #endif cfs_rq->nr_running++; } @@ -3215,8 +3215,6 @@ static int move_one_task(struct lb_env *env) static unsigned long task_h_load(struct task_struct *p); -static const unsigned int sched_nr_migrate_break = 32; - /* * move_tasks tries to move up to load_move weighted load from busiest to * this_rq, as part of a balancing operation within domain "sd". @@ -3244,7 +3242,7 @@ static int move_tasks(struct lb_env *env) /* take a breather every nr_migrate tasks */ if (env->loop > env->loop_break) { - env->loop_break += sched_nr_migrate_break; + env->loop_break += sysctl_sched_nr_migrate; env->flags |= LBF_NEED_BREAK; break; } @@ -3254,7 +3252,7 @@ static int move_tasks(struct lb_env *env) load = task_h_load(p); - if (sched_feat(LB_MIN) && load < 16 && !env->sd->nr_balance_failed) + if (load < 16 && !env->sd->nr_balance_failed) goto next; if ((load / 2) > env->load_move) @@ -4409,7 +4407,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, .dst_cpu = this_cpu, .dst_rq = this_rq, .idle = idle, - .loop_break = sched_nr_migrate_break, + .loop_break = sysctl_sched_nr_migrate, }; cpumask_copy(cpus, cpu_active_mask); @@ -4447,10 +4445,10 @@ static int load_balance(int this_cpu, struct rq *this_rq, * correctly treated as an imbalance. */ env.flags |= LBF_ALL_PINNED; - env.load_move = imbalance; - env.src_cpu = busiest->cpu; - env.src_rq = busiest; - env.loop_max = min_t(unsigned long, sysctl_sched_nr_migrate, busiest->nr_running); + env.load_move = imbalance; + env.src_cpu = busiest->cpu; + env.src_rq = busiest; + env.loop_max = busiest->nr_running; more_balance: local_irq_save(flags); diff --git a/trunk/kernel/sched/features.h b/trunk/kernel/sched/features.h index de00a486c5c6..e61fd73913d0 100644 --- a/trunk/kernel/sched/features.h +++ b/trunk/kernel/sched/features.h @@ -68,4 +68,3 @@ SCHED_FEAT(TTWU_QUEUE, true) SCHED_FEAT(FORCE_SD_OVERLAP, false) SCHED_FEAT(RT_RUNTIME_SHARE, true) -SCHED_FEAT(LB_MIN, false) diff --git a/trunk/kernel/sched/sched.h b/trunk/kernel/sched/sched.h index fb3acba4d52e..42b1f304b044 100644 --- a/trunk/kernel/sched/sched.h +++ b/trunk/kernel/sched/sched.h @@ -681,9 +681,6 @@ static inline int task_running(struct rq *rq, struct task_struct *p) #ifndef finish_arch_switch # define finish_arch_switch(prev) do { } while (0) #endif -#ifndef finish_arch_post_lock_switch -# define finish_arch_post_lock_switch() do { } while (0) -#endif #ifndef __ARCH_WANT_UNLOCKED_CTXSW static inline void prepare_lock_switch(struct rq *rq, struct task_struct *next) diff --git a/trunk/kernel/sysctl.c b/trunk/kernel/sysctl.c index 4ab11879aeb4..52b3a06a02f8 100644 --- a/trunk/kernel/sysctl.c +++ b/trunk/kernel/sysctl.c @@ -170,7 +170,7 @@ static int proc_taint(struct ctl_table *table, int write, #endif #ifdef CONFIG_PRINTK -static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, +static int proc_dmesg_restrict(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); #endif @@ -703,7 +703,7 @@ static struct ctl_table kern_table[] = { .data = &dmesg_restrict, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec_minmax_sysadmin, + .proc_handler = proc_dointvec_minmax, .extra1 = &zero, .extra2 = &one, }, @@ -712,7 +712,7 @@ static struct ctl_table kern_table[] = { .data = &kptr_restrict, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec_minmax_sysadmin, + .proc_handler = proc_dmesg_restrict, .extra1 = &zero, .extra2 = &two, }, @@ -1943,7 +1943,7 @@ static int proc_taint(struct ctl_table *table, int write, } #ifdef CONFIG_PRINTK -static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, +static int proc_dmesg_restrict(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { if (write && !capable(CAP_SYS_ADMIN)) diff --git a/trunk/kernel/time/Kconfig b/trunk/kernel/time/Kconfig index a20dc8a3c949..2cf9cc7aa103 100644 --- a/trunk/kernel/time/Kconfig +++ b/trunk/kernel/time/Kconfig @@ -1,10 +1,6 @@ # # Timer subsystem related configuration options # - -# Core internal switch. Selected by NO_HZ / HIGH_RES_TIMERS. This is -# only related to the tick functionality. Oneshot clockevent devices -# are supported independ of this. config TICK_ONESHOT bool diff --git a/trunk/kernel/time/tick-broadcast.c b/trunk/kernel/time/tick-broadcast.c index f113755695e2..e883f57a3cd3 100644 --- a/trunk/kernel/time/tick-broadcast.c +++ b/trunk/kernel/time/tick-broadcast.c @@ -346,8 +346,7 @@ int tick_resume_broadcast(void) tick_get_broadcast_mask()); break; case TICKDEV_MODE_ONESHOT: - if (!cpumask_empty(tick_get_broadcast_mask())) - broadcast = tick_resume_broadcast_oneshot(bc); + broadcast = tick_resume_broadcast_oneshot(bc); break; } } @@ -374,9 +373,6 @@ static int tick_broadcast_set_event(ktime_t expires, int force) { struct clock_event_device *bc = tick_broadcast_device.evtdev; - if (bc->mode != CLOCK_EVT_MODE_ONESHOT) - clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); - return clockevents_program_event(bc, expires, force); } @@ -535,6 +531,7 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc) int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC; bc->event_handler = tick_handle_oneshot_broadcast; + clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); /* Take the do_timer update */ tick_do_timer_cpu = cpu; @@ -552,7 +549,6 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc) to_cpumask(tmpmask)); if (was_periodic && !cpumask_empty(to_cpumask(tmpmask))) { - clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); tick_broadcast_init_next_event(to_cpumask(tmpmask), tick_next_period); tick_broadcast_set_event(tick_next_period, 1); @@ -579,12 +575,15 @@ void tick_broadcast_switch_to_oneshot(void) unsigned long flags; raw_spin_lock_irqsave(&tick_broadcast_lock, flags); + if (cpumask_empty(tick_get_broadcast_mask())) + goto end; tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT; bc = tick_broadcast_device.evtdev; if (bc) tick_broadcast_setup_oneshot(bc); +end: raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); } diff --git a/trunk/kernel/time/tick-sched.c b/trunk/kernel/time/tick-sched.c index 6a3a5b9ff561..3526038f2836 100644 --- a/trunk/kernel/time/tick-sched.c +++ b/trunk/kernel/time/tick-sched.c @@ -534,9 +534,9 @@ static void tick_nohz_restart(struct tick_sched *ts, ktime_t now) hrtimer_get_expires(&ts->sched_timer), 0)) break; } - /* Reread time and update jiffies */ - now = ktime_get(); + /* Update jiffies and reread time */ tick_do_update_jiffies64(now); + now = ktime_get(); } } diff --git a/trunk/kernel/trace/Kconfig b/trunk/kernel/trace/Kconfig index a1d2849f2473..cd3134510f3d 100644 --- a/trunk/kernel/trace/Kconfig +++ b/trunk/kernel/trace/Kconfig @@ -141,7 +141,7 @@ if FTRACE config FUNCTION_TRACER bool "Kernel Function Tracer" depends on HAVE_FUNCTION_TRACER - select FRAME_POINTER if !ARM_UNWIND && !PPC && !S390 && !MICROBLAZE + select FRAME_POINTER if !ARM_UNWIND && !S390 && !MICROBLAZE select KALLSYMS select GENERIC_TRACER select CONTEXT_SWITCH_TRACER diff --git a/trunk/kernel/trace/blktrace.c b/trunk/kernel/trace/blktrace.c index c0bd0308741c..cdea7b56b0c9 100644 --- a/trunk/kernel/trace/blktrace.c +++ b/trunk/kernel/trace/blktrace.c @@ -311,6 +311,13 @@ int blk_trace_remove(struct request_queue *q) } EXPORT_SYMBOL_GPL(blk_trace_remove); +static int blk_dropped_open(struct inode *inode, struct file *filp) +{ + filp->private_data = inode->i_private; + + return 0; +} + static ssize_t blk_dropped_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos) { @@ -324,11 +331,18 @@ static ssize_t blk_dropped_read(struct file *filp, char __user *buffer, static const struct file_operations blk_dropped_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = blk_dropped_open, .read = blk_dropped_read, .llseek = default_llseek, }; +static int blk_msg_open(struct inode *inode, struct file *filp) +{ + filp->private_data = inode->i_private; + + return 0; +} + static ssize_t blk_msg_write(struct file *filp, const char __user *buffer, size_t count, loff_t *ppos) { @@ -357,7 +371,7 @@ static ssize_t blk_msg_write(struct file *filp, const char __user *buffer, static const struct file_operations blk_msg_fops = { .owner = THIS_MODULE, - .open = simple_open, + .open = blk_msg_open, .write = blk_msg_write, .llseek = noop_llseek, }; diff --git a/trunk/kernel/trace/ftrace.c b/trunk/kernel/trace/ftrace.c index 0fa92f677c92..867bd1dd2dd0 100644 --- a/trunk/kernel/trace/ftrace.c +++ b/trunk/kernel/trace/ftrace.c @@ -249,8 +249,7 @@ static void update_ftrace_function(void) #else __ftrace_trace_function = func; #endif - ftrace_trace_function = - (func == ftrace_stub) ? func : ftrace_test_stop_func; + ftrace_trace_function = ftrace_test_stop_func; #endif } diff --git a/trunk/kernel/trace/ring_buffer.c b/trunk/kernel/trace/ring_buffer.c index cf8d11e91efd..f5b7b5c1195b 100644 --- a/trunk/kernel/trace/ring_buffer.c +++ b/trunk/kernel/trace/ring_buffer.c @@ -154,11 +154,34 @@ enum { static unsigned long ring_buffer_flags __read_mostly = RB_BUFFERS_ON; -/* Used for individual buffers (after the counter) */ -#define RB_BUFFER_OFF (1 << 20) - #define BUF_PAGE_HDR_SIZE offsetof(struct buffer_data_page, data) +/** + * tracing_on - enable all tracing buffers + * + * This function enables all tracing buffers that may have been + * disabled with tracing_off. + */ +void tracing_on(void) +{ + set_bit(RB_BUFFERS_ON_BIT, &ring_buffer_flags); +} +EXPORT_SYMBOL_GPL(tracing_on); + +/** + * tracing_off - turn off all tracing buffers + * + * This function stops all tracing buffers from recording data. + * It does not disable any overhead the tracers themselves may + * be causing. This function simply causes all recording to + * the ring buffers to fail. + */ +void tracing_off(void) +{ + clear_bit(RB_BUFFERS_ON_BIT, &ring_buffer_flags); +} +EXPORT_SYMBOL_GPL(tracing_off); + /** * tracing_off_permanent - permanently disable ring buffers * @@ -170,6 +193,15 @@ void tracing_off_permanent(void) set_bit(RB_BUFFERS_DISABLED_BIT, &ring_buffer_flags); } +/** + * tracing_is_on - show state of ring buffers enabled + */ +int tracing_is_on(void) +{ + return ring_buffer_flags == RB_BUFFERS_ON; +} +EXPORT_SYMBOL_GPL(tracing_is_on); + #define RB_EVNT_HDR_SIZE (offsetof(struct ring_buffer_event, array)) #define RB_ALIGNMENT 4U #define RB_MAX_SMALL_DATA (RB_ALIGNMENT * RINGBUF_TYPE_DATA_TYPE_LEN_MAX) @@ -2586,63 +2618,6 @@ void ring_buffer_record_enable(struct ring_buffer *buffer) } EXPORT_SYMBOL_GPL(ring_buffer_record_enable); -/** - * ring_buffer_record_off - stop all writes into the buffer - * @buffer: The ring buffer to stop writes to. - * - * This prevents all writes to the buffer. Any attempt to write - * to the buffer after this will fail and return NULL. - * - * This is different than ring_buffer_record_disable() as - * it works like an on/off switch, where as the disable() verison - * must be paired with a enable(). - */ -void ring_buffer_record_off(struct ring_buffer *buffer) -{ - unsigned int rd; - unsigned int new_rd; - - do { - rd = atomic_read(&buffer->record_disabled); - new_rd = rd | RB_BUFFER_OFF; - } while (atomic_cmpxchg(&buffer->record_disabled, rd, new_rd) != rd); -} -EXPORT_SYMBOL_GPL(ring_buffer_record_off); - -/** - * ring_buffer_record_on - restart writes into the buffer - * @buffer: The ring buffer to start writes to. - * - * This enables all writes to the buffer that was disabled by - * ring_buffer_record_off(). - * - * This is different than ring_buffer_record_enable() as - * it works like an on/off switch, where as the enable() verison - * must be paired with a disable(). - */ -void ring_buffer_record_on(struct ring_buffer *buffer) -{ - unsigned int rd; - unsigned int new_rd; - - do { - rd = atomic_read(&buffer->record_disabled); - new_rd = rd & ~RB_BUFFER_OFF; - } while (atomic_cmpxchg(&buffer->record_disabled, rd, new_rd) != rd); -} -EXPORT_SYMBOL_GPL(ring_buffer_record_on); - -/** - * ring_buffer_record_is_on - return true if the ring buffer can write - * @buffer: The ring buffer to see if write is enabled - * - * Returns true if the ring buffer is in a state that it accepts writes. - */ -int ring_buffer_record_is_on(struct ring_buffer *buffer) -{ - return !atomic_read(&buffer->record_disabled); -} - /** * ring_buffer_record_disable_cpu - stop all writes into the cpu_buffer * @buffer: The ring buffer to stop writes to. @@ -4064,6 +4039,68 @@ int ring_buffer_read_page(struct ring_buffer *buffer, } EXPORT_SYMBOL_GPL(ring_buffer_read_page); +#ifdef CONFIG_TRACING +static ssize_t +rb_simple_read(struct file *filp, char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + unsigned long *p = filp->private_data; + char buf[64]; + int r; + + if (test_bit(RB_BUFFERS_DISABLED_BIT, p)) + r = sprintf(buf, "permanently disabled\n"); + else + r = sprintf(buf, "%d\n", test_bit(RB_BUFFERS_ON_BIT, p)); + + return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); +} + +static ssize_t +rb_simple_write(struct file *filp, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + unsigned long *p = filp->private_data; + unsigned long val; + int ret; + + ret = kstrtoul_from_user(ubuf, cnt, 10, &val); + if (ret) + return ret; + + if (val) + set_bit(RB_BUFFERS_ON_BIT, p); + else + clear_bit(RB_BUFFERS_ON_BIT, p); + + (*ppos)++; + + return cnt; +} + +static const struct file_operations rb_simple_fops = { + .open = tracing_open_generic, + .read = rb_simple_read, + .write = rb_simple_write, + .llseek = default_llseek, +}; + + +static __init int rb_init_debugfs(void) +{ + struct dentry *d_tracer; + + d_tracer = tracing_init_dentry(); + + trace_create_file("tracing_on", 0644, d_tracer, + &ring_buffer_flags, &rb_simple_fops); + + return 0; +} + +fs_initcall(rb_init_debugfs); +#endif + #ifdef CONFIG_HOTPLUG_CPU static int rb_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) diff --git a/trunk/kernel/trace/trace.c b/trunk/kernel/trace/trace.c index 2a22255c1010..10d5503f0d04 100644 --- a/trunk/kernel/trace/trace.c +++ b/trunk/kernel/trace/trace.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include "trace.h" @@ -352,59 +351,6 @@ static void wakeup_work_handler(struct work_struct *work) static DECLARE_DELAYED_WORK(wakeup_work, wakeup_work_handler); -/** - * tracing_on - enable tracing buffers - * - * This function enables tracing buffers that may have been - * disabled with tracing_off. - */ -void tracing_on(void) -{ - if (global_trace.buffer) - ring_buffer_record_on(global_trace.buffer); - /* - * This flag is only looked at when buffers haven't been - * allocated yet. We don't really care about the race - * between setting this flag and actually turning - * on the buffer. - */ - global_trace.buffer_disabled = 0; -} -EXPORT_SYMBOL_GPL(tracing_on); - -/** - * tracing_off - turn off tracing buffers - * - * This function stops the tracing buffers from recording data. - * It does not disable any overhead the tracers themselves may - * be causing. This function simply causes all recording to - * the ring buffers to fail. - */ -void tracing_off(void) -{ - if (global_trace.buffer) - ring_buffer_record_on(global_trace.buffer); - /* - * This flag is only looked at when buffers haven't been - * allocated yet. We don't really care about the race - * between setting this flag and actually turning - * on the buffer. - */ - global_trace.buffer_disabled = 1; -} -EXPORT_SYMBOL_GPL(tracing_off); - -/** - * tracing_is_on - show state of ring buffers enabled - */ -int tracing_is_on(void) -{ - if (global_trace.buffer) - return ring_buffer_record_is_on(global_trace.buffer); - return !global_trace.buffer_disabled; -} -EXPORT_SYMBOL_GPL(tracing_is_on); - /** * trace_wake_up - wake up tasks waiting for trace input * @@ -1698,7 +1644,6 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, int cpu_file = iter->cpu_file; u64 next_ts = 0, ts; int next_cpu = -1; - int next_size = 0; int cpu; /* @@ -1730,12 +1675,9 @@ __find_next_entry(struct trace_iterator *iter, int *ent_cpu, next_cpu = cpu; next_ts = ts; next_lost = lost_events; - next_size = iter->ent_size; } } - iter->ent_size = next_size; - if (ent_cpu) *ent_cpu = next_cpu; @@ -4625,57 +4567,6 @@ static __init void create_trace_options_dir(void) create_trace_option_core_file(trace_options[i], i); } -static ssize_t -rb_simple_read(struct file *filp, char __user *ubuf, - size_t cnt, loff_t *ppos) -{ - struct trace_array *tr = filp->private_data; - struct ring_buffer *buffer = tr->buffer; - char buf[64]; - int r; - - if (buffer) - r = ring_buffer_record_is_on(buffer); - else - r = 0; - - r = sprintf(buf, "%d\n", r); - - return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); -} - -static ssize_t -rb_simple_write(struct file *filp, const char __user *ubuf, - size_t cnt, loff_t *ppos) -{ - struct trace_array *tr = filp->private_data; - struct ring_buffer *buffer = tr->buffer; - unsigned long val; - int ret; - - ret = kstrtoul_from_user(ubuf, cnt, 10, &val); - if (ret) - return ret; - - if (buffer) { - if (val) - ring_buffer_record_on(buffer); - else - ring_buffer_record_off(buffer); - } - - (*ppos)++; - - return cnt; -} - -static const struct file_operations rb_simple_fops = { - .open = tracing_open_generic, - .read = rb_simple_read, - .write = rb_simple_write, - .llseek = default_llseek, -}; - static __init int tracer_init_debugfs(void) { struct dentry *d_tracer; @@ -4735,9 +4626,6 @@ static __init int tracer_init_debugfs(void) trace_create_file("trace_clock", 0644, d_tracer, NULL, &trace_clock_fops); - trace_create_file("tracing_on", 0644, d_tracer, - &global_trace, &rb_simple_fops); - #ifdef CONFIG_DYNAMIC_FTRACE trace_create_file("dyn_ftrace_total_info", 0444, d_tracer, &ftrace_update_tot_cnt, &tracing_dyn_info_fops); @@ -4910,7 +4798,6 @@ __ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode) if (ret != TRACE_TYPE_NO_CONSUME) trace_consume(&iter); } - touch_nmi_watchdog(); trace_printk_seq(&iter.seq); } @@ -4976,8 +4863,6 @@ __init static int tracer_alloc_buffers(void) goto out_free_cpumask; } global_trace.entries = ring_buffer_size(global_trace.buffer); - if (global_trace.buffer_disabled) - tracing_off(); #ifdef CONFIG_TRACER_MAX_TRACE diff --git a/trunk/kernel/trace/trace.h b/trunk/kernel/trace/trace.h index f95d65da6db8..54faec790bc1 100644 --- a/trunk/kernel/trace/trace.h +++ b/trunk/kernel/trace/trace.h @@ -154,7 +154,6 @@ struct trace_array { struct ring_buffer *buffer; unsigned long entries; int cpu; - int buffer_disabled; cycle_t time_start; struct task_struct *waiter; struct trace_array_cpu *data[NR_CPUS]; @@ -836,11 +835,13 @@ extern const char *__stop___trace_bprintk_fmt[]; filter) #include "trace_entries.h" -#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_FUNCTION_TRACER) +#ifdef CONFIG_PERF_EVENTS +#ifdef CONFIG_FUNCTION_TRACER int perf_ftrace_event_register(struct ftrace_event_call *call, enum trace_reg type, void *data); #else #define perf_ftrace_event_register NULL -#endif +#endif /* CONFIG_FUNCTION_TRACER */ +#endif /* CONFIG_PERF_EVENTS */ #endif /* _LINUX_KERNEL_TRACE_H */ diff --git a/trunk/kernel/trace/trace_entries.h b/trunk/kernel/trace/trace_entries.h index 4108e1250ca2..d91eb0541b3a 100644 --- a/trunk/kernel/trace/trace_entries.h +++ b/trunk/kernel/trace/trace_entries.h @@ -166,12 +166,6 @@ FTRACE_ENTRY_DUP(wakeup, ctx_switch_entry, #define FTRACE_STACK_ENTRIES 8 -#ifndef CONFIG_64BIT -# define IP_FMT "%08lx" -#else -# define IP_FMT "%016lx" -#endif - FTRACE_ENTRY(kernel_stack, stack_entry, TRACE_STACK, @@ -181,9 +175,8 @@ FTRACE_ENTRY(kernel_stack, stack_entry, __dynamic_array(unsigned long, caller ) ), - F_printk("\t=> (" IP_FMT ")\n\t=> (" IP_FMT ")\n\t=> (" IP_FMT ")\n" - "\t=> (" IP_FMT ")\n\t=> (" IP_FMT ")\n\t=> (" IP_FMT ")\n" - "\t=> (" IP_FMT ")\n\t=> (" IP_FMT ")\n", + F_printk("\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n" + "\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n", __entry->caller[0], __entry->caller[1], __entry->caller[2], __entry->caller[3], __entry->caller[4], __entry->caller[5], __entry->caller[6], __entry->caller[7]), @@ -200,9 +193,8 @@ FTRACE_ENTRY(user_stack, userstack_entry, __array( unsigned long, caller, FTRACE_STACK_ENTRIES ) ), - F_printk("\t=> (" IP_FMT ")\n\t=> (" IP_FMT ")\n\t=> (" IP_FMT ")\n" - "\t=> (" IP_FMT ")\n\t=> (" IP_FMT ")\n\t=> (" IP_FMT ")\n" - "\t=> (" IP_FMT ")\n\t=> (" IP_FMT ")\n", + F_printk("\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n" + "\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n", __entry->caller[0], __entry->caller[1], __entry->caller[2], __entry->caller[3], __entry->caller[4], __entry->caller[5], __entry->caller[6], __entry->caller[7]), diff --git a/trunk/kernel/trace/trace_export.c b/trunk/kernel/trace/trace_export.c index 3dd15e8bc856..7b46c9bd22ae 100644 --- a/trunk/kernel/trace/trace_export.c +++ b/trunk/kernel/trace/trace_export.c @@ -162,7 +162,7 @@ ftrace_define_fields_##name(struct ftrace_event_call *event_call) \ #define __dynamic_array(type, item) #undef F_printk -#define F_printk(fmt, args...) __stringify(fmt) ", " __stringify(args) +#define F_printk(fmt, args...) #fmt ", " __stringify(args) #undef FTRACE_ENTRY_REG #define FTRACE_ENTRY_REG(call, struct_name, etype, tstruct, print, filter,\ diff --git a/trunk/kernel/trace/trace_output.c b/trunk/kernel/trace/trace_output.c index df611a0e76c5..859fae6b1825 100644 --- a/trunk/kernel/trace/trace_output.c +++ b/trunk/kernel/trace/trace_output.c @@ -652,8 +652,6 @@ int trace_print_lat_context(struct trace_iterator *iter) { u64 next_ts; int ret; - /* trace_find_next_entry will reset ent_size */ - int ent_size = iter->ent_size; struct trace_seq *s = &iter->seq; struct trace_entry *entry = iter->ent, *next_entry = trace_find_next_entry(iter, NULL, @@ -662,9 +660,6 @@ int trace_print_lat_context(struct trace_iterator *iter) unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start); unsigned long rel_usecs; - /* Restore the original ent_size */ - iter->ent_size = ent_size; - if (!next_entry) next_ts = iter->ts; rel_usecs = ns2usecs(next_ts - iter->ts); diff --git a/trunk/lib/kobject.c b/trunk/lib/kobject.c index aeefa8bc8b1c..21dee7c19afd 100644 --- a/trunk/lib/kobject.c +++ b/trunk/lib/kobject.c @@ -192,14 +192,14 @@ static int kobject_add_internal(struct kobject *kobj) /* be noisy on error issues */ if (error == -EEXIST) - WARN(1, "%s failed for %s with " - "-EEXIST, don't try to register things with " - "the same name in the same directory.\n", - __func__, kobject_name(kobj)); + printk(KERN_ERR "%s failed for %s with " + "-EEXIST, don't try to register things with " + "the same name in the same directory.\n", + __func__, kobject_name(kobj)); else - WARN(1, "%s failed for %s (error: %d parent: %s)\n", - __func__, kobject_name(kobj), error, - parent ? kobject_name(parent) : "'none'"); + printk(KERN_ERR "%s failed for %s (%d)\n", + __func__, kobject_name(kobj), error); + dump_stack(); } else kobj->state_in_sysfs = 1; diff --git a/trunk/lib/mpi/mpi-bit.c b/trunk/lib/mpi/mpi-bit.c index 0c505361da19..2f526627e4f5 100644 --- a/trunk/lib/mpi/mpi-bit.c +++ b/trunk/lib/mpi/mpi-bit.c @@ -177,8 +177,8 @@ int mpi_rshift(MPI x, MPI a, unsigned n) */ int mpi_lshift_limbs(MPI a, unsigned int count) { - const int n = a->nlimbs; - mpi_ptr_t ap; + mpi_ptr_t ap = a->d; + int n = a->nlimbs; int i; if (!count || !n) @@ -187,7 +187,6 @@ int mpi_lshift_limbs(MPI a, unsigned int count) if (RESIZE_IF_NEEDED(a, n + count) < 0) return -ENOMEM; - ap = a->d; for (i = n - 1; i >= 0; i--) ap[i + count] = ap[i]; for (i = 0; i < count; i++) diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index 5a16423a512c..b8ce6f450956 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -532,7 +532,7 @@ static struct page *dequeue_huge_page_vma(struct hstate *h, struct vm_area_struct *vma, unsigned long address, int avoid_reserve) { - struct page *page = NULL; + struct page *page; struct mempolicy *mpol; nodemask_t *nodemask; struct zonelist *zonelist; @@ -2791,7 +2791,6 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, * so no worry about deadlock. */ page = pte_page(entry); - get_page(page); if (page != pagecache_page) lock_page(page); @@ -2823,7 +2822,6 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, } if (page != pagecache_page) unlock_page(page); - put_page(page); out_mutex: mutex_unlock(&hugetlb_instantiation_mutex); diff --git a/trunk/mm/memblock.c b/trunk/mm/memblock.c index a44eab3157f8..99f285599501 100644 --- a/trunk/mm/memblock.c +++ b/trunk/mm/memblock.c @@ -330,9 +330,6 @@ static int __init_memblock memblock_add_region(struct memblock_type *type, phys_addr_t end = base + memblock_cap_size(base, &size); int i, nr_new; - if (!size) - return 0; - /* special case for empty array */ if (type->regions[0].size == 0) { WARN_ON(type->cnt != 1 || type->total_size); @@ -433,9 +430,6 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type, *start_rgn = *end_rgn = 0; - if (!size) - return 0; - /* we'll create at most two more regions */ while (type->cnt + 2 > type->max) if (memblock_double_array(type) < 0) @@ -520,6 +514,7 @@ int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size) (unsigned long long)base, (unsigned long long)base + size, (void *)_RET_IP_); + BUG_ON(0 == size); return memblock_add_region(_rgn, base, size, MAX_NUMNODES); } diff --git a/trunk/mm/memcontrol.c b/trunk/mm/memcontrol.c index 31ab9c3f0178..7d698df4a067 100644 --- a/trunk/mm/memcontrol.c +++ b/trunk/mm/memcontrol.c @@ -2165,7 +2165,7 @@ static int __cpuinit memcg_cpu_hotplug_callback(struct notifier_block *nb, if (action == CPU_ONLINE) return NOTIFY_OK; - if (action != CPU_DEAD && action != CPU_DEAD_FROZEN) + if ((action != CPU_DEAD) || action != CPU_DEAD_FROZEN) return NOTIFY_OK; for_each_mem_cgroup(iter) @@ -2476,10 +2476,10 @@ struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page) static void __mem_cgroup_commit_charge(struct mem_cgroup *memcg, struct page *page, unsigned int nr_pages, + struct page_cgroup *pc, enum charge_type ctype, bool lrucare) { - struct page_cgroup *pc = lookup_page_cgroup(page); struct zone *uninitialized_var(zone); bool was_on_lru = false; bool anon; @@ -2716,6 +2716,7 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm, { struct mem_cgroup *memcg = NULL; unsigned int nr_pages = 1; + struct page_cgroup *pc; bool oom = true; int ret; @@ -2729,10 +2730,11 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm, oom = false; } + pc = lookup_page_cgroup(page); ret = __mem_cgroup_try_charge(mm, gfp_mask, nr_pages, &memcg, oom); if (ret == -ENOMEM) return ret; - __mem_cgroup_commit_charge(memcg, page, nr_pages, ctype, false); + __mem_cgroup_commit_charge(memcg, page, nr_pages, pc, ctype, false); return 0; } @@ -2829,13 +2831,16 @@ static void __mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *memcg, enum charge_type ctype) { + struct page_cgroup *pc; + if (mem_cgroup_disabled()) return; if (!memcg) return; cgroup_exclude_rmdir(&memcg->css); - __mem_cgroup_commit_charge(memcg, page, 1, ctype, true); + pc = lookup_page_cgroup(page); + __mem_cgroup_commit_charge(memcg, page, 1, pc, ctype, true); /* * Now swap is on-memory. This means this page may be * counted both as mem and swap....double count. @@ -3293,13 +3298,14 @@ int mem_cgroup_prepare_migration(struct page *page, * page. In the case new page is migrated but not remapped, new page's * mapcount will be finally 0 and we call uncharge in end_migration(). */ + pc = lookup_page_cgroup(newpage); if (PageAnon(page)) ctype = MEM_CGROUP_CHARGE_TYPE_MAPPED; else if (page_is_file_cache(page)) ctype = MEM_CGROUP_CHARGE_TYPE_CACHE; else ctype = MEM_CGROUP_CHARGE_TYPE_SHMEM; - __mem_cgroup_commit_charge(memcg, newpage, 1, ctype, false); + __mem_cgroup_commit_charge(memcg, newpage, 1, pc, ctype, false); return ret; } @@ -3386,7 +3392,7 @@ void mem_cgroup_replace_page_cache(struct page *oldpage, * the newpage may be on LRU(or pagevec for LRU) already. We lock * LRU while we overwrite pc->mem_cgroup. */ - __mem_cgroup_commit_charge(memcg, newpage, 1, type, true); + __mem_cgroup_commit_charge(memcg, newpage, 1, pc, type, true); } #ifdef CONFIG_DEBUG_VM @@ -3757,7 +3763,7 @@ static int mem_cgroup_force_empty(struct mem_cgroup *memcg, bool free_all) goto try_to_free; cond_resched(); /* "ret" should also be checked to ensure all lists are empty. */ - } while (res_counter_read_u64(&memcg->res, RES_USAGE) > 0 || ret); + } while (memcg->res.usage > 0 || ret); out: css_put(&memcg->css); return ret; @@ -3772,7 +3778,7 @@ static int mem_cgroup_force_empty(struct mem_cgroup *memcg, bool free_all) lru_add_drain_all(); /* try to free all pages in this cgroup */ shrink = 1; - while (nr_retries && res_counter_read_u64(&memcg->res, RES_USAGE) > 0) { + while (nr_retries && memcg->res.usage > 0) { int progress; if (signal_pending(current)) { diff --git a/trunk/mm/mempolicy.c b/trunk/mm/mempolicy.c index b19569137529..cfb6c8678754 100644 --- a/trunk/mm/mempolicy.c +++ b/trunk/mm/mempolicy.c @@ -1361,14 +1361,11 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode, mm = get_task_mm(task); put_task_struct(task); - - if (!mm) { + if (mm) + err = do_migrate_pages(mm, old, new, + capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE); + else err = -EINVAL; - goto out; - } - - err = do_migrate_pages(mm, old, new, - capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE); mmput(mm); out: diff --git a/trunk/mm/migrate.c b/trunk/mm/migrate.c index 11072383ae12..51c08a0c6f68 100644 --- a/trunk/mm/migrate.c +++ b/trunk/mm/migrate.c @@ -1388,14 +1388,14 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages, mm = get_task_mm(task); put_task_struct(task); - if (!mm) - return -EINVAL; - - if (nodes) - err = do_pages_move(mm, task_nodes, nr_pages, pages, - nodes, status, flags); - else - err = do_pages_stat(mm, nr_pages, pages, status); + if (mm) { + if (nodes) + err = do_pages_move(mm, task_nodes, nr_pages, pages, + nodes, status, flags); + else + err = do_pages_stat(mm, nr_pages, pages, status); + } else + err = -EINVAL; mmput(mm); return err; diff --git a/trunk/mm/mmap.c b/trunk/mm/mmap.c index 848ef52d9603..a7bf6a31c9f6 100644 --- a/trunk/mm/mmap.c +++ b/trunk/mm/mmap.c @@ -240,8 +240,6 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) return next; } -static unsigned long do_brk(unsigned long addr, unsigned long len); - SYSCALL_DEFINE1(brk, unsigned long, brk) { unsigned long rlim, retval; @@ -953,7 +951,7 @@ static inline unsigned long round_hint_to_min(unsigned long hint) * The caller must hold down_write(¤t->mm->mmap_sem). */ -static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, +unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long pgoff) { @@ -1089,32 +1087,7 @@ static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, return mmap_region(file, addr, len, flags, vm_flags, pgoff); } - -unsigned long do_mmap(struct file *file, unsigned long addr, - unsigned long len, unsigned long prot, - unsigned long flag, unsigned long offset) -{ - if (unlikely(offset + PAGE_ALIGN(len) < offset)) - return -EINVAL; - if (unlikely(offset & ~PAGE_MASK)) - return -EINVAL; - return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); -} -EXPORT_SYMBOL(do_mmap); - -unsigned long vm_mmap(struct file *file, unsigned long addr, - unsigned long len, unsigned long prot, - unsigned long flag, unsigned long offset) -{ - unsigned long ret; - struct mm_struct *mm = current->mm; - - down_write(&mm->mmap_sem); - ret = do_mmap(file, addr, len, prot, flag, offset); - up_write(&mm->mmap_sem); - return ret; -} -EXPORT_SYMBOL(vm_mmap); +EXPORT_SYMBOL(do_mmap_pgoff); SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, @@ -2132,25 +2105,21 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) return 0; } + EXPORT_SYMBOL(do_munmap); -int vm_munmap(unsigned long start, size_t len) +SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) { int ret; struct mm_struct *mm = current->mm; + profile_munmap(addr); + down_write(&mm->mmap_sem); - ret = do_munmap(mm, start, len); + ret = do_munmap(mm, addr, len); up_write(&mm->mmap_sem); return ret; } -EXPORT_SYMBOL(vm_munmap); - -SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) -{ - profile_munmap(addr); - return vm_munmap(addr, len); -} static inline void verify_mm_writelocked(struct mm_struct *mm) { @@ -2167,7 +2136,7 @@ static inline void verify_mm_writelocked(struct mm_struct *mm) * anonymous maps. eventually we may be able to do some * brk-specific accounting here. */ -static unsigned long do_brk(unsigned long addr, unsigned long len) +unsigned long do_brk(unsigned long addr, unsigned long len) { struct mm_struct * mm = current->mm; struct vm_area_struct * vma, * prev; @@ -2263,17 +2232,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) return addr; } -unsigned long vm_brk(unsigned long addr, unsigned long len) -{ - struct mm_struct *mm = current->mm; - unsigned long ret; - - down_write(&mm->mmap_sem); - ret = do_brk(addr, len); - up_write(&mm->mmap_sem); - return ret; -} -EXPORT_SYMBOL(vm_brk); +EXPORT_SYMBOL(do_brk); /* Release all mmaps. */ void exit_mmap(struct mm_struct *mm) diff --git a/trunk/mm/nobootmem.c b/trunk/mm/nobootmem.c index e53bb8a256b1..24f0fc1a56d6 100644 --- a/trunk/mm/nobootmem.c +++ b/trunk/mm/nobootmem.c @@ -298,19 +298,13 @@ void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size, if (WARN_ON_ONCE(slab_is_available())) return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id); -again: ptr = __alloc_memory_core_early(pgdat->node_id, size, align, goal, -1ULL); if (ptr) return ptr; - ptr = __alloc_memory_core_early(MAX_NUMNODES, size, align, - goal, -1ULL); - if (!ptr && goal) { - goal = 0; - goto again; - } - return ptr; + return __alloc_memory_core_early(MAX_NUMNODES, size, align, + goal, -1ULL); } void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size, diff --git a/trunk/mm/nommu.c b/trunk/mm/nommu.c index bb8f4f004a82..f59e170fceb4 100644 --- a/trunk/mm/nommu.c +++ b/trunk/mm/nommu.c @@ -1233,7 +1233,7 @@ static int do_mmap_private(struct vm_area_struct *vma, /* * handle mapping creation for uClinux */ -static unsigned long do_mmap_pgoff(struct file *file, +unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, @@ -1470,32 +1470,7 @@ static unsigned long do_mmap_pgoff(struct file *file, show_free_areas(0); return -ENOMEM; } - -unsigned long do_mmap(struct file *file, unsigned long addr, - unsigned long len, unsigned long prot, - unsigned long flag, unsigned long offset) -{ - if (unlikely(offset + PAGE_ALIGN(len) < offset)) - return -EINVAL; - if (unlikely(offset & ~PAGE_MASK)) - return -EINVAL; - return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); -} -EXPORT_SYMBOL(do_mmap); - -unsigned long vm_mmap(struct file *file, unsigned long addr, - unsigned long len, unsigned long prot, - unsigned long flag, unsigned long offset) -{ - unsigned long ret; - struct mm_struct *mm = current->mm; - - down_write(&mm->mmap_sem); - ret = do_mmap(file, addr, len, prot, flag, offset); - up_write(&mm->mmap_sem); - return ret; -} -EXPORT_SYMBOL(vm_mmap); +EXPORT_SYMBOL(do_mmap_pgoff); SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, @@ -1734,22 +1709,16 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) } EXPORT_SYMBOL(do_munmap); -int vm_munmap(unsigned long addr, size_t len) +SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) { - struct mm_struct *mm = current->mm; int ret; + struct mm_struct *mm = current->mm; down_write(&mm->mmap_sem); ret = do_munmap(mm, addr, len); up_write(&mm->mmap_sem); return ret; } -EXPORT_SYMBOL(vm_munmap); - -SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) -{ - return vm_munmap(addr, len); -} /* * release all the mappings made in a process's VM space @@ -1775,7 +1744,7 @@ void exit_mmap(struct mm_struct *mm) kleave(""); } -unsigned long vm_brk(unsigned long addr, unsigned long len) +unsigned long do_brk(unsigned long addr, unsigned long len) { return -ENOMEM; } diff --git a/trunk/mm/swap_state.c b/trunk/mm/swap_state.c index 4c5ff7f284d9..9d3dd3763cf7 100644 --- a/trunk/mm/swap_state.c +++ b/trunk/mm/swap_state.c @@ -26,7 +26,7 @@ */ static const struct address_space_operations swap_aops = { .writepage = swap_writepage, - .set_page_dirty = __set_page_dirty_no_writeback, + .set_page_dirty = __set_page_dirty_nobuffers, .migratepage = migrate_page, }; diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index 33dc256033b5..33c332bbab73 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -1568,14 +1568,9 @@ shrink_inactive_list(unsigned long nr_to_scan, struct mem_cgroup_zone *mz, reclaim_stat->recent_scanned[0] += nr_anon; reclaim_stat->recent_scanned[1] += nr_file; - if (global_reclaim(sc)) { - if (current_is_kswapd()) - __count_zone_vm_events(PGSTEAL_KSWAPD, zone, - nr_reclaimed); - else - __count_zone_vm_events(PGSTEAL_DIRECT, zone, - nr_reclaimed); - } + if (current_is_kswapd()) + __count_vm_events(KSWAPD_STEAL, nr_reclaimed); + __count_zone_vm_events(PGSTEAL, zone, nr_reclaimed); putback_inactive_pages(mz, &page_list); @@ -2112,7 +2107,12 @@ static void shrink_mem_cgroup_zone(int priority, struct mem_cgroup_zone *mz, * with multiple processes reclaiming pages, the total * freeing target can get unreasonably large. */ - if (nr_reclaimed >= nr_to_reclaim && priority < DEF_PRIORITY) + if (nr_reclaimed >= nr_to_reclaim) + nr_to_reclaim = 0; + else + nr_to_reclaim -= nr_reclaimed; + + if (!nr_to_reclaim && priority < DEF_PRIORITY) break; } blk_finish_plug(&plug); diff --git a/trunk/mm/vmstat.c b/trunk/mm/vmstat.c index 7db1b9bab492..f600557a7659 100644 --- a/trunk/mm/vmstat.c +++ b/trunk/mm/vmstat.c @@ -738,8 +738,7 @@ const char * const vmstat_text[] = { "pgmajfault", TEXTS_FOR_ZONES("pgrefill") - TEXTS_FOR_ZONES("pgsteal_kswapd") - TEXTS_FOR_ZONES("pgsteal_direct") + TEXTS_FOR_ZONES("pgsteal") TEXTS_FOR_ZONES("pgscan_kswapd") TEXTS_FOR_ZONES("pgscan_direct") @@ -748,6 +747,7 @@ const char * const vmstat_text[] = { #endif "pginodesteal", "slabs_scanned", + "kswapd_steal", "kswapd_inodesteal", "kswapd_low_wmark_hit_quickly", "kswapd_high_wmark_hit_quickly", diff --git a/trunk/net/802/garp.c b/trunk/net/802/garp.c index a5c224830439..8e21b6db3981 100644 --- a/trunk/net/802/garp.c +++ b/trunk/net/802/garp.c @@ -167,8 +167,7 @@ static struct garp_attr *garp_attr_lookup(const struct garp_applicant *app, return NULL; } -static struct garp_attr *garp_attr_create(struct garp_applicant *app, - const void *data, u8 len, u8 type) +static void garp_attr_insert(struct garp_applicant *app, struct garp_attr *new) { struct rb_node *parent = NULL, **p = &app->gid.rb_node; struct garp_attr *attr; @@ -177,16 +176,21 @@ static struct garp_attr *garp_attr_create(struct garp_applicant *app, while (*p) { parent = *p; attr = rb_entry(parent, struct garp_attr, node); - d = garp_attr_cmp(attr, data, len, type); + d = garp_attr_cmp(attr, new->data, new->dlen, new->type); if (d < 0) p = &parent->rb_left; else if (d > 0) p = &parent->rb_right; - else { - /* The attribute already exists; re-use it. */ - return attr; - } } + rb_link_node(&new->node, parent, p); + rb_insert_color(&new->node, &app->gid); +} + +static struct garp_attr *garp_attr_create(struct garp_applicant *app, + const void *data, u8 len, u8 type) +{ + struct garp_attr *attr; + attr = kmalloc(sizeof(*attr) + len, GFP_ATOMIC); if (!attr) return attr; @@ -194,9 +198,7 @@ static struct garp_attr *garp_attr_create(struct garp_applicant *app, attr->type = type; attr->dlen = len; memcpy(attr->data, data, len); - - rb_link_node(&attr->node, parent, p); - rb_insert_color(&attr->node, &app->gid); + garp_attr_insert(app, attr); return attr; } diff --git a/trunk/net/ax25/af_ax25.c b/trunk/net/ax25/af_ax25.c index 9d9a6a3edbd5..0906c194a413 100644 --- a/trunk/net/ax25/af_ax25.c +++ b/trunk/net/ax25/af_ax25.c @@ -2011,17 +2011,16 @@ static void __exit ax25_exit(void) proc_net_remove(&init_net, "ax25_route"); proc_net_remove(&init_net, "ax25"); proc_net_remove(&init_net, "ax25_calls"); + ax25_rt_free(); + ax25_uid_free(); + ax25_dev_free(); - unregister_netdevice_notifier(&ax25_dev_notifier); ax25_unregister_sysctl(); + unregister_netdevice_notifier(&ax25_dev_notifier); dev_remove_pack(&ax25_packet_type); sock_unregister(PF_AX25); proto_unregister(&ax25_proto); - - ax25_rt_free(); - ax25_uid_free(); - ax25_dev_free(); } module_exit(ax25_exit); diff --git a/trunk/net/bluetooth/hci_core.c b/trunk/net/bluetooth/hci_core.c index edfd61addcec..e33af63a884a 100644 --- a/trunk/net/bluetooth/hci_core.c +++ b/trunk/net/bluetooth/hci_core.c @@ -665,11 +665,6 @@ int hci_dev_open(__u16 dev) hci_req_lock(hdev); - if (test_bit(HCI_UNREGISTER, &hdev->dev_flags)) { - ret = -ENODEV; - goto done; - } - if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) { ret = -ERFKILL; goto done; @@ -1215,40 +1210,40 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) return NULL; } -static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, +static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, u8 key_type, u8 old_key_type) { /* Legacy key */ if (key_type < 0x03) - return true; + return 1; /* Debug keys are insecure so don't store them persistently */ if (key_type == HCI_LK_DEBUG_COMBINATION) - return false; + return 0; /* Changed combination key and there's no previous one */ if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) - return false; + return 0; /* Security mode 3 case */ if (!conn) - return true; + return 1; /* Neither local nor remote side had no-bonding as requirement */ if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) - return true; + return 1; /* Local side had dedicated bonding as requirement */ if (conn->auth_type == 0x02 || conn->auth_type == 0x03) - return true; + return 1; /* Remote side had dedicated bonding as requirement */ if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) - return true; + return 1; /* If none of the above criteria match, then don't store the key * persistently */ - return false; + return 0; } struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) @@ -1285,8 +1280,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) { struct link_key *key, *old_key; - u8 old_key_type; - bool persistent; + u8 old_key_type, persistent; old_key = hci_find_link_key(hdev, bdaddr); if (old_key) { @@ -1329,8 +1323,10 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, mgmt_new_link_key(hdev, key, persistent); - if (conn) - conn->flush_key = !persistent; + if (!persistent) { + list_del(&key->list); + kfree(key); + } return 0; } @@ -1853,8 +1849,6 @@ void hci_unregister_dev(struct hci_dev *hdev) BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); - set_bit(HCI_UNREGISTER, &hdev->dev_flags); - write_lock(&hci_dev_list_lock); list_del(&hdev->list); write_unlock(&hci_dev_list_lock); diff --git a/trunk/net/bluetooth/hci_event.c b/trunk/net/bluetooth/hci_event.c index 6c065254afc0..b37531094c49 100644 --- a/trunk/net/bluetooth/hci_event.c +++ b/trunk/net/bluetooth/hci_event.c @@ -1901,8 +1901,6 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff } if (ev->status == 0) { - if (conn->type == ACL_LINK && conn->flush_key) - hci_remove_link_key(hdev, &conn->dst); hci_proto_disconn_cfm(conn, ev->reason); hci_conn_del(conn); } @@ -2313,7 +2311,6 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk case HCI_OP_USER_PASSKEY_NEG_REPLY: hci_cc_user_passkey_neg_reply(hdev, skb); - break; case HCI_OP_LE_SET_SCAN_PARAM: hci_cc_le_set_scan_param(hdev, skb); diff --git a/trunk/net/bluetooth/l2cap_core.c b/trunk/net/bluetooth/l2cap_core.c index 94552b33d528..b8e17e4dac8b 100644 --- a/trunk/net/bluetooth/l2cap_core.c +++ b/trunk/net/bluetooth/l2cap_core.c @@ -1308,7 +1308,6 @@ static void l2cap_monitor_timeout(struct work_struct *work) if (chan->retry_count >= chan->remote_max_tx) { l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); l2cap_chan_unlock(chan); - l2cap_chan_put(chan); return; } @@ -1317,7 +1316,6 @@ static void l2cap_monitor_timeout(struct work_struct *work) l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); l2cap_chan_unlock(chan); - l2cap_chan_put(chan); } static void l2cap_retrans_timeout(struct work_struct *work) @@ -1337,7 +1335,6 @@ static void l2cap_retrans_timeout(struct work_struct *work) l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); l2cap_chan_unlock(chan); - l2cap_chan_put(chan); } static void l2cap_drop_acked_frames(struct l2cap_chan *chan) diff --git a/trunk/net/bluetooth/l2cap_sock.c b/trunk/net/bluetooth/l2cap_sock.c index 29122ed28ea9..c4fe583b0af6 100644 --- a/trunk/net/bluetooth/l2cap_sock.c +++ b/trunk/net/bluetooth/l2cap_sock.c @@ -82,7 +82,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) } if (la.l2_cid) - err = l2cap_add_scid(chan, __le16_to_cpu(la.l2_cid)); + err = l2cap_add_scid(chan, la.l2_cid); else err = l2cap_add_psm(chan, &la.l2_bdaddr, la.l2_psm); @@ -123,8 +123,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al if (la.l2_cid && la.l2_psm) return -EINVAL; - err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid), - &la.l2_bdaddr); + err = l2cap_chan_connect(chan, la.l2_psm, la.l2_cid, &la.l2_bdaddr); if (err) return err; diff --git a/trunk/net/bluetooth/mgmt.c b/trunk/net/bluetooth/mgmt.c index 4bb03b111122..7fcff8887131 100644 --- a/trunk/net/bluetooth/mgmt.c +++ b/trunk/net/bluetooth/mgmt.c @@ -2523,18 +2523,13 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev, if (cp->val) { type = PAGE_SCAN_TYPE_INTERLACED; - - /* 22.5 msec page scan interval */ - acp.interval = __constant_cpu_to_le16(0x0024); + acp.interval = 0x0024; /* 22.5 msec page scan interval */ } else { type = PAGE_SCAN_TYPE_STANDARD; /* default */ - - /* default 1.28 sec page scan */ - acp.interval = __constant_cpu_to_le16(0x0800); + acp.interval = 0x0800; /* default 1.28 sec page scan */ } - /* default 11.25 msec page scan window */ - acp.window = __constant_cpu_to_le16(0x0012); + acp.window = 0x0012; /* default 11.25 msec page scan window */ err = hci_send_cmd(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY, sizeof(acp), &acp); @@ -2884,7 +2879,7 @@ int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status) return 0; } -int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, bool persistent) +int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, u8 persistent) { struct mgmt_ev_new_link_key ev; @@ -2941,7 +2936,7 @@ int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, name, name_len); if (dev_class && memcmp(dev_class, "\0\0\0", 3) != 0) - eir_len = eir_append_data(ev->eir, eir_len, + eir_len = eir_append_data(&ev->eir[eir_len], eir_len, EIR_CLASS_OF_DEV, dev_class, 3); put_unaligned_le16(eir_len, &ev->eir_len); diff --git a/trunk/net/bridge/br_forward.c b/trunk/net/bridge/br_forward.c index a2098e3de500..61f65344e711 100644 --- a/trunk/net/bridge/br_forward.c +++ b/trunk/net/bridge/br_forward.c @@ -47,7 +47,6 @@ int br_dev_queue_push_xmit(struct sk_buff *skb) kfree_skb(skb); } else { skb_push(skb, ETH_HLEN); - br_drop_fake_rtable(skb); dev_queue_xmit(skb); } diff --git a/trunk/net/bridge/br_multicast.c b/trunk/net/bridge/br_multicast.c index 27ca25ed7021..702a1ae9220b 100644 --- a/trunk/net/bridge/br_multicast.c +++ b/trunk/net/bridge/br_multicast.c @@ -241,6 +241,7 @@ static void br_multicast_group_expired(unsigned long data) hlist_del_rcu(&mp->hlist[mdb->ver]); mdb->size--; + del_timer(&mp->query_timer); call_rcu_bh(&mp->rcu, br_multicast_free_group); out: @@ -270,6 +271,7 @@ static void br_multicast_del_pg(struct net_bridge *br, rcu_assign_pointer(*pp, p->next); hlist_del_init(&p->mglist); del_timer(&p->timer); + del_timer(&p->query_timer); call_rcu_bh(&p->rcu, br_multicast_free_pg); if (!mp->ports && !mp->mglist && @@ -505,6 +507,74 @@ static struct sk_buff *br_multicast_alloc_query(struct net_bridge *br, return NULL; } +static void br_multicast_send_group_query(struct net_bridge_mdb_entry *mp) +{ + struct net_bridge *br = mp->br; + struct sk_buff *skb; + + skb = br_multicast_alloc_query(br, &mp->addr); + if (!skb) + goto timer; + + netif_rx(skb); + +timer: + if (++mp->queries_sent < br->multicast_last_member_count) + mod_timer(&mp->query_timer, + jiffies + br->multicast_last_member_interval); +} + +static void br_multicast_group_query_expired(unsigned long data) +{ + struct net_bridge_mdb_entry *mp = (void *)data; + struct net_bridge *br = mp->br; + + spin_lock(&br->multicast_lock); + if (!netif_running(br->dev) || !mp->mglist || + mp->queries_sent >= br->multicast_last_member_count) + goto out; + + br_multicast_send_group_query(mp); + +out: + spin_unlock(&br->multicast_lock); +} + +static void br_multicast_send_port_group_query(struct net_bridge_port_group *pg) +{ + struct net_bridge_port *port = pg->port; + struct net_bridge *br = port->br; + struct sk_buff *skb; + + skb = br_multicast_alloc_query(br, &pg->addr); + if (!skb) + goto timer; + + br_deliver(port, skb); + +timer: + if (++pg->queries_sent < br->multicast_last_member_count) + mod_timer(&pg->query_timer, + jiffies + br->multicast_last_member_interval); +} + +static void br_multicast_port_group_query_expired(unsigned long data) +{ + struct net_bridge_port_group *pg = (void *)data; + struct net_bridge_port *port = pg->port; + struct net_bridge *br = port->br; + + spin_lock(&br->multicast_lock); + if (!netif_running(br->dev) || hlist_unhashed(&pg->mglist) || + pg->queries_sent >= br->multicast_last_member_count) + goto out; + + br_multicast_send_port_group_query(pg); + +out: + spin_unlock(&br->multicast_lock); +} + static struct net_bridge_mdb_entry *br_multicast_get_group( struct net_bridge *br, struct net_bridge_port *port, struct br_ip *group, int hash) @@ -620,6 +690,8 @@ static struct net_bridge_mdb_entry *br_multicast_new_group( mp->addr = *group; setup_timer(&mp->timer, br_multicast_group_expired, (unsigned long)mp); + setup_timer(&mp->query_timer, br_multicast_group_query_expired, + (unsigned long)mp); hlist_add_head_rcu(&mp->hlist[mdb->ver], &mdb->mhash[hash]); mdb->size++; @@ -674,6 +746,8 @@ static int br_multicast_add_group(struct net_bridge *br, hlist_add_head(&p->mglist, &port->mglist); setup_timer(&p->timer, br_multicast_port_group_expired, (unsigned long)p); + setup_timer(&p->query_timer, br_multicast_port_group_query_expired, + (unsigned long)p); rcu_assign_pointer(*pp, p); @@ -1217,6 +1291,9 @@ static void br_multicast_leave_group(struct net_bridge *br, time_after(mp->timer.expires, time) : try_to_del_timer_sync(&mp->timer) >= 0)) { mod_timer(&mp->timer, time); + + mp->queries_sent = 0; + mod_timer(&mp->query_timer, now); } goto out; @@ -1233,6 +1310,9 @@ static void br_multicast_leave_group(struct net_bridge *br, time_after(p->timer.expires, time) : try_to_del_timer_sync(&p->timer) >= 0)) { mod_timer(&p->timer, time); + + p->queries_sent = 0; + mod_timer(&p->query_timer, now); } break; @@ -1601,6 +1681,7 @@ void br_multicast_stop(struct net_bridge *br) hlist_for_each_entry_safe(mp, p, n, &mdb->mhash[i], hlist[ver]) { del_timer(&mp->timer); + del_timer(&mp->query_timer); call_rcu_bh(&mp->rcu, br_multicast_free_group); } } diff --git a/trunk/net/bridge/br_netfilter.c b/trunk/net/bridge/br_netfilter.c index d7f49b63ab0f..dec4f3817133 100644 --- a/trunk/net/bridge/br_netfilter.c +++ b/trunk/net/bridge/br_netfilter.c @@ -156,7 +156,7 @@ void br_netfilter_rtable_init(struct net_bridge *br) rt->dst.dev = br->dev; rt->dst.path = &rt->dst; dst_init_metrics(&rt->dst, br_dst_default_metrics, true); - rt->dst.flags = DST_NOXFRM | DST_NOPEER | DST_FAKE_RTABLE; + rt->dst.flags = DST_NOXFRM | DST_NOPEER; rt->dst.ops = &fake_dst_ops; } @@ -694,7 +694,11 @@ static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff *skb, const struct net_device *out, int (*okfn)(struct sk_buff *)) { - br_drop_fake_rtable(skb); + struct rtable *rt = skb_rtable(skb); + + if (rt && rt == bridge_parent_rtable(in)) + skb_dst_drop(skb); + return NF_ACCEPT; } diff --git a/trunk/net/bridge/br_private.h b/trunk/net/bridge/br_private.h index e1d882257877..0b67a63ad7a8 100644 --- a/trunk/net/bridge/br_private.h +++ b/trunk/net/bridge/br_private.h @@ -82,7 +82,9 @@ struct net_bridge_port_group { struct hlist_node mglist; struct rcu_head rcu; struct timer_list timer; + struct timer_list query_timer; struct br_ip addr; + u32 queries_sent; }; struct net_bridge_mdb_entry @@ -92,8 +94,10 @@ struct net_bridge_mdb_entry struct net_bridge_port_group __rcu *ports; struct rcu_head rcu; struct timer_list timer; + struct timer_list query_timer; struct br_ip addr; bool mglist; + u32 queries_sent; }; struct net_bridge_mdb_htable diff --git a/trunk/net/caif/chnl_net.c b/trunk/net/caif/chnl_net.c index d09340e1523f..20618dd3088b 100644 --- a/trunk/net/caif/chnl_net.c +++ b/trunk/net/caif/chnl_net.c @@ -103,7 +103,6 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt) skb->protocol = htons(ETH_P_IPV6); break; default: - kfree_skb(skb); priv->netdev->stats.rx_errors++; return -EINVAL; } @@ -221,16 +220,14 @@ static int chnl_net_start_xmit(struct sk_buff *skb, struct net_device *dev) if (skb->len > priv->netdev->mtu) { pr_warn("Size of skb exceeded MTU\n"); - kfree_skb(skb); dev->stats.tx_errors++; - return NETDEV_TX_OK; + return -ENOSPC; } if (!priv->flowenabled) { pr_debug("dropping packets flow off\n"); - kfree_skb(skb); dev->stats.tx_dropped++; - return NETDEV_TX_OK; + return NETDEV_TX_BUSY; } if (priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP) @@ -245,7 +242,7 @@ static int chnl_net_start_xmit(struct sk_buff *skb, struct net_device *dev) result = priv->chnl.dn->transmit(priv->chnl.dn, pkt); if (result) { dev->stats.tx_dropped++; - return NETDEV_TX_OK; + return result; } /* Update statistics. */ diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 9bb8f87c4cda..5d59155adf2a 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1409,34 +1409,14 @@ EXPORT_SYMBOL(register_netdevice_notifier); * register_netdevice_notifier(). The notifier is unlinked into the * kernel structures and may then be reused. A negative errno code * is returned on a failure. - * - * After unregistering unregister and down device events are synthesized - * for all devices on the device list to the removed notifier to remove - * the need for special case cleanup code. */ int unregister_netdevice_notifier(struct notifier_block *nb) { - struct net_device *dev; - struct net *net; int err; rtnl_lock(); err = raw_notifier_chain_unregister(&netdev_chain, nb); - if (err) - goto unlock; - - for_each_net(net) { - for_each_netdev(net, dev) { - if (dev->flags & IFF_UP) { - nb->notifier_call(nb, NETDEV_GOING_DOWN, dev); - nb->notifier_call(nb, NETDEV_DOWN, dev); - } - nb->notifier_call(nb, NETDEV_UNREGISTER, dev); - nb->notifier_call(nb, NETDEV_UNREGISTER_BATCH, dev); - } - } -unlock: rtnl_unlock(); return err; } @@ -1616,7 +1596,6 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) kfree_skb(skb); return NET_RX_DROP; } - skb->skb_iif = 0; skb_set_dev(skb, dev); skb->tstamp.tv64 = 0; skb->pkt_type = PACKET_HOST; @@ -4048,41 +4027,54 @@ static int dev_ifconf(struct net *net, char __user *arg) #ifdef CONFIG_PROC_FS -#define BUCKET_SPACE (32 - NETDEV_HASHBITS - 1) +#define BUCKET_SPACE (32 - NETDEV_HASHBITS) + +struct dev_iter_state { + struct seq_net_private p; + unsigned int pos; /* bucket << BUCKET_SPACE + offset */ +}; #define get_bucket(x) ((x) >> BUCKET_SPACE) #define get_offset(x) ((x) & ((1 << BUCKET_SPACE) - 1)) #define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o)) -static inline struct net_device *dev_from_same_bucket(struct seq_file *seq, loff_t *pos) +static inline struct net_device *dev_from_same_bucket(struct seq_file *seq) { + struct dev_iter_state *state = seq->private; struct net *net = seq_file_net(seq); struct net_device *dev; struct hlist_node *p; struct hlist_head *h; - unsigned int count = 0, offset = get_offset(*pos); + unsigned int count, bucket, offset; - h = &net->dev_name_head[get_bucket(*pos)]; + bucket = get_bucket(state->pos); + offset = get_offset(state->pos); + h = &net->dev_name_head[bucket]; + count = 0; hlist_for_each_entry_rcu(dev, p, h, name_hlist) { - if (++count == offset) + if (count++ == offset) { + state->pos = set_bucket_offset(bucket, count); return dev; + } } return NULL; } -static inline struct net_device *dev_from_bucket(struct seq_file *seq, loff_t *pos) +static inline struct net_device *dev_from_new_bucket(struct seq_file *seq) { + struct dev_iter_state *state = seq->private; struct net_device *dev; unsigned int bucket; + bucket = get_bucket(state->pos); do { - dev = dev_from_same_bucket(seq, pos); + dev = dev_from_same_bucket(seq); if (dev) return dev; - bucket = get_bucket(*pos) + 1; - *pos = set_bucket_offset(bucket, 1); + bucket++; + state->pos = set_bucket_offset(bucket, 0); } while (bucket < NETDEV_HASHENTRIES); return NULL; @@ -4095,20 +4087,33 @@ static inline struct net_device *dev_from_bucket(struct seq_file *seq, loff_t *p void *dev_seq_start(struct seq_file *seq, loff_t *pos) __acquires(RCU) { + struct dev_iter_state *state = seq->private; + rcu_read_lock(); if (!*pos) return SEQ_START_TOKEN; - if (get_bucket(*pos) >= NETDEV_HASHENTRIES) + /* check for end of the hash */ + if (state->pos == 0 && *pos > 1) return NULL; - return dev_from_bucket(seq, pos); + return dev_from_new_bucket(seq); } void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) { + struct net_device *dev; + ++*pos; - return dev_from_bucket(seq, pos); + + if (v == SEQ_START_TOKEN) + return dev_from_new_bucket(seq); + + dev = dev_from_same_bucket(seq); + if (dev) + return dev; + + return dev_from_new_bucket(seq); } void dev_seq_stop(struct seq_file *seq, void *v) @@ -4207,7 +4212,13 @@ static const struct seq_operations dev_seq_ops = { static int dev_seq_open(struct inode *inode, struct file *file) { return seq_open_net(inode, file, &dev_seq_ops, - sizeof(struct seq_net_private)); + sizeof(struct dev_iter_state)); +} + +int dev_seq_open_ops(struct inode *inode, struct file *file, + const struct seq_operations *ops) +{ + return seq_open_net(inode, file, ops, sizeof(struct dev_iter_state)); } static const struct file_operations dev_seq_fops = { diff --git a/trunk/net/core/dev_addr_lists.c b/trunk/net/core/dev_addr_lists.c index 626698f0db8b..29c07fef9228 100644 --- a/trunk/net/core/dev_addr_lists.c +++ b/trunk/net/core/dev_addr_lists.c @@ -696,8 +696,7 @@ static const struct seq_operations dev_mc_seq_ops = { static int dev_mc_seq_open(struct inode *inode, struct file *file) { - return seq_open_net(inode, file, &dev_mc_seq_ops, - sizeof(struct seq_net_private)); + return dev_seq_open_ops(inode, file, &dev_mc_seq_ops); } static const struct file_operations dev_mc_seq_fops = { diff --git a/trunk/net/core/drop_monitor.c b/trunk/net/core/drop_monitor.c index a7cad741df01..7f36b38e060f 100644 --- a/trunk/net/core/drop_monitor.c +++ b/trunk/net/core/drop_monitor.c @@ -42,14 +42,13 @@ static void send_dm_alert(struct work_struct *unused); * netlink alerts */ static int trace_state = TRACE_OFF; -static DEFINE_MUTEX(trace_state_mutex); +static DEFINE_SPINLOCK(trace_state_lock); struct per_cpu_dm_data { struct work_struct dm_alert_work; - struct sk_buff __rcu *skb; + struct sk_buff *skb; atomic_t dm_hit_count; struct timer_list send_timer; - int cpu; }; struct dm_hw_stat_delta { @@ -80,53 +79,29 @@ static void reset_per_cpu_data(struct per_cpu_dm_data *data) size_t al; struct net_dm_alert_msg *msg; struct nlattr *nla; - struct sk_buff *skb; - struct sk_buff *oskb = rcu_dereference_protected(data->skb, 1); al = sizeof(struct net_dm_alert_msg); al += dm_hit_limit * sizeof(struct net_dm_drop_point); al += sizeof(struct nlattr); - skb = genlmsg_new(al, GFP_KERNEL); - - if (skb) { - genlmsg_put(skb, 0, 0, &net_drop_monitor_family, - 0, NET_DM_CMD_ALERT); - nla = nla_reserve(skb, NLA_UNSPEC, - sizeof(struct net_dm_alert_msg)); - msg = nla_data(nla); - memset(msg, 0, al); - } else - schedule_work_on(data->cpu, &data->dm_alert_work); - - /* - * Don't need to lock this, since we are guaranteed to only - * run this on a single cpu at a time. - * Note also that we only update data->skb if the old and new skb - * pointers don't match. This ensures that we don't continually call - * synchornize_rcu if we repeatedly fail to alloc a new netlink message. - */ - if (skb != oskb) { - rcu_assign_pointer(data->skb, skb); - - synchronize_rcu(); - - atomic_set(&data->dm_hit_count, dm_hit_limit); - } - + data->skb = genlmsg_new(al, GFP_KERNEL); + genlmsg_put(data->skb, 0, 0, &net_drop_monitor_family, + 0, NET_DM_CMD_ALERT); + nla = nla_reserve(data->skb, NLA_UNSPEC, sizeof(struct net_dm_alert_msg)); + msg = nla_data(nla); + memset(msg, 0, al); + atomic_set(&data->dm_hit_count, dm_hit_limit); } static void send_dm_alert(struct work_struct *unused) { struct sk_buff *skb; - struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data); - - WARN_ON_ONCE(data->cpu != smp_processor_id()); + struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data); /* * Grab the skb we're about to send */ - skb = rcu_dereference_protected(data->skb, 1); + skb = data->skb; /* * Replace it with a new one @@ -136,10 +111,8 @@ static void send_dm_alert(struct work_struct *unused) /* * Ship it! */ - if (skb) - genlmsg_multicast(skb, 0, NET_DM_GRP_ALERT, GFP_KERNEL); + genlmsg_multicast(skb, 0, NET_DM_GRP_ALERT, GFP_KERNEL); - put_cpu_var(dm_cpu_data); } /* @@ -150,11 +123,9 @@ static void send_dm_alert(struct work_struct *unused) */ static void sched_send_work(unsigned long unused) { - struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data); - - schedule_work_on(smp_processor_id(), &data->dm_alert_work); + struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data); - put_cpu_var(dm_cpu_data); + schedule_work(&data->dm_alert_work); } static void trace_drop_common(struct sk_buff *skb, void *location) @@ -163,15 +134,8 @@ static void trace_drop_common(struct sk_buff *skb, void *location) struct nlmsghdr *nlh; struct nlattr *nla; int i; - struct sk_buff *dskb; - struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data); - - - rcu_read_lock(); - dskb = rcu_dereference(data->skb); + struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data); - if (!dskb) - goto out; if (!atomic_add_unless(&data->dm_hit_count, -1, 0)) { /* @@ -180,13 +144,12 @@ static void trace_drop_common(struct sk_buff *skb, void *location) goto out; } - nlh = (struct nlmsghdr *)dskb->data; + nlh = (struct nlmsghdr *)data->skb->data; nla = genlmsg_data(nlmsg_data(nlh)); msg = nla_data(nla); for (i = 0; i < msg->entries; i++) { if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) { msg->points[i].count++; - atomic_inc(&data->dm_hit_count); goto out; } } @@ -194,7 +157,7 @@ static void trace_drop_common(struct sk_buff *skb, void *location) /* * We need to create a new entry */ - __nla_reserve_nohdr(dskb, sizeof(struct net_dm_drop_point)); + __nla_reserve_nohdr(data->skb, sizeof(struct net_dm_drop_point)); nla->nla_len += NLA_ALIGN(sizeof(struct net_dm_drop_point)); memcpy(msg->points[msg->entries].pc, &location, sizeof(void *)); msg->points[msg->entries].count = 1; @@ -206,8 +169,6 @@ static void trace_drop_common(struct sk_buff *skb, void *location) } out: - rcu_read_unlock(); - put_cpu_var(dm_cpu_data); return; } @@ -252,7 +213,7 @@ static int set_all_monitor_traces(int state) struct dm_hw_stat_delta *new_stat = NULL; struct dm_hw_stat_delta *temp; - mutex_lock(&trace_state_mutex); + spin_lock(&trace_state_lock); if (state == trace_state) { rc = -EAGAIN; @@ -291,7 +252,7 @@ static int set_all_monitor_traces(int state) rc = -EINPROGRESS; out_unlock: - mutex_unlock(&trace_state_mutex); + spin_unlock(&trace_state_lock); return rc; } @@ -334,12 +295,12 @@ static int dropmon_net_event(struct notifier_block *ev_block, new_stat->dev = dev; new_stat->last_rx = jiffies; - mutex_lock(&trace_state_mutex); + spin_lock(&trace_state_lock); list_add_rcu(&new_stat->list, &hw_stats_list); - mutex_unlock(&trace_state_mutex); + spin_unlock(&trace_state_lock); break; case NETDEV_UNREGISTER: - mutex_lock(&trace_state_mutex); + spin_lock(&trace_state_lock); list_for_each_entry_safe(new_stat, tmp, &hw_stats_list, list) { if (new_stat->dev == dev) { new_stat->dev = NULL; @@ -350,7 +311,7 @@ static int dropmon_net_event(struct notifier_block *ev_block, } } } - mutex_unlock(&trace_state_mutex); + spin_unlock(&trace_state_lock); break; } out: @@ -406,15 +367,13 @@ static int __init init_net_drop_monitor(void) for_each_present_cpu(cpu) { data = &per_cpu(dm_cpu_data, cpu); - data->cpu = cpu; + reset_per_cpu_data(data); INIT_WORK(&data->dm_alert_work, send_dm_alert); init_timer(&data->send_timer); data->send_timer.data = cpu; data->send_timer.function = sched_send_work; - reset_per_cpu_data(data); } - goto out; out_unreg: diff --git a/trunk/net/core/filter.c b/trunk/net/core/filter.c index 6f755cca4520..cf4989ac503b 100644 --- a/trunk/net/core/filter.c +++ b/trunk/net/core/filter.c @@ -39,11 +39,8 @@ #include #include -/* No hurry in this branch - * - * Exported for the bpf jit load helper. - */ -void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb, int k, unsigned int size) +/* No hurry in this branch */ +static void *__load_pointer(const struct sk_buff *skb, int k, unsigned int size) { u8 *ptr = NULL; @@ -62,7 +59,7 @@ static inline void *load_pointer(const struct sk_buff *skb, int k, { if (k >= 0) return skb_header_pointer(skb, k, size, buffer); - return bpf_internal_load_pointer_neg_helper(skb, k, size); + return __load_pointer(skb, k, size); } /** diff --git a/trunk/net/core/net_namespace.c b/trunk/net/core/net_namespace.c index 31a5ae51a45c..0e950fda9a0a 100644 --- a/trunk/net/core/net_namespace.c +++ b/trunk/net/core/net_namespace.c @@ -83,29 +83,21 @@ static int net_assign_generic(struct net *net, int id, void *data) static int ops_init(const struct pernet_operations *ops, struct net *net) { - int err = -ENOMEM; - void *data = NULL; - + int err; if (ops->id && ops->size) { - data = kzalloc(ops->size, GFP_KERNEL); + void *data = kzalloc(ops->size, GFP_KERNEL); if (!data) - goto out; + return -ENOMEM; err = net_assign_generic(net, *ops->id, data); - if (err) - goto cleanup; + if (err) { + kfree(data); + return err; + } } - err = 0; if (ops->init) - err = ops->init(net); - if (!err) - return 0; - -cleanup: - kfree(data); - -out: - return err; + return ops->init(net); + return 0; } static void ops_free(const struct pernet_operations *ops, struct net *net) @@ -456,7 +448,12 @@ static void __unregister_pernet_operations(struct pernet_operations *ops) static int __register_pernet_operations(struct list_head *list, struct pernet_operations *ops) { - return ops_init(ops, &init_net); + int err = 0; + err = ops_init(ops, &init_net); + if (err) + ops_free(ops, &init_net); + return err; + } static void __unregister_pernet_operations(struct pernet_operations *ops) diff --git a/trunk/net/core/skbuff.c b/trunk/net/core/skbuff.c index e59840010d45..f223cdc75da6 100644 --- a/trunk/net/core/skbuff.c +++ b/trunk/net/core/skbuff.c @@ -952,11 +952,9 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, goto adjust_others; } - data = kmalloc(size + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)), - gfp_mask); + data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); if (!data) goto nodata; - size = SKB_WITH_OVERHEAD(ksize(data)); /* Copy only real data... and, alas, header. This should be * optimized for the cases when header is void. @@ -3163,8 +3161,6 @@ static void sock_rmem_free(struct sk_buff *skb) */ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb) { - int len = skb->len; - if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= (unsigned)sk->sk_rcvbuf) return -ENOMEM; @@ -3179,7 +3175,7 @@ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb) skb_queue_tail(&sk->sk_error_queue, skb); if (!sock_flag(sk, SOCK_DEAD)) - sk->sk_data_ready(sk, len); + sk->sk_data_ready(sk, skb->len); return 0; } EXPORT_SYMBOL(sock_queue_err_skb); diff --git a/trunk/net/ieee802154/6lowpan.c b/trunk/net/ieee802154/6lowpan.c index 840821b90bcd..368515885368 100644 --- a/trunk/net/ieee802154/6lowpan.c +++ b/trunk/net/ieee802154/6lowpan.c @@ -1044,24 +1044,6 @@ static void lowpan_dev_free(struct net_device *dev) free_netdev(dev); } -static struct wpan_phy *lowpan_get_phy(const struct net_device *dev) -{ - struct net_device *real_dev = lowpan_dev_info(dev)->real_dev; - return ieee802154_mlme_ops(real_dev)->get_phy(real_dev); -} - -static u16 lowpan_get_pan_id(const struct net_device *dev) -{ - struct net_device *real_dev = lowpan_dev_info(dev)->real_dev; - return ieee802154_mlme_ops(real_dev)->get_pan_id(real_dev); -} - -static u16 lowpan_get_short_addr(const struct net_device *dev) -{ - struct net_device *real_dev = lowpan_dev_info(dev)->real_dev; - return ieee802154_mlme_ops(real_dev)->get_short_addr(real_dev); -} - static struct header_ops lowpan_header_ops = { .create = lowpan_header_create, }; @@ -1071,12 +1053,6 @@ static const struct net_device_ops lowpan_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, }; -static struct ieee802154_mlme_ops lowpan_mlme = { - .get_pan_id = lowpan_get_pan_id, - .get_phy = lowpan_get_phy, - .get_short_addr = lowpan_get_short_addr, -}; - static void lowpan_setup(struct net_device *dev) { pr_debug("(%s)\n", __func__); @@ -1094,7 +1070,6 @@ static void lowpan_setup(struct net_device *dev) dev->netdev_ops = &lowpan_netdev_ops; dev->header_ops = &lowpan_header_ops; - dev->ml_priv = &lowpan_mlme; dev->destructor = lowpan_dev_free; } @@ -1168,8 +1143,6 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev, list_add_tail(&entry->list, &lowpan_devices); mutex_unlock(&lowpan_dev_info(dev)->dev_list_mtx); - spin_lock_init(&flist_lock); - register_netdevice(dev); return 0; @@ -1179,20 +1152,11 @@ static void lowpan_dellink(struct net_device *dev, struct list_head *head) { struct lowpan_dev_info *lowpan_dev = lowpan_dev_info(dev); struct net_device *real_dev = lowpan_dev->real_dev; - struct lowpan_dev_record *entry, *tmp; - struct lowpan_fragment *frame, *tframe; + struct lowpan_dev_record *entry; + struct lowpan_dev_record *tmp; ASSERT_RTNL(); - spin_lock(&flist_lock); - list_for_each_entry_safe(frame, tframe, &lowpan_fragments, list) { - del_timer(&frame->timer); - list_del(&frame->list); - dev_kfree_skb(frame->skb); - kfree(frame); - } - spin_unlock(&flist_lock); - mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx); list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) { if (entry->ldev == dev) { diff --git a/trunk/net/ipv4/inet_diag.c b/trunk/net/ipv4/inet_diag.c index 8f8db724bfaf..8d25a1c557eb 100644 --- a/trunk/net/ipv4/inet_diag.c +++ b/trunk/net/ipv4/inet_diag.c @@ -141,7 +141,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, goto rtattr_failure; if (icsk == NULL) { - handler->idiag_get_info(sk, r, NULL); + r->idiag_rqueue = r->idiag_wqueue = 0; goto out; } diff --git a/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index cf73cc70ed2d..de9da21113a1 100644 --- a/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -74,24 +74,16 @@ static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph); if (iph == NULL) - return -NF_ACCEPT; + return -NF_DROP; /* Conntrack defragments packets, we might still see fragments * inside ICMP packets though. */ if (iph->frag_off & htons(IP_OFFSET)) - return -NF_ACCEPT; + return -NF_DROP; *dataoff = nhoff + (iph->ihl << 2); *protonum = iph->protocol; - /* Check bogus IP headers */ - if (*dataoff > skb->len) { - pr_debug("nf_conntrack_ipv4: bogus IPv4 packet: " - "nhoff %u, ihl %u, skblen %u\n", - nhoff, iph->ihl << 2, skb->len); - return -NF_ACCEPT; - } - return NF_ACCEPT; } diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index 167ea10b521a..4dc1c104c942 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -2041,7 +2041,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, if (err < 0) goto e_err; } - rth = rt_dst_alloc(dev_net(dev)->loopback_dev, + rth = rt_dst_alloc(init_net.loopback_dev, IN_DEV_CONF_GET(in_dev, NOPOLICY), false); if (!rth) goto e_nobufs; diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index 1272a88c2a63..cfd7edda0a8e 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -701,12 +701,11 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp) skb = alloc_skb_fclone(size + sk->sk_prot->max_header, gfp); if (skb) { if (sk_wmem_schedule(sk, skb->truesize)) { - skb_reserve(skb, sk->sk_prot->max_header); /* * Make sure that we have exactly size bytes * available to the caller, no more, no less. */ - skb->avail_size = size; + skb_reserve(skb, skb_tailroom(skb) - size); return skb; } __kfree_skb(skb); @@ -861,7 +860,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse } out: - if (copied && !(flags & MSG_SENDPAGE_NOTLAST)) + if (copied) tcp_push(sk, flags, mss_now, tp->nonagle); return copied; @@ -996,9 +995,10 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, copy = seglen; /* Where to copy to? */ - if (skb_availroom(skb) > 0) { + if (skb_tailroom(skb) > 0) { /* We have some space in skb head. Superb! */ - copy = min_t(int, copy, skb_availroom(skb)); + if (copy > skb_tailroom(skb)) + copy = skb_tailroom(skb); err = skb_add_data_nocache(sk, skb, from, copy); if (err) goto do_fault; @@ -1452,7 +1452,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, if ((available < target) && (len > sysctl_tcp_dma_copybreak) && !(flags & MSG_PEEK) && !sysctl_tcp_low_latency && - net_dma_find_channel()) { + dma_find_channel(DMA_MEMCPY)) { preempt_enable_no_resched(); tp->ucopy.pinned_list = dma_pin_iovec_pages(msg->msg_iov, len); @@ -1667,7 +1667,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, if (!(flags & MSG_TRUNC)) { #ifdef CONFIG_NET_DMA if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list) - tp->ucopy.dma_chan = net_dma_find_channel(); + tp->ucopy.dma_chan = dma_find_channel(DMA_MEMCPY); if (tp->ucopy.dma_chan) { tp->ucopy.dma_cookie = dma_skb_copy_datagram_iovec( @@ -3243,7 +3243,7 @@ void __init tcp_init(void) { struct sk_buff *skb = NULL; unsigned long limit; - int max_rshare, max_wshare, cnt; + int max_share, cnt; unsigned int i; unsigned long jiffy = jiffies; @@ -3302,17 +3302,17 @@ void __init tcp_init(void) tcp_init_mem(&init_net); /* Set per-socket limits to no more than 1/128 the pressure threshold */ - limit = nr_free_buffer_pages() << (PAGE_SHIFT - 7); - max_wshare = min(4UL*1024*1024, limit); - max_rshare = min(6UL*1024*1024, limit); + limit = nr_free_buffer_pages() << (PAGE_SHIFT - 10); + limit = max(limit, 128UL); + max_share = min(4UL*1024*1024, limit); sysctl_tcp_wmem[0] = SK_MEM_QUANTUM; sysctl_tcp_wmem[1] = 16*1024; - sysctl_tcp_wmem[2] = max(64*1024, max_wshare); + sysctl_tcp_wmem[2] = max(64*1024, max_share); sysctl_tcp_rmem[0] = SK_MEM_QUANTUM; sysctl_tcp_rmem[1] = 87380; - sysctl_tcp_rmem[2] = max(87380, max_rshare); + sysctl_tcp_rmem[2] = max(87380, max_share); pr_info("Hash tables configured (established %u bind %u)\n", tcp_hashinfo.ehash_mask + 1, tcp_hashinfo.bhash_size); diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 257b61789eeb..e886e2f7fa8d 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -85,7 +85,7 @@ int sysctl_tcp_ecn __read_mostly = 2; EXPORT_SYMBOL(sysctl_tcp_ecn); int sysctl_tcp_dsack __read_mostly = 1; int sysctl_tcp_app_win __read_mostly = 31; -int sysctl_tcp_adv_win_scale __read_mostly = 1; +int sysctl_tcp_adv_win_scale __read_mostly = 2; EXPORT_SYMBOL(sysctl_tcp_adv_win_scale); int sysctl_tcp_stdurg __read_mostly; @@ -335,7 +335,6 @@ static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb) incr = __tcp_grow_window(sk, skb); if (incr) { - incr = max_t(int, incr, 2 * skb->len); tp->rcv_ssthresh = min(tp->rcv_ssthresh + incr, tp->window_clamp); inet_csk(sk)->icsk_ack.quick |= 1; @@ -475,11 +474,8 @@ static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep) if (!win_dep) { m -= (new_sample >> 3); new_sample += m; - } else { - m <<= 3; - if (m < new_sample) - new_sample = m; - } + } else if (m < new_sample) + new_sample = m << 3; } else { /* No previous measure. */ new_sample = m << 3; @@ -495,7 +491,7 @@ static inline void tcp_rcv_rtt_measure(struct tcp_sock *tp) goto new_measure; if (before(tp->rcv_nxt, tp->rcv_rtt_est.seq)) return; - tcp_rcv_rtt_update(tp, tcp_time_stamp - tp->rcv_rtt_est.time, 1); + tcp_rcv_rtt_update(tp, jiffies - tp->rcv_rtt_est.time, 1); new_measure: tp->rcv_rtt_est.seq = tp->rcv_nxt + tp->rcv_wnd; @@ -2868,14 +2864,11 @@ static inline void tcp_complete_cwr(struct sock *sk) /* Do not moderate cwnd if it's already undone in cwr or recovery. */ if (tp->undo_marker) { - if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR) { + if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR) tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh); - tp->snd_cwnd_stamp = tcp_time_stamp; - } else if (tp->snd_ssthresh < TCP_INFINITE_SSTHRESH) { - /* PRR algorithm. */ + else /* PRR */ tp->snd_cwnd = tp->snd_ssthresh; - tp->snd_cwnd_stamp = tcp_time_stamp; - } + tp->snd_cwnd_stamp = tcp_time_stamp; } tcp_ca_event(sk, CA_EVENT_COMPLETE_CWR); } @@ -5232,7 +5225,7 @@ static int tcp_dma_try_early_copy(struct sock *sk, struct sk_buff *skb, return 0; if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list) - tp->ucopy.dma_chan = net_dma_find_channel(); + tp->ucopy.dma_chan = dma_find_channel(DMA_MEMCPY); if (tp->ucopy.dma_chan && skb_csum_unnecessary(skb)) { diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index 0cb86ceb652f..3a25cf743f8b 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -1730,7 +1730,7 @@ int tcp_v4_rcv(struct sk_buff *skb) #ifdef CONFIG_NET_DMA struct tcp_sock *tp = tcp_sk(sk); if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list) - tp->ucopy.dma_chan = net_dma_find_channel(); + tp->ucopy.dma_chan = dma_find_channel(DMA_MEMCPY); if (tp->ucopy.dma_chan) ret = tcp_v4_do_rcv(sk, skb); else diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index 7ac6423117ad..364784a91939 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -1096,7 +1096,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; @@ -2061,7 +2060,7 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to, /* Punt if not enough space exists in the first SKB for * the data in the second */ - if (skb->len > skb_availroom(to)) + if (skb->len > skb_tailroom(to)) break; if (after(TCP_SKB_CB(skb)->end_seq, tcp_wnd_end(tp))) diff --git a/trunk/net/ipv4/udp_diag.c b/trunk/net/ipv4/udp_diag.c index a7f86a3cd502..8a949f19deb6 100644 --- a/trunk/net/ipv4/udp_diag.c +++ b/trunk/net/ipv4/udp_diag.c @@ -146,17 +146,9 @@ static int udp_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh, return udp_dump_one(&udp_table, in_skb, nlh, req); } -static void udp_diag_get_info(struct sock *sk, struct inet_diag_msg *r, - void *info) -{ - r->idiag_rqueue = sk_rmem_alloc_get(sk); - r->idiag_wqueue = sk_wmem_alloc_get(sk); -} - static const struct inet_diag_handler udp_diag_handler = { .dump = udp_diag_dump, .dump_one = udp_diag_dump_one, - .idiag_get_info = udp_diag_get_info, .idiag_type = IPPROTO_UDP, }; @@ -175,7 +167,6 @@ static int udplite_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr * static const struct inet_diag_handler udplite_diag_handler = { .dump = udplite_diag_dump, .dump_one = udplite_diag_dump_one, - .idiag_get_info = udp_diag_get_info, .idiag_type = IPPROTO_UDPLITE, }; diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index 7d5cb975cc6f..6a3bb6077e19 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -803,7 +803,8 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) ip6_del_rt(rt); rt = NULL; } else if (!(rt->rt6i_flags & RTF_EXPIRES)) { - rt6_set_expires(rt, expires); + rt->dst.expires = expires; + rt->rt6i_flags |= RTF_EXPIRES; } } dst_release(&rt->dst); @@ -1886,9 +1887,11 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) rt = NULL; } else if (addrconf_finite_timeout(rt_expires)) { /* not infinity */ - rt6_set_expires(rt, jiffies + rt_expires); + rt->dst.expires = jiffies + rt_expires; + rt->rt6i_flags |= RTF_EXPIRES; } else { - rt6_clean_expires(rt); + rt->rt6i_flags &= ~RTF_EXPIRES; + rt->dst.expires = 0; } } else if (valid_lft) { clock_t expires = 0; diff --git a/trunk/net/ipv6/ip6_fib.c b/trunk/net/ipv6/ip6_fib.c index 93717435013e..5b27fbcae346 100644 --- a/trunk/net/ipv6/ip6_fib.c +++ b/trunk/net/ipv6/ip6_fib.c @@ -673,10 +673,11 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, &rt->rt6i_gateway)) { if (!(iter->rt6i_flags & RTF_EXPIRES)) return -EEXIST; - if (!(rt->rt6i_flags & RTF_EXPIRES)) - rt6_clean_expires(iter); - else - rt6_set_expires(iter, rt->dst.expires); + iter->dst.expires = rt->dst.expires; + if (!(rt->rt6i_flags & RTF_EXPIRES)) { + iter->rt6i_flags &= ~RTF_EXPIRES; + iter->dst.expires = 0; + } return -EEXIST; } } diff --git a/trunk/net/ipv6/mcast.c b/trunk/net/ipv6/mcast.c index b2869cab2092..16c33e308121 100644 --- a/trunk/net/ipv6/mcast.c +++ b/trunk/net/ipv6/mcast.c @@ -2044,7 +2044,7 @@ static int ip6_mc_add_src(struct inet6_dev *idev, const struct in6_addr *pmca, if (!delta) pmc->mca_sfcount[sfmode]--; for (j=0; jmca_sfcount[MCAST_EXCLUDE] != 0)) { struct ip6_sf_list *psf; diff --git a/trunk/net/ipv6/ndisc.c b/trunk/net/ipv6/ndisc.c index 176b469322ac..3dcdb81ec3e8 100644 --- a/trunk/net/ipv6/ndisc.c +++ b/trunk/net/ipv6/ndisc.c @@ -1264,7 +1264,8 @@ static void ndisc_router_discovery(struct sk_buff *skb) } if (rt) - rt6_set_expires(rt, jiffies + (HZ * lifetime)); + rt->dst.expires = jiffies + (HZ * lifetime); + if (ra_msg->icmph.icmp6_hop_limit) { in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit; if (rt) diff --git a/trunk/net/ipv6/netfilter/ip6_tables.c b/trunk/net/ipv6/netfilter/ip6_tables.c index 9d4e15559319..94874b0bdcdc 100644 --- a/trunk/net/ipv6/netfilter/ip6_tables.c +++ b/trunk/net/ipv6/netfilter/ip6_tables.c @@ -78,6 +78,19 @@ EXPORT_SYMBOL_GPL(ip6t_alloc_initial_table); Hence the start of any table is given by get_table() below. */ +/* Check for an extension */ +int +ip6t_ext_hdr(u8 nexthdr) +{ + return (nexthdr == IPPROTO_HOPOPTS) || + (nexthdr == IPPROTO_ROUTING) || + (nexthdr == IPPROTO_FRAGMENT) || + (nexthdr == IPPROTO_ESP) || + (nexthdr == IPPROTO_AH) || + (nexthdr == IPPROTO_NONE) || + (nexthdr == IPPROTO_DSTOPTS); +} + /* Returns whether matches rule or not. */ /* Performance critical - called for every packet */ static inline bool @@ -2353,6 +2366,7 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, EXPORT_SYMBOL(ip6t_register_table); EXPORT_SYMBOL(ip6t_unregister_table); EXPORT_SYMBOL(ip6t_do_table); +EXPORT_SYMBOL(ip6t_ext_hdr); EXPORT_SYMBOL(ipv6_find_hdr); module_init(ip6_tables_init); diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index bc4888d902b2..496b62712fe8 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -62,7 +62,7 @@ #include #endif -static struct rt6_info *ip6_rt_copy(struct rt6_info *ort, +static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, const struct in6_addr *dest); static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); static unsigned int ip6_default_advmss(const struct dst_entry *dst); @@ -285,10 +285,6 @@ static void ip6_dst_destroy(struct dst_entry *dst) rt->rt6i_idev = NULL; in6_dev_put(idev); } - - if (!(rt->rt6i_flags & RTF_EXPIRES) && dst->from) - dst_release(dst->from); - if (peer) { rt->rt6i_peer = NULL; inet_putpeer(peer); @@ -333,17 +329,8 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, static __inline__ int rt6_check_expired(const struct rt6_info *rt) { - struct rt6_info *ort = NULL; - - if (rt->rt6i_flags & RTF_EXPIRES) { - if (time_after(jiffies, rt->dst.expires)) - return 1; - } else if (rt->dst.from) { - ort = (struct rt6_info *) rt->dst.from; - return (ort->rt6i_flags & RTF_EXPIRES) && - time_after(jiffies, ort->dst.expires); - } - return 0; + return (rt->rt6i_flags & RTF_EXPIRES) && + time_after(jiffies, rt->dst.expires); } static inline int rt6_need_strict(const struct in6_addr *daddr) @@ -633,11 +620,12 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref); if (rt) { - if (!addrconf_finite_timeout(lifetime)) - rt6_clean_expires(rt); - else - rt6_set_expires(rt, jiffies + HZ * lifetime); - + if (!addrconf_finite_timeout(lifetime)) { + rt->rt6i_flags &= ~RTF_EXPIRES; + } else { + rt->dst.expires = jiffies + HZ * lifetime; + rt->rt6i_flags |= RTF_EXPIRES; + } dst_release(&rt->dst); } return 0; @@ -742,7 +730,7 @@ int ip6_ins_rt(struct rt6_info *rt) return __ip6_ins_rt(rt, &info); } -static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, +static struct rt6_info *rt6_alloc_cow(const struct rt6_info *ort, const struct in6_addr *daddr, const struct in6_addr *saddr) { @@ -893,16 +881,6 @@ static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table * return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags); } -static struct dst_entry *ip6_route_input_lookup(struct net *net, - struct net_device *dev, - struct flowi6 *fl6, int flags) -{ - if (rt6_need_strict(&fl6->daddr) && dev->type != ARPHRD_PIMREG) - flags |= RT6_LOOKUP_F_IFACE; - - return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_input); -} - void ip6_route_input(struct sk_buff *skb) { const struct ipv6hdr *iph = ipv6_hdr(skb); @@ -917,7 +895,10 @@ void ip6_route_input(struct sk_buff *skb) .flowi6_proto = iph->nexthdr, }; - skb_dst_set(skb, ip6_route_input_lookup(net, skb->dev, &fl6, flags)); + if (rt6_need_strict(&iph->daddr) && skb->dev->type != ARPHRD_PIMREG) + flags |= RT6_LOOKUP_F_IFACE; + + skb_dst_set(skb, fib6_rule_lookup(net, &fl6, flags, ip6_pol_route_input)); } static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table, @@ -966,10 +947,10 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori rt->rt6i_idev = ort->rt6i_idev; if (rt->rt6i_idev) in6_dev_hold(rt->rt6i_idev); + rt->dst.expires = 0; rt->rt6i_gateway = ort->rt6i_gateway; - rt->rt6i_flags = ort->rt6i_flags; - rt6_clean_expires(rt); + rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; rt->rt6i_metric = 0; memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key)); @@ -1031,9 +1012,10 @@ static void ip6_link_failure(struct sk_buff *skb) rt = (struct rt6_info *) skb_dst(skb); if (rt) { - if (rt->rt6i_flags & RTF_CACHE) - rt6_update_expires(rt, 0); - else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT)) + if (rt->rt6i_flags & RTF_CACHE) { + dst_set_expires(&rt->dst, 0); + rt->rt6i_flags |= RTF_EXPIRES; + } else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT)) rt->rt6i_node->fn_sernum = -1; } } @@ -1300,12 +1282,9 @@ int ip6_route_add(struct fib6_config *cfg) } rt->dst.obsolete = -1; - - if (cfg->fc_flags & RTF_EXPIRES) - rt6_set_expires(rt, jiffies + - clock_t_to_jiffies(cfg->fc_expires)); - else - rt6_clean_expires(rt); + rt->dst.expires = (cfg->fc_flags & RTF_EXPIRES) ? + jiffies + clock_t_to_jiffies(cfg->fc_expires) : + 0; if (cfg->fc_protocol == RTPROT_UNSPEC) cfg->fc_protocol = RTPROT_BOOT; @@ -1750,8 +1729,8 @@ static void rt6_do_pmtu_disc(const struct in6_addr *daddr, const struct in6_addr features |= RTAX_FEATURE_ALLFRAG; dst_metric_set(&rt->dst, RTAX_FEATURES, features); } - rt6_update_expires(rt, net->ipv6.sysctl.ip6_rt_mtu_expires); - rt->rt6i_flags |= RTF_MODIFIED; + dst_set_expires(&rt->dst, net->ipv6.sysctl.ip6_rt_mtu_expires); + rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES; goto out; } @@ -1779,8 +1758,9 @@ static void rt6_do_pmtu_disc(const struct in6_addr *daddr, const struct in6_addr * which is 10 mins. After 10 mins the decreased pmtu is expired * and detecting PMTU increase will be automatically happened. */ - rt6_update_expires(nrt, net->ipv6.sysctl.ip6_rt_mtu_expires); - nrt->rt6i_flags |= RTF_DYNAMIC; + dst_set_expires(&nrt->dst, net->ipv6.sysctl.ip6_rt_mtu_expires); + nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES; + ip6_ins_rt(nrt); } out: @@ -1812,7 +1792,7 @@ void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *sad * Misc support functions */ -static struct rt6_info *ip6_rt_copy(struct rt6_info *ort, +static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, const struct in6_addr *dest) { struct net *net = dev_net(ort->dst.dev); @@ -1832,14 +1812,10 @@ static struct rt6_info *ip6_rt_copy(struct rt6_info *ort, if (rt->rt6i_idev) in6_dev_hold(rt->rt6i_idev); rt->dst.lastuse = jiffies; + rt->dst.expires = 0; rt->rt6i_gateway = ort->rt6i_gateway; - rt->rt6i_flags = ort->rt6i_flags; - if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) == - (RTF_DEFAULT | RTF_ADDRCONF)) - rt6_set_from(rt, ort); - else - rt6_clean_expires(rt); + rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; rt->rt6i_metric = 0; #ifdef CONFIG_IPV6_SUBTREES @@ -2561,7 +2537,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void struct sk_buff *skb; struct rtmsg *rtm; struct flowi6 fl6; - int err, iif = 0, oif = 0; + int err, iif = 0; err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy); if (err < 0) @@ -2588,29 +2564,15 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void iif = nla_get_u32(tb[RTA_IIF]); if (tb[RTA_OIF]) - oif = nla_get_u32(tb[RTA_OIF]); + fl6.flowi6_oif = nla_get_u32(tb[RTA_OIF]); if (iif) { struct net_device *dev; - int flags = 0; - dev = __dev_get_by_index(net, iif); if (!dev) { err = -ENODEV; goto errout; } - - fl6.flowi6_iif = iif; - - if (!ipv6_addr_any(&fl6.saddr)) - flags |= RT6_LOOKUP_F_HAS_SADDR; - - rt = (struct rt6_info *)ip6_route_input_lookup(net, dev, &fl6, - flags); - } else { - fl6.flowi6_oif = oif; - - rt = (struct rt6_info *)ip6_route_output(net, NULL, &fl6); } skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); @@ -2625,6 +2587,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void skb_reset_mac_header(skb); skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr)); + rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl6); skb_dst_set(skb, &rt->dst); err = rt6_fill_node(net, skb, rt, &fl6.daddr, &fl6.saddr, iif, diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index 98256cf72f9d..12c6ece67f39 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -1383,10 +1383,6 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, tcp_mtup_init(newsk); tcp_sync_mss(newsk, dst_mtu(dst)); newtp->advmss = dst_metric_advmss(dst); - if (tcp_sk(sk)->rx_opt.user_mss && - tcp_sk(sk)->rx_opt.user_mss < newtp->advmss) - newtp->advmss = tcp_sk(sk)->rx_opt.user_mss; - tcp_initialize_rcv_mss(newsk); if (tcp_rsk(req)->snt_synack) tcp_valid_rtt_meas(newsk, @@ -1649,7 +1645,7 @@ static int tcp_v6_rcv(struct sk_buff *skb) #ifdef CONFIG_NET_DMA struct tcp_sock *tp = tcp_sk(sk); if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list) - tp->ucopy.dma_chan = net_dma_find_channel(); + tp->ucopy.dma_chan = dma_find_channel(DMA_MEMCPY); if (tp->ucopy.dma_chan) ret = tcp_v6_do_rcv(sk, skb); else diff --git a/trunk/net/key/af_key.c b/trunk/net/key/af_key.c index 7e5d927b576f..11dbb2255ccb 100644 --- a/trunk/net/key/af_key.c +++ b/trunk/net/key/af_key.c @@ -3480,7 +3480,7 @@ static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, /* Addresses to be used by KM for negotiation, if ext is available */ if (k != NULL && (set_sadb_kmaddress(skb, k) < 0)) - goto err; + return -EINVAL; /* selector src */ set_sadb_address(skb, sasize_sel, SADB_EXT_ADDRESS_SRC, sel); diff --git a/trunk/net/l2tp/l2tp_ip.c b/trunk/net/l2tp/l2tp_ip.c index 6274f0be82b0..55670ec3cd0f 100644 --- a/trunk/net/l2tp/l2tp_ip.c +++ b/trunk/net/l2tp/l2tp_ip.c @@ -232,7 +232,7 @@ static void l2tp_ip_close(struct sock *sk, long timeout) { write_lock_bh(&l2tp_ip_lock); hlist_del_init(&sk->sk_bind_node); - sk_del_node_init(sk); + hlist_del_init(&sk->sk_node); write_unlock_bh(&l2tp_ip_lock); sk_common_release(sk); } @@ -271,8 +271,7 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) goto out; - if (addr->l2tp_addr.s_addr) - inet->inet_rcv_saddr = inet->inet_saddr = addr->l2tp_addr.s_addr; + inet->inet_rcv_saddr = inet->inet_saddr = addr->l2tp_addr.s_addr; if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) inet->inet_saddr = 0; /* Use device */ sk_dst_reset(sk); @@ -442,9 +441,8 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m daddr = lip->l2tp_addr.s_addr; } else { - rc = -EDESTADDRREQ; if (sk->sk_state != TCP_ESTABLISHED) - goto out; + return -EDESTADDRREQ; daddr = inet->inet_daddr; connected = 1; diff --git a/trunk/net/mac80211/agg-rx.c b/trunk/net/mac80211/agg-rx.c index 64d3ce5ea1a0..1068f668ac4e 100644 --- a/trunk/net/mac80211/agg-rx.c +++ b/trunk/net/mac80211/agg-rx.c @@ -49,8 +49,6 @@ static void ieee80211_free_tid_rx(struct rcu_head *h) container_of(h, struct tid_ampdu_rx, rcu_head); int i; - del_timer_sync(&tid_rx->reorder_timer); - for (i = 0; i < tid_rx->buf_size; i++) dev_kfree_skb(tid_rx->reorder_buf[i]); kfree(tid_rx->reorder_buf); @@ -93,6 +91,7 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, tid, WLAN_BACK_RECIPIENT, reason); del_timer_sync(&tid_rx->session_timer); + del_timer_sync(&tid_rx->reorder_timer); call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx); } diff --git a/trunk/net/mac80211/debugfs.c b/trunk/net/mac80211/debugfs.c index 778e5916d7c3..cc5b7a6e7e0b 100644 --- a/trunk/net/mac80211/debugfs.c +++ b/trunk/net/mac80211/debugfs.c @@ -15,6 +15,12 @@ #include "rate.h" #include "debugfs.h" +int mac80211_open_file_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + #define DEBUGFS_FORMAT_BUFFER_SIZE 100 int mac80211_format_buffer(char __user *userbuf, size_t count, @@ -44,7 +50,7 @@ static ssize_t name## _read(struct file *file, char __user *userbuf, \ #define DEBUGFS_READONLY_FILE_OPS(name) \ static const struct file_operations name## _ops = { \ .read = name## _read, \ - .open = simple_open, \ + .open = mac80211_open_file_generic, \ .llseek = generic_file_llseek, \ }; @@ -87,7 +93,7 @@ static ssize_t reset_write(struct file *file, const char __user *user_buf, static const struct file_operations reset_ops = { .write = reset_write, - .open = simple_open, + .open = mac80211_open_file_generic, .llseek = noop_llseek, }; @@ -248,7 +254,7 @@ static ssize_t stats_ ##name## _read(struct file *file, \ \ static const struct file_operations stats_ ##name## _ops = { \ .read = stats_ ##name## _read, \ - .open = simple_open, \ + .open = mac80211_open_file_generic, \ .llseek = generic_file_llseek, \ }; diff --git a/trunk/net/mac80211/debugfs.h b/trunk/net/mac80211/debugfs.h index 9be4e6d71d00..7c87529630f5 100644 --- a/trunk/net/mac80211/debugfs.h +++ b/trunk/net/mac80211/debugfs.h @@ -3,6 +3,7 @@ #ifdef CONFIG_MAC80211_DEBUGFS extern void debugfs_hw_add(struct ieee80211_local *local); +extern int mac80211_open_file_generic(struct inode *inode, struct file *file); extern int mac80211_format_buffer(char __user *userbuf, size_t count, loff_t *ppos, char *fmt, ...); #else diff --git a/trunk/net/mac80211/debugfs_key.c b/trunk/net/mac80211/debugfs_key.c index 7932767bb482..59edcd95a58d 100644 --- a/trunk/net/mac80211/debugfs_key.c +++ b/trunk/net/mac80211/debugfs_key.c @@ -30,7 +30,7 @@ static ssize_t key_##name##_read(struct file *file, \ #define KEY_OPS(name) \ static const struct file_operations key_ ##name## _ops = { \ .read = key_##name##_read, \ - .open = simple_open, \ + .open = mac80211_open_file_generic, \ .llseek = generic_file_llseek, \ } @@ -45,7 +45,7 @@ static const struct file_operations key_ ##name## _ops = { \ #define KEY_CONF_OPS(name) \ static const struct file_operations key_ ##name## _ops = { \ .read = key_conf_##name##_read, \ - .open = simple_open, \ + .open = mac80211_open_file_generic, \ .llseek = generic_file_llseek, \ } diff --git a/trunk/net/mac80211/debugfs_netdev.c b/trunk/net/mac80211/debugfs_netdev.c index 30f99c344847..a32eeda04aa3 100644 --- a/trunk/net/mac80211/debugfs_netdev.c +++ b/trunk/net/mac80211/debugfs_netdev.c @@ -135,7 +135,7 @@ static ssize_t ieee80211_if_read_##name(struct file *file, \ static const struct file_operations name##_ops = { \ .read = ieee80211_if_read_##name, \ .write = (_write), \ - .open = simple_open, \ + .open = mac80211_open_file_generic, \ .llseek = generic_file_llseek, \ } diff --git a/trunk/net/mac80211/debugfs_sta.c b/trunk/net/mac80211/debugfs_sta.c index 832b2da5e4cd..6d45804d09bc 100644 --- a/trunk/net/mac80211/debugfs_sta.c +++ b/trunk/net/mac80211/debugfs_sta.c @@ -33,7 +33,7 @@ static ssize_t sta_ ##name## _read(struct file *file, \ #define STA_OPS(name) \ static const struct file_operations sta_ ##name## _ops = { \ .read = sta_##name##_read, \ - .open = simple_open, \ + .open = mac80211_open_file_generic, \ .llseek = generic_file_llseek, \ } @@ -41,7 +41,7 @@ static const struct file_operations sta_ ##name## _ops = { \ static const struct file_operations sta_ ##name## _ops = { \ .read = sta_##name##_read, \ .write = sta_##name##_write, \ - .open = simple_open, \ + .open = mac80211_open_file_generic, \ .llseek = generic_file_llseek, \ } diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index cef7c29214a8..33fd8d9f714e 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -457,8 +457,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, * fall back to HT20 if we don't use or use * the other extension channel */ - if (!(channel_type == NL80211_CHAN_HT40MINUS || - channel_type == NL80211_CHAN_HT40PLUS) || + if ((channel_type == NL80211_CHAN_HT40MINUS || + channel_type == NL80211_CHAN_HT40PLUS) && channel_type != sdata->u.ibss.channel_type) sta_ht_cap_new.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; diff --git a/trunk/net/mac80211/ieee80211_i.h b/trunk/net/mac80211/ieee80211_i.h index db8fae51714c..d9798a307f20 100644 --- a/trunk/net/mac80211/ieee80211_i.h +++ b/trunk/net/mac80211/ieee80211_i.h @@ -1210,7 +1210,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata); void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata); -void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata); +void ieee80211_mgd_teardown(struct ieee80211_sub_if_data *sdata); /* IBSS code */ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c index c20051b7ffcd..401c01f0731e 100644 --- a/trunk/net/mac80211/iface.c +++ b/trunk/net/mac80211/iface.c @@ -486,8 +486,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, /* free all potentially still buffered bcast frames */ local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps_bc_buf); skb_queue_purge(&sdata->u.ap.ps_bc_buf); - } else if (sdata->vif.type == NL80211_IFTYPE_STATION) { - ieee80211_mgd_stop(sdata); } if (going_down) @@ -646,6 +644,8 @@ static void ieee80211_teardown_sdata(struct net_device *dev) if (ieee80211_vif_is_mesh(&sdata->vif)) mesh_rmc_free(sdata); + else if (sdata->vif.type == NL80211_IFTYPE_STATION) + ieee80211_mgd_teardown(sdata); flushed = sta_info_flush(local, sdata); WARN_ON(flushed); diff --git a/trunk/net/mac80211/main.c b/trunk/net/mac80211/main.c index 16336480c631..b581a24fa15c 100644 --- a/trunk/net/mac80211/main.c +++ b/trunk/net/mac80211/main.c @@ -102,6 +102,9 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) might_sleep(); + /* If this off-channel logic ever changes, ieee80211_on_oper_channel + * may need to change as well. + */ offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; if (local->scan_channel) { chan = local->scan_channel; diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index 20c680bfc3ae..576fb25456dd 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -3387,7 +3387,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, */ printk(KERN_DEBUG "%s: waiting for beacon from %pM\n", sdata->name, ifmgd->bssid); - assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval); + assoc_data->timeout = jiffies + + TU_TO_EXP_TIME(req->bss->beacon_interval); } else { assoc_data->have_beacon = true; assoc_data->sent_assoc = false; @@ -3497,7 +3498,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, return 0; } -void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata) +void ieee80211_mgd_teardown(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; diff --git a/trunk/net/mac80211/rate.c b/trunk/net/mac80211/rate.c index 3313c117b322..b4f7600a3e36 100644 --- a/trunk/net/mac80211/rate.c +++ b/trunk/net/mac80211/rate.c @@ -145,7 +145,7 @@ static ssize_t rcname_read(struct file *file, char __user *userbuf, static const struct file_operations rcname_ops = { .read = rcname_read, - .open = simple_open, + .open = mac80211_open_file_generic, .llseek = default_llseek, }; #endif diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index d64e285400aa..bcfe8c77c839 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -103,7 +103,7 @@ static void ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, struct sk_buff *skb, struct ieee80211_rate *rate, - int rtap_len, bool has_fcs) + int rtap_len) { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_radiotap_header *rthdr; @@ -134,7 +134,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, } /* IEEE80211_RADIOTAP_FLAGS */ - if (has_fcs && (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)) + if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) *pos |= IEEE80211_RADIOTAP_F_FCS; if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) *pos |= IEEE80211_RADIOTAP_F_BADFCS; @@ -294,8 +294,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, } /* prepend radiotap information */ - ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom, - true); + ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom); skb_reset_mac_header(skb); skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -2572,8 +2571,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, goto out_free_skb; /* prepend radiotap information */ - ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom, - false); + ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom); skb_set_mac_header(skb, 0); skb->ip_summed = CHECKSUM_UNNECESSARY; diff --git a/trunk/net/mac80211/scan.c b/trunk/net/mac80211/scan.c index c70e17677135..33cd16901378 100644 --- a/trunk/net/mac80211/scan.c +++ b/trunk/net/mac80211/scan.c @@ -370,7 +370,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) */ drv_sw_scan_start(local); - local->leave_oper_channel_time = jiffies; + local->leave_oper_channel_time = 0; local->next_scan_state = SCAN_DECISION; local->scan_channel_idx = 0; diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index e76facc69e95..782a60198df4 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -1158,8 +1158,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, tx->sta = rcu_dereference(sdata->u.vlan.sta); if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr) return TX_DROP; - } else if (info->flags & IEEE80211_TX_CTL_INJECTED || - tx->sdata->control_port_protocol == tx->skb->protocol) { + } else if (info->flags & IEEE80211_TX_CTL_INJECTED) { tx->sta = sta_info_get_bss(sdata, hdr->addr1); } if (!tx->sta) diff --git a/trunk/net/netfilter/ipvs/ip_vs_core.c b/trunk/net/netfilter/ipvs/ip_vs_core.c index 00bdb1d9d690..2555816e7788 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_core.c +++ b/trunk/net/netfilter/ipvs/ip_vs_core.c @@ -1924,7 +1924,6 @@ static int __net_init __ip_vs_init(struct net *net) control_fail: ip_vs_estimator_net_cleanup(net); estimator_fail: - net->ipvs = NULL; return -ENOMEM; } @@ -1937,7 +1936,6 @@ static void __net_exit __ip_vs_cleanup(struct net *net) ip_vs_control_net_cleanup(net); ip_vs_estimator_net_cleanup(net); IP_VS_DBG(2, "ipvs netns %d released\n", net_ipvs(net)->gen); - net->ipvs = NULL; } static void __net_exit __ip_vs_dev_cleanup(struct net *net) @@ -1995,18 +1993,10 @@ static int __init ip_vs_init(void) goto cleanup_dev; } - ret = ip_vs_register_nl_ioctl(); - if (ret < 0) { - pr_err("can't register netlink/ioctl.\n"); - goto cleanup_hooks; - } - pr_info("ipvs loaded.\n"); return ret; -cleanup_hooks: - nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops)); cleanup_dev: unregister_pernet_device(&ipvs_core_dev_ops); cleanup_sub: @@ -2022,7 +2012,6 @@ static int __init ip_vs_init(void) static void __exit ip_vs_cleanup(void) { - ip_vs_unregister_nl_ioctl(); nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops)); unregister_pernet_device(&ipvs_core_dev_ops); unregister_pernet_subsys(&ipvs_core_ops); /* free ip_vs struct */ diff --git a/trunk/net/netfilter/ipvs/ip_vs_ctl.c b/trunk/net/netfilter/ipvs/ip_vs_ctl.c index f5589987fc80..b3afe189af61 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_ctl.c +++ b/trunk/net/netfilter/ipvs/ip_vs_ctl.c @@ -3680,7 +3680,7 @@ int __net_init ip_vs_control_net_init_sysctl(struct net *net) return 0; } -void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net) +void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net) { struct netns_ipvs *ipvs = net_ipvs(net); @@ -3692,7 +3692,7 @@ void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net) #else int __net_init ip_vs_control_net_init_sysctl(struct net *net) { return 0; } -void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net) { } +void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net) { } #endif @@ -3750,10 +3750,21 @@ void __net_exit ip_vs_control_net_cleanup(struct net *net) free_percpu(ipvs->tot_stats.cpustats); } -int __init ip_vs_register_nl_ioctl(void) +int __init ip_vs_control_init(void) { + int idx; int ret; + EnterFunction(2); + + /* Initialize svc_table, ip_vs_svc_fwm_table, rs_table */ + for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { + INIT_LIST_HEAD(&ip_vs_svc_table[idx]); + INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]); + } + + smp_wmb(); /* Do we really need it now ? */ + ret = nf_register_sockopt(&ip_vs_sockopts); if (ret) { pr_err("cannot register sockopt.\n"); @@ -3765,41 +3776,20 @@ int __init ip_vs_register_nl_ioctl(void) pr_err("cannot register Generic Netlink interface.\n"); goto err_genl; } - return 0; - -err_genl: - nf_unregister_sockopt(&ip_vs_sockopts); -err_sock: - return ret; -} - -void ip_vs_unregister_nl_ioctl(void) -{ - ip_vs_genl_unregister(); - nf_unregister_sockopt(&ip_vs_sockopts); -} - -int __init ip_vs_control_init(void) -{ - int idx; - int ret; - - EnterFunction(2); - - /* Initialize svc_table, ip_vs_svc_fwm_table, rs_table */ - for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { - INIT_LIST_HEAD(&ip_vs_svc_table[idx]); - INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]); - } - - smp_wmb(); /* Do we really need it now ? */ ret = register_netdevice_notifier(&ip_vs_dst_notifier); if (ret < 0) - return ret; + goto err_notf; LeaveFunction(2); return 0; + +err_notf: + ip_vs_genl_unregister(); +err_genl: + nf_unregister_sockopt(&ip_vs_sockopts); +err_sock: + return ret; } @@ -3807,5 +3797,7 @@ void ip_vs_control_cleanup(void) { EnterFunction(2); unregister_netdevice_notifier(&ip_vs_dst_notifier); + ip_vs_genl_unregister(); + nf_unregister_sockopt(&ip_vs_sockopts); LeaveFunction(2); } diff --git a/trunk/net/netfilter/ipvs/ip_vs_ftp.c b/trunk/net/netfilter/ipvs/ip_vs_ftp.c index e39f693dd3e4..538d74ee4f68 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_ftp.c +++ b/trunk/net/netfilter/ipvs/ip_vs_ftp.c @@ -439,8 +439,6 @@ static int __net_init __ip_vs_ftp_init(struct net *net) struct ip_vs_app *app; struct netns_ipvs *ipvs = net_ipvs(net); - if (!ipvs) - return -ENOENT; app = kmemdup(&ip_vs_ftp, sizeof(struct ip_vs_app), GFP_KERNEL); if (!app) return -ENOMEM; diff --git a/trunk/net/netfilter/ipvs/ip_vs_lblc.c b/trunk/net/netfilter/ipvs/ip_vs_lblc.c index caa43704e55e..0f16283fd058 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_lblc.c +++ b/trunk/net/netfilter/ipvs/ip_vs_lblc.c @@ -551,9 +551,6 @@ static int __net_init __ip_vs_lblc_init(struct net *net) { struct netns_ipvs *ipvs = net_ipvs(net); - if (!ipvs) - return -ENOENT; - if (!net_eq(net, &init_net)) { ipvs->lblc_ctl_table = kmemdup(vs_vars_table, sizeof(vs_vars_table), diff --git a/trunk/net/netfilter/ipvs/ip_vs_lblcr.c b/trunk/net/netfilter/ipvs/ip_vs_lblcr.c index 548bf37aa29e..eec797f8cce7 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_lblcr.c +++ b/trunk/net/netfilter/ipvs/ip_vs_lblcr.c @@ -745,9 +745,6 @@ static int __net_init __ip_vs_lblcr_init(struct net *net) { struct netns_ipvs *ipvs = net_ipvs(net); - if (!ipvs) - return -ENOENT; - if (!net_eq(net, &init_net)) { ipvs->lblcr_ctl_table = kmemdup(vs_vars_table, sizeof(vs_vars_table), diff --git a/trunk/net/netfilter/ipvs/ip_vs_proto.c b/trunk/net/netfilter/ipvs/ip_vs_proto.c index ed835e67a07e..f843a8833250 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_proto.c +++ b/trunk/net/netfilter/ipvs/ip_vs_proto.c @@ -59,6 +59,9 @@ static int __used __init register_ip_vs_protocol(struct ip_vs_protocol *pp) return 0; } +#if defined(CONFIG_IP_VS_PROTO_TCP) || defined(CONFIG_IP_VS_PROTO_UDP) || \ + defined(CONFIG_IP_VS_PROTO_SCTP) || defined(CONFIG_IP_VS_PROTO_AH) || \ + defined(CONFIG_IP_VS_PROTO_ESP) /* * register an ipvs protocols netns related data */ @@ -78,18 +81,12 @@ register_ip_vs_proto_netns(struct net *net, struct ip_vs_protocol *pp) ipvs->proto_data_table[hash] = pd; atomic_set(&pd->appcnt, 0); /* Init app counter */ - if (pp->init_netns != NULL) { - int ret = pp->init_netns(net, pd); - if (ret) { - /* unlink an free proto data */ - ipvs->proto_data_table[hash] = pd->next; - kfree(pd); - return ret; - } - } + if (pp->init_netns != NULL) + pp->init_netns(net, pd); return 0; } +#endif /* * unregister an ipvs protocol @@ -319,35 +316,22 @@ ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp, */ int __net_init ip_vs_protocol_net_init(struct net *net) { - int i, ret; - static struct ip_vs_protocol *protos[] = { #ifdef CONFIG_IP_VS_PROTO_TCP - &ip_vs_protocol_tcp, + register_ip_vs_proto_netns(net, &ip_vs_protocol_tcp); #endif #ifdef CONFIG_IP_VS_PROTO_UDP - &ip_vs_protocol_udp, + register_ip_vs_proto_netns(net, &ip_vs_protocol_udp); #endif #ifdef CONFIG_IP_VS_PROTO_SCTP - &ip_vs_protocol_sctp, + register_ip_vs_proto_netns(net, &ip_vs_protocol_sctp); #endif #ifdef CONFIG_IP_VS_PROTO_AH - &ip_vs_protocol_ah, + register_ip_vs_proto_netns(net, &ip_vs_protocol_ah); #endif #ifdef CONFIG_IP_VS_PROTO_ESP - &ip_vs_protocol_esp, + register_ip_vs_proto_netns(net, &ip_vs_protocol_esp); #endif - }; - - for (i = 0; i < ARRAY_SIZE(protos); i++) { - ret = register_ip_vs_proto_netns(net, protos[i]); - if (ret < 0) - goto cleanup; - } return 0; - -cleanup: - ip_vs_protocol_net_cleanup(net); - return ret; } void __net_exit ip_vs_protocol_net_cleanup(struct net *net) diff --git a/trunk/net/netfilter/ipvs/ip_vs_proto_sctp.c b/trunk/net/netfilter/ipvs/ip_vs_proto_sctp.c index 9f3fb751c491..1fbf7a2816f5 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_proto_sctp.c +++ b/trunk/net/netfilter/ipvs/ip_vs_proto_sctp.c @@ -1090,7 +1090,7 @@ static int sctp_app_conn_bind(struct ip_vs_conn *cp) * timeouts is netns related now. * --------------------------------------------- */ -static int __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd) +static void __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd) { struct netns_ipvs *ipvs = net_ipvs(net); @@ -1098,9 +1098,6 @@ static int __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd) spin_lock_init(&ipvs->sctp_app_lock); pd->timeout_table = ip_vs_create_timeout_table((int *)sctp_timeouts, sizeof(sctp_timeouts)); - if (!pd->timeout_table) - return -ENOMEM; - return 0; } static void __ip_vs_sctp_exit(struct net *net, struct ip_vs_proto_data *pd) diff --git a/trunk/net/netfilter/ipvs/ip_vs_proto_tcp.c b/trunk/net/netfilter/ipvs/ip_vs_proto_tcp.c index cd609cc62721..ef8641f7af83 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_proto_tcp.c +++ b/trunk/net/netfilter/ipvs/ip_vs_proto_tcp.c @@ -677,7 +677,7 @@ void ip_vs_tcp_conn_listen(struct net *net, struct ip_vs_conn *cp) * timeouts is netns related now. * --------------------------------------------- */ -static int __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd) +static void __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd) { struct netns_ipvs *ipvs = net_ipvs(net); @@ -685,10 +685,7 @@ static int __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd) spin_lock_init(&ipvs->tcp_app_lock); pd->timeout_table = ip_vs_create_timeout_table((int *)tcp_timeouts, sizeof(tcp_timeouts)); - if (!pd->timeout_table) - return -ENOMEM; pd->tcp_state_table = tcp_states; - return 0; } static void __ip_vs_tcp_exit(struct net *net, struct ip_vs_proto_data *pd) diff --git a/trunk/net/netfilter/ipvs/ip_vs_proto_udp.c b/trunk/net/netfilter/ipvs/ip_vs_proto_udp.c index 2fedb2dcb3d1..f4b7262896bb 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_proto_udp.c +++ b/trunk/net/netfilter/ipvs/ip_vs_proto_udp.c @@ -467,7 +467,7 @@ udp_state_transition(struct ip_vs_conn *cp, int direction, cp->timeout = pd->timeout_table[IP_VS_UDP_S_NORMAL]; } -static int __udp_init(struct net *net, struct ip_vs_proto_data *pd) +static void __udp_init(struct net *net, struct ip_vs_proto_data *pd) { struct netns_ipvs *ipvs = net_ipvs(net); @@ -475,9 +475,6 @@ static int __udp_init(struct net *net, struct ip_vs_proto_data *pd) spin_lock_init(&ipvs->udp_app_lock); pd->timeout_table = ip_vs_create_timeout_table((int *)udp_timeouts, sizeof(udp_timeouts)); - if (!pd->timeout_table) - return -ENOMEM; - return 0; } static void __udp_exit(struct net *net, struct ip_vs_proto_data *pd) diff --git a/trunk/net/netfilter/nf_conntrack_core.c b/trunk/net/netfilter/nf_conntrack_core.c index 729f157a0efa..cbdb754dbb10 100644 --- a/trunk/net/netfilter/nf_conntrack_core.c +++ b/trunk/net/netfilter/nf_conntrack_core.c @@ -735,7 +735,6 @@ __nf_conntrack_alloc(struct net *net, u16 zone, #ifdef CONFIG_NF_CONNTRACK_ZONES out_free: - atomic_dec(&net->ct.count); kmem_cache_free(net->ct.nf_conntrack_cachep, ct); return ERR_PTR(-ENOMEM); #endif @@ -1592,7 +1591,7 @@ static int nf_conntrack_init_net(struct net *net) return 0; err_timeout: - nf_conntrack_ecache_fini(net); + nf_conntrack_timeout_fini(net); err_ecache: nf_conntrack_tstamp_fini(net); err_tstamp: diff --git a/trunk/net/netfilter/nf_conntrack_proto_tcp.c b/trunk/net/netfilter/nf_conntrack_proto_tcp.c index 0d07a1dcf605..361eade62a09 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_tcp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_tcp.c @@ -584,8 +584,8 @@ static bool tcp_in_window(const struct nf_conn *ct, * Let's try to use the data from the packet. */ sender->td_end = end; - swin = win << sender->td_scale; - sender->td_maxwin = (swin == 0 ? 1 : swin); + win <<= sender->td_scale; + sender->td_maxwin = (win == 0 ? 1 : win); sender->td_maxend = end + sender->td_maxwin; /* * We haven't seen traffic in the other direction yet diff --git a/trunk/net/netfilter/nfnetlink_acct.c b/trunk/net/netfilter/nfnetlink_acct.c index d98c868c148b..3eb348bfc4fb 100644 --- a/trunk/net/netfilter/nfnetlink_acct.c +++ b/trunk/net/netfilter/nfnetlink_acct.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -18,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/trunk/net/netfilter/xt_CT.c b/trunk/net/netfilter/xt_CT.c index 3746d8b9a478..0c8e43810ce3 100644 --- a/trunk/net/netfilter/xt_CT.c +++ b/trunk/net/netfilter/xt_CT.c @@ -150,17 +150,6 @@ static int xt_ct_tg_check_v0(const struct xt_tgchk_param *par) return ret; } -#ifdef CONFIG_NF_CONNTRACK_TIMEOUT -static void __xt_ct_tg_timeout_put(struct ctnl_timeout *timeout) -{ - typeof(nf_ct_timeout_put_hook) timeout_put; - - timeout_put = rcu_dereference(nf_ct_timeout_put_hook); - if (timeout_put) - timeout_put(timeout); -} -#endif - static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) { struct xt_ct_target_info_v1 *info = par->targinfo; @@ -169,9 +158,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) struct nf_conn *ct; int ret = 0; u8 proto; -#ifdef CONFIG_NF_CONNTRACK_TIMEOUT - struct ctnl_timeout *timeout; -#endif + if (info->flags & ~XT_CT_NOTRACK) return -EINVAL; @@ -227,8 +214,9 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) } #ifdef CONFIG_NF_CONNTRACK_TIMEOUT - if (info->timeout[0]) { + if (info->timeout) { typeof(nf_ct_timeout_find_get_hook) timeout_find_get; + struct ctnl_timeout *timeout; struct nf_conn_timeout *timeout_ext; rcu_read_lock(); @@ -257,7 +245,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) pr_info("Timeout policy `%s' can only be " "used by L3 protocol number %d\n", info->timeout, timeout->l3num); - goto err5; + goto err4; } /* Make sure the timeout policy matches any existing * protocol tracker, otherwise default to generic. @@ -270,13 +258,13 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) "used by L4 protocol number %d\n", info->timeout, timeout->l4proto->l4proto); - goto err5; + goto err4; } timeout_ext = nf_ct_timeout_ext_add(ct, timeout, - GFP_ATOMIC); + GFP_KERNEL); if (timeout_ext == NULL) { ret = -ENOMEM; - goto err5; + goto err4; } } else { ret = -ENOENT; @@ -293,12 +281,8 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) info->ct = ct; return 0; -#ifdef CONFIG_NF_CONNTRACK_TIMEOUT -err5: - __xt_ct_tg_timeout_put(timeout); err4: rcu_read_unlock(); -#endif err3: nf_conntrack_free(ct); err2: diff --git a/trunk/net/netlink/af_netlink.c b/trunk/net/netlink/af_netlink.c index faa48f70b7c9..32bb75324e76 100644 --- a/trunk/net/netlink/af_netlink.c +++ b/trunk/net/netlink/af_netlink.c @@ -829,19 +829,12 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb, return 0; } -static int __netlink_sendskb(struct sock *sk, struct sk_buff *skb) +int netlink_sendskb(struct sock *sk, struct sk_buff *skb) { int len = skb->len; skb_queue_tail(&sk->sk_receive_queue, skb); sk->sk_data_ready(sk, len); - return len; -} - -int netlink_sendskb(struct sock *sk, struct sk_buff *skb) -{ - int len = __netlink_sendskb(sk, skb); - sock_put(sk); return len; } @@ -964,7 +957,8 @@ static int netlink_broadcast_deliver(struct sock *sk, struct sk_buff *skb) if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf && !test_bit(0, &nlk->state)) { skb_set_owner_r(skb, sk); - __netlink_sendskb(sk, skb); + skb_queue_tail(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk, skb->len); return atomic_read(&sk->sk_rmem_alloc) > (sk->sk_rcvbuf >> 1); } return -1; @@ -1704,8 +1698,10 @@ static int netlink_dump(struct sock *sk) if (sk_filter(sk, skb)) kfree_skb(skb); - else - __netlink_sendskb(sk, skb); + else { + skb_queue_tail(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk, skb->len); + } return 0; } @@ -1719,8 +1715,10 @@ static int netlink_dump(struct sock *sk) if (sk_filter(sk, skb)) kfree_skb(skb); - else - __netlink_sendskb(sk, skb); + else { + skb_queue_tail(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk, skb->len); + } if (cb->done) cb->done(cb); diff --git a/trunk/net/nfc/llcp/commands.c b/trunk/net/nfc/llcp/commands.c index ef10ffcb4b6f..7b76eb7192f3 100644 --- a/trunk/net/nfc/llcp/commands.c +++ b/trunk/net/nfc/llcp/commands.c @@ -474,7 +474,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, while (remaining_len > 0) { - frag_len = min_t(size_t, local->remote_miu, remaining_len); + frag_len = min_t(u16, local->remote_miu, remaining_len); pr_debug("Fragment %zd bytes remaining %zd", frag_len, remaining_len); @@ -497,7 +497,7 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, release_sock(sk); remaining_len -= frag_len; - msg_ptr += frag_len; + msg_ptr += len; } kfree(msg_data); diff --git a/trunk/net/phonet/pep.c b/trunk/net/phonet/pep.c index 9726fe684ab8..9f60008740e3 100644 --- a/trunk/net/phonet/pep.c +++ b/trunk/net/phonet/pep.c @@ -1130,9 +1130,6 @@ static int pep_sendmsg(struct kiocb *iocb, struct sock *sk, int flags = msg->msg_flags; int err, done; - if (len > USHRT_MAX) - return -EMSGSIZE; - if ((msg->msg_flags & ~(MSG_DONTWAIT|MSG_EOR|MSG_NOSIGNAL| MSG_CMSG_COMPAT)) || !(msg->msg_flags & MSG_EOR)) diff --git a/trunk/net/phonet/pn_dev.c b/trunk/net/phonet/pn_dev.c index bf5cf69c820a..9b9a85ecc4c7 100644 --- a/trunk/net/phonet/pn_dev.c +++ b/trunk/net/phonet/pn_dev.c @@ -331,6 +331,23 @@ static int __net_init phonet_init_net(struct net *net) static void __net_exit phonet_exit_net(struct net *net) { + struct phonet_net *pnn = phonet_pernet(net); + struct net_device *dev; + unsigned i; + + rtnl_lock(); + for_each_netdev(net, dev) + phonet_device_destroy(dev); + + for (i = 0; i < 64; i++) { + dev = pnn->routes.table[i]; + if (dev) { + rtm_phonet_notify(RTM_DELROUTE, dev, i); + dev_put(dev); + } + } + rtnl_unlock(); + proc_net_remove(net, "phonet"); } @@ -344,7 +361,7 @@ static struct pernet_operations phonet_net_ops = { /* Initialize Phonet devices list */ int __init phonet_device_init(void) { - int err = register_pernet_subsys(&phonet_net_ops); + int err = register_pernet_device(&phonet_net_ops); if (err) return err; @@ -360,7 +377,7 @@ void phonet_device_exit(void) { rtnl_unregister_all(PF_PHONET); unregister_netdevice_notifier(&phonet_device_notifier); - unregister_pernet_subsys(&phonet_net_ops); + unregister_pernet_device(&phonet_net_ops); proc_net_remove(&init_net, "pnresource"); } diff --git a/trunk/net/rose/rose_dev.c b/trunk/net/rose/rose_dev.c index 906cc05bba63..1ab8689726ec 100644 --- a/trunk/net/rose/rose_dev.c +++ b/trunk/net/rose/rose_dev.c @@ -95,11 +95,11 @@ static int rose_set_mac_address(struct net_device *dev, void *addr) struct sockaddr *sa = addr; int err; - if (!memcmp(dev->dev_addr, sa->sa_data, dev->addr_len)) + if (!memcpy(dev->dev_addr, sa->sa_data, dev->addr_len)) return 0; if (dev->flags & IFF_UP) { - err = rose_add_loopback_node((rose_address *)sa->sa_data); + err = rose_add_loopback_node((rose_address *)dev->dev_addr); if (err) return err; diff --git a/trunk/net/sched/sch_gred.c b/trunk/net/sched/sch_gred.c index 8179494c269a..0b15236be7b6 100644 --- a/trunk/net/sched/sch_gred.c +++ b/trunk/net/sched/sch_gred.c @@ -565,8 +565,11 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) opt.packets = q->packetsin; opt.bytesin = q->bytesin; - if (gred_wred_mode(table)) - gred_load_wred_set(table, q); + if (gred_wred_mode(table)) { + q->vars.qidlestart = + table->tab[table->def]->vars.qidlestart; + q->vars.qavg = table->tab[table->def]->vars.qavg; + } opt.qave = red_calc_qavg(&q->parms, &q->vars, q->vars.qavg); diff --git a/trunk/net/sched/sch_netem.c b/trunk/net/sched/sch_netem.c index ebd22966f748..5da548fa7ae9 100644 --- a/trunk/net/sched/sch_netem.c +++ b/trunk/net/sched/sch_netem.c @@ -408,8 +408,10 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor)) { if (!(skb = skb_unshare(skb, GFP_ATOMIC)) || (skb->ip_summed == CHECKSUM_PARTIAL && - skb_checksum_help(skb))) - return qdisc_drop(skb, sch); + skb_checksum_help(skb))) { + sch->qstats.drops++; + return NET_XMIT_DROP; + } skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8); } diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index 92ba71dfe080..06b42b7f5a02 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -4133,10 +4133,9 @@ static int sctp_getsockopt_disable_fragments(struct sock *sk, int len, static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval, int __user *optlen) { - if (len <= 0) + if (len < sizeof(struct sctp_event_subscribe)) return -EINVAL; - if (len > sizeof(struct sctp_event_subscribe)) - len = sizeof(struct sctp_event_subscribe); + len = sizeof(struct sctp_event_subscribe); if (put_user(len, optlen)) return -EFAULT; if (copy_to_user(optval, &sctp_sk(sk)->subscribe, len)) diff --git a/trunk/net/socket.c b/trunk/net/socket.c index 851edcd6b098..484cc6953fc6 100644 --- a/trunk/net/socket.c +++ b/trunk/net/socket.c @@ -811,9 +811,9 @@ static ssize_t sock_sendpage(struct file *file, struct page *page, sock = file->private_data; - flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0; - /* more is a combination of MSG_MORE and MSG_SENDPAGE_NOTLAST */ - flags |= more; + flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT; + if (more) + flags |= MSG_MORE; return kernel_sendpage(sock, page, offset, size, flags); } diff --git a/trunk/net/sunrpc/clnt.c b/trunk/net/sunrpc/clnt.c index adf2990acebf..67972462a543 100644 --- a/trunk/net/sunrpc/clnt.c +++ b/trunk/net/sunrpc/clnt.c @@ -176,22 +176,16 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name) return 0; } -static inline int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event) -{ - if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) || - ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry)) - return 1; - return 0; -} - -static int __rpc_clnt_handle_event(struct rpc_clnt *clnt, unsigned long event, - struct super_block *sb) +static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event, + struct super_block *sb) { struct dentry *dentry; int err = 0; switch (event) { case RPC_PIPEFS_MOUNT: + if (clnt->cl_program->pipe_dir_name == NULL) + break; dentry = rpc_setup_pipedir_sb(sb, clnt, clnt->cl_program->pipe_dir_name); BUG_ON(dentry == NULL); @@ -214,20 +208,6 @@ static int __rpc_clnt_handle_event(struct rpc_clnt *clnt, unsigned long event, return err; } -static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event, - struct super_block *sb) -{ - int error = 0; - - for (;; clnt = clnt->cl_parent) { - if (!rpc_clnt_skip_event(clnt, event)) - error = __rpc_clnt_handle_event(clnt, event, sb); - if (error || clnt == clnt->cl_parent) - break; - } - return error; -} - static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event) { struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); @@ -235,12 +215,10 @@ static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event) spin_lock(&sn->rpc_client_lock); list_for_each_entry(clnt, &sn->all_clients, cl_clients) { - if (clnt->cl_program->pipe_dir_name == NULL) - break; - if (rpc_clnt_skip_event(clnt, event)) - continue; - if (atomic_inc_not_zero(&clnt->cl_count) == 0) + if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) || + ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry)) continue; + atomic_inc(&clnt->cl_count); spin_unlock(&sn->rpc_client_lock); return clnt; } @@ -279,14 +257,6 @@ void rpc_clients_notifier_unregister(void) return rpc_pipefs_notifier_unregister(&rpc_clients_block); } -static void rpc_clnt_set_nodename(struct rpc_clnt *clnt, const char *nodename) -{ - clnt->cl_nodelen = strlen(nodename); - if (clnt->cl_nodelen > UNX_MAXNODENAME) - clnt->cl_nodelen = UNX_MAXNODENAME; - memcpy(clnt->cl_nodename, nodename, clnt->cl_nodelen); -} - static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) { const struct rpc_program *program = args->program; @@ -367,7 +337,10 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru } /* save the nodename */ - rpc_clnt_set_nodename(clnt, utsname()->nodename); + clnt->cl_nodelen = strlen(init_utsname()->nodename); + if (clnt->cl_nodelen > UNX_MAXNODENAME) + clnt->cl_nodelen = UNX_MAXNODENAME; + memcpy(clnt->cl_nodename, init_utsname()->nodename, clnt->cl_nodelen); rpc_register_client(clnt); return clnt; @@ -526,7 +499,6 @@ rpc_clone_client(struct rpc_clnt *clnt) err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); if (err != 0) goto out_no_path; - rpc_clnt_set_nodename(new, utsname()->nodename); if (new->cl_auth) atomic_inc(&new->cl_auth->au_count); atomic_inc(&clnt->cl_count); diff --git a/trunk/net/sunrpc/rpc_pipe.c b/trunk/net/sunrpc/rpc_pipe.c index 3b62cf288031..0af37fc46818 100644 --- a/trunk/net/sunrpc/rpc_pipe.c +++ b/trunk/net/sunrpc/rpc_pipe.c @@ -1126,20 +1126,19 @@ rpc_fill_super(struct super_block *sb, void *data, int silent) return -ENOMEM; dprintk("RPC: sending pipefs MOUNT notification for net %p%s\n", net, NET_NAME(net)); - sn->pipefs_sb = sb; err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list, RPC_PIPEFS_MOUNT, sb); if (err) goto err_depopulate; sb->s_fs_info = get_net(net); + sn->pipefs_sb = sb; return 0; err_depopulate: blocking_notifier_call_chain(&rpc_pipefs_notifier_list, RPC_PIPEFS_UMOUNT, sb); - sn->pipefs_sb = NULL; __rpc_depopulate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF); return err; } diff --git a/trunk/net/sunrpc/sunrpc_syms.c b/trunk/net/sunrpc/sunrpc_syms.c index 3d6498af9adc..8adfc88e793a 100644 --- a/trunk/net/sunrpc/sunrpc_syms.c +++ b/trunk/net/sunrpc/sunrpc_syms.c @@ -75,20 +75,19 @@ static struct pernet_operations sunrpc_net_ops = { static int __init init_sunrpc(void) { - int err = rpc_init_mempool(); + int err = register_rpc_pipefs(); if (err) goto out; - err = rpcauth_init_module(); + err = rpc_init_mempool(); if (err) goto out2; + err = rpcauth_init_module(); + if (err) + goto out3; cache_initialize(); err = register_pernet_subsys(&sunrpc_net_ops); - if (err) - goto out3; - - err = register_rpc_pipefs(); if (err) goto out4; #ifdef RPC_DEBUG @@ -99,11 +98,11 @@ init_sunrpc(void) return 0; out4: - unregister_pernet_subsys(&sunrpc_net_ops); -out3: rpcauth_remove_module(); -out2: +out3: rpc_destroy_mempool(); +out2: + unregister_rpc_pipefs(); out: return err; } diff --git a/trunk/net/wireless/debugfs.c b/trunk/net/wireless/debugfs.c index 920cabe0461b..39765bcfb472 100644 --- a/trunk/net/wireless/debugfs.c +++ b/trunk/net/wireless/debugfs.c @@ -13,6 +13,12 @@ #include "core.h" #include "debugfs.h" +static int cfg80211_open_file_generic(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + #define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \ static ssize_t name## _read(struct file *file, char __user *userbuf, \ size_t count, loff_t *ppos) \ @@ -27,7 +33,7 @@ static ssize_t name## _read(struct file *file, char __user *userbuf, \ \ static const struct file_operations name## _ops = { \ .read = name## _read, \ - .open = simple_open, \ + .open = cfg80211_open_file_generic, \ .llseek = generic_file_llseek, \ }; @@ -96,7 +102,7 @@ static ssize_t ht40allow_map_read(struct file *file, static const struct file_operations ht40allow_map_ops = { .read = ht40allow_map_read, - .open = simple_open, + .open = cfg80211_open_file_generic, .llseek = default_llseek, }; diff --git a/trunk/net/wireless/nl80211.c b/trunk/net/wireless/nl80211.c index f432c57af05d..4c1eb9472ddb 100644 --- a/trunk/net/wireless/nl80211.c +++ b/trunk/net/wireless/nl80211.c @@ -1294,11 +1294,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) goto bad_res; } - if (!netif_running(netdev)) { - result = -ENETDOWN; - goto bad_res; - } - nla_for_each_nested(nl_txq_params, info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], rem_txq_params) { @@ -2391,9 +2386,7 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, } static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, - int flags, - struct cfg80211_registered_device *rdev, - struct net_device *dev, + int flags, struct net_device *dev, const u8 *mac_addr, struct station_info *sinfo) { void *hdr; @@ -2432,18 +2425,12 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, if (sinfo->filled & STATION_INFO_PLINK_STATE) NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE, sinfo->plink_state); - switch (rdev->wiphy.signal_type) { - case CFG80211_SIGNAL_TYPE_MBM: - if (sinfo->filled & STATION_INFO_SIGNAL) - NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL, - sinfo->signal); - if (sinfo->filled & STATION_INFO_SIGNAL_AVG) - NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG, - sinfo->signal_avg); - break; - default: - break; - } + if (sinfo->filled & STATION_INFO_SIGNAL) + NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL, + sinfo->signal); + if (sinfo->filled & STATION_INFO_SIGNAL_AVG) + NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL_AVG, + sinfo->signal_avg); if (sinfo->filled & STATION_INFO_TX_BITRATE) { if (!nl80211_put_sta_rate(msg, &sinfo->txrate, NL80211_STA_INFO_TX_BITRATE)) @@ -2536,7 +2523,7 @@ static int nl80211_dump_station(struct sk_buff *skb, if (nl80211_send_station(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, NLM_F_MULTI, - dev, netdev, mac_addr, + netdev, mac_addr, &sinfo) < 0) goto out; @@ -2581,7 +2568,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) return -ENOMEM; if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0, - rdev, dev, mac_addr, &sinfo) < 0) { + dev, mac_addr, &sinfo) < 0) { nlmsg_free(msg); return -ENOBUFS; } @@ -6389,7 +6376,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_get_key, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6421,7 +6408,7 @@ static struct genl_ops nl80211_ops[] = { .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, .doit = nl80211_set_beacon, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6429,7 +6416,7 @@ static struct genl_ops nl80211_ops[] = { .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, .doit = nl80211_start_ap, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6437,7 +6424,7 @@ static struct genl_ops nl80211_ops[] = { .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, .doit = nl80211_stop_ap, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6453,7 +6440,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_set_station, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6469,7 +6456,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_del_station, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6502,7 +6489,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_del_mpath, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6510,7 +6497,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_set_bss, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6536,7 +6523,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_get_mesh_config, .policy = nl80211_policy, /* can be retrieved by unprivileged users */ - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6669,7 +6656,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_setdel_pmksa, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6677,7 +6664,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_setdel_pmksa, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6685,7 +6672,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_flush_pmksa, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -6845,7 +6832,7 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_probe_client, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + .internal_flags = NL80211_FLAG_NEED_NETDEV | NL80211_FLAG_NEED_RTNL, }, { @@ -7609,8 +7596,7 @@ void nl80211_send_sta_event(struct cfg80211_registered_device *rdev, if (!msg) return; - if (nl80211_send_station(msg, 0, 0, 0, - rdev, dev, mac_addr, sinfo) < 0) { + if (nl80211_send_station(msg, 0, 0, 0, dev, mac_addr, sinfo) < 0) { nlmsg_free(msg); return; } diff --git a/trunk/net/wireless/util.c b/trunk/net/wireless/util.c index 957f25621617..1b7a08df933c 100644 --- a/trunk/net/wireless/util.c +++ b/trunk/net/wireless/util.c @@ -989,7 +989,7 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, if (rdev->wiphy.software_iftypes & BIT(iftype)) continue; for (j = 0; j < c->n_limits; j++) { - if (!(limits[j].types & BIT(iftype))) + if (!(limits[j].types & iftype)) continue; if (limits[j].max < num[iftype]) goto cont; diff --git a/trunk/net/wireless/wext-core.c b/trunk/net/wireless/wext-core.c index af648e08e61b..0af7f54e4f61 100644 --- a/trunk/net/wireless/wext-core.c +++ b/trunk/net/wireless/wext-core.c @@ -780,10 +780,8 @@ static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd, if (cmd == SIOCSIWENCODEEXT) { struct iw_encode_ext *ee = (void *) extra; - if (iwp->length < sizeof(*ee) + ee->key_len) { - err = -EFAULT; - goto out; - } + if (iwp->length < sizeof(*ee) + ee->key_len) + return -EFAULT; } } diff --git a/trunk/scripts/Kbuild.include b/trunk/scripts/Kbuild.include index 6a3ee981931d..d897278b1f97 100644 --- a/trunk/scripts/Kbuild.include +++ b/trunk/scripts/Kbuild.include @@ -104,7 +104,7 @@ as-option = $(call try-run,\ # Usage: cflags-y += $(call as-instr,instr,option1,option2) as-instr = $(call try-run,\ - printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3)) + /bin/echo -e "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3)) # cc-option # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) diff --git a/trunk/scripts/Makefile.build b/trunk/scripts/Makefile.build index ff1720d28d0c..d2b366c16b64 100644 --- a/trunk/scripts/Makefile.build +++ b/trunk/scripts/Makefile.build @@ -69,7 +69,6 @@ warning-1 += -Wmissing-prototypes warning-1 += -Wold-style-definition warning-1 += $(call cc-option, -Wmissing-include-dirs) warning-1 += $(call cc-option, -Wunused-but-set-variable) -warning-1 += $(call cc-disable-warning, missing-field-initializers) warning-2 := -Waggregate-return warning-2 += -Wcast-align @@ -77,7 +76,6 @@ warning-2 += -Wdisabled-optimization warning-2 += -Wnested-externs warning-2 += -Wshadow warning-2 += $(call cc-option, -Wlogical-op) -warning-2 += $(call cc-option, -Wmissing-field-initializers) warning-3 := -Wbad-function-cast warning-3 += -Wcast-qual diff --git a/trunk/scripts/Makefile.lib b/trunk/scripts/Makefile.lib index 0be6f110cce7..00c368c6e996 100644 --- a/trunk/scripts/Makefile.lib +++ b/trunk/scripts/Makefile.lib @@ -304,30 +304,6 @@ cmd_lzo = (cat $(filter-out FORCE,$^) | \ lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ (rm -f $@ ; false) -# U-Boot mkimage -# --------------------------------------------------------------------------- - -MKIMAGE := $(srctree)/scripts/mkuboot.sh - -# SRCARCH just happens to match slightly more than ARCH (on sparc), so reduces -# the number of overrides in arch makefiles -UIMAGE_ARCH ?= $(SRCARCH) -UIMAGE_COMPRESSION ?= $(if $(2),$(2),none) -UIMAGE_OPTS-y ?= -UIMAGE_TYPE ?= kernel -UIMAGE_LOADADDR ?= arch_must_set_this -UIMAGE_ENTRYADDR ?= $(UIMAGE_LOADADDR) -UIMAGE_NAME ?= 'Linux-$(KERNELRELEASE)' -UIMAGE_IN ?= $< -UIMAGE_OUT ?= $@ - -quiet_cmd_uimage = UIMAGE $(UIMAGE_OUT) - cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(UIMAGE_ARCH) -O linux \ - -C $(UIMAGE_COMPRESSION) $(UIMAGE_OPTS-y) \ - -T $(UIMAGE_TYPE) \ - -a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR) \ - -n $(UIMAGE_NAME) -d $(UIMAGE_IN) $(UIMAGE_OUT) - # XZ # --------------------------------------------------------------------------- # Use xzkern to compress the kernel image and xzmisc to compress other things. diff --git a/trunk/scripts/checkpatch.pl b/trunk/scripts/checkpatch.pl index faea0ec612bf..de639eeeed50 100755 --- a/trunk/scripts/checkpatch.pl +++ b/trunk/scripts/checkpatch.pl @@ -1869,6 +1869,12 @@ sub process { "No space is necessary after a cast\n" . $hereprev); } + if ($rawline =~ /^\+[ \t]*\/\*[ \t]*$/ && + $prevrawline =~ /^\+[ \t]*$/) { + CHK("BLOCK_COMMENT_STYLE", + "Don't begin block comments with only a /* line, use /* comment...\n" . $hereprev); + } + # check for spaces at the beginning of a line. # Exceptions: # 1) within comments diff --git a/trunk/scripts/coccinelle/api/ptr_ret.cocci b/trunk/scripts/coccinelle/api/ptr_ret.cocci deleted file mode 100644 index cbfd08c7d8c7..000000000000 --- a/trunk/scripts/coccinelle/api/ptr_ret.cocci +++ /dev/null @@ -1,70 +0,0 @@ -/// -/// Use PTR_RET rather than if(IS_ERR(...)) + PTR_ERR -/// -// Confidence: High -// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. -// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. -// URL: http://coccinelle.lip6.fr/ -// Options: -no_includes -include_headers -// -// Keywords: ERR_PTR, PTR_ERR, PTR_RET -// Version min: 2.6.39 -// - -virtual context -virtual patch -virtual org -virtual report - -@depends on patch@ -expression ptr; -@@ - -- if (IS_ERR(ptr)) return PTR_ERR(ptr); else return 0; -+ return PTR_RET(ptr); - -@depends on patch@ -expression ptr; -@@ - -- if (IS_ERR(ptr)) return PTR_ERR(ptr); return 0; -+ return PTR_RET(ptr); - -@r1 depends on !patch@ -expression ptr; -position p1; -@@ - -* if@p1 (IS_ERR(ptr)) return PTR_ERR(ptr); else return 0; - -@r2 depends on !patch@ -expression ptr; -position p2; -@@ - -* if@p2 (IS_ERR(ptr)) return PTR_ERR(ptr); return 0; - -@script:python depends on org@ -p << r1.p1; -@@ - -coccilib.org.print_todo(p[0], "WARNING: PTR_RET can be used") - - -@script:python depends on org@ -p << r2.p2; -@@ - -coccilib.org.print_todo(p[0], "WARNING: PTR_RET can be used") - -@script:python depends on report@ -p << r1.p1; -@@ - -coccilib.report.print_report(p[0], "WARNING: PTR_RET can be used") - -@script:python depends on report@ -p << r2.p2; -@@ - -coccilib.report.print_report(p[0], "WARNING: PTR_RET can be used") diff --git a/trunk/scripts/coccinelle/api/simple_open.cocci b/trunk/scripts/coccinelle/api/simple_open.cocci deleted file mode 100644 index 05962f7be155..000000000000 --- a/trunk/scripts/coccinelle/api/simple_open.cocci +++ /dev/null @@ -1,70 +0,0 @@ -/// This removes an open coded simple_open() function -/// and replaces file operations references to the function -/// with simple_open() instead. -/// -// Confidence: High -// Comments: -// Options: -no_includes -include_headers - -virtual patch -virtual report - -@ open depends on patch @ -identifier open_f != simple_open; -identifier i, f; -@@ --int open_f(struct inode *i, struct file *f) --{ -( --if (i->i_private) --f->private_data = i->i_private; -| --f->private_data = i->i_private; -) --return 0; --} - -@ has_open depends on open @ -identifier fops; -identifier open.open_f; -@@ -struct file_operations fops = { -..., --.open = open_f, -+.open = simple_open, -... -}; - -@ openr depends on report @ -identifier open_f != simple_open; -identifier i, f; -position p; -@@ -int open_f@p(struct inode *i, struct file *f) -{ -( -if (i->i_private) -f->private_data = i->i_private; -| -f->private_data = i->i_private; -) -return 0; -} - -@ has_openr depends on openr @ -identifier fops; -identifier openr.open_f; -position p; -@@ -struct file_operations fops = { -..., -.open = open_f@p, -... -}; - -@script:python@ -pf << openr.p; -ps << has_openr.p; -@@ - -coccilib.report.print_report(pf[0],"WARNING opportunity for simple_open, see also structure on line %s"%(ps[0].line)) diff --git a/trunk/scripts/coccinelle/free/clk_put.cocci b/trunk/scripts/coccinelle/free/clk_put.cocci deleted file mode 100644 index 46747adfd20a..000000000000 --- a/trunk/scripts/coccinelle/free/clk_put.cocci +++ /dev/null @@ -1,67 +0,0 @@ -/// Find missing clk_puts. -/// -//# This only signals a missing clk_put when there is a clk_put later -//# in the same function. -//# False positives can be due to loops. -// -// Confidence: Moderate -// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. -// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. -// URL: http://coccinelle.lip6.fr/ -// Comments: -// Options: - -virtual context -virtual org -virtual report - -@clk@ -expression e; -statement S,S1; -int ret; -position p1,p2,p3; -@@ - -e = clk_get@p1(...) -... when != clk_put(e) -if (<+...e...+>) S -... when any - when != clk_put(e) - when != if (...) { ... clk_put(e); ... } -( - if (ret == 0) S1 -| -if (...) - { ... - return 0; } -| -if (...) - { ... - return <+...e...+>; } -| -*if@p2 (...) - { ... when != clk_put(e) - when forall - return@p3 ...; } -) -... when any -clk_put(e); - -@script:python depends on org@ -p1 << clk.p1; -p2 << clk.p2; -p3 << clk.p3; -@@ - -cocci.print_main("clk_get",p1) -cocci.print_secs("if",p2) -cocci.print_secs("needed clk_put",p3) - -@script:python depends on report@ -p1 << clk.p1; -p2 << clk.p2; -p3 << clk.p3; -@@ - -msg = "ERROR: missing clk_put; clk_get on line %s and execution via conditional on line %s" % (p1[0].line,p2[0].line) -coccilib.report.print_report(p3[0],msg) diff --git a/trunk/scripts/coccinelle/free/iounmap.cocci b/trunk/scripts/coccinelle/free/iounmap.cocci deleted file mode 100644 index 5384f4ba1192..000000000000 --- a/trunk/scripts/coccinelle/free/iounmap.cocci +++ /dev/null @@ -1,67 +0,0 @@ -/// Find missing iounmaps. -/// -//# This only signals a missing iounmap when there is an iounmap later -//# in the same function. -//# False positives can be due to loops. -// -// Confidence: Moderate -// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. -// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. -// URL: http://coccinelle.lip6.fr/ -// Comments: -// Options: - -virtual context -virtual org -virtual report - -@iom@ -expression e; -statement S,S1; -int ret; -position p1,p2,p3; -@@ - -e = \(ioremap@p1\|ioremap_nocache@p1\)(...) -... when != iounmap(e) -if (<+...e...+>) S -... when any - when != iounmap(e) - when != if (...) { ... iounmap(e); ... } -( - if (ret == 0) S1 -| -if (...) - { ... - return 0; } -| -if (...) - { ... - return <+...e...+>; } -| -*if@p2 (...) - { ... when != iounmap(e) - when forall - return@p3 ...; } -) -... when any -iounmap(e); - -@script:python depends on org@ -p1 << iom.p1; -p2 << iom.p2; -p3 << iom.p3; -@@ - -cocci.print_main("ioremap",p1) -cocci.print_secs("if",p2) -cocci.print_secs("needed iounmap",p3) - -@script:python depends on report@ -p1 << iom.p1; -p2 << iom.p2; -p3 << iom.p3; -@@ - -msg = "ERROR: missing iounmap; ioremap on line %s and execution via conditional on line %s" % (p1[0].line,p2[0].line) -coccilib.report.print_report(p3[0],msg) diff --git a/trunk/scripts/coccinelle/misc/boolinit.cocci b/trunk/scripts/coccinelle/misc/boolinit.cocci deleted file mode 100644 index 97ce41ce8135..000000000000 --- a/trunk/scripts/coccinelle/misc/boolinit.cocci +++ /dev/null @@ -1,178 +0,0 @@ -/// Bool initializations should use true and false. Bool tests don't need -/// comparisons. Based on contributions from Joe Perches, Rusty Russell -/// and Bruce W Allan. -/// -// Confidence: High -// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. -// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. -// URL: http://coccinelle.lip6.fr/ -// Options: -include_headers - -virtual patch -virtual context -virtual org -virtual report - -@depends on patch@ -bool t; -symbol true; -symbol false; -@@ - -( -- t == true -+ t -| -- true == t -+ t -| -- t != true -+ !t -| -- true != t -+ !t -| -- t == false -+ !t -| -- false == t -+ !t -| -- t != false -+ t -| -- false != t -+ t -) - -@depends on patch disable is_zero, isnt_zero@ -bool t; -@@ - -( -- t == 1 -+ t -| -- t != 1 -+ !t -| -- t == 0 -+ !t -| -- t != 0 -+ t -) - -@depends on patch@ -bool b; -@@ -( - b = -- 0 -+ false -| - b = -- 1 -+ true -) - -// --------------------------------------------------------------------- - -@r1 depends on !patch@ -bool t; -position p; -@@ - -( -* t@p == true -| -* true == t@p -| -* t@p != true -| -* true != t@p -| -* t@p == false -| -* false == t@p -| -* t@p != false -| -* false != t@p -) - -@r2 depends on !patch disable is_zero, isnt_zero@ -bool t; -position p; -@@ - -( -* t@p == 1 -| -* t@p != 1 -| -* t@p == 0 -| -* t@p != 0 -) - -@r3 depends on !patch@ -bool b; -position p1,p2; -constant c; -@@ -( -*b@p1 = 0 -| -*b@p1 = 1 -| -*b@p2 = c -) - -@script:python depends on org@ -p << r1.p; -@@ - -cocci.print_main("WARNING: Comparison to bool",p) - -@script:python depends on org@ -p << r2.p; -@@ - -cocci.print_main("WARNING: Comparison of bool to 0/1",p) - -@script:python depends on org@ -p1 << r3.p1; -@@ - -cocci.print_main("WARNING: Assignment of bool to 0/1",p1) - -@script:python depends on org@ -p2 << r3.p2; -@@ - -cocci.print_main("ERROR: Assignment of bool to non-0/1 constant",p2) - -@script:python depends on report@ -p << r1.p; -@@ - -coccilib.report.print_report(p[0],"WARNING: Comparison to bool") - -@script:python depends on report@ -p << r2.p; -@@ - -coccilib.report.print_report(p[0],"WARNING: Comparison of bool to 0/1") - -@script:python depends on report@ -p1 << r3.p1; -@@ - -coccilib.report.print_report(p1[0],"WARNING: Assignment of bool to 0/1") - -@script:python depends on report@ -p2 << r3.p2; -@@ - -coccilib.report.print_report(p2[0],"ERROR: Assignment of bool to non-0/1 constant") diff --git a/trunk/scripts/coccinelle/misc/cstptr.cocci b/trunk/scripts/coccinelle/misc/cstptr.cocci deleted file mode 100644 index d42564484528..000000000000 --- a/trunk/scripts/coccinelle/misc/cstptr.cocci +++ /dev/null @@ -1,41 +0,0 @@ -/// PTR_ERR should be applied before its argument is reassigned, typically -/// to NULL -/// -// Confidence: High -// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. -// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. -// URL: http://coccinelle.lip6.fr/ -// Comments: -// Options: -no_includes -include_headers - -virtual org -virtual report -virtual context - -@r exists@ -expression e,e1; -constant c; -position p1,p2; -@@ - -*e@p1 = c -... when != e = e1 - when != &e - when != true IS_ERR(e) -*PTR_ERR@p2(e) - -@script:python depends on org@ -p1 << r.p1; -p2 << r.p2; -@@ - -cocci.print_main("PTR_ERR",p2) -cocci.print_secs("assignment",p1) - -@script:python depends on report@ -p1 << r.p1; -p2 << r.p2; -@@ - -msg = "ERROR: PTR_ERR applied after initialization to constant on line %s" % (p1[0].line) -coccilib.report.print_report(p2[0],msg) diff --git a/trunk/scripts/coccinelle/null/badzero.cocci b/trunk/scripts/coccinelle/null/badzero.cocci deleted file mode 100644 index d79baf7220e7..000000000000 --- a/trunk/scripts/coccinelle/null/badzero.cocci +++ /dev/null @@ -1,237 +0,0 @@ -/// Compare pointer-typed values to NULL rather than 0 -/// -//# This makes an effort to choose between !x and x == NULL. !x is used -//# if it has previously been used with the function used to initialize x. -//# This relies on type information. More type information can be obtained -//# using the option -all_includes and the option -I to specify an -//# include path. -// -// Confidence: High -// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. -// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. -// URL: http://coccinelle.lip6.fr/ -// Comments: -// Options: - -virtual patch -virtual context -virtual org -virtual report - -@initialize:ocaml@ -let negtable = Hashtbl.create 101 - -@depends on patch@ -expression *E; -identifier f; -@@ - -( - (E = f(...)) == -- 0 -+ NULL -| - (E = f(...)) != -- 0 -+ NULL -| -- 0 -+ NULL - == (E = f(...)) -| -- 0 -+ NULL - != (E = f(...)) -) - - -@t1 depends on !patch@ -expression *E; -identifier f; -position p; -@@ - -( - (E = f(...)) == -* 0@p -| - (E = f(...)) != -* 0@p -| -* 0@p - == (E = f(...)) -| -* 0@p - != (E = f(...)) -) - -@script:python depends on org@ -p << t1.p; -@@ - -coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") - -@script:python depends on report@ -p << t1.p; -@@ - -coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") - -// Tests of returned values - -@s@ -identifier f; -expression E,E1; -@@ - - E = f(...) - ... when != E = E1 - !E - -@script:ocaml depends on s@ -f << s.f; -@@ - -try let _ = Hashtbl.find negtable f in () -with Not_found -> Hashtbl.add negtable f () - -@ r disable is_zero,isnt_zero exists @ -expression *E; -identifier f; -@@ - -E = f(...) -... -(E == 0 -|E != 0 -|0 == E -|0 != E -) - -@script:ocaml@ -f << r.f; -@@ - -try let _ = Hashtbl.find negtable f in () -with Not_found -> include_match false - -// This rule may lead to inconsistent path problems, if E is defined in two -// places -@ depends on patch disable is_zero,isnt_zero @ -expression *E; -expression E1; -identifier r.f; -@@ - -E = f(...) -<... -( -- E == 0 -+ !E -| -- E != 0 -+ E -| -- 0 == E -+ !E -| -- 0 != E -+ E -) -...> -?E = E1 - -@t2 depends on !patch disable is_zero,isnt_zero @ -expression *E; -expression E1; -identifier r.f; -position p1; -position p2; -@@ - -E = f(...) -<... -( -* E == 0@p1 -| -* E != 0@p2 -| -* 0@p1 == E -| -* 0@p1 != E -) -...> -?E = E1 - -@script:python depends on org@ -p << t2.p1; -@@ - -coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0, suggest !E") - -@script:python depends on org@ -p << t2.p2; -@@ - -coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") - -@script:python depends on report@ -p << t2.p1; -@@ - -coccilib.report.print_report(p[0], "WARNING comparing pointer to 0, suggest !E") - -@script:python depends on report@ -p << t2.p2; -@@ - -coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") - -@ depends on patch disable is_zero,isnt_zero @ -expression *E; -@@ - -( - E == -- 0 -+ NULL -| - E != -- 0 -+ NULL -| -- 0 -+ NULL - == E -| -- 0 -+ NULL - != E -) - -@ t3 depends on !patch disable is_zero,isnt_zero @ -expression *E; -position p; -@@ - -( -* E == 0@p -| -* E != 0@p -| -* 0@p == E -| -* 0@p != E -) - -@script:python depends on org@ -p << t3.p; -@@ - -coccilib.org.print_todo(p[0], "WARNING comparing pointer to 0") - -@script:python depends on report@ -p << t3.p; -@@ - -coccilib.report.print_report(p[0], "WARNING comparing pointer to 0") diff --git a/trunk/scripts/dtc/dtc.c b/trunk/scripts/dtc/dtc.c index 2ef5e2e3dd38..451c92d31b19 100644 --- a/trunk/scripts/dtc/dtc.c +++ b/trunk/scripts/dtc/dtc.c @@ -101,7 +101,7 @@ int main(int argc, char *argv[]) const char *outform = "dts"; const char *outname = "-"; const char *depname = NULL; - int force = 0, sort = 0; + int force = 0, check = 0, sort = 0; const char *arg; int opt; FILE *outf = NULL; @@ -143,6 +143,9 @@ int main(int argc, char *argv[]) case 'f': force = 1; break; + case 'c': + check = 1; + break; case 'q': quiet++; break; diff --git a/trunk/scripts/dtc/flattree.c b/trunk/scripts/dtc/flattree.c index 28d0b2381df6..ead0332c87e1 100644 --- a/trunk/scripts/dtc/flattree.c +++ b/trunk/scripts/dtc/flattree.c @@ -697,6 +697,7 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) { struct reserve_info *reservelist = NULL; struct reserve_info *new; + const char *p; struct fdt_reserve_entry re; /* @@ -705,6 +706,7 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) * * First pass, count entries. */ + p = inb->ptr; while (1) { flat_read_chunk(inb, &re, sizeof(re)); re.address = fdt64_to_cpu(re.address); diff --git a/trunk/scripts/headers_check.pl b/trunk/scripts/headers_check.pl index 64ac2380e4d5..7957e7a5166a 100644 --- a/trunk/scripts/headers_check.pl +++ b/trunk/scripts/headers_check.pl @@ -19,7 +19,6 @@ # 3) Check for leaked CONFIG_ symbols use strict; -use File::Basename; my ($dir, $arch, @files) = @ARGV; @@ -100,39 +99,6 @@ sub check_asm_types } my $linux_types; -my %import_stack = (); -sub check_include_typesh -{ - my $path = $_[0]; - my $import_path; - - my $fh; - my @file_paths = ($path, $dir . "/" . $path, dirname($filename) . "/" . $path); - for my $possible ( @file_paths ) { - if (not $import_stack{$possible} and open($fh, '<', $possible)) { - $import_path = $possible; - $import_stack{$import_path} = 1; - last; - } - } - if (eof $fh) { - return; - } - - my $line; - while ($line = <$fh>) { - if ($line =~ m/^\s*#\s*include\s+/) { - $linux_types = 1; - last; - } - if (my $included = ($line =~ /^\s*#\s*include\s+[<"](\S+)[>"]/)[0]) { - check_include_typesh($included); - } - } - close $fh; - delete $import_stack{$import_path}; -} - sub check_sizetypes { if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) { @@ -147,9 +113,6 @@ sub check_sizetypes $linux_types = 1; return; } - if (my $included = ($line =~ /^\s*#\s*include\s+[<"](\S+)[>"]/)[0]) { - check_include_typesh($included); - } if ($line =~ m/__[us](8|16|32|64)\b/) { printf STDERR "$filename:$lineno: " . "found __[us]{8,16,32,64} type " . @@ -159,3 +122,4 @@ sub check_sizetypes #$ret = 1; } } + diff --git a/trunk/scripts/kconfig/confdata.c b/trunk/scripts/kconfig/confdata.c index 52577f052bc1..7c7a5a6cc3f5 100644 --- a/trunk/scripts/kconfig/confdata.c +++ b/trunk/scripts/kconfig/confdata.c @@ -344,8 +344,10 @@ int conf_read_simple(const char *name, int def) int conf_read(const char *name) { - struct symbol *sym; - int i; + struct symbol *sym, *choice_sym; + struct property *prop; + struct expr *e; + int i, flags; sym_set_change_count(0); @@ -355,7 +357,7 @@ int conf_read(const char *name) for_all_symbols(i, sym) { sym_calc_value(sym); if (sym_is_choice(sym) || (sym->flags & SYMBOL_AUTO)) - continue; + goto sym_ok; if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { /* check that calculated value agrees with saved value */ switch (sym->type) { @@ -364,18 +366,30 @@ int conf_read(const char *name) if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym)) break; if (!sym_is_choice(sym)) - continue; + goto sym_ok; /* fall through */ default: if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) - continue; + goto sym_ok; break; } } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) /* no previous value and not saved */ - continue; + goto sym_ok; conf_unsaved++; /* maybe print value in verbose mode... */ + sym_ok: + if (!sym_is_choice(sym)) + continue; + /* The choice symbol only has a set value (and thus is not new) + * if all its visible childs have values. + */ + prop = sym_get_choice_prop(sym); + flags = sym->flags; + expr_list_for_each_sym(prop->expr, e, choice_sym) + if (choice_sym->visible != no) + flags &= choice_sym->flags; + sym->flags &= flags | ~SYMBOL_DEF_USER; } for_all_symbols(i, sym) { @@ -539,6 +553,35 @@ static struct conf_printer header_printer_cb = .print_comment = header_print_comment, }; +/* + * Generate the __enabled_CONFIG_* and __enabled_CONFIG_*_MODULE macros for + * use by the IS_{ENABLED,BUILTIN,MODULE} macros. The _MODULE variant is + * generated even for booleans so that the IS_ENABLED() macro works. + */ +static void +header_print__enabled_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg) +{ + + switch (sym->type) { + case S_BOOLEAN: + case S_TRISTATE: { + fprintf(fp, "#define __enabled_" CONFIG_ "%s %d\n", + sym->name, (*value == 'y')); + fprintf(fp, "#define __enabled_" CONFIG_ "%s_MODULE %d\n", + sym->name, (*value == 'm')); + break; + } + default: + break; + } +} + +static struct conf_printer header__enabled_printer_cb = +{ + .print_symbol = header_print__enabled_symbol, + .print_comment = header_print_comment, +}; + /* * Tristate printer * @@ -920,11 +963,16 @@ int conf_write_autoconf(void) conf_write_heading(out_h, &header_printer_cb, NULL); for_all_symbols(i, sym) { + if (!sym->name) + continue; + sym_calc_value(sym); - if (!(sym->flags & SYMBOL_WRITE) || !sym->name) + + conf_write_symbol(out_h, sym, &header__enabled_printer_cb, NULL); + + if (!(sym->flags & SYMBOL_WRITE)) continue; - /* write symbol to auto.conf, tristate and header files */ conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1); conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1); diff --git a/trunk/scripts/kconfig/merge_config.sh b/trunk/scripts/kconfig/merge_config.sh old mode 100755 new mode 100644 index 974d5cb7e30a..ceadf0e150cf --- a/trunk/scripts/kconfig/merge_config.sh +++ b/trunk/scripts/kconfig/merge_config.sh @@ -31,12 +31,10 @@ usage() { echo " -h display this help text" echo " -m only merge the fragments, do not execute the make command" echo " -n use allnoconfig instead of alldefconfig" - echo " -r list redundant entries when merging fragments" } MAKE=true ALLTARGET=alldefconfig -WARNREDUN=false while true; do case $1 in @@ -54,27 +52,18 @@ while true; do usage exit ;; - "-r") - WARNREDUN=true - shift - continue - ;; *) break ;; esac done -INITFILE=$1 -shift; + MERGE_LIST=$* SED_CONFIG_EXP="s/^\(# \)\{0,1\}\(CONFIG_[a-zA-Z0-9_]*\)[= ].*/\2/p" TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX) -echo "Using $INITFILE as base" -cat $INITFILE > $TMP_FILE - # Merge files, printing warnings on overrided values for MERGE_FILE in $MERGE_LIST ; do echo "Merging $MERGE_FILE" @@ -90,8 +79,6 @@ for MERGE_FILE in $MERGE_LIST ; do echo Previous value: $PREV_VAL echo New value: $NEW_VAL echo - elif [ "$WARNREDUN" = "true" ]; then - echo Value of $CFG is redundant by fragment $MERGE_FILE: fi sed -i "/$CFG[ =]/d" $TMP_FILE fi diff --git a/trunk/scripts/kconfig/symbol.c b/trunk/scripts/kconfig/symbol.c index 22a3c400fc41..071f00c3046e 100644 --- a/trunk/scripts/kconfig/symbol.c +++ b/trunk/scripts/kconfig/symbol.c @@ -262,18 +262,11 @@ static struct symbol *sym_calc_choice(struct symbol *sym) struct symbol *def_sym; struct property *prop; struct expr *e; - int flags; /* first calculate all choice values' visibilities */ - flags = sym->flags; prop = sym_get_choice_prop(sym); - expr_list_for_each_sym(prop->expr, e, def_sym) { + expr_list_for_each_sym(prop->expr, e, def_sym) sym_calc_visibility(def_sym); - if (def_sym->visible != no) - flags &= def_sym->flags; - } - - sym->flags &= flags | ~SYMBOL_DEF_USER; /* is the user choice visible? */ def_sym = sym->def[S_DEF_USER].val; diff --git a/trunk/scripts/mod/file2alias.c b/trunk/scripts/mod/file2alias.c index 44ddaa542db6..8e730ccc3f2b 100644 --- a/trunk/scripts/mod/file2alias.c +++ b/trunk/scripts/mod/file2alias.c @@ -1100,10 +1100,6 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections) return; - /* We're looking for an object */ - if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) - return; - /* All our symbols are of form __mod_XXX_device_table. */ name = strstr(symname, "__mod_"); if (!name) diff --git a/trunk/scripts/mod/modpost.c b/trunk/scripts/mod/modpost.c index c4e7d1510f9d..9adb667dd31a 100644 --- a/trunk/scripts/mod/modpost.c +++ b/trunk/scripts/mod/modpost.c @@ -132,10 +132,8 @@ static struct module *new_module(char *modname) /* strip trailing .o */ s = strrchr(p, '.'); if (s != NULL) - if (strcmp(s, ".o") == 0) { + if (strcmp(s, ".o") == 0) *s = '\0'; - mod->is_dot_o = 1; - } /* add to list */ mod->name = p; @@ -589,8 +587,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, unsigned int crc; enum export export; - if ((!is_vmlinux(mod->name) || mod->is_dot_o) && - strncmp(symname, "__ksymtab", 9) == 0) + if (!is_vmlinux(mod->name) && strncmp(symname, "__ksymtab", 9) == 0) export = export_from_secname(info, get_secindex(info, sym)); else export = export_from_sec(info, get_secindex(info, sym)); @@ -852,7 +849,7 @@ static void check_section(const char *modname, struct elf_info *elf, #define ALL_INIT_DATA_SECTIONS \ ".init.setup$", ".init.rodata$", \ - ".devinit.rodata$", ".cpuinit.rodata$", ".meminit.rodata$", \ + ".devinit.rodata$", ".cpuinit.rodata$", ".meminit.rodata$" \ ".init.data$", ".devinit.data$", ".cpuinit.data$", ".meminit.data$" #define ALL_EXIT_DATA_SECTIONS \ ".exit.data$", ".devexit.data$", ".cpuexit.data$", ".memexit.data$" diff --git a/trunk/scripts/mod/modpost.h b/trunk/scripts/mod/modpost.h index 51207e4d5f8b..2031119080dc 100644 --- a/trunk/scripts/mod/modpost.h +++ b/trunk/scripts/mod/modpost.h @@ -113,7 +113,6 @@ struct module { int has_cleanup; struct buffer dev_table_buf; char srcversion[25]; - int is_dot_o; }; struct elf_info { diff --git a/trunk/scripts/package/builddeb b/trunk/scripts/package/builddeb index eee5f8ed2493..3c6c0b14c807 100644 --- a/trunk/scripts/package/builddeb +++ b/trunk/scripts/package/builddeb @@ -97,7 +97,6 @@ mkdir -m 755 -p "$libc_headers_dir/DEBIAN" mkdir -p "$libc_headers_dir/usr/share/doc/$libc_headers_packagename" mkdir -m 755 -p "$kernel_headers_dir/DEBIAN" mkdir -p "$kernel_headers_dir/usr/share/doc/$kernel_headers_packagename" -mkdir -p "$kernel_headers_dir/lib/modules/$version/" if [ "$ARCH" = "um" ] ; then mkdir -p "$tmpdir/usr/lib/uml/modules/$version" "$tmpdir/usr/bin" fi @@ -121,19 +120,15 @@ else fi if grep -q '^CONFIG_MODULES=y' .config ; then - INSTALL_MOD_PATH="$tmpdir" $MAKE KBUILD_SRC= modules_install - rm -f "$tmpdir/lib/modules/$version/build" - rm -f "$tmpdir/lib/modules/$version/source" + INSTALL_MOD_PATH="$tmpdir" make KBUILD_SRC= modules_install if [ "$ARCH" = "um" ] ; then mv "$tmpdir/lib/modules/$version"/* "$tmpdir/usr/lib/uml/modules/$version/" rmdir "$tmpdir/lib/modules/$version" fi fi -if [ "$ARCH" != "um" ]; then - $MAKE headers_check KBUILD_SRC= - $MAKE headers_install KBUILD_SRC= INSTALL_HDR_PATH="$libc_headers_dir/usr" -fi +make headers_check +make headers_install INSTALL_HDR_PATH="$libc_headers_dir/usr" # Install the maintainer scripts # Note: hook scripts under /etc/kernel are also executed by official Debian @@ -250,7 +245,6 @@ destdir=$kernel_headers_dir/usr/src/linux-headers-$version mkdir -p "$destdir" (cd $srctree; tar -c -f - -T "$objtree/debian/hdrsrcfiles") | (cd $destdir; tar -xf -) (cd $objtree; tar -c -f - -T "$objtree/debian/hdrobjfiles") | (cd $destdir; tar -xf -) -ln -sf "/usr/src/linux-headers-$version" "$kernel_headers_dir/lib/modules/$version/build" rm -f "$objtree/debian/hdrsrcfiles" "$objtree/debian/hdrobjfiles" arch=$(dpkg --print-architecture) @@ -265,6 +259,8 @@ Description: Linux kernel headers for $KERNELRELEASE on $arch This is useful for people who need to build external modules EOF +create_package "$kernel_headers_packagename" "$kernel_headers_dir" + # Do we have firmware? Move it out of the way and build it into a package. if [ -e "$tmpdir/lib/firmware" ]; then mv "$tmpdir/lib/firmware" "$fwdir/lib/" @@ -291,11 +287,7 @@ Description: Linux support headers for userspace development are used by the installed headers for GNU glibc and other system libraries. EOF -if [ "$ARCH" != "um" ]; then - create_package "$kernel_headers_packagename" "$kernel_headers_dir" - create_package "$libc_headers_packagename" "$libc_headers_dir" -fi - +create_package "$libc_headers_packagename" "$libc_headers_dir" create_package "$packagename" "$tmpdir" exit 0 diff --git a/trunk/scripts/patch-kernel b/trunk/scripts/patch-kernel index d000ea3a41fd..20fb25c23382 100755 --- a/trunk/scripts/patch-kernel +++ b/trunk/scripts/patch-kernel @@ -116,10 +116,6 @@ findFile () { ext=".bz2" name="bzip2" uncomp="bunzip2 -dc" - elif [ -r ${filebase}.xz ]; then - ext=".xz" - name="xz" - uncomp="xz -dc" elif [ -r ${filebase}.zip ]; then ext=".zip" name="zip" diff --git a/trunk/scripts/setlocalversion b/trunk/scripts/setlocalversion index bd6dca8a0ab2..4d403844e137 100755 --- a/trunk/scripts/setlocalversion +++ b/trunk/scripts/setlocalversion @@ -75,7 +75,8 @@ scm_version() [ -w . ] && git update-index --refresh --unmerged > /dev/null # Check for uncommitted changes - if git diff-index --name-only HEAD | grep -qv "^scripts/package"; then + if git diff-index --name-only HEAD | grep -v "^scripts/package" \ + | read dummy; then printf '%s' -dirty fi diff --git a/trunk/scripts/tags.sh b/trunk/scripts/tags.sh index cf7b12fee573..833813a99e7c 100755 --- a/trunk/scripts/tags.sh +++ b/trunk/scripts/tags.sh @@ -116,7 +116,7 @@ docscope() dogtags() { - all_sources | gtags -i -f - + all_sources | gtags -f - } exuberant() @@ -166,6 +166,9 @@ exuberant() all_defconfigs | xargs -r $1 -a \ --langdef=dotconfig --language-force=dotconfig \ --regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/' + + # Remove structure forward declarations. + LANG=C sed -i -e '/^\([a-zA-Z_][a-zA-Z0-9_]*\)\t.*\t\/\^struct \1;.*\$\/;"\tx$/d' tags } emacs() @@ -230,7 +233,6 @@ if [ "${ARCH}" = "um" ]; then fi fi -remove_structs= case "$1" in "cscope") docscope @@ -243,17 +245,10 @@ case "$1" in "tags") rm -f tags xtags ctags - remove_structs=y ;; "TAGS") rm -f TAGS xtags etags - remove_structs=y ;; esac - -# Remove structure forward declarations. -if [ -n "$remove_structs" ]; then - LANG=C sed -i -e '/^\([a-zA-Z_][a-zA-Z0-9_]*\)\t.*\t\/\^struct \1;.*\$\/;"\tx$/d' $1 -fi diff --git a/trunk/scripts/xz_wrap.sh b/trunk/scripts/xz_wrap.sh index 7a2d372f4885..17a5798c29da 100644 --- a/trunk/scripts/xz_wrap.sh +++ b/trunk/scripts/xz_wrap.sh @@ -12,8 +12,8 @@ BCJ= LZMA2OPTS= -case $SRCARCH in - x86) BCJ=--x86 ;; +case $ARCH in + x86|x86_64) BCJ=--x86 ;; powerpc) BCJ=--powerpc ;; ia64) BCJ=--ia64; LZMA2OPTS=pb=4 ;; arm) BCJ=--arm ;; diff --git a/trunk/security/apparmor/audit.c b/trunk/security/apparmor/audit.c index cc3520d39a78..5ff67776a5ad 100644 --- a/trunk/security/apparmor/audit.c +++ b/trunk/security/apparmor/audit.c @@ -115,23 +115,23 @@ static void audit_pre(struct audit_buffer *ab, void *ca) if (aa_g_audit_header) { audit_log_format(ab, "apparmor="); - audit_log_string(ab, aa_audit_type[sa->aad->type]); + audit_log_string(ab, aa_audit_type[sa->aad.type]); } - if (sa->aad->op) { + if (sa->aad.op) { audit_log_format(ab, " operation="); - audit_log_string(ab, op_table[sa->aad->op]); + audit_log_string(ab, op_table[sa->aad.op]); } - if (sa->aad->info) { + if (sa->aad.info) { audit_log_format(ab, " info="); - audit_log_string(ab, sa->aad->info); - if (sa->aad->error) - audit_log_format(ab, " error=%d", sa->aad->error); + audit_log_string(ab, sa->aad.info); + if (sa->aad.error) + audit_log_format(ab, " error=%d", sa->aad.error); } - if (sa->aad->profile) { - struct aa_profile *profile = sa->aad->profile; + if (sa->aad.profile) { + struct aa_profile *profile = sa->aad.profile; pid_t pid; rcu_read_lock(); pid = rcu_dereference(tsk->real_parent)->pid; @@ -145,9 +145,9 @@ static void audit_pre(struct audit_buffer *ab, void *ca) audit_log_untrustedstring(ab, profile->base.hname); } - if (sa->aad->name) { + if (sa->aad.name) { audit_log_format(ab, " name="); - audit_log_untrustedstring(ab, sa->aad->name); + audit_log_untrustedstring(ab, sa->aad.name); } } @@ -159,8 +159,10 @@ static void audit_pre(struct audit_buffer *ab, void *ca) void aa_audit_msg(int type, struct common_audit_data *sa, void (*cb) (struct audit_buffer *, void *)) { - sa->aad->type = type; - common_lsm_audit(sa, audit_pre, cb); + sa->aad.type = type; + sa->lsm_pre_audit = audit_pre; + sa->lsm_post_audit = cb; + common_lsm_audit(sa); } /** @@ -182,7 +184,7 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp, BUG_ON(!profile); if (type == AUDIT_APPARMOR_AUTO) { - if (likely(!sa->aad->error)) { + if (likely(!sa->aad.error)) { if (AUDIT_MODE(profile) != AUDIT_ALL) return 0; type = AUDIT_APPARMOR_AUDIT; @@ -194,21 +196,21 @@ int aa_audit(int type, struct aa_profile *profile, gfp_t gfp, if (AUDIT_MODE(profile) == AUDIT_QUIET || (type == AUDIT_APPARMOR_DENIED && AUDIT_MODE(profile) == AUDIT_QUIET)) - return sa->aad->error; + return sa->aad.error; if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED) type = AUDIT_APPARMOR_KILL; if (!unconfined(profile)) - sa->aad->profile = profile; + sa->aad.profile = profile; aa_audit_msg(type, sa, cb); - if (sa->aad->type == AUDIT_APPARMOR_KILL) + if (sa->aad.type == AUDIT_APPARMOR_KILL) (void)send_sig_info(SIGKILL, NULL, sa->tsk ? sa->tsk : current); - if (sa->aad->type == AUDIT_APPARMOR_ALLOWED) - return complain_error(sa->aad->error); + if (sa->aad.type == AUDIT_APPARMOR_ALLOWED) + return complain_error(sa->aad.error); - return sa->aad->error; + return sa->aad.error; } diff --git a/trunk/security/apparmor/capability.c b/trunk/security/apparmor/capability.c index 088dba3bf7dc..9982c48def4e 100644 --- a/trunk/security/apparmor/capability.c +++ b/trunk/security/apparmor/capability.c @@ -64,13 +64,11 @@ static int audit_caps(struct aa_profile *profile, struct task_struct *task, struct audit_cache *ent; int type = AUDIT_APPARMOR_AUTO; struct common_audit_data sa; - struct apparmor_audit_data aad = {0,}; COMMON_AUDIT_DATA_INIT(&sa, CAP); - sa.aad = &aad; sa.tsk = task; sa.u.cap = cap; - sa.aad->op = OP_CAPABLE; - sa.aad->error = error; + sa.aad.op = OP_CAPABLE; + sa.aad.error = error; if (likely(!error)) { /* test if auditing is being forced */ diff --git a/trunk/security/apparmor/file.c b/trunk/security/apparmor/file.c index 2f8fcba9ce4b..5d176f2530c9 100644 --- a/trunk/security/apparmor/file.c +++ b/trunk/security/apparmor/file.c @@ -67,22 +67,22 @@ static void file_audit_cb(struct audit_buffer *ab, void *va) struct common_audit_data *sa = va; uid_t fsuid = current_fsuid(); - if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) { + if (sa->aad.fs.request & AA_AUDIT_FILE_MASK) { audit_log_format(ab, " requested_mask="); - audit_file_mask(ab, sa->aad->fs.request); + audit_file_mask(ab, sa->aad.fs.request); } - if (sa->aad->fs.denied & AA_AUDIT_FILE_MASK) { + if (sa->aad.fs.denied & AA_AUDIT_FILE_MASK) { audit_log_format(ab, " denied_mask="); - audit_file_mask(ab, sa->aad->fs.denied); + audit_file_mask(ab, sa->aad.fs.denied); } - if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) { + if (sa->aad.fs.request & AA_AUDIT_FILE_MASK) { audit_log_format(ab, " fsuid=%d", fsuid); - audit_log_format(ab, " ouid=%d", sa->aad->fs.ouid); + audit_log_format(ab, " ouid=%d", sa->aad.fs.ouid); } - if (sa->aad->fs.target) { + if (sa->aad.fs.target) { audit_log_format(ab, " target="); - audit_log_untrustedstring(ab, sa->aad->fs.target); + audit_log_untrustedstring(ab, sa->aad.fs.target); } } @@ -107,47 +107,45 @@ int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, { int type = AUDIT_APPARMOR_AUTO; struct common_audit_data sa; - struct apparmor_audit_data aad = {0,}; COMMON_AUDIT_DATA_INIT(&sa, NONE); - sa.aad = &aad; - aad.op = op, - aad.fs.request = request; - aad.name = name; - aad.fs.target = target; - aad.fs.ouid = ouid; - aad.info = info; - aad.error = error; - - if (likely(!sa.aad->error)) { + sa.aad.op = op, + sa.aad.fs.request = request; + sa.aad.name = name; + sa.aad.fs.target = target; + sa.aad.fs.ouid = ouid; + sa.aad.info = info; + sa.aad.error = error; + + if (likely(!sa.aad.error)) { u32 mask = perms->audit; if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL)) mask = 0xffff; /* mask off perms that are not being force audited */ - sa.aad->fs.request &= mask; + sa.aad.fs.request &= mask; - if (likely(!sa.aad->fs.request)) + if (likely(!sa.aad.fs.request)) return 0; type = AUDIT_APPARMOR_AUDIT; } else { /* only report permissions that were denied */ - sa.aad->fs.request = sa.aad->fs.request & ~perms->allow; + sa.aad.fs.request = sa.aad.fs.request & ~perms->allow; - if (sa.aad->fs.request & perms->kill) + if (sa.aad.fs.request & perms->kill) type = AUDIT_APPARMOR_KILL; /* quiet known rejects, assumes quiet and kill do not overlap */ - if ((sa.aad->fs.request & perms->quiet) && + if ((sa.aad.fs.request & perms->quiet) && AUDIT_MODE(profile) != AUDIT_NOQUIET && AUDIT_MODE(profile) != AUDIT_ALL) - sa.aad->fs.request &= ~perms->quiet; + sa.aad.fs.request &= ~perms->quiet; - if (!sa.aad->fs.request) - return COMPLAIN_MODE(profile) ? 0 : sa.aad->error; + if (!sa.aad.fs.request) + return COMPLAIN_MODE(profile) ? 0 : sa.aad.error; } - sa.aad->fs.denied = sa.aad->fs.request & ~perms->allow; + sa.aad.fs.denied = sa.aad.fs.request & ~perms->allow; return aa_audit(type, profile, gfp, &sa, file_audit_cb); } diff --git a/trunk/security/apparmor/include/audit.h b/trunk/security/apparmor/include/audit.h index 3868b1e5d5ba..4ba78c203af1 100644 --- a/trunk/security/apparmor/include/audit.h +++ b/trunk/security/apparmor/include/audit.h @@ -103,33 +103,7 @@ enum aa_ops { }; -struct apparmor_audit_data { - int error; - int op; - int type; - void *profile; - const char *name; - const char *info; - union { - void *target; - struct { - long pos; - void *target; - } iface; - struct { - int rlim; - unsigned long max; - } rlim; - struct { - const char *target; - u32 request; - u32 denied; - uid_t ouid; - } fs; - }; -}; - -/* define a short hand for apparmor_audit_data structure */ +/* define a short hand for apparmor_audit_data portion of common_audit_data */ #define aad apparmor_audit_data void aa_audit_msg(int type, struct common_audit_data *sa, diff --git a/trunk/security/apparmor/ipc.c b/trunk/security/apparmor/ipc.c index c3da93a5150d..7ee05c6f3c64 100644 --- a/trunk/security/apparmor/ipc.c +++ b/trunk/security/apparmor/ipc.c @@ -26,7 +26,7 @@ static void audit_cb(struct audit_buffer *ab, void *va) { struct common_audit_data *sa = va; audit_log_format(ab, " target="); - audit_log_untrustedstring(ab, sa->aad->target); + audit_log_untrustedstring(ab, sa->aad.target); } /** @@ -41,12 +41,10 @@ static int aa_audit_ptrace(struct aa_profile *profile, struct aa_profile *target, int error) { struct common_audit_data sa; - struct apparmor_audit_data aad = {0,}; COMMON_AUDIT_DATA_INIT(&sa, NONE); - sa.aad = &aad; - aad.op = OP_PTRACE; - aad.target = target; - aad.error = error; + sa.aad.op = OP_PTRACE; + sa.aad.target = target; + sa.aad.error = error; return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_ATOMIC, &sa, audit_cb); diff --git a/trunk/security/apparmor/lib.c b/trunk/security/apparmor/lib.c index e75829ba0ff9..9516948041ad 100644 --- a/trunk/security/apparmor/lib.c +++ b/trunk/security/apparmor/lib.c @@ -65,10 +65,8 @@ void aa_info_message(const char *str) { if (audit_enabled) { struct common_audit_data sa; - struct apparmor_audit_data aad = {0,}; COMMON_AUDIT_DATA_INIT(&sa, NONE); - sa.aad = &aad; - aad.info = str; + sa.aad.info = str; aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL); } printk(KERN_INFO "AppArmor: %s\n", str); diff --git a/trunk/security/apparmor/lsm.c b/trunk/security/apparmor/lsm.c index ad05d391974d..97ce8fae49b3 100644 --- a/trunk/security/apparmor/lsm.c +++ b/trunk/security/apparmor/lsm.c @@ -588,12 +588,10 @@ static int apparmor_setprocattr(struct task_struct *task, char *name, error = aa_setprocattr_permipc(args); } else { struct common_audit_data sa; - struct apparmor_audit_data aad = {0,}; COMMON_AUDIT_DATA_INIT(&sa, NONE); - sa.aad = &aad; - aad.op = OP_SETPROCATTR; - aad.info = name; - aad.error = -EINVAL; + sa.aad.op = OP_SETPROCATTR; + sa.aad.info = name; + sa.aad.error = -EINVAL; return aa_audit(AUDIT_APPARMOR_DENIED, __aa_current_profile(), GFP_KERNEL, &sa, NULL); diff --git a/trunk/security/apparmor/policy.c b/trunk/security/apparmor/policy.c index f1f7506a464d..906414383022 100644 --- a/trunk/security/apparmor/policy.c +++ b/trunk/security/apparmor/policy.c @@ -964,13 +964,11 @@ static int audit_policy(int op, gfp_t gfp, const char *name, const char *info, int error) { struct common_audit_data sa; - struct apparmor_audit_data aad = {0,}; COMMON_AUDIT_DATA_INIT(&sa, NONE); - sa.aad = &aad; - aad.op = op; - aad.name = name; - aad.info = info; - aad.error = error; + sa.aad.op = op; + sa.aad.name = name; + sa.aad.info = info; + sa.aad.error = error; return aa_audit(AUDIT_APPARMOR_STATUS, __aa_current_profile(), gfp, &sa, NULL); diff --git a/trunk/security/apparmor/policy_unpack.c b/trunk/security/apparmor/policy_unpack.c index deab7c7e8dc0..25fd51edc8da 100644 --- a/trunk/security/apparmor/policy_unpack.c +++ b/trunk/security/apparmor/policy_unpack.c @@ -70,13 +70,13 @@ struct aa_ext { static void audit_cb(struct audit_buffer *ab, void *va) { struct common_audit_data *sa = va; - if (sa->aad->iface.target) { - struct aa_profile *name = sa->aad->iface.target; + if (sa->aad.iface.target) { + struct aa_profile *name = sa->aad.iface.target; audit_log_format(ab, " name="); audit_log_untrustedstring(ab, name->base.hname); } - if (sa->aad->iface.pos) - audit_log_format(ab, " offset=%ld", sa->aad->iface.pos); + if (sa->aad.iface.pos) + audit_log_format(ab, " offset=%ld", sa->aad.iface.pos); } /** @@ -94,15 +94,13 @@ static int audit_iface(struct aa_profile *new, const char *name, { struct aa_profile *profile = __aa_current_profile(); struct common_audit_data sa; - struct apparmor_audit_data aad = {0,}; COMMON_AUDIT_DATA_INIT(&sa, NONE); - sa.aad = &aad; if (e) - aad.iface.pos = e->pos - e->start; - aad.iface.target = new; - aad.name = name; - aad.info = info; - aad.error = error; + sa.aad.iface.pos = e->pos - e->start; + sa.aad.iface.target = new; + sa.aad.name = name; + sa.aad.info = info; + sa.aad.error = error; return aa_audit(AUDIT_APPARMOR_STATUS, profile, GFP_KERNEL, &sa, audit_cb); diff --git a/trunk/security/apparmor/resource.c b/trunk/security/apparmor/resource.c index 2fe8613efe33..72c25a4f2cfd 100644 --- a/trunk/security/apparmor/resource.c +++ b/trunk/security/apparmor/resource.c @@ -34,7 +34,7 @@ static void audit_cb(struct audit_buffer *ab, void *va) struct common_audit_data *sa = va; audit_log_format(ab, " rlimit=%s value=%lu", - rlim_names[sa->aad->rlim.rlim], sa->aad->rlim.max); + rlim_names[sa->aad.rlim.rlim], sa->aad.rlim.max); } /** @@ -50,14 +50,12 @@ static int audit_resource(struct aa_profile *profile, unsigned int resource, unsigned long value, int error) { struct common_audit_data sa; - struct apparmor_audit_data aad = {0,}; COMMON_AUDIT_DATA_INIT(&sa, NONE); - sa.aad = &aad; - aad.op = OP_SETRLIMIT, - aad.rlim.rlim = resource; - aad.rlim.max = value; - aad.error = error; + sa.aad.op = OP_SETRLIMIT, + sa.aad.rlim.rlim = resource; + sa.aad.rlim.max = value; + sa.aad.error = error; return aa_audit(AUDIT_APPARMOR_AUTO, profile, GFP_KERNEL, &sa, audit_cb); } diff --git a/trunk/security/commoncap.c b/trunk/security/commoncap.c index 71a166a05975..0cf4b53480a7 100644 --- a/trunk/security/commoncap.c +++ b/trunk/security/commoncap.c @@ -29,7 +29,6 @@ #include #include #include -#include /* * If a non-root user executes a setuid-root binary in @@ -506,11 +505,6 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) } skip: - /* if we have fs caps, clear dangerous personality flags */ - if (!cap_issubset(new->cap_permitted, old->cap_permitted)) - bprm->per_clear |= PER_CLEAR_ON_SETID; - - /* Don't let someone trace a set[ug]id/setpcap binary with the revised * credentials unless they have the appropriate permit */ diff --git a/trunk/security/lsm_audit.c b/trunk/security/lsm_audit.c index 90c129b0102f..8b8f0902f6e5 100644 --- a/trunk/security/lsm_audit.c +++ b/trunk/security/lsm_audit.c @@ -49,8 +49,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, if (ih == NULL) return -EINVAL; - ad->u.net->v4info.saddr = ih->saddr; - ad->u.net->v4info.daddr = ih->daddr; + ad->u.net.v4info.saddr = ih->saddr; + ad->u.net.v4info.daddr = ih->daddr; if (proto) *proto = ih->protocol; @@ -64,8 +64,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, if (th == NULL) break; - ad->u.net->sport = th->source; - ad->u.net->dport = th->dest; + ad->u.net.sport = th->source; + ad->u.net.dport = th->dest; break; } case IPPROTO_UDP: { @@ -73,8 +73,8 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, if (uh == NULL) break; - ad->u.net->sport = uh->source; - ad->u.net->dport = uh->dest; + ad->u.net.sport = uh->source; + ad->u.net.dport = uh->dest; break; } case IPPROTO_DCCP: { @@ -82,16 +82,16 @@ int ipv4_skb_to_auditdata(struct sk_buff *skb, if (dh == NULL) break; - ad->u.net->sport = dh->dccph_sport; - ad->u.net->dport = dh->dccph_dport; + ad->u.net.sport = dh->dccph_sport; + ad->u.net.dport = dh->dccph_dport; break; } case IPPROTO_SCTP: { struct sctphdr *sh = sctp_hdr(skb); if (sh == NULL) break; - ad->u.net->sport = sh->source; - ad->u.net->dport = sh->dest; + ad->u.net.sport = sh->source; + ad->u.net.dport = sh->dest; break; } default: @@ -119,8 +119,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, ip6 = ipv6_hdr(skb); if (ip6 == NULL) return -EINVAL; - ad->u.net->v6info.saddr = ip6->saddr; - ad->u.net->v6info.daddr = ip6->daddr; + ad->u.net.v6info.saddr = ip6->saddr; + ad->u.net.v6info.daddr = ip6->daddr; ret = 0; /* IPv6 can have several extension header before the Transport header * skip them */ @@ -140,8 +140,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, if (th == NULL) break; - ad->u.net->sport = th->source; - ad->u.net->dport = th->dest; + ad->u.net.sport = th->source; + ad->u.net.dport = th->dest; break; } case IPPROTO_UDP: { @@ -151,8 +151,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, if (uh == NULL) break; - ad->u.net->sport = uh->source; - ad->u.net->dport = uh->dest; + ad->u.net.sport = uh->source; + ad->u.net.dport = uh->dest; break; } case IPPROTO_DCCP: { @@ -162,8 +162,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, if (dh == NULL) break; - ad->u.net->sport = dh->dccph_sport; - ad->u.net->dport = dh->dccph_dport; + ad->u.net.sport = dh->dccph_sport; + ad->u.net.dport = dh->dccph_dport; break; } case IPPROTO_SCTP: { @@ -172,8 +172,8 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph); if (sh == NULL) break; - ad->u.net->sport = sh->source; - ad->u.net->dport = sh->dest; + ad->u.net.sport = sh->source; + ad->u.net.dport = sh->dest; break; } default: @@ -281,8 +281,8 @@ static void dump_common_audit_data(struct audit_buffer *ab, } break; case LSM_AUDIT_DATA_NET: - if (a->u.net->sk) { - struct sock *sk = a->u.net->sk; + if (a->u.net.sk) { + struct sock *sk = a->u.net.sk; struct unix_sock *u; int len = 0; char *p = NULL; @@ -330,29 +330,29 @@ static void dump_common_audit_data(struct audit_buffer *ab, } } - switch (a->u.net->family) { + switch (a->u.net.family) { case AF_INET: - print_ipv4_addr(ab, a->u.net->v4info.saddr, - a->u.net->sport, + print_ipv4_addr(ab, a->u.net.v4info.saddr, + a->u.net.sport, "saddr", "src"); - print_ipv4_addr(ab, a->u.net->v4info.daddr, - a->u.net->dport, + print_ipv4_addr(ab, a->u.net.v4info.daddr, + a->u.net.dport, "daddr", "dest"); break; case AF_INET6: - print_ipv6_addr(ab, &a->u.net->v6info.saddr, - a->u.net->sport, + print_ipv6_addr(ab, &a->u.net.v6info.saddr, + a->u.net.sport, "saddr", "src"); - print_ipv6_addr(ab, &a->u.net->v6info.daddr, - a->u.net->dport, + print_ipv6_addr(ab, &a->u.net.v6info.daddr, + a->u.net.dport, "daddr", "dest"); break; } - if (a->u.net->netif > 0) { + if (a->u.net.netif > 0) { struct net_device *dev; /* NOTE: we always use init's namespace */ - dev = dev_get_by_index(&init_net, a->u.net->netif); + dev = dev_get_by_index(&init_net, a->u.net.netif); if (dev) { audit_log_format(ab, " netif=%s", dev->name); dev_put(dev); @@ -378,15 +378,11 @@ static void dump_common_audit_data(struct audit_buffer *ab, /** * common_lsm_audit - generic LSM auditing function * @a: auxiliary audit data - * @pre_audit: lsm-specific pre-audit callback - * @post_audit: lsm-specific post-audit callback * * setup the audit buffer for common security information * uses callback to print LSM specific information */ -void common_lsm_audit(struct common_audit_data *a, - void (*pre_audit)(struct audit_buffer *, void *), - void (*post_audit)(struct audit_buffer *, void *)) +void common_lsm_audit(struct common_audit_data *a) { struct audit_buffer *ab; @@ -398,13 +394,13 @@ void common_lsm_audit(struct common_audit_data *a, if (ab == NULL) return; - if (pre_audit) - pre_audit(ab, a); + if (a->lsm_pre_audit) + a->lsm_pre_audit(ab, a); dump_common_audit_data(ab, a); - if (post_audit) - post_audit(ab, a); + if (a->lsm_post_audit) + a->lsm_post_audit(ab, a); audit_log_end(ab); } diff --git a/trunk/security/selinux/avc.c b/trunk/security/selinux/avc.c index 8ee42b2a5f19..6989472d0957 100644 --- a/trunk/security/selinux/avc.c +++ b/trunk/security/selinux/avc.c @@ -436,9 +436,9 @@ static void avc_audit_pre_callback(struct audit_buffer *ab, void *a) { struct common_audit_data *ad = a; audit_log_format(ab, "avc: %s ", - ad->selinux_audit_data->slad->denied ? "denied" : "granted"); - avc_dump_av(ab, ad->selinux_audit_data->slad->tclass, - ad->selinux_audit_data->slad->audited); + ad->selinux_audit_data.denied ? "denied" : "granted"); + avc_dump_av(ab, ad->selinux_audit_data.tclass, + ad->selinux_audit_data.audited); audit_log_format(ab, " for "); } @@ -452,25 +452,22 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) { struct common_audit_data *ad = a; audit_log_format(ab, " "); - avc_dump_query(ab, ad->selinux_audit_data->slad->ssid, - ad->selinux_audit_data->slad->tsid, - ad->selinux_audit_data->slad->tclass); + avc_dump_query(ab, ad->selinux_audit_data.ssid, + ad->selinux_audit_data.tsid, + ad->selinux_audit_data.tclass); } /* This is the slow part of avc audit with big stack footprint */ static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, u32 requested, u32 audited, u32 denied, - struct common_audit_data *a, + struct av_decision *avd, struct common_audit_data *a, unsigned flags) { struct common_audit_data stack_data; - struct selinux_audit_data sad = {0,}; - struct selinux_late_audit_data slad; if (!a) { a = &stack_data; COMMON_AUDIT_DATA_INIT(a, NONE); - a->selinux_audit_data = &sad; } /* @@ -484,15 +481,15 @@ static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, (flags & MAY_NOT_BLOCK)) return -ECHILD; - slad.tclass = tclass; - slad.requested = requested; - slad.ssid = ssid; - slad.tsid = tsid; - slad.audited = audited; - slad.denied = denied; - - a->selinux_audit_data->slad = &slad; - common_lsm_audit(a, avc_audit_pre_callback, avc_audit_post_callback); + a->selinux_audit_data.tclass = tclass; + a->selinux_audit_data.requested = requested; + a->selinux_audit_data.ssid = ssid; + a->selinux_audit_data.tsid = tsid; + a->selinux_audit_data.audited = audited; + a->selinux_audit_data.denied = denied; + a->lsm_pre_audit = avc_audit_pre_callback; + a->lsm_post_audit = avc_audit_post_callback; + common_lsm_audit(a); return 0; } @@ -516,7 +513,7 @@ static noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass, * be performed under a lock, to allow the lock to be released * before calling the auditing code. */ -inline int avc_audit(u32 ssid, u32 tsid, +int avc_audit(u32 ssid, u32 tsid, u16 tclass, u32 requested, struct av_decision *avd, int result, struct common_audit_data *a, unsigned flags) @@ -526,7 +523,7 @@ inline int avc_audit(u32 ssid, u32 tsid, if (unlikely(denied)) { audited = denied & avd->auditdeny; /* - * a->selinux_audit_data->auditdeny is TRICKY! Setting a bit in + * a->selinux_audit_data.auditdeny is TRICKY! Setting a bit in * this field means that ANY denials should NOT be audited if * the policy contains an explicit dontaudit rule for that * permission. Take notice that this is unrelated to the @@ -535,15 +532,15 @@ inline int avc_audit(u32 ssid, u32 tsid, * * denied == READ * avd.auditdeny & ACCESS == 0 (not set means explicit rule) - * selinux_audit_data->auditdeny & ACCESS == 1 + * selinux_audit_data.auditdeny & ACCESS == 1 * * We will NOT audit the denial even though the denied * permission was READ and the auditdeny checks were for * ACCESS */ if (a && - a->selinux_audit_data->auditdeny && - !(a->selinux_audit_data->auditdeny & avd->auditdeny)) + a->selinux_audit_data.auditdeny && + !(a->selinux_audit_data.auditdeny & avd->auditdeny)) audited = 0; } else if (result) audited = denied = requested; @@ -554,7 +551,7 @@ inline int avc_audit(u32 ssid, u32 tsid, return slow_avc_audit(ssid, tsid, tclass, requested, audited, denied, - a, flags); + avd, a, flags); } /** @@ -744,41 +741,6 @@ int avc_ss_reset(u32 seqno) return rc; } -/* - * Slow-path helper function for avc_has_perm_noaudit, - * when the avc_node lookup fails. We get called with - * the RCU read lock held, and need to return with it - * still held, but drop if for the security compute. - * - * Don't inline this, since it's the slow-path and just - * results in a bigger stack frame. - */ -static noinline struct avc_node *avc_compute_av(u32 ssid, u32 tsid, - u16 tclass, struct av_decision *avd) -{ - rcu_read_unlock(); - security_compute_av(ssid, tsid, tclass, avd); - rcu_read_lock(); - return avc_insert(ssid, tsid, tclass, avd); -} - -static noinline int avc_denied(u32 ssid, u32 tsid, - u16 tclass, u32 requested, - unsigned flags, - struct av_decision *avd) -{ - if (flags & AVC_STRICT) - return -EACCES; - - if (selinux_enforcing && !(avd->flags & AVD_FLAGS_PERMISSIVE)) - return -EACCES; - - avc_update_node(AVC_CALLBACK_GRANT, requested, ssid, - tsid, tclass, avd->seqno); - return 0; -} - - /** * avc_has_perm_noaudit - Check permissions but perform no auditing. * @ssid: source security identifier @@ -799,7 +761,7 @@ static noinline int avc_denied(u32 ssid, u32 tsid, * auditing, e.g. in cases where a lock must be held for the check but * should be released for the auditing. */ -inline int avc_has_perm_noaudit(u32 ssid, u32 tsid, +int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested, unsigned flags, struct av_decision *avd) @@ -814,15 +776,26 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid, node = avc_lookup(ssid, tsid, tclass); if (unlikely(!node)) { - node = avc_compute_av(ssid, tsid, tclass, avd); + rcu_read_unlock(); + security_compute_av(ssid, tsid, tclass, avd); + rcu_read_lock(); + node = avc_insert(ssid, tsid, tclass, avd); } else { memcpy(avd, &node->ae.avd, sizeof(*avd)); avd = &node->ae.avd; } denied = requested & ~(avd->allowed); - if (unlikely(denied)) - rc = avc_denied(ssid, tsid, tclass, requested, flags, avd); + + if (denied) { + if (flags & AVC_STRICT) + rc = -EACCES; + else if (!selinux_enforcing || (avd->flags & AVD_FLAGS_PERMISSIVE)) + avc_update_node(AVC_CALLBACK_GRANT, requested, ssid, + tsid, tclass, avd->seqno); + else + rc = -EACCES; + } rcu_read_unlock(); return rc; diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index d85b793c9321..15c6c567468b 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -1420,7 +1421,6 @@ static int cred_has_capability(const struct cred *cred, int cap, int audit) { struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; struct av_decision avd; u16 sclass; u32 sid = cred_sid(cred); @@ -1428,7 +1428,6 @@ static int cred_has_capability(const struct cred *cred, int rc; COMMON_AUDIT_DATA_INIT(&ad, CAP); - ad.selinux_audit_data = &sad; ad.tsk = current; ad.u.cap = cap; @@ -1494,11 +1493,9 @@ static int inode_has_perm_noadp(const struct cred *cred, unsigned flags) { struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; COMMON_AUDIT_DATA_INIT(&ad, INODE); ad.u.inode = inode; - ad.selinux_audit_data = &sad; return inode_has_perm(cred, inode, perms, &ad, flags); } @@ -1511,11 +1508,9 @@ static inline int dentry_has_perm(const struct cred *cred, { struct inode *inode = dentry->d_inode; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; COMMON_AUDIT_DATA_INIT(&ad, DENTRY); ad.u.dentry = dentry; - ad.selinux_audit_data = &sad; return inode_has_perm(cred, inode, av, &ad, 0); } @@ -1528,11 +1523,9 @@ static inline int path_has_perm(const struct cred *cred, { struct inode *inode = path->dentry->d_inode; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; COMMON_AUDIT_DATA_INIT(&ad, PATH); ad.u.path = *path; - ad.selinux_audit_data = &sad; return inode_has_perm(cred, inode, av, &ad, 0); } @@ -1551,13 +1544,11 @@ static int file_has_perm(const struct cred *cred, struct file_security_struct *fsec = file->f_security; struct inode *inode = file->f_path.dentry->d_inode; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; u32 sid = cred_sid(cred); int rc; COMMON_AUDIT_DATA_INIT(&ad, PATH); ad.u.path = file->f_path; - ad.selinux_audit_data = &sad; if (sid != fsec->sid) { rc = avc_has_perm(sid, fsec->sid, @@ -1587,7 +1578,6 @@ static int may_create(struct inode *dir, struct superblock_security_struct *sbsec; u32 sid, newsid; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; int rc; dsec = dir->i_security; @@ -1598,7 +1588,6 @@ static int may_create(struct inode *dir, COMMON_AUDIT_DATA_INIT(&ad, DENTRY); ad.u.dentry = dentry; - ad.selinux_audit_data = &sad; rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, DIR__ADD_NAME | DIR__SEARCH, @@ -1643,7 +1632,6 @@ static int may_link(struct inode *dir, { struct inode_security_struct *dsec, *isec; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); u32 av; int rc; @@ -1653,7 +1641,6 @@ static int may_link(struct inode *dir, COMMON_AUDIT_DATA_INIT(&ad, DENTRY); ad.u.dentry = dentry; - ad.selinux_audit_data = &sad; av = DIR__SEARCH; av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); @@ -1688,7 +1675,6 @@ static inline int may_rename(struct inode *old_dir, { struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); u32 av; int old_is_dir, new_is_dir; @@ -1700,7 +1686,6 @@ static inline int may_rename(struct inode *old_dir, new_dsec = new_dir->i_security; COMMON_AUDIT_DATA_INIT(&ad, DENTRY); - ad.selinux_audit_data = &sad; ad.u.dentry = old_dentry; rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, @@ -1986,7 +1971,6 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) struct task_security_struct *new_tsec; struct inode_security_struct *isec; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; struct inode *inode = bprm->file->f_path.dentry->d_inode; int rc; @@ -2026,7 +2010,6 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) } COMMON_AUDIT_DATA_INIT(&ad, PATH); - ad.selinux_audit_data = &sad; ad.u.path = bprm->file->f_path; if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) @@ -2116,7 +2099,6 @@ static inline void flush_unauthorized_files(const struct cred *cred, struct files_struct *files) { struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; struct file *file, *devnull = NULL; struct tty_struct *tty; struct fdtable *fdt; @@ -2154,7 +2136,6 @@ static inline void flush_unauthorized_files(const struct cred *cred, /* Revalidate access to inherited open files. */ COMMON_AUDIT_DATA_INIT(&ad, INODE); - ad.selinux_audit_data = &sad; spin_lock(&files->file_lock); for (;;) { @@ -2492,7 +2473,6 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) { const struct cred *cred = current_cred(); struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; int rc; rc = superblock_doinit(sb, data); @@ -2504,7 +2484,6 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) return 0; COMMON_AUDIT_DATA_INIT(&ad, DENTRY); - ad.selinux_audit_data = &sad; ad.u.dentry = sb->s_root; return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); } @@ -2513,10 +2492,8 @@ static int selinux_sb_statfs(struct dentry *dentry) { const struct cred *cred = current_cred(); struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; COMMON_AUDIT_DATA_INIT(&ad, DENTRY); - ad.selinux_audit_data = &sad; ad.u.dentry = dentry->d_sb->s_root; return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); } @@ -2680,7 +2657,6 @@ static int selinux_inode_permission(struct inode *inode, int mask) { const struct cred *cred = current_cred(); struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; u32 perms; bool from_access; unsigned flags = mask & MAY_NOT_BLOCK; @@ -2693,11 +2669,10 @@ static int selinux_inode_permission(struct inode *inode, int mask) return 0; COMMON_AUDIT_DATA_INIT(&ad, INODE); - ad.selinux_audit_data = &sad; ad.u.inode = inode; if (from_access) - ad.selinux_audit_data->auditdeny |= FILE__AUDIT_ACCESS; + ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS; perms = file_mask_to_av(inode->i_mode, mask); @@ -2763,7 +2738,6 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, struct inode_security_struct *isec = inode->i_security; struct superblock_security_struct *sbsec; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; u32 newsid, sid = current_sid(); int rc = 0; @@ -2778,7 +2752,6 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, return -EPERM; COMMON_AUDIT_DATA_INIT(&ad, DENTRY); - ad.selinux_audit_data = &sad; ad.u.dentry = dentry; rc = avc_has_perm(sid, isec->sid, isec->sclass, @@ -2998,15 +2971,15 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, /* fall through */ case FIGETBSZ: /* fall through */ - case FS_IOC_GETFLAGS: + case EXT2_IOC_GETFLAGS: /* fall through */ - case FS_IOC_GETVERSION: + case EXT2_IOC_GETVERSION: error = file_has_perm(cred, file, FILE__GETATTR); break; - case FS_IOC_SETFLAGS: + case EXT2_IOC_SETFLAGS: /* fall through */ - case FS_IOC_SETVERSION: + case EXT2_IOC_SETVERSION: error = file_has_perm(cred, file, FILE__SETATTR); break; @@ -3373,12 +3346,10 @@ static int selinux_kernel_module_request(char *kmod_name) { u32 sid; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; sid = task_sid(current); COMMON_AUDIT_DATA_INIT(&ad, KMOD); - ad.selinux_audit_data = &sad; ad.u.kmod_name = kmod_name; return avc_has_perm(sid, SECINITSID_KERNEL, SECCLASS_SYSTEM, @@ -3517,8 +3488,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, if (ihlen < sizeof(_iph)) goto out; - ad->u.net->v4info.saddr = ih->saddr; - ad->u.net->v4info.daddr = ih->daddr; + ad->u.net.v4info.saddr = ih->saddr; + ad->u.net.v4info.daddr = ih->daddr; ret = 0; if (proto) @@ -3536,8 +3507,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, if (th == NULL) break; - ad->u.net->sport = th->source; - ad->u.net->dport = th->dest; + ad->u.net.sport = th->source; + ad->u.net.dport = th->dest; break; } @@ -3552,8 +3523,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, if (uh == NULL) break; - ad->u.net->sport = uh->source; - ad->u.net->dport = uh->dest; + ad->u.net.sport = uh->source; + ad->u.net.dport = uh->dest; break; } @@ -3568,8 +3539,8 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, if (dh == NULL) break; - ad->u.net->sport = dh->dccph_sport; - ad->u.net->dport = dh->dccph_dport; + ad->u.net.sport = dh->dccph_sport; + ad->u.net.dport = dh->dccph_dport; break; } @@ -3596,8 +3567,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, if (ip6 == NULL) goto out; - ad->u.net->v6info.saddr = ip6->saddr; - ad->u.net->v6info.daddr = ip6->daddr; + ad->u.net.v6info.saddr = ip6->saddr; + ad->u.net.v6info.daddr = ip6->daddr; ret = 0; nexthdr = ip6->nexthdr; @@ -3617,8 +3588,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, if (th == NULL) break; - ad->u.net->sport = th->source; - ad->u.net->dport = th->dest; + ad->u.net.sport = th->source; + ad->u.net.dport = th->dest; break; } @@ -3629,8 +3600,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, if (uh == NULL) break; - ad->u.net->sport = uh->source; - ad->u.net->dport = uh->dest; + ad->u.net.sport = uh->source; + ad->u.net.dport = uh->dest; break; } @@ -3641,8 +3612,8 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, if (dh == NULL) break; - ad->u.net->sport = dh->dccph_sport; - ad->u.net->dport = dh->dccph_dport; + ad->u.net.sport = dh->dccph_sport; + ad->u.net.dport = dh->dccph_dport; break; } @@ -3662,13 +3633,13 @@ static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad, char *addrp; int ret; - switch (ad->u.net->family) { + switch (ad->u.net.family) { case PF_INET: ret = selinux_parse_skb_ipv4(skb, ad, proto); if (ret) goto parse_error; - addrp = (char *)(src ? &ad->u.net->v4info.saddr : - &ad->u.net->v4info.daddr); + addrp = (char *)(src ? &ad->u.net.v4info.saddr : + &ad->u.net.v4info.daddr); goto okay; #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) @@ -3676,8 +3647,8 @@ static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad, ret = selinux_parse_skb_ipv6(skb, ad, proto); if (ret) goto parse_error; - addrp = (char *)(src ? &ad->u.net->v6info.saddr : - &ad->u.net->v6info.daddr); + addrp = (char *)(src ? &ad->u.net.v6info.saddr : + &ad->u.net.v6info.daddr); goto okay; #endif /* IPV6 */ default: @@ -3751,17 +3722,13 @@ static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms) { struct sk_security_struct *sksec = sk->sk_security; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; - struct lsm_network_audit net = {0,}; u32 tsid = task_sid(task); if (sksec->sid == SECINITSID_KERNEL) return 0; COMMON_AUDIT_DATA_INIT(&ad, NET); - ad.selinux_audit_data = &sad; - ad.u.net = &net; - ad.u.net->sk = sk; + ad.u.net.sk = sk; return avc_has_perm(tsid, sksec->sid, sksec->sclass, perms, &ad); } @@ -3839,8 +3806,6 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in char *addrp; struct sk_security_struct *sksec = sk->sk_security; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; - struct lsm_network_audit net = {0,}; struct sockaddr_in *addr4 = NULL; struct sockaddr_in6 *addr6 = NULL; unsigned short snum; @@ -3867,10 +3832,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in if (err) goto out; COMMON_AUDIT_DATA_INIT(&ad, NET); - ad.selinux_audit_data = &sad; - ad.u.net = &net; - ad.u.net->sport = htons(snum); - ad.u.net->family = family; + ad.u.net.sport = htons(snum); + ad.u.net.family = family; err = avc_has_perm(sksec->sid, sid, sksec->sclass, SOCKET__NAME_BIND, &ad); @@ -3902,15 +3865,13 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in goto out; COMMON_AUDIT_DATA_INIT(&ad, NET); - ad.selinux_audit_data = &sad; - ad.u.net = &net; - ad.u.net->sport = htons(snum); - ad.u.net->family = family; + ad.u.net.sport = htons(snum); + ad.u.net.family = family; if (family == PF_INET) - ad.u.net->v4info.saddr = addr4->sin_addr.s_addr; + ad.u.net.v4info.saddr = addr4->sin_addr.s_addr; else - ad.u.net->v6info.saddr = addr6->sin6_addr; + ad.u.net.v6info.saddr = addr6->sin6_addr; err = avc_has_perm(sksec->sid, sid, sksec->sclass, node_perm, &ad); @@ -3937,8 +3898,6 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, if (sksec->sclass == SECCLASS_TCP_SOCKET || sksec->sclass == SECCLASS_DCCP_SOCKET) { struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; - struct lsm_network_audit net = {0,}; struct sockaddr_in *addr4 = NULL; struct sockaddr_in6 *addr6 = NULL; unsigned short snum; @@ -3964,10 +3923,8 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT; COMMON_AUDIT_DATA_INIT(&ad, NET); - ad.selinux_audit_data = &sad; - ad.u.net = &net; - ad.u.net->dport = htons(snum); - ad.u.net->family = sk->sk_family; + ad.u.net.dport = htons(snum); + ad.u.net.family = sk->sk_family; err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad); if (err) goto out; @@ -4056,14 +4013,10 @@ static int selinux_socket_unix_stream_connect(struct sock *sock, struct sk_security_struct *sksec_other = other->sk_security; struct sk_security_struct *sksec_new = newsk->sk_security; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; - struct lsm_network_audit net = {0,}; int err; COMMON_AUDIT_DATA_INIT(&ad, NET); - ad.selinux_audit_data = &sad; - ad.u.net = &net; - ad.u.net->sk = other; + ad.u.net.sk = other; err = avc_has_perm(sksec_sock->sid, sksec_other->sid, sksec_other->sclass, @@ -4090,13 +4043,9 @@ static int selinux_socket_unix_may_send(struct socket *sock, struct sk_security_struct *ssec = sock->sk->sk_security; struct sk_security_struct *osec = other->sk->sk_security; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; - struct lsm_network_audit net = {0,}; COMMON_AUDIT_DATA_INIT(&ad, NET); - ad.selinux_audit_data = &sad; - ad.u.net = &net; - ad.u.net->sk = other->sk; + ad.u.net.sk = other->sk; return avc_has_perm(ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO, &ad); @@ -4132,15 +4081,11 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, struct sk_security_struct *sksec = sk->sk_security; u32 sk_sid = sksec->sid; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; - struct lsm_network_audit net = {0,}; char *addrp; COMMON_AUDIT_DATA_INIT(&ad, NET); - ad.selinux_audit_data = &sad; - ad.u.net = &net; - ad.u.net->netif = skb->skb_iif; - ad.u.net->family = family; + ad.u.net.netif = skb->skb_iif; + ad.u.net.family = family; err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); if (err) return err; @@ -4167,8 +4112,6 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) u16 family = sk->sk_family; u32 sk_sid = sksec->sid; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; - struct lsm_network_audit net = {0,}; char *addrp; u8 secmark_active; u8 peerlbl_active; @@ -4193,10 +4136,8 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) return 0; COMMON_AUDIT_DATA_INIT(&ad, NET); - ad.selinux_audit_data = &sad; - ad.u.net = &net; - ad.u.net->netif = skb->skb_iif; - ad.u.net->family = family; + ad.u.net.netif = skb->skb_iif; + ad.u.net.family = family; err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); if (err) return err; @@ -4531,8 +4472,6 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, char *addrp; u32 peer_sid; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; - struct lsm_network_audit net = {0,}; u8 secmark_active; u8 netlbl_active; u8 peerlbl_active; @@ -4550,10 +4489,8 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, return NF_DROP; COMMON_AUDIT_DATA_INIT(&ad, NET); - ad.selinux_audit_data = &sad; - ad.u.net = &net; - ad.u.net->netif = ifindex; - ad.u.net->family = family; + ad.u.net.netif = ifindex; + ad.u.net.family = family; if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0) return NF_DROP; @@ -4640,8 +4577,6 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, struct sock *sk = skb->sk; struct sk_security_struct *sksec; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; - struct lsm_network_audit net = {0,}; char *addrp; u8 proto; @@ -4650,10 +4585,8 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, sksec = sk->sk_security; COMMON_AUDIT_DATA_INIT(&ad, NET); - ad.selinux_audit_data = &sad; - ad.u.net = &net; - ad.u.net->netif = ifindex; - ad.u.net->family = family; + ad.u.net.netif = ifindex; + ad.u.net.family = family; if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto)) return NF_DROP; @@ -4675,8 +4608,6 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, u32 peer_sid; struct sock *sk; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; - struct lsm_network_audit net = {0,}; char *addrp; u8 secmark_active; u8 peerlbl_active; @@ -4723,10 +4654,8 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, } COMMON_AUDIT_DATA_INIT(&ad, NET); - ad.selinux_audit_data = &sad; - ad.u.net = &net; - ad.u.net->netif = ifindex; - ad.u.net->family = family; + ad.u.net.netif = ifindex; + ad.u.net.family = family; if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL)) return NF_DROP; @@ -4841,13 +4770,11 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, { struct ipc_security_struct *isec; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); isec = ipc_perms->security; COMMON_AUDIT_DATA_INIT(&ad, IPC); - ad.selinux_audit_data = &sad; ad.u.ipc_id = ipc_perms->key; return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); @@ -4868,7 +4795,6 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq) { struct ipc_security_struct *isec; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); int rc; @@ -4879,7 +4805,6 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq) isec = msq->q_perm.security; COMMON_AUDIT_DATA_INIT(&ad, IPC); - ad.selinux_audit_data = &sad; ad.u.ipc_id = msq->q_perm.key; rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, @@ -4900,13 +4825,11 @@ static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg) { struct ipc_security_struct *isec; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); isec = msq->q_perm.security; COMMON_AUDIT_DATA_INIT(&ad, IPC); - ad.selinux_audit_data = &sad; ad.u.ipc_id = msq->q_perm.key; return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, @@ -4946,7 +4869,6 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, struct ipc_security_struct *isec; struct msg_security_struct *msec; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); int rc; @@ -4968,7 +4890,6 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, } COMMON_AUDIT_DATA_INIT(&ad, IPC); - ad.selinux_audit_data = &sad; ad.u.ipc_id = msq->q_perm.key; /* Can this process write to the queue? */ @@ -4993,7 +4914,6 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, struct ipc_security_struct *isec; struct msg_security_struct *msec; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; u32 sid = task_sid(target); int rc; @@ -5001,7 +4921,6 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, msec = msg->security; COMMON_AUDIT_DATA_INIT(&ad, IPC); - ad.selinux_audit_data = &sad; ad.u.ipc_id = msq->q_perm.key; rc = avc_has_perm(sid, isec->sid, @@ -5017,7 +4936,6 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp) { struct ipc_security_struct *isec; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); int rc; @@ -5028,7 +4946,6 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp) isec = shp->shm_perm.security; COMMON_AUDIT_DATA_INIT(&ad, IPC); - ad.selinux_audit_data = &sad; ad.u.ipc_id = shp->shm_perm.key; rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM, @@ -5049,13 +4966,11 @@ static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg) { struct ipc_security_struct *isec; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); isec = shp->shm_perm.security; COMMON_AUDIT_DATA_INIT(&ad, IPC); - ad.selinux_audit_data = &sad; ad.u.ipc_id = shp->shm_perm.key; return avc_has_perm(sid, isec->sid, SECCLASS_SHM, @@ -5113,7 +5028,6 @@ static int selinux_sem_alloc_security(struct sem_array *sma) { struct ipc_security_struct *isec; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); int rc; @@ -5124,7 +5038,6 @@ static int selinux_sem_alloc_security(struct sem_array *sma) isec = sma->sem_perm.security; COMMON_AUDIT_DATA_INIT(&ad, IPC); - ad.selinux_audit_data = &sad; ad.u.ipc_id = sma->sem_perm.key; rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM, @@ -5145,13 +5058,11 @@ static int selinux_sem_associate(struct sem_array *sma, int semflg) { struct ipc_security_struct *isec; struct common_audit_data ad; - struct selinux_audit_data sad = {0,}; u32 sid = current_sid(); isec = sma->sem_perm.security; COMMON_AUDIT_DATA_INIT(&ad, IPC); - ad.selinux_audit_data = &sad; ad.u.ipc_id = sma->sem_perm.key; return avc_has_perm(sid, isec->sid, SECCLASS_SEM, diff --git a/trunk/security/selinux/include/avc.h b/trunk/security/selinux/include/avc.h index 1931370233d7..005a91bcb200 100644 --- a/trunk/security/selinux/include/avc.h +++ b/trunk/security/selinux/include/avc.h @@ -46,31 +46,6 @@ struct avc_cache_stats { unsigned int frees; }; -/* - * We only need this data after we have decided to send an audit message. - */ -struct selinux_late_audit_data { - u32 ssid; - u32 tsid; - u16 tclass; - u32 requested; - u32 audited; - u32 denied; - int result; -}; - -/* - * We collect this at the beginning or during an selinux security operation - */ -struct selinux_audit_data { - /* - * auditdeny is a bit tricky and unintuitive. See the - * comments in avc.c for it's meaning and usage. - */ - u32 auditdeny; - struct selinux_late_audit_data *slad; -}; - /* * AVC operations */ diff --git a/trunk/security/selinux/selinuxfs.c b/trunk/security/selinux/selinuxfs.c index d7018bfa1f00..48a7d0014b4f 100644 --- a/trunk/security/selinux/selinuxfs.c +++ b/trunk/security/selinux/selinuxfs.c @@ -344,7 +344,7 @@ static int sel_make_classes(void); static int sel_make_policycap(void); /* declaration for sel_make_class_dirs */ -static struct dentry *sel_make_dir(struct dentry *dir, const char *name, +static int sel_make_dir(struct inode *dir, struct dentry *dentry, unsigned long *ino); static ssize_t sel_read_mls(struct file *filp, char __user *buf, @@ -1678,9 +1678,13 @@ static int sel_make_class_dir_entries(char *classname, int index, inode->i_ino = sel_class_to_ino(index); d_add(dentry, inode); - dentry = sel_make_dir(dir, "perms", &last_class_ino); - if (IS_ERR(dentry)) - return PTR_ERR(dentry); + dentry = d_alloc_name(dir, "perms"); + if (!dentry) + return -ENOMEM; + + rc = sel_make_dir(dir->d_inode, dentry, &last_class_ino); + if (rc) + return rc; rc = sel_make_perm_files(classname, index, dentry); @@ -1729,12 +1733,15 @@ static int sel_make_classes(void) for (i = 0; i < nclasses; i++) { struct dentry *class_name_dir; - class_name_dir = sel_make_dir(class_dir, classes[i], + rc = -ENOMEM; + class_name_dir = d_alloc_name(class_dir, classes[i]); + if (!class_name_dir) + goto out; + + rc = sel_make_dir(class_dir->d_inode, class_name_dir, &last_class_ino); - if (IS_ERR(class_name_dir)) { - rc = PTR_ERR(class_name_dir); + if (rc) goto out; - } /* i+1 since class values are 1-indexed */ rc = sel_make_class_dir_entries(classes[i], i + 1, @@ -1780,20 +1787,14 @@ static int sel_make_policycap(void) return 0; } -static struct dentry *sel_make_dir(struct dentry *dir, const char *name, +static int sel_make_dir(struct inode *dir, struct dentry *dentry, unsigned long *ino) { - struct dentry *dentry = d_alloc_name(dir, name); struct inode *inode; - if (!dentry) - return ERR_PTR(-ENOMEM); - - inode = sel_make_inode(dir->d_sb, S_IFDIR | S_IRUGO | S_IXUGO); - if (!inode) { - dput(dentry); - return ERR_PTR(-ENOMEM); - } + inode = sel_make_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO); + if (!inode) + return -ENOMEM; inode->i_op = &simple_dir_inode_operations; inode->i_fop = &simple_dir_operations; @@ -1802,16 +1803,16 @@ static struct dentry *sel_make_dir(struct dentry *dir, const char *name, inc_nlink(inode); d_add(dentry, inode); /* bump link count on parent directory, too */ - inc_nlink(dir->d_inode); + inc_nlink(dir); - return dentry; + return 0; } static int sel_fill_super(struct super_block *sb, void *data, int silent) { int ret; struct dentry *dentry; - struct inode *inode; + struct inode *inode, *root_inode; struct inode_security_struct *isec; static struct tree_descr selinux_files[] = { @@ -1838,12 +1839,18 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) if (ret) goto err; - bool_dir = sel_make_dir(sb->s_root, BOOL_DIR_NAME, &sel_last_ino); - if (IS_ERR(bool_dir)) { - ret = PTR_ERR(bool_dir); - bool_dir = NULL; + root_inode = sb->s_root->d_inode; + + ret = -ENOMEM; + dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME); + if (!dentry) goto err; - } + + ret = sel_make_dir(root_inode, dentry, &sel_last_ino); + if (ret) + goto err; + + bool_dir = dentry; ret = -ENOMEM; dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME); @@ -1865,39 +1872,54 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) d_add(dentry, inode); selinux_null = dentry; - dentry = sel_make_dir(sb->s_root, "avc", &sel_last_ino); - if (IS_ERR(dentry)) { - ret = PTR_ERR(dentry); + ret = -ENOMEM; + dentry = d_alloc_name(sb->s_root, "avc"); + if (!dentry) + goto err; + + ret = sel_make_dir(root_inode, dentry, &sel_last_ino); + if (ret) goto err; - } ret = sel_make_avc_files(dentry); if (ret) goto err; - dentry = sel_make_dir(sb->s_root, "initial_contexts", &sel_last_ino); - if (IS_ERR(dentry)) { - ret = PTR_ERR(dentry); + ret = -ENOMEM; + dentry = d_alloc_name(sb->s_root, "initial_contexts"); + if (!dentry) + goto err; + + ret = sel_make_dir(root_inode, dentry, &sel_last_ino); + if (ret) goto err; - } ret = sel_make_initcon_files(dentry); if (ret) goto err; - class_dir = sel_make_dir(sb->s_root, "class", &sel_last_ino); - if (IS_ERR(class_dir)) { - ret = PTR_ERR(class_dir); - class_dir = NULL; + ret = -ENOMEM; + dentry = d_alloc_name(sb->s_root, "class"); + if (!dentry) + goto err; + + ret = sel_make_dir(root_inode, dentry, &sel_last_ino); + if (ret) + goto err; + + class_dir = dentry; + + ret = -ENOMEM; + dentry = d_alloc_name(sb->s_root, "policy_capabilities"); + if (!dentry) goto err; - } - policycap_dir = sel_make_dir(sb->s_root, "policy_capabilities", &sel_last_ino); - if (IS_ERR(policycap_dir)) { - ret = PTR_ERR(policycap_dir); - policycap_dir = NULL; + ret = sel_make_dir(root_inode, dentry, &sel_last_ino); + if (ret) goto err; - } + + policycap_dir = dentry; + return 0; err: printk(KERN_ERR "SELinux: %s: failed while creating inodes\n", diff --git a/trunk/security/smack/smack.h b/trunk/security/smack/smack.h index 4ede719922ed..2ad00657b801 100644 --- a/trunk/security/smack/smack.h +++ b/trunk/security/smack/smack.h @@ -185,15 +185,6 @@ struct smack_known { */ #define SMK_NUM_ACCESS_TYPE 5 -/* SMACK data */ -struct smack_audit_data { - const char *function; - char *subject; - char *object; - char *request; - int result; -}; - /* * Smack audit data; is empty if CONFIG_AUDIT not set * to save some stack @@ -201,7 +192,6 @@ struct smack_audit_data { struct smk_audit_info { #ifdef CONFIG_AUDIT struct common_audit_data a; - struct smack_audit_data sad; #endif }; /* @@ -321,16 +311,7 @@ static inline void smk_ad_init(struct smk_audit_info *a, const char *func, { memset(a, 0, sizeof(*a)); a->a.type = type; - a->a.smack_audit_data = &a->sad; - a->a.smack_audit_data->function = func; -} - -static inline void smk_ad_init_net(struct smk_audit_info *a, const char *func, - char type, struct lsm_network_audit *net) -{ - smk_ad_init(a, func, type); - memset(net, 0, sizeof(*net)); - a->a.u.net = net; + a->a.smack_audit_data.function = func; } static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, @@ -356,7 +337,7 @@ static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a, static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a, struct sock *sk) { - a->a.u.net->sk = sk; + a->a.u.net.sk = sk; } #else /* no AUDIT */ diff --git a/trunk/security/smack/smack_access.c b/trunk/security/smack/smack_access.c index c8115f7308f8..cc7cb6edba08 100644 --- a/trunk/security/smack/smack_access.c +++ b/trunk/security/smack/smack_access.c @@ -275,9 +275,9 @@ static inline void smack_str_from_perm(char *string, int access) static void smack_log_callback(struct audit_buffer *ab, void *a) { struct common_audit_data *ad = a; - struct smack_audit_data *sad = ad->smack_audit_data; + struct smack_audit_data *sad = &ad->smack_audit_data; audit_log_format(ab, "lsm=SMACK fn=%s action=%s", - ad->smack_audit_data->function, + ad->smack_audit_data.function, sad->result ? "denied" : "granted"); audit_log_format(ab, " subject="); audit_log_untrustedstring(ab, sad->subject); @@ -310,19 +310,19 @@ void smack_log(char *subject_label, char *object_label, int request, if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0) return; - sad = a->smack_audit_data; - - if (sad->function == NULL) - sad->function = "unknown"; + if (a->smack_audit_data.function == NULL) + a->smack_audit_data.function = "unknown"; /* end preparing the audit data */ + sad = &a->smack_audit_data; smack_str_from_perm(request_buffer, request); sad->subject = subject_label; sad->object = object_label; sad->request = request_buffer; sad->result = result; + a->lsm_pre_audit = smack_log_callback; - common_lsm_audit(a, smack_log_callback, NULL); + common_lsm_audit(a); } #else /* #ifdef CONFIG_AUDIT */ void smack_log(char *subject_label, char *object_label, int request, diff --git a/trunk/security/smack/smack_lsm.c b/trunk/security/smack/smack_lsm.c index 45c32f074166..cd667b4089a5 100644 --- a/trunk/security/smack/smack_lsm.c +++ b/trunk/security/smack/smack_lsm.c @@ -1943,15 +1943,13 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) rcu_read_lock(); hostsp = smack_host_label(sap); if (hostsp != NULL) { + sk_lbl = SMACK_UNLABELED_SOCKET; #ifdef CONFIG_AUDIT - struct lsm_network_audit net; - - smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); - ad.a.u.net->family = sap->sin_family; - ad.a.u.net->dport = sap->sin_port; - ad.a.u.net->v4info.daddr = sap->sin_addr.s_addr; + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); + ad.a.u.net.family = sap->sin_family; + ad.a.u.net.dport = sap->sin_port; + ad.a.u.net.v4info.daddr = sap->sin_addr.s_addr; #endif - sk_lbl = SMACK_UNLABELED_SOCKET; rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad); } else { sk_lbl = SMACK_CIPSO_SOCKET; @@ -2812,12 +2810,8 @@ static int smack_unix_stream_connect(struct sock *sock, struct smk_audit_info ad; int rc = 0; -#ifdef CONFIG_AUDIT - struct lsm_network_audit net; - - smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); smk_ad_setfield_u_net_sk(&ad, other); -#endif if (!capable(CAP_MAC_OVERRIDE)) rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); @@ -2848,12 +2842,8 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) struct smk_audit_info ad; int rc = 0; -#ifdef CONFIG_AUDIT - struct lsm_network_audit net; - - smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); smk_ad_setfield_u_net_sk(&ad, other->sk); -#endif if (!capable(CAP_MAC_OVERRIDE)) rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); @@ -3000,9 +2990,6 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) char *csp; int rc; struct smk_audit_info ad; -#ifdef CONFIG_AUDIT - struct lsm_network_audit net; -#endif if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) return 0; @@ -3020,9 +3007,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) netlbl_secattr_destroy(&secattr); #ifdef CONFIG_AUDIT - smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); - ad.a.u.net->family = sk->sk_family; - ad.a.u.net->netif = skb->skb_iif; + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); + ad.a.u.net.family = sk->sk_family; + ad.a.u.net.netif = skb->skb_iif; ipv4_skb_to_auditdata(skb, &ad.a, NULL); #endif /* @@ -3165,9 +3152,6 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, char *sp; int rc; struct smk_audit_info ad; -#ifdef CONFIG_AUDIT - struct lsm_network_audit net; -#endif /* handle mapped IPv4 packets arriving via IPv6 sockets */ if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) @@ -3182,9 +3166,9 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, netlbl_secattr_destroy(&secattr); #ifdef CONFIG_AUDIT - smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); - ad.a.u.net->family = family; - ad.a.u.net->netif = skb->skb_iif; + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); + ad.a.u.net.family = family; + ad.a.u.net.netif = skb->skb_iif; ipv4_skb_to_auditdata(skb, &ad.a, NULL); #endif /* @@ -3640,38 +3624,8 @@ struct security_operations smack_ops = { }; -static __init void init_smack_known_list(void) +static __init void init_smack_know_list(void) { - /* - * Initialize CIPSO locks - */ - spin_lock_init(&smack_known_huh.smk_cipsolock); - spin_lock_init(&smack_known_hat.smk_cipsolock); - spin_lock_init(&smack_known_star.smk_cipsolock); - spin_lock_init(&smack_known_floor.smk_cipsolock); - spin_lock_init(&smack_known_invalid.smk_cipsolock); - spin_lock_init(&smack_known_web.smk_cipsolock); - /* - * Initialize rule list locks - */ - mutex_init(&smack_known_huh.smk_rules_lock); - mutex_init(&smack_known_hat.smk_rules_lock); - mutex_init(&smack_known_floor.smk_rules_lock); - mutex_init(&smack_known_star.smk_rules_lock); - mutex_init(&smack_known_invalid.smk_rules_lock); - mutex_init(&smack_known_web.smk_rules_lock); - /* - * Initialize rule lists - */ - INIT_LIST_HEAD(&smack_known_huh.smk_rules); - INIT_LIST_HEAD(&smack_known_hat.smk_rules); - INIT_LIST_HEAD(&smack_known_star.smk_rules); - INIT_LIST_HEAD(&smack_known_floor.smk_rules); - INIT_LIST_HEAD(&smack_known_invalid.smk_rules); - INIT_LIST_HEAD(&smack_known_web.smk_rules); - /* - * Create the known labels list - */ list_add(&smack_known_huh.list, &smack_known_list); list_add(&smack_known_hat.list, &smack_known_list); list_add(&smack_known_star.list, &smack_known_list); @@ -3706,8 +3660,16 @@ static __init int smack_init(void) cred = (struct cred *) current->cred; cred->security = tsp; - /* initialize the smack_known_list */ - init_smack_known_list(); + /* initialize the smack_know_list */ + init_smack_know_list(); + /* + * Initialize locks + */ + spin_lock_init(&smack_known_huh.smk_cipsolock); + spin_lock_init(&smack_known_hat.smk_cipsolock); + spin_lock_init(&smack_known_star.smk_cipsolock); + spin_lock_init(&smack_known_floor.smk_cipsolock); + spin_lock_init(&smack_known_invalid.smk_cipsolock); /* * Register with LSM diff --git a/trunk/security/smack/smackfs.c b/trunk/security/smack/smackfs.c index 038811cb7e62..5c32f36ff706 100644 --- a/trunk/security/smack/smackfs.c +++ b/trunk/security/smack/smackfs.c @@ -1614,6 +1614,20 @@ static int __init init_smk_fs(void) smk_cipso_doi(); smk_unlbl_ambient(NULL); + mutex_init(&smack_known_floor.smk_rules_lock); + mutex_init(&smack_known_hat.smk_rules_lock); + mutex_init(&smack_known_huh.smk_rules_lock); + mutex_init(&smack_known_invalid.smk_rules_lock); + mutex_init(&smack_known_star.smk_rules_lock); + mutex_init(&smack_known_web.smk_rules_lock); + + INIT_LIST_HEAD(&smack_known_floor.smk_rules); + INIT_LIST_HEAD(&smack_known_hat.smk_rules); + INIT_LIST_HEAD(&smack_known_huh.smk_rules); + INIT_LIST_HEAD(&smack_known_invalid.smk_rules); + INIT_LIST_HEAD(&smack_known_star.smk_rules); + INIT_LIST_HEAD(&smack_known_web.smk_rules); + return err; } diff --git a/trunk/sound/core/seq/seq_dummy.c b/trunk/sound/core/seq/seq_dummy.c index dbc550716790..bbe32d2177d9 100644 --- a/trunk/sound/core/seq/seq_dummy.c +++ b/trunk/sound/core/seq/seq_dummy.c @@ -46,7 +46,7 @@ The number of ports to be created can be specified via the module parameter "ports". For example, to create four ports, add the - following option in a configuration file under /etc/modprobe.d/: + following option in /etc/modprobe.conf: option snd-seq-dummy ports=4 diff --git a/trunk/sound/core/vmaster.c b/trunk/sound/core/vmaster.c index 857586135d18..14a286a7bf2b 100644 --- a/trunk/sound/core/vmaster.c +++ b/trunk/sound/core/vmaster.c @@ -419,7 +419,6 @@ EXPORT_SYMBOL(snd_ctl_make_virtual_master); * snd_ctl_add_vmaster_hook - Add a hook to a vmaster control * @kcontrol: vmaster kctl element * @hook: the hook function - * @private_data: the private_data pointer to be saved * * Adds the given hook to the vmaster control element so that it's called * at each time when the value is changed. diff --git a/trunk/sound/drivers/Kconfig b/trunk/sound/drivers/Kconfig index fe5ae09ffccb..c8961165277c 100644 --- a/trunk/sound/drivers/Kconfig +++ b/trunk/sound/drivers/Kconfig @@ -50,8 +50,7 @@ config SND_PCSP before the other sound driver of yours, making the pc-speaker a default sound device. Which is likely not what you want. To make this driver play nicely with other - sound driver, you can add this in a configuration file under - /etc/modprobe.d/ directory: + sound driver, you can add this into your /etc/modprobe.conf: options snd-pcsp index=2 You don't need this driver if you only want your pc-speaker to beep. diff --git a/trunk/sound/isa/opti9xx/opti92x-ad1848.c b/trunk/sound/isa/opti9xx/opti92x-ad1848.c index d7ccf28bd66a..babaedd242f7 100644 --- a/trunk/sound/isa/opti9xx/opti92x-ad1848.c +++ b/trunk/sound/isa/opti9xx/opti92x-ad1848.c @@ -65,7 +65,7 @@ static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ //static bool enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */ #ifdef CONFIG_PNP -static bool isapnp = true; /* Enable ISA PnP detection */ +static int isapnp = 1; /* Enable ISA PnP detection */ #endif static long port = SNDRV_DEFAULT_PORT1; /* 0x530,0xe80,0xf40,0x604 */ static long mpu_port = SNDRV_DEFAULT_PORT1; /* 0x300,0x310,0x320,0x330 */ diff --git a/trunk/sound/isa/sscape.c b/trunk/sound/isa/sscape.c index 8490f59709bb..b4a6aa960f4b 100644 --- a/trunk/sound/isa/sscape.c +++ b/trunk/sound/isa/sscape.c @@ -1019,15 +1019,13 @@ static int __devinit create_sscape(int dev, struct snd_card *card) irq_cfg = get_irq_config(sscape->type, irq[dev]); if (irq_cfg == INVALID_IRQ) { snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", irq[dev]); - err = -ENXIO; - goto _release_dma; + return -ENXIO; } mpu_irq_cfg = get_irq_config(sscape->type, mpu_irq[dev]); if (mpu_irq_cfg == INVALID_IRQ) { snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]); - err = -ENXIO; - goto _release_dma; + return -ENXIO; } /* diff --git a/trunk/sound/last.c b/trunk/sound/last.c index 7ffc182e0844..bdd0857b8871 100644 --- a/trunk/sound/last.c +++ b/trunk/sound/last.c @@ -38,4 +38,4 @@ static int __init alsa_sound_last_init(void) return 0; } -late_initcall_sync(alsa_sound_last_init); +__initcall(alsa_sound_last_init); diff --git a/trunk/sound/oss/msnd_pinnacle.c b/trunk/sound/oss/msnd_pinnacle.c index 536c4c0514d3..eba734560f6f 100644 --- a/trunk/sound/oss/msnd_pinnacle.c +++ b/trunk/sound/oss/msnd_pinnacle.c @@ -1294,8 +1294,6 @@ static int __init calibrate_adc(WORD srate) static int upload_dsp_code(void) { - int ret = 0; - msnd_outb(HPBLKSEL_0, dev.io + HP_BLKS); #ifndef HAVE_DSPCODEH INITCODESIZE = mod_firmware_load(INITCODEFILE, &INITCODE); @@ -1314,8 +1312,7 @@ static int upload_dsp_code(void) memcpy_toio(dev.base, PERMCODE, PERMCODESIZE); if (msnd_upload_host(&dev, INITCODE, INITCODESIZE) < 0) { printk(KERN_WARNING LOGNAME ": Error uploading to DSP\n"); - ret = -ENODEV; - goto out; + return -ENODEV; } #ifdef HAVE_DSPCODEH printk(KERN_INFO LOGNAME ": DSP firmware uploaded (resident)\n"); @@ -1323,13 +1320,12 @@ static int upload_dsp_code(void) printk(KERN_INFO LOGNAME ": DSP firmware uploaded\n"); #endif -out: #ifndef HAVE_DSPCODEH vfree(INITCODE); vfree(PERMCODE); #endif - return ret; + return 0; } #ifdef MSND_CLASSIC @@ -1635,7 +1631,7 @@ static int ide_irq __initdata = 0; static int joystick_io __initdata = 0; /* If we have the digital daugherboard... */ -static bool digital __initdata = false; +static int digital __initdata = 0; #endif static int fifosize __initdata = DEFFIFOSIZE; diff --git a/trunk/sound/pci/Kconfig b/trunk/sound/pci/Kconfig index 5ca0939e4223..88168044375f 100644 --- a/trunk/sound/pci/Kconfig +++ b/trunk/sound/pci/Kconfig @@ -2,8 +2,8 @@ config SND_TEA575X tristate - depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 || RADIO_MAXIRADIO - default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 || RADIO_MAXIRADIO + depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 + default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 menuconfig SND_PCI bool "PCI sound devices" diff --git a/trunk/sound/pci/asihpi/hpi_internal.h b/trunk/sound/pci/asihpi/hpi_internal.h index bc86cb726d79..4cc315daeda0 100644 --- a/trunk/sound/pci/asihpi/hpi_internal.h +++ b/trunk/sound/pci/asihpi/hpi_internal.h @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2012 AudioScience Inc. + Copyright (C) 1997-2011 AudioScience Inc. 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 diff --git a/trunk/sound/pci/asihpi/hpios.c b/trunk/sound/pci/asihpi/hpios.c index 5ef4fe964366..2d7d1c2e1d0d 100644 --- a/trunk/sound/pci/asihpi/hpios.c +++ b/trunk/sound/pci/asihpi/hpios.c @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2012 AudioScience Inc. + Copyright (C) 1997-2011 AudioScience Inc. 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 @@ -39,9 +39,9 @@ void hpios_delay_micro_seconds(u32 num_micro_sec) } -/** Allocate an area of locked memory for bus master DMA operations. +/** Allocated an area of locked memory for bus master DMA operations. -If allocation fails, return 1, and *pMemArea.size = 0 +On error, return -ENOMEM, and *pMemArea.size = 0 */ u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size, struct pci_dev *pdev) @@ -62,7 +62,7 @@ u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size, HPI_DEBUG_LOG(WARNING, "failed to allocate %d bytes locked memory\n", size); p_mem_area->size = 0; - return 1; + return -ENOMEM; } } diff --git a/trunk/sound/pci/hda/hda_codec.h b/trunk/sound/pci/hda/hda_codec.h index 56b4f74c0b13..9a9f372e1be4 100644 --- a/trunk/sound/pci/hda/hda_codec.h +++ b/trunk/sound/pci/hda/hda_codec.h @@ -851,9 +851,6 @@ struct hda_codec { unsigned int pin_amp_workaround:1; /* pin out-amp takes index * (e.g. Conexant codecs) */ - unsigned int single_adc_amp:1; /* adc in-amp takes no index - * (e.g. CX20549 codec) - */ unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */ unsigned int pins_shutup:1; /* pins are shut up */ unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ diff --git a/trunk/sound/pci/hda/hda_eld.c b/trunk/sound/pci/hda/hda_eld.c index 4c054f4486b9..b58b4b1687fa 100644 --- a/trunk/sound/pci/hda/hda_eld.c +++ b/trunk/sound/pci/hda/hda_eld.c @@ -418,7 +418,7 @@ static void hdmi_show_short_audio_desc(struct cea_sad *a) else buf2[0] = '\0'; - _snd_printd(SND_PR_VERBOSE, "HDMI: supports coding type %s:" + printk(KERN_INFO "HDMI: supports coding type %s:" " channels = %d, rates =%s%s\n", cea_audio_coding_type_names[a->format], a->channels, @@ -442,14 +442,14 @@ void snd_hdmi_show_eld(struct hdmi_eld *e) { int i; - _snd_printd(SND_PR_VERBOSE, "HDMI: detected monitor %s at connection type %s\n", + printk(KERN_INFO "HDMI: detected monitor %s at connection type %s\n", e->monitor_name, eld_connection_type_names[e->conn_type]); if (e->spk_alloc) { char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf)); - _snd_printd(SND_PR_VERBOSE, "HDMI: available speakers:%s\n", buf); + printk(KERN_INFO "HDMI: available speakers:%s\n", buf); } for (i = 0; i < e->sad_count; i++) diff --git a/trunk/sound/pci/hda/hda_proc.c b/trunk/sound/pci/hda/hda_proc.c index e59e2f059b6e..254ab5204603 100644 --- a/trunk/sound/pci/hda/hda_proc.c +++ b/trunk/sound/pci/hda/hda_proc.c @@ -651,16 +651,9 @@ static void print_codec_info(struct snd_info_entry *entry, snd_iprintf(buffer, " Amp-In caps: "); print_amp_caps(buffer, codec, nid, HDA_INPUT); snd_iprintf(buffer, " Amp-In vals: "); - if (wid_type == AC_WID_PIN || - (codec->single_adc_amp && - wid_type == AC_WID_AUD_IN)) - print_amp_vals(buffer, codec, nid, HDA_INPUT, - wid_caps & AC_WCAP_STEREO, - 1); - else - print_amp_vals(buffer, codec, nid, HDA_INPUT, - wid_caps & AC_WCAP_STEREO, - conn_len); + print_amp_vals(buffer, codec, nid, HDA_INPUT, + wid_caps & AC_WCAP_STEREO, + wid_type == AC_WID_PIN ? 1 : conn_len); } if (wid_caps & AC_WCAP_OUT_AMP) { snd_iprintf(buffer, " Amp-Out caps: "); diff --git a/trunk/sound/pci/hda/patch_conexant.c b/trunk/sound/pci/hda/patch_conexant.c index d906c5b74cf0..8c6523bbc797 100644 --- a/trunk/sound/pci/hda/patch_conexant.c +++ b/trunk/sound/pci/hda/patch_conexant.c @@ -141,6 +141,7 @@ struct conexant_spec { unsigned int hp_laptop:1; unsigned int asus:1; unsigned int pin_eapd_ctrls:1; + unsigned int single_adc_amp:1; unsigned int adc_switching:1; @@ -686,26 +687,27 @@ static const struct hda_channel_mode cxt5045_modes[1] = { static const struct hda_input_mux cxt5045_capture_source = { .num_items = 2, .items = { - { "Internal Mic", 0x1 }, - { "Mic", 0x2 }, + { "IntMic", 0x1 }, + { "ExtMic", 0x2 }, } }; static const struct hda_input_mux cxt5045_capture_source_benq = { - .num_items = 4, + .num_items = 5, .items = { - { "Internal Mic", 0x1 }, - { "Mic", 0x2 }, - { "Line", 0x3 }, - { "Mixer", 0x0 }, + { "IntMic", 0x1 }, + { "ExtMic", 0x2 }, + { "LineIn", 0x3 }, + { "CD", 0x4 }, + { "Mixer", 0x0 }, } }; static const struct hda_input_mux cxt5045_capture_source_hp530 = { .num_items = 2, .items = { - { "Mic", 0x1 }, - { "Internal Mic", 0x2 }, + { "ExtMic", 0x1 }, + { "IntMic", 0x2 }, } }; @@ -796,8 +798,10 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec, } static const struct snd_kcontrol_new cxt5045_mixers[] = { - HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x00, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT), @@ -818,15 +822,27 @@ static const struct snd_kcontrol_new cxt5045_mixers[] = { }; static const struct snd_kcontrol_new cxt5045_benq_mixers[] = { - HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x3, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x3, HDA_INPUT), + HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x4, HDA_INPUT), + + HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT), + HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT), + HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT), + HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT), + + HDA_CODEC_VOLUME("Mixer Capture Volume", 0x1a, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mixer Capture Switch", 0x1a, 0x0, HDA_INPUT), {} }; static const struct snd_kcontrol_new cxt5045_mixers_hp530[] = { - HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x00, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT), @@ -930,10 +946,10 @@ static const struct snd_kcontrol_new cxt5045_test_mixer[] = { /* Output controls */ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("HP-OUT Playback Volume", 0x11, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("HP-OUT Playback Switch", 0x11, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x12, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("LINE1 Playback Switch", 0x12, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT), /* Modes for retasking pin widgets */ CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT), @@ -944,16 +960,16 @@ static const struct snd_kcontrol_new cxt5045_test_mixer[] = { /* Loopback mixer controls */ - HDA_CODEC_VOLUME("PCM Volume", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("PCM Switch", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("MIC1 pin Volume", 0x17, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("MIC1 pin Switch", 0x17, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("LINE1 pin Volume", 0x17, 0x2, HDA_INPUT), - HDA_CODEC_MUTE("LINE1 pin Switch", 0x17, 0x2, HDA_INPUT), - HDA_CODEC_VOLUME("HP-OUT pin Volume", 0x17, 0x3, HDA_INPUT), - HDA_CODEC_MUTE("HP-OUT pin Switch", 0x17, 0x3, HDA_INPUT), - HDA_CODEC_VOLUME("CD pin Volume", 0x17, 0x4, HDA_INPUT), - HDA_CODEC_MUTE("CD pin Switch", 0x17, 0x4, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Input Source", @@ -962,8 +978,16 @@ static const struct snd_kcontrol_new cxt5045_test_mixer[] = { .put = conexant_mux_enum_put, }, /* Audio input controls */ - HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT), + HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT), + HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT), { } /* end */ }; @@ -985,6 +1009,10 @@ static const struct hda_verb cxt5045_test_init_verbs[] = { {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0}, + /* Start with output sum widgets muted and their output gains at min */ + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + /* Unmute retasking pin widget output buffers since the default * state appears to be output. As the pin mode is changed by the * user the pin mode control will take care of enabling the pin's @@ -999,11 +1027,11 @@ static const struct hda_verb cxt5045_test_init_verbs[] = { /* Set ADC connection select to match default mixer setting (mic1 * pin) */ - {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, - {0x17, AC_VERB_SET_CONNECT_SEL, 0x01}, + {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Mute all inputs to mixer widget (even unconnected ones) */ - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer */ + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* Mic1 pin */ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* Line pin */ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* HP pin */ @@ -1082,7 +1110,7 @@ static int patch_cxt5045(struct hda_codec *codec) if (!spec) return -ENOMEM; codec->spec = spec; - codec->single_adc_amp = 1; + codec->pin_amp_workaround = 1; spec->multiout.max_channels = 2; spec->multiout.num_dacs = ARRAY_SIZE(cxt5045_dac_nids); @@ -3971,14 +3999,9 @@ static void cx_auto_init_output(struct hda_codec *codec) int i; mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids); - for (i = 0; i < cfg->hp_outs; i++) { - unsigned int val = PIN_OUT; - if (snd_hda_query_pin_caps(codec, cfg->hp_pins[i]) & - AC_PINCAP_HP_DRV) - val |= AC_PINCTL_HP_EN; + for (i = 0; i < cfg->hp_outs; i++) snd_hda_codec_write(codec, cfg->hp_pins[i], 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, val); - } + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); mute_outputs(codec, cfg->hp_outs, cfg->hp_pins); mute_outputs(codec, cfg->line_outs, cfg->line_out_pins); mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins); @@ -4197,7 +4220,7 @@ static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid, int idx = get_input_connection(codec, adc_nid, nid); if (idx < 0) continue; - if (codec->single_adc_amp) + if (spec->single_adc_amp) idx = 0; return cx_auto_add_volume_idx(codec, label, pfx, cidx, adc_nid, HDA_INPUT, idx); @@ -4252,7 +4275,7 @@ static int cx_auto_build_input_controls(struct hda_codec *codec) if (cidx < 0) continue; input_conn[i] = spec->imux_info[i].adc; - if (!codec->single_adc_amp) + if (!spec->single_adc_amp) input_conn[i] |= cidx << 8; if (i > 0 && input_conn[i] != input_conn[0]) multi_connection = 1; @@ -4396,10 +4419,8 @@ static void apply_pin_fixup(struct hda_codec *codec, enum { CXT_PINCFG_LENOVO_X200, - CXT_PINCFG_LENOVO_TP410, }; -/* ThinkPad X200 & co with cxt5051 */ static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = { { 0x16, 0x042140ff }, /* HP (seq# overridden) */ { 0x17, 0x21a11000 }, /* dock-mic */ @@ -4408,33 +4429,15 @@ static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = { {} }; -/* ThinkPad 410/420/510/520, X201 & co with cxt5066 */ -static const struct cxt_pincfg cxt_pincfg_lenovo_tp410[] = { - { 0x19, 0x042110ff }, /* HP (seq# overridden) */ - { 0x1a, 0x21a190f0 }, /* dock-mic */ - { 0x1c, 0x212140ff }, /* dock-HP */ - {} -}; - static const struct cxt_pincfg *cxt_pincfg_tbl[] = { [CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200, - [CXT_PINCFG_LENOVO_TP410] = cxt_pincfg_lenovo_tp410, }; -static const struct snd_pci_quirk cxt5051_fixups[] = { +static const struct snd_pci_quirk cxt_fixups[] = { SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200), {} }; -static const struct snd_pci_quirk cxt5066_fixups[] = { - SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), - SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410), - SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410), - SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410), - SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410), - {} -}; - /* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches * can be created (bko#42825) */ @@ -4463,21 +4466,19 @@ static int patch_conexant_auto(struct hda_codec *codec) if (!spec) return -ENOMEM; codec->spec = spec; + codec->pin_amp_workaround = 1; switch (codec->vendor_id) { case 0x14f15045: - codec->single_adc_amp = 1; + spec->single_adc_amp = 1; break; case 0x14f15051: add_cx5051_fake_mutes(codec); - codec->pin_amp_workaround = 1; - apply_pin_fixup(codec, cxt5051_fixups, cxt_pincfg_tbl); break; - default: - codec->pin_amp_workaround = 1; - apply_pin_fixup(codec, cxt5066_fixups, cxt_pincfg_tbl); } + apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); + /* Show mute-led control only on HP laptops * This is a sort of white-list: on HP laptops, EAPD corresponds * only to the mute-LED without actualy amp function. Meanwhile, diff --git a/trunk/sound/pci/hda/patch_hdmi.c b/trunk/sound/pci/hda/patch_hdmi.c index 83f345f3c961..540cd13f7f15 100644 --- a/trunk/sound/pci/hda/patch_hdmi.c +++ b/trunk/sound/pci/hda/patch_hdmi.c @@ -757,6 +757,8 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) struct hdmi_spec *spec = codec->spec; int tag = res >> AC_UNSOL_RES_TAG_SHIFT; int pin_nid; + int pd = !!(res & AC_UNSOL_RES_PD); + int eldv = !!(res & AC_UNSOL_RES_ELDV); int pin_idx; struct hda_jack_tbl *jack; @@ -766,10 +768,9 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) pin_nid = jack->nid; jack->jack_dirty = 1; - _snd_printd(SND_PR_VERBOSE, + printk(KERN_INFO "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", - codec->addr, pin_nid, - !!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV)); + codec->addr, pin_nid, pd, eldv); pin_idx = pin_nid_to_pin_index(spec, pin_nid); if (pin_idx < 0) @@ -991,7 +992,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) if (eld->monitor_present) eld_valid = !!(present & AC_PINSENSE_ELDV); - _snd_printd(SND_PR_VERBOSE, + printk(KERN_INFO "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", codec->addr, pin_nid, eld->monitor_present, eld_valid); diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 818f90bc7d57..8ea2fd654327 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -1445,13 +1445,6 @@ enum { ALC_FIXUP_ACT_BUILD, }; -static void alc_apply_pincfgs(struct hda_codec *codec, - const struct alc_pincfg *cfg) -{ - for (; cfg->nid; cfg++) - snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); -} - static void alc_apply_fixup(struct hda_codec *codec, int action) { struct alc_spec *spec = codec->spec; @@ -1485,7 +1478,9 @@ static void alc_apply_fixup(struct hda_codec *codec, int action) snd_printdd(KERN_INFO "hda_codec: %s: " "Apply pincfg for %s\n", codec->chip_name, modelname); - alc_apply_pincfgs(codec, cfg); + for (; cfg->nid; cfg++) + snd_hda_codec_set_pincfg(codec, cfg->nid, + cfg->val); break; case ALC_FIXUP_VERBS: if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs) @@ -2722,6 +2717,9 @@ static int alc_auto_fill_adc_caps(struct hda_codec *codec) int max_nums = ARRAY_SIZE(spec->private_adc_nids); int i, nums = 0; + if (spec->shared_mic_hp) + max_nums = 1; /* no multi streams with the shared HP/mic */ + nid = codec->start_nid; for (i = 0; i < codec->num_nodes; i++, nid++) { hda_nid_t src; @@ -3403,10 +3401,8 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) for (;;) { badness = fill_and_eval_dacs(codec, fill_hardwired, fill_mio_first); - if (badness < 0) { - kfree(best_cfg); + if (badness < 0) return badness; - } debug_badness("==> lo_type=%d, wired=%d, mio=%d, badness=0x%x\n", cfg->line_out_type, fill_hardwired, fill_mio_first, badness); @@ -3441,7 +3437,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; fill_hardwired = true; continue; - } + } if (cfg->hp_outs > 0 && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { cfg->speaker_outs = cfg->line_outs; @@ -3455,7 +3451,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) cfg->line_out_type = AUTO_PIN_HP_OUT; fill_hardwired = true; continue; - } + } break; } @@ -4080,7 +4076,6 @@ static void alc_remove_invalid_adc_nids(struct hda_codec *codec) if (spec->dyn_adc_switch) return; - again: nums = 0; for (n = 0; n < spec->num_adc_nids; n++) { hda_nid_t cap = spec->private_capsrc_nids[n]; @@ -4101,11 +4096,6 @@ static void alc_remove_invalid_adc_nids(struct hda_codec *codec) if (!nums) { /* check whether ADC-switch is possible */ if (!alc_check_dyn_adc_switch(codec)) { - if (spec->shared_mic_hp) { - spec->shared_mic_hp = 0; - spec->private_imux[0].num_items = 1; - goto again; - } printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" " using fallback 0x%x\n", codec->chip_name, spec->private_adc_nids[0]); @@ -4123,7 +4113,7 @@ static void alc_remove_invalid_adc_nids(struct hda_codec *codec) if (spec->auto_mic) alc_auto_mic_check_imux(codec); /* check auto-mic setups */ - else if (spec->input_mux->num_items == 1 || spec->shared_mic_hp) + else if (spec->input_mux->num_items == 1) spec->num_adc_nids = 1; /* reduce to a single ADC */ } @@ -4430,7 +4420,7 @@ static int alc_parse_auto_config(struct hda_codec *codec, static int alc880_parse_auto_config(struct hda_codec *codec) { static const hda_nid_t alc880_ignore[] = { 0x1d, 0 }; - static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 }; + static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 }; return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids); } @@ -4866,7 +4856,6 @@ enum { ALC260_FIXUP_GPIO1_TOGGLE, ALC260_FIXUP_REPLACER, ALC260_FIXUP_HP_B1900, - ALC260_FIXUP_KN1, }; static void alc260_gpio1_automute(struct hda_codec *codec) @@ -4894,36 +4883,6 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, } } -static void alc260_fixup_kn1(struct hda_codec *codec, - const struct alc_fixup *fix, int action) -{ - struct alc_spec *spec = codec->spec; - static const struct alc_pincfg pincfgs[] = { - { 0x0f, 0x02214000 }, /* HP/speaker */ - { 0x12, 0x90a60160 }, /* int mic */ - { 0x13, 0x02a19000 }, /* ext mic */ - { 0x18, 0x01446000 }, /* SPDIF out */ - /* disable bogus I/O pins */ - { 0x10, 0x411111f0 }, - { 0x11, 0x411111f0 }, - { 0x14, 0x411111f0 }, - { 0x15, 0x411111f0 }, - { 0x16, 0x411111f0 }, - { 0x17, 0x411111f0 }, - { 0x19, 0x411111f0 }, - { } - }; - - switch (action) { - case ALC_FIXUP_ACT_PRE_PROBE: - alc_apply_pincfgs(codec, pincfgs); - break; - case ALC_FIXUP_ACT_PROBE: - spec->init_amp = ALC_INIT_NONE; - break; - } -} - static const struct alc_fixup alc260_fixups[] = { [ALC260_FIXUP_HP_DC5750] = { .type = ALC_FIXUP_PINS, @@ -4974,11 +4933,7 @@ static const struct alc_fixup alc260_fixups[] = { .v.func = alc260_fixup_gpio1_toggle, .chained = true, .chain_id = ALC260_FIXUP_COEF, - }, - [ALC260_FIXUP_KN1] = { - .type = ALC_FIXUP_FUNC, - .v.func = alc260_fixup_kn1, - }, + } }; static const struct snd_pci_quirk alc260_fixup_tbl[] = { @@ -4988,7 +4943,6 @@ static const struct snd_pci_quirk alc260_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900), SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), - SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1), SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER), SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF), {} @@ -5312,9 +5266,7 @@ static const struct alc_fixup alc882_fixups[] = { { 0x16, 0x99130111 }, /* CLFE speaker */ { 0x17, 0x99130112 }, /* surround speaker */ { } - }, - .chained = true, - .chain_id = ALC882_FIXUP_GPIO1, + } }, [ALC882_FIXUP_ACER_ASPIRE_8930G] = { .type = ALC_FIXUP_PINS, @@ -5357,9 +5309,7 @@ static const struct alc_fixup alc882_fixups[] = { { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, { } - }, - .chained = true, - .chain_id = ALC882_FIXUP_GPIO1, + } }, [ALC885_FIXUP_MACPRO_GPIO] = { .type = ALC_FIXUP_FUNC, @@ -5406,7 +5356,6 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { ALC882_FIXUP_ACER_ASPIRE_4930G), SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE), - SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G), SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), @@ -5432,7 +5381,6 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), - SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO), SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), @@ -5448,13 +5396,6 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { {} }; -static const struct alc_model_fixup alc882_fixup_models[] = { - {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, - {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, - {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, - {} -}; - /* * BIOS auto configuration */ @@ -5495,8 +5436,7 @@ static int patch_alc882(struct hda_codec *codec) if (err < 0) goto error; - alc_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl, - alc882_fixups); + alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups); alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); alc_auto_parse_customize_define(codec); @@ -6109,7 +6049,6 @@ static const struct alc_fixup alc269_fixups[] = { static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED), - SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), @@ -6137,7 +6076,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { * Basically the device should work as is without the fixup table. * If BIOS doesn't give a proper info, enable the corresponding * fixup entry. - */ + */ SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", ALC269_FIXUP_AMIC), SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), @@ -6354,7 +6293,7 @@ static void alc_fixup_no_jack_detect(struct hda_codec *codec, { if (action == ALC_FIXUP_ACT_PRE_PROBE) codec->no_jack_detect = 1; -} +} static const struct alc_fixup alc861_fixups[] = { [ALC861_FIXUP_FSC_AMILO_PI1505] = { @@ -6772,7 +6711,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { * Basically the device should work as is without the fixup table. * If BIOS doesn't give a proper info, enable the corresponding * fixup entry. - */ + */ SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1), SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3), SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1), diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index 4742cac26aa9..33a9946b492c 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -5063,11 +5063,12 @@ static void stac92xx_update_led_status(struct hda_codec *codec, int enabled) if (spec->gpio_led_polarity) muted = !muted; + /*polarity defines *not* muted state level*/ if (!spec->vref_mute_led_nid) { if (muted) - spec->gpio_data |= spec->gpio_led; + spec->gpio_data &= ~spec->gpio_led; /* orange */ else - spec->gpio_data &= ~spec->gpio_led; + spec->gpio_data |= spec->gpio_led; /* white */ stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); } else { diff --git a/trunk/sound/soc/blackfin/bf5xx-ssm2602.c b/trunk/sound/soc/blackfin/bf5xx-ssm2602.c index b39ad356b92b..df3ac73f8778 100644 --- a/trunk/sound/soc/blackfin/bf5xx-ssm2602.c +++ b/trunk/sound/soc/blackfin/bf5xx-ssm2602.c @@ -99,7 +99,6 @@ static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = { .platform_name = "bfin-i2s-pcm-audio", .codec_name = "ssm2602.0-001b", .ops = &bf5xx_ssm2602_ops, - .dai_fmt = BF5XX_SSM2602_DAIFMT, }, { .name = "ssm2602", @@ -109,7 +108,6 @@ static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = { .platform_name = "bfin-i2s-pcm-audio", .codec_name = "ssm2602.0-001b", .ops = &bf5xx_ssm2602_ops, - .dai_fmt = BF5XX_SSM2602_DAIFMT, }, }; diff --git a/trunk/sound/soc/codecs/Kconfig b/trunk/sound/soc/codecs/Kconfig index 59d8efaa17e9..6508e8b790bb 100644 --- a/trunk/sound/soc/codecs/Kconfig +++ b/trunk/sound/soc/codecs/Kconfig @@ -57,7 +57,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_TPA6130A2 if I2C select SND_SOC_TLV320DAC33 if I2C select SND_SOC_TWL4030 if TWL4030_CORE - select SND_SOC_TWL6040 if TWL6040_CORE + select SND_SOC_TWL6040 if TWL4030_CORE select SND_SOC_UDA134X select SND_SOC_UDA1380 if I2C select SND_SOC_WL1273 if MFD_WL1273_CORE @@ -276,6 +276,7 @@ config SND_SOC_TWL4030 tristate config SND_SOC_TWL6040 + select TWL6040_CORE tristate config SND_SOC_UDA134X diff --git a/trunk/sound/soc/codecs/ak4642.c b/trunk/sound/soc/codecs/ak4642.c index b3e24f289421..f8e10ced244a 100644 --- a/trunk/sound/soc/codecs/ak4642.c +++ b/trunk/sound/soc/codecs/ak4642.c @@ -140,7 +140,7 @@ * min : 0xFE : -115.0 dB * mute: 0xFF */ -static const DECLARE_TLV_DB_SCALE(out_tlv, -11550, 50, 1); +static const DECLARE_TLV_DB_SCALE(out_tlv, -11500, 50, 1); static const struct snd_kcontrol_new ak4642_snd_controls[] = { diff --git a/trunk/sound/soc/codecs/cs42l73.c b/trunk/sound/soc/codecs/cs42l73.c index 07c44b71f096..78979b3e0e95 100644 --- a/trunk/sound/soc/codecs/cs42l73.c +++ b/trunk/sound/soc/codecs/cs42l73.c @@ -929,8 +929,6 @@ static int cs42l73_set_mclk(struct snd_soc_dai *dai, unsigned int freq) /* MCLKX -> MCLK */ mclkx_coeff = cs42l73_get_mclkx_coeff(freq); - if (mclkx_coeff < 0) - return mclkx_coeff; mclk = cs42l73_mclkx_coeffs[mclkx_coeff].mclkx / cs42l73_mclkx_coeffs[mclkx_coeff].ratio; diff --git a/trunk/sound/soc/codecs/sgtl5000.c b/trunk/sound/soc/codecs/sgtl5000.c index 8e92fb88ed09..d1926266fe00 100644 --- a/trunk/sound/soc/codecs/sgtl5000.c +++ b/trunk/sound/soc/codecs/sgtl5000.c @@ -143,11 +143,11 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w, } /* - * As manual described, ADC/DAC only works when VAG powerup, - * So enabled VAG before ADC/DAC up. - * In power down case, we need wait 400ms when vag fully ramped down. + * using codec assist to small pop, hp_powerup or lineout_powerup + * should stay setting until vag_powerup is fully ramped down, + * vag fully ramped down require 400ms. */ -static int power_vag_event(struct snd_soc_dapm_widget *w, +static int small_pop_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { switch (event) { @@ -156,7 +156,7 @@ static int power_vag_event(struct snd_soc_dapm_widget *w, SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP); break; - case SND_SOC_DAPM_POST_PMD: + case SND_SOC_DAPM_PRE_PMD: snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER, SGTL5000_VAG_POWERUP, 0); msleep(400); @@ -201,8 +201,12 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = { mic_bias_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_PGA("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0), - SND_SOC_DAPM_PGA("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA_E("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0, + small_pop_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_PGA_E("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0, + small_pop_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0, &adc_mux), SND_SOC_DAPM_MUX("Headphone Mux", SND_SOC_NOPM, 0, 0, &dac_mux), @@ -217,11 +221,8 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = { 0, SGTL5000_CHIP_DIG_POWER, 1, 0), - SND_SOC_DAPM_SUPPLY("VAG_POWER", SGTL5000_CHIP_ANA_POWER, 7, 0, - power_vag_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0), + SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0), }; @@ -230,11 +231,9 @@ static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = { {"Capture Mux", "LINE_IN", "LINE_IN"}, /* line_in --> adc_mux */ {"Capture Mux", "MIC_IN", "MIC_IN"}, /* mic_in --> adc_mux */ - {"ADC", NULL, "VAG_POWER"}, {"ADC", NULL, "Capture Mux"}, /* adc_mux --> adc */ {"AIFOUT", NULL, "ADC"}, /* adc --> i2s_out */ - {"DAC", NULL, "VAG_POWER"}, {"DAC", NULL, "AIFIN"}, /* i2s-->dac,skip audio mux */ {"Headphone Mux", "DAC", "DAC"}, /* dac --> hp_mux */ {"LO", NULL, "DAC"}, /* dac --> line_out */ diff --git a/trunk/sound/soc/codecs/tlv320aic23.c b/trunk/sound/soc/codecs/tlv320aic23.c index df1e07ffac32..16d55f91a653 100644 --- a/trunk/sound/soc/codecs/tlv320aic23.c +++ b/trunk/sound/soc/codecs/tlv320aic23.c @@ -472,7 +472,7 @@ static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai, static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0x17f; + u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0xff7f; switch (level) { case SND_SOC_BIAS_ON: @@ -491,7 +491,7 @@ static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_OFF: /* everything off, dac mute, inactive */ snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0); - snd_soc_write(codec, TLV320AIC23_PWR, 0x1ff); + snd_soc_write(codec, TLV320AIC23_PWR, 0xffff); break; } codec->dapm.bias_level = level; diff --git a/trunk/sound/soc/codecs/twl6040.c b/trunk/sound/soc/codecs/twl6040.c index dc7509b9d53a..2d8c6b825e57 100644 --- a/trunk/sound/soc/codecs/twl6040.c +++ b/trunk/sound/soc/codecs/twl6040.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -1527,7 +1528,7 @@ static int twl6040_resume(struct snd_soc_codec *codec) static int twl6040_probe(struct snd_soc_codec *codec) { struct twl6040_data *priv; - struct twl6040_codec_data *pdata = dev_get_platdata(codec->dev); + struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev); struct platform_device *pdev = container_of(codec->dev, struct platform_device, dev); int ret = 0; diff --git a/trunk/sound/soc/codecs/wm8350.c b/trunk/sound/soc/codecs/wm8350.c index aa12c6b6beeb..8c4c9591ec05 100644 --- a/trunk/sound/soc/codecs/wm8350.c +++ b/trunk/sound/soc/codecs/wm8350.c @@ -60,7 +60,7 @@ struct wm8350_jack_data { }; struct wm8350_data { - struct wm8350 *wm8350; + struct snd_soc_codec codec; struct wm8350_output out1; struct wm8350_output out2; struct wm8350_jack_data hpl; @@ -1309,7 +1309,7 @@ static void wm8350_hp_work(struct wm8350_data *priv, struct wm8350_jack_data *jack, u16 mask) { - struct wm8350 *wm8350 = priv->wm8350; + struct wm8350 *wm8350 = priv->codec.control_data; u16 reg; int report; @@ -1342,7 +1342,7 @@ static void wm8350_hpr_work(struct work_struct *work) static irqreturn_t wm8350_hp_jack_handler(int irq, void *data) { struct wm8350_data *priv = data; - struct wm8350 *wm8350 = priv->wm8350; + struct wm8350 *wm8350 = priv->codec.control_data; struct wm8350_jack_data *jack = NULL; switch (irq - wm8350->irq_base) { @@ -1427,7 +1427,7 @@ EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect); static irqreturn_t wm8350_mic_handler(int irq, void *data) { struct wm8350_data *priv = data; - struct wm8350 *wm8350 = priv->wm8350; + struct wm8350 *wm8350 = priv->codec.control_data; u16 reg; int report = 0; @@ -1536,8 +1536,6 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) return -ENOMEM; snd_soc_codec_set_drvdata(codec, priv); - priv->wm8350 = wm8350; - for (i = 0; i < ARRAY_SIZE(supply_names); i++) priv->supplies[i].supply = supply_names[i]; @@ -1546,6 +1544,7 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) if (ret != 0) return ret; + wm8350->codec.codec = codec; codec->control_data = wm8350; /* Put the codec into reset if it wasn't already */ diff --git a/trunk/sound/soc/codecs/wm8994.c b/trunk/sound/soc/codecs/wm8994.c index 6c1fe3afd4b5..fe7fbaeb7146 100644 --- a/trunk/sound/soc/codecs/wm8994.c +++ b/trunk/sound/soc/codecs/wm8994.c @@ -1000,170 +1000,61 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec) } } -static int aif1clk_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) +static int late_enable_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; - struct wm8994 *control = codec->control_data; - int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA; - int dac; - int adc; - int val; - - switch (control->type) { - case WM8994: - case WM8958: - mask |= WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA; - break; - default: - break; - } + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); switch (event) { case SND_SOC_DAPM_PRE_PMU: - val = snd_soc_read(codec, WM8994_AIF1_CONTROL_1); - if ((val & WM8994_AIF1ADCL_SRC) && - (val & WM8994_AIF1ADCR_SRC)) - adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA; - else if (!(val & WM8994_AIF1ADCL_SRC) && - !(val & WM8994_AIF1ADCR_SRC)) - adc = WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC2L_ENA; - else - adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA | - WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC2L_ENA; - - val = snd_soc_read(codec, WM8994_AIF1_CONTROL_2); - if ((val & WM8994_AIF1DACL_SRC) && - (val & WM8994_AIF1DACR_SRC)) - dac = WM8994_AIF1DAC1R_ENA | WM8994_AIF1DAC2R_ENA; - else if (!(val & WM8994_AIF1DACL_SRC) && - !(val & WM8994_AIF1DACR_SRC)) - dac = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC2L_ENA; - else - dac = WM8994_AIF1DAC1R_ENA | WM8994_AIF1DAC2R_ENA | - WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC2L_ENA; - - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, - mask, adc); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, - mask, dac); - snd_soc_update_bits(codec, WM8994_CLOCKING_1, - WM8994_AIF1DSPCLK_ENA | - WM8994_SYSDSPCLK_ENA, - WM8994_AIF1DSPCLK_ENA | - WM8994_SYSDSPCLK_ENA); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, mask, - WM8994_AIF1ADC1R_ENA | - WM8994_AIF1ADC1L_ENA | - WM8994_AIF1ADC2R_ENA | - WM8994_AIF1ADC2L_ENA); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, mask, - WM8994_AIF1DAC1R_ENA | - WM8994_AIF1DAC1L_ENA | - WM8994_AIF1DAC2R_ENA | - WM8994_AIF1DAC2L_ENA); - break; - - case SND_SOC_DAPM_PRE_PMD: - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, - mask, 0); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, - mask, 0); - - val = snd_soc_read(codec, WM8994_CLOCKING_1); - if (val & WM8994_AIF2DSPCLK_ENA) - val = WM8994_SYSDSPCLK_ENA; - else - val = 0; - snd_soc_update_bits(codec, WM8994_CLOCKING_1, - WM8994_SYSDSPCLK_ENA | - WM8994_AIF1DSPCLK_ENA, val); + if (wm8994->aif1clk_enable) { + snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, + WM8994_AIF1CLK_ENA_MASK, + WM8994_AIF1CLK_ENA); + wm8994->aif1clk_enable = 0; + } + if (wm8994->aif2clk_enable) { + snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, + WM8994_AIF2CLK_ENA_MASK, + WM8994_AIF2CLK_ENA); + wm8994->aif2clk_enable = 0; + } break; } + /* We may also have postponed startup of DSP, handle that. */ + wm8958_aif_ev(w, kcontrol, event); + return 0; } -static int aif2clk_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) +static int late_disable_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; - int dac; - int adc; - int val; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); switch (event) { - case SND_SOC_DAPM_PRE_PMU: - val = snd_soc_read(codec, WM8994_AIF2_CONTROL_1); - if ((val & WM8994_AIF2ADCL_SRC) && - (val & WM8994_AIF2ADCR_SRC)) - adc = WM8994_AIF2ADCR_ENA; - else if (!(val & WM8994_AIF2ADCL_SRC) && - !(val & WM8994_AIF2ADCR_SRC)) - adc = WM8994_AIF2ADCL_ENA; - else - adc = WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA; - - - val = snd_soc_read(codec, WM8994_AIF2_CONTROL_2); - if ((val & WM8994_AIF2DACL_SRC) && - (val & WM8994_AIF2DACR_SRC)) - dac = WM8994_AIF2DACR_ENA; - else if (!(val & WM8994_AIF2DACL_SRC) && - !(val & WM8994_AIF2DACR_SRC)) - dac = WM8994_AIF2DACL_ENA; - else - dac = WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA; - - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, - WM8994_AIF2ADCL_ENA | - WM8994_AIF2ADCR_ENA, adc); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, - WM8994_AIF2DACL_ENA | - WM8994_AIF2DACR_ENA, dac); - snd_soc_update_bits(codec, WM8994_CLOCKING_1, - WM8994_AIF2DSPCLK_ENA | - WM8994_SYSDSPCLK_ENA, - WM8994_AIF2DSPCLK_ENA | - WM8994_SYSDSPCLK_ENA); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, - WM8994_AIF2ADCL_ENA | - WM8994_AIF2ADCR_ENA, - WM8994_AIF2ADCL_ENA | - WM8994_AIF2ADCR_ENA); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, - WM8994_AIF2DACL_ENA | - WM8994_AIF2DACR_ENA, - WM8994_AIF2DACL_ENA | - WM8994_AIF2DACR_ENA); - break; - - case SND_SOC_DAPM_PRE_PMD: case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, - WM8994_AIF2DACL_ENA | - WM8994_AIF2DACR_ENA, 0); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, - WM8994_AIF2ADCL_ENA | - WM8994_AIF2ADCR_ENA, 0); - - val = snd_soc_read(codec, WM8994_CLOCKING_1); - if (val & WM8994_AIF1DSPCLK_ENA) - val = WM8994_SYSDSPCLK_ENA; - else - val = 0; - snd_soc_update_bits(codec, WM8994_CLOCKING_1, - WM8994_SYSDSPCLK_ENA | - WM8994_AIF2DSPCLK_ENA, val); + if (wm8994->aif1clk_disable) { + snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, + WM8994_AIF1CLK_ENA_MASK, 0); + wm8994->aif1clk_disable = 0; + } + if (wm8994->aif2clk_disable) { + snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, + WM8994_AIF2CLK_ENA_MASK, 0); + wm8994->aif2clk_disable = 0; + } break; } return 0; } -static int aif1clk_late_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) +static int aif1clk_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); @@ -1180,8 +1071,8 @@ static int aif1clk_late_ev(struct snd_soc_dapm_widget *w, return 0; } -static int aif2clk_late_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) +static int aif2clk_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); @@ -1198,63 +1089,6 @@ static int aif2clk_late_ev(struct snd_soc_dapm_widget *w, return 0; } -static int late_enable_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (wm8994->aif1clk_enable) { - aif1clk_ev(w, kcontrol, event); - snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, - WM8994_AIF1CLK_ENA_MASK, - WM8994_AIF1CLK_ENA); - wm8994->aif1clk_enable = 0; - } - if (wm8994->aif2clk_enable) { - aif2clk_ev(w, kcontrol, event); - snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, - WM8994_AIF2CLK_ENA_MASK, - WM8994_AIF2CLK_ENA); - wm8994->aif2clk_enable = 0; - } - break; - } - - /* We may also have postponed startup of DSP, handle that. */ - wm8958_aif_ev(w, kcontrol, event); - - return 0; -} - -static int late_disable_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - - switch (event) { - case SND_SOC_DAPM_POST_PMD: - if (wm8994->aif1clk_disable) { - snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, - WM8994_AIF1CLK_ENA_MASK, 0); - aif1clk_ev(w, kcontrol, event); - wm8994->aif1clk_disable = 0; - } - if (wm8994->aif2clk_disable) { - snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, - WM8994_AIF2CLK_ENA_MASK, 0); - aif2clk_ev(w, kcontrol, event); - wm8994->aif2clk_disable = 0; - } - break; - } - - return 0; -} - static int adc_mux_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -1551,9 +1385,9 @@ static const struct snd_kcontrol_new aif2dacr_src_mux = SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum); static const struct snd_soc_dapm_widget wm8994_lateclk_revd_widgets[] = { -SND_SOC_DAPM_SUPPLY("AIF1CLK", SND_SOC_NOPM, 0, 0, aif1clk_late_ev, +SND_SOC_DAPM_SUPPLY("AIF1CLK", SND_SOC_NOPM, 0, 0, aif1clk_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), -SND_SOC_DAPM_SUPPLY("AIF2CLK", SND_SOC_NOPM, 0, 0, aif2clk_late_ev, +SND_SOC_DAPM_SUPPLY("AIF2CLK", SND_SOC_NOPM, 0, 0, aif2clk_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PGA_E("Late DAC1L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0, @@ -1582,10 +1416,8 @@ SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev) }; static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = { -SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, aif1clk_ev, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), -SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, aif2clk_ev, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), +SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0, left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)), @@ -1638,30 +1470,30 @@ SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, vmid_event, SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), -SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, 3, 0, NULL, 0), -SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM, 2, 0, NULL, 0), -SND_SOC_DAPM_SUPPLY("DSPINTCLK", SND_SOC_NOPM, 1, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8994_CLOCKING_1, 3, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0), SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", NULL, - 0, SND_SOC_NOPM, 9, 0), + 0, WM8994_POWER_MANAGEMENT_4, 9, 0), SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", NULL, - 0, SND_SOC_NOPM, 8, 0), + 0, WM8994_POWER_MANAGEMENT_4, 8, 0), SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0, - SND_SOC_NOPM, 9, 0, wm8958_aif_ev, + WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_AIF_IN_E("AIF1DAC1R", NULL, 0, - SND_SOC_NOPM, 8, 0, wm8958_aif_ev, + WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", NULL, - 0, SND_SOC_NOPM, 11, 0), + 0, WM8994_POWER_MANAGEMENT_4, 11, 0), SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", NULL, - 0, SND_SOC_NOPM, 10, 0), + 0, WM8994_POWER_MANAGEMENT_4, 10, 0), SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0, - SND_SOC_NOPM, 11, 0, wm8958_aif_ev, + WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_AIF_IN_E("AIF1DAC2R", NULL, 0, - SND_SOC_NOPM, 10, 0, wm8958_aif_ev, + WM8994_POWER_MANAGEMENT_5, 10, 0, wm8958_aif_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0, @@ -1688,14 +1520,14 @@ SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0, dac1r_mix, ARRAY_SIZE(dac1r_mix)), SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0, - SND_SOC_NOPM, 13, 0), + WM8994_POWER_MANAGEMENT_4, 13, 0), SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0, - SND_SOC_NOPM, 12, 0), + WM8994_POWER_MANAGEMENT_4, 12, 0), SND_SOC_DAPM_AIF_IN_E("AIF2DACL", NULL, 0, - SND_SOC_NOPM, 13, 0, wm8958_aif_ev, + WM8994_POWER_MANAGEMENT_5, 13, 0, wm8958_aif_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0, - SND_SOC_NOPM, 12, 0, wm8958_aif_ev, + WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_AIF_IN("AIF1DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0), @@ -3797,7 +3629,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) case 2: case 3: wm8994->hubs.dcs_codes_l = -9; - wm8994->hubs.dcs_codes_r = -7; + wm8994->hubs.dcs_codes_r = -5; break; default: break; diff --git a/trunk/sound/soc/codecs/wm_hubs.c b/trunk/sound/soc/codecs/wm_hubs.c index 6c028c470601..f13f2886339c 100644 --- a/trunk/sound/soc/codecs/wm_hubs.c +++ b/trunk/sound/soc/codecs/wm_hubs.c @@ -1035,7 +1035,7 @@ void wm_hubs_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); - int mask, val; + int val; switch (level) { case SND_SOC_BIAS_STANDBY: @@ -1047,13 +1047,6 @@ void wm_hubs_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_ON: /* Turn off any unneded single ended outputs */ val = 0; - mask = 0; - - if (hubs->lineout1_se) - mask |= WM8993_LINEOUT1N_ENA | WM8993_LINEOUT1P_ENA; - - if (hubs->lineout2_se) - mask |= WM8993_LINEOUT2N_ENA | WM8993_LINEOUT2P_ENA; if (hubs->lineout1_se && hubs->lineout1n_ena) val |= WM8993_LINEOUT1N_ENA; @@ -1068,7 +1061,11 @@ void wm_hubs_set_bias_level(struct snd_soc_codec *codec, val |= WM8993_LINEOUT2P_ENA; snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3, - mask, val); + WM8993_LINEOUT1N_ENA | + WM8993_LINEOUT1P_ENA | + WM8993_LINEOUT2N_ENA | + WM8993_LINEOUT2P_ENA, + val); /* Remove the input clamps */ snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG, diff --git a/trunk/sound/soc/fsl/mpc8610_hpcd.c b/trunk/sound/soc/fsl/mpc8610_hpcd.c index 3fea5a15ffe8..afbabf427f27 100644 --- a/trunk/sound/soc/fsl/mpc8610_hpcd.c +++ b/trunk/sound/soc/fsl/mpc8610_hpcd.c @@ -58,9 +58,9 @@ static int mpc8610_hpcd_machine_probe(struct snd_soc_card *card) { struct mpc8610_hpcd_data *machine_data = container_of(card, struct mpc8610_hpcd_data, card); - struct ccsr_guts __iomem *guts; + struct ccsr_guts_86xx __iomem *guts; - guts = ioremap(guts_phys, sizeof(struct ccsr_guts)); + guts = ioremap(guts_phys, sizeof(struct ccsr_guts_86xx)); if (!guts) { dev_err(card->dev, "could not map global utilities\n"); return -ENOMEM; @@ -142,9 +142,9 @@ static int mpc8610_hpcd_machine_remove(struct snd_soc_card *card) { struct mpc8610_hpcd_data *machine_data = container_of(card, struct mpc8610_hpcd_data, card); - struct ccsr_guts __iomem *guts; + struct ccsr_guts_86xx __iomem *guts; - guts = ioremap(guts_phys, sizeof(struct ccsr_guts)); + guts = ioremap(guts_phys, sizeof(struct ccsr_guts_86xx)); if (!guts) { dev_err(card->dev, "could not map global utilities\n"); return -ENOMEM; diff --git a/trunk/sound/soc/fsl/p1022_ds.c b/trunk/sound/soc/fsl/p1022_ds.c index 982a1c944983..46623405a2ce 100644 --- a/trunk/sound/soc/fsl/p1022_ds.c +++ b/trunk/sound/soc/fsl/p1022_ds.c @@ -46,7 +46,7 @@ * ch: The channel on the DMA controller (0, 1, 2, or 3) * device: The device to set as the target (CCSR_GUTS_DMUXCR_xxx) */ -static inline void guts_set_dmuxcr(struct ccsr_guts __iomem *guts, +static inline void guts_set_dmuxcr(struct ccsr_guts_85xx __iomem *guts, unsigned int co, unsigned int ch, unsigned int device) { unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch)); @@ -90,9 +90,9 @@ static int p1022_ds_machine_probe(struct snd_soc_card *card) { struct machine_data *mdata = container_of(card, struct machine_data, card); - struct ccsr_guts __iomem *guts; + struct ccsr_guts_85xx __iomem *guts; - guts = ioremap(guts_phys, sizeof(struct ccsr_guts)); + guts = ioremap(guts_phys, sizeof(struct ccsr_guts_85xx)); if (!guts) { dev_err(card->dev, "could not map global utilities\n"); return -ENOMEM; @@ -164,9 +164,9 @@ static int p1022_ds_machine_remove(struct snd_soc_card *card) { struct machine_data *mdata = container_of(card, struct machine_data, card); - struct ccsr_guts __iomem *guts; + struct ccsr_guts_85xx __iomem *guts; - guts = ioremap(guts_phys, sizeof(struct ccsr_guts)); + guts = ioremap(guts_phys, sizeof(struct ccsr_guts_85xx)); if (!guts) { dev_err(card->dev, "could not map global utilities\n"); return -ENOMEM; diff --git a/trunk/sound/soc/imx/imx-audmux.c b/trunk/sound/soc/imx/imx-audmux.c index f23700359c67..601df809a26a 100644 --- a/trunk/sound/soc/imx/imx-audmux.c +++ b/trunk/sound/soc/imx/imx-audmux.c @@ -40,6 +40,12 @@ static void __iomem *audmux_base; #ifdef CONFIG_DEBUG_FS static struct dentry *audmux_debugfs_root; +static int audmux_open_file(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + /* There is an annoying discontinuity in the SSI numbering with regard * to the Linux number of the devices */ static const char *audmux_port_string(int port) @@ -73,9 +79,6 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf, if (!buf) return -ENOMEM; - if (!audmux_base) - return -ENOSYS; - if (audmux_clk) clk_prepare_enable(audmux_clk); @@ -139,7 +142,7 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf, } static const struct file_operations audmux_debugfs_fops = { - .open = simple_open, + .open = audmux_open_file, .read = audmux_read_file, .llseek = default_llseek, }; @@ -155,7 +158,7 @@ static void __init audmux_debugfs_init(void) return; } - for (i = 0; i < MX31_AUDMUX_PORT6_SSI_PINS_6 + 1; i++) { + for (i = 1; i < 8; i++) { snprintf(buf, sizeof(buf), "ssi%d", i); if (!debugfs_create_file(buf, 0444, audmux_debugfs_root, (void *)i, &audmux_debugfs_fops)) diff --git a/trunk/sound/soc/mxs/mxs-pcm.c b/trunk/sound/soc/mxs/mxs-pcm.c index e373fbbc97a0..6ca1f46d84a4 100644 --- a/trunk/sound/soc/mxs/mxs-pcm.c +++ b/trunk/sound/soc/mxs/mxs-pcm.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -37,6 +36,7 @@ #include #include +#include #include "mxs-pcm.h" struct mxs_pcm_dma_data { diff --git a/trunk/sound/soc/mxs/mxs-saif.c b/trunk/sound/soc/mxs/mxs-saif.c index 53f4fd8feced..12be05b16880 100644 --- a/trunk/sound/soc/mxs/mxs-saif.c +++ b/trunk/sound/soc/mxs/mxs-saif.c @@ -24,12 +24,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include #include diff --git a/trunk/sound/soc/omap/Kconfig b/trunk/sound/soc/omap/Kconfig index deafbfaacdbf..e00dd0b1139c 100644 --- a/trunk/sound/soc/omap/Kconfig +++ b/trunk/sound/soc/omap/Kconfig @@ -97,7 +97,7 @@ config SND_OMAP_SOC_SDP3430 config SND_OMAP_SOC_OMAP_ABE_TWL6040 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" - depends on TWL6040_CORE && SND_OMAP_SOC && ARCH_OMAP4 + depends on TWL4030_CORE && SND_OMAP_SOC && ARCH_OMAP4 select SND_OMAP_SOC_DMIC select SND_OMAP_SOC_MCPDM select SND_SOC_TWL6040 diff --git a/trunk/sound/soc/omap/omap-pcm.c b/trunk/sound/soc/omap/omap-pcm.c index 5a649da9122a..a59bd352d342 100644 --- a/trunk/sound/soc/omap/omap-pcm.c +++ b/trunk/sound/soc/omap/omap-pcm.c @@ -401,10 +401,6 @@ static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd) } out: - /* free preallocated buffers in case of error */ - if (ret) - omap_pcm_free_dma_buffers(pcm); - return ret; } diff --git a/trunk/sound/soc/pxa/pxa2xx-i2s.c b/trunk/sound/soc/pxa/pxa2xx-i2s.c index d08583790d23..609abd51e55f 100644 --- a/trunk/sound/soc/pxa/pxa2xx-i2s.c +++ b/trunk/sound/soc/pxa/pxa2xx-i2s.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/sound/soc/samsung/s3c2412-i2s.c b/trunk/sound/soc/samsung/s3c2412-i2s.c index 79fbeea99d46..72185078ddf8 100644 --- a/trunk/sound/soc/samsung/s3c2412-i2s.c +++ b/trunk/sound/soc/samsung/s3c2412-i2s.c @@ -166,7 +166,7 @@ static struct snd_soc_dai_driver s3c2412_i2s_dai = { static __devinit int s3c2412_iis_dev_probe(struct platform_device *pdev) { - return s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai); + return snd_soc_register_dai(&pdev->dev, &s3c2412_i2s_dai); } static __devexit int s3c2412_iis_dev_remove(struct platform_device *pdev) diff --git a/trunk/sound/soc/sh/fsi.c b/trunk/sound/soc/sh/fsi.c index 74ed2dffbffd..378cc5b056d7 100644 --- a/trunk/sound/soc/sh/fsi.c +++ b/trunk/sound/soc/sh/fsi.c @@ -1001,10 +1001,11 @@ static void fsi_dma_do_tasklet(unsigned long data) sg_dma_address(&sg) = buf; sg_dma_len(&sg) = len; - desc = dmaengine_prep_slave_sg(chan, &sg, 1, dir, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + desc = chan->device->device_prep_slave_sg(chan, &sg, 1, dir, + DMA_PREP_INTERRUPT | + DMA_CTRL_ACK); if (!desc) { - dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n"); + dev_err(dai->dev, "device_prep_slave_sg() fail\n"); return; } diff --git a/trunk/sound/soc/soc-core.c b/trunk/sound/soc/soc-core.c index c88d9741b9e7..a4deebc0801a 100644 --- a/trunk/sound/soc/soc-core.c +++ b/trunk/sound/soc/soc-core.c @@ -201,6 +201,12 @@ static ssize_t pmdown_time_set(struct device *dev, static DEVICE_ATTR(pmdown_time, 0644, pmdown_time_show, pmdown_time_set); #ifdef CONFIG_DEBUG_FS +static int codec_reg_open_file(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -258,7 +264,7 @@ static ssize_t codec_reg_write_file(struct file *file, } static const struct file_operations codec_reg_fops = { - .open = simple_open, + .open = codec_reg_open_file, .read = codec_reg_read_file, .write = codec_reg_write_file, .llseek = default_llseek, @@ -1081,8 +1087,6 @@ static int soc_probe_platform(struct snd_soc_card *card, snd_soc_dapm_new_controls(&platform->dapm, driver->dapm_widgets, driver->num_dapm_widgets); - platform->dapm.idle_bias_off = 1; - if (driver->probe) { ret = driver->probe(platform); if (ret < 0) { @@ -3113,7 +3117,6 @@ int snd_soc_register_card(struct snd_soc_card *card) GFP_KERNEL); if (card->rtd == NULL) return -ENOMEM; - card->num_rtd = 0; card->rtd_aux = &card->rtd[card->num_links]; for (i = 0; i < card->num_links; i++) @@ -3625,10 +3628,10 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, int i, ret; num_routes = of_property_count_strings(np, propname); - if (num_routes < 0 || num_routes & 1) { + if (num_routes & 1) { dev_err(card->dev, - "Property '%s' does not exist or its length is not even\n", - propname); + "Property '%s's length is not even\n", + propname); return -EINVAL; } num_routes /= 2; diff --git a/trunk/sound/soc/soc-dapm.c b/trunk/sound/soc/soc-dapm.c index 1bb6d4a63cd8..6241490fff30 100644 --- a/trunk/sound/soc/soc-dapm.c +++ b/trunk/sound/soc/soc-dapm.c @@ -67,7 +67,6 @@ static int dapm_up_seq[] = { [snd_soc_dapm_out_drv] = 10, [snd_soc_dapm_hp] = 10, [snd_soc_dapm_spk] = 10, - [snd_soc_dapm_line] = 10, [snd_soc_dapm_post] = 11, }; @@ -76,7 +75,6 @@ static int dapm_down_seq[] = { [snd_soc_dapm_adc] = 1, [snd_soc_dapm_hp] = 2, [snd_soc_dapm_spk] = 2, - [snd_soc_dapm_line] = 2, [snd_soc_dapm_out_drv] = 2, [snd_soc_dapm_pga] = 4, [snd_soc_dapm_mixer_named_ctl] = 5, @@ -1546,6 +1544,12 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) } #ifdef CONFIG_DEBUG_FS +static int dapm_widget_power_open_file(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static ssize_t dapm_widget_power_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -1609,11 +1613,17 @@ static ssize_t dapm_widget_power_read_file(struct file *file, } static const struct file_operations dapm_widget_power_fops = { - .open = simple_open, + .open = dapm_widget_power_open_file, .read = dapm_widget_power_read_file, .llseek = default_llseek, }; +static int dapm_bias_open_file(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + static ssize_t dapm_bias_read_file(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -1644,7 +1654,7 @@ static ssize_t dapm_bias_read_file(struct file *file, char __user *user_buf, } static const struct file_operations dapm_bias_fops = { - .open = simple_open, + .open = dapm_bias_open_file, .read = dapm_bias_read_file, .llseek = default_llseek, }; diff --git a/trunk/sound/soc/soc-dmaengine-pcm.c b/trunk/sound/soc/soc-dmaengine-pcm.c index 475695234b3d..4420b7030c83 100644 --- a/trunk/sound/soc/soc-dmaengine-pcm.c +++ b/trunk/sound/soc/soc-dmaengine-pcm.c @@ -143,7 +143,7 @@ static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream) direction = snd_pcm_substream_to_dma_direction(substream); prtd->pos = 0; - desc = dmaengine_prep_dma_cyclic(chan, + desc = chan->device->device_prep_dma_cyclic(chan, substream->runtime->dma_addr, snd_pcm_lib_buffer_bytes(substream), snd_pcm_lib_period_bytes(substream), direction); diff --git a/trunk/sound/soc/tegra/tegra_i2s.c b/trunk/sound/soc/tegra/tegra_i2s.c index e53349912b2e..33509de52540 100644 --- a/trunk/sound/soc/tegra/tegra_i2s.c +++ b/trunk/sound/soc/tegra/tegra_i2s.c @@ -79,15 +79,11 @@ static int tegra_i2s_show(struct seq_file *s, void *unused) struct tegra_i2s *i2s = s->private; int i; - clk_enable(i2s->clk_i2s); - for (i = 0; i < ARRAY_SIZE(regs); i++) { u32 val = tegra_i2s_read(i2s, regs[i].offset); seq_printf(s, "%s = %08x\n", regs[i].name, val); } - clk_disable(i2s->clk_i2s); - return 0; } @@ -116,7 +112,7 @@ static void tegra_i2s_debug_remove(struct tegra_i2s *i2s) debugfs_remove(i2s->debug); } #else -static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s) +static inline void tegra_i2s_debug_add(struct tegra_i2s *i2s, int id) { } diff --git a/trunk/sound/soc/tegra/tegra_spdif.c b/trunk/sound/soc/tegra/tegra_spdif.c index 9ff2c601445f..475428cf270e 100644 --- a/trunk/sound/soc/tegra/tegra_spdif.c +++ b/trunk/sound/soc/tegra/tegra_spdif.c @@ -79,15 +79,11 @@ static int tegra_spdif_show(struct seq_file *s, void *unused) struct tegra_spdif *spdif = s->private; int i; - clk_enable(spdif->clk_spdif_out); - for (i = 0; i < ARRAY_SIZE(regs); i++) { u32 val = tegra_spdif_read(spdif, regs[i].offset); seq_printf(s, "%s = %08x\n", regs[i].name, val); } - clk_disable(spdif->clk_spdif_out); - return 0; } diff --git a/trunk/tools/perf/.gitignore b/trunk/tools/perf/.gitignore index 26b823b61aa1..416684be0ad3 100644 --- a/trunk/tools/perf/.gitignore +++ b/trunk/tools/perf/.gitignore @@ -19,5 +19,3 @@ TAGS cscope* config.mak config.mak.autogen -*-bison.* -*-flex.* diff --git a/trunk/tools/perf/Documentation/perf-report.txt b/trunk/tools/perf/Documentation/perf-report.txt index 2d89f02719b5..87feeee8b90c 100644 --- a/trunk/tools/perf/Documentation/perf-report.txt +++ b/trunk/tools/perf/Documentation/perf-report.txt @@ -48,9 +48,6 @@ OPTIONS Only consider these symbols. CSV that understands file://filename entries. ---symbol-filter=:: - Only show symbols that match (partially) with this filter. - -U:: --hide-unresolved:: Only display entries resolved to a symbol. @@ -113,8 +110,6 @@ OPTIONS requires a tty, if one is not present, as when piping to other commands, the stdio interface is used. ---gtk:: Use the GTK2 interface. - -k:: --vmlinux=:: vmlinux pathname diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile index 9bf3fc759344..74fd7f89208a 100644 --- a/trunk/tools/perf/Makefile +++ b/trunk/tools/perf/Makefile @@ -182,7 +182,7 @@ endif ### --- END CONFIGURATION SECTION --- -BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)/util -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE +BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE BASIC_LDFLAGS = # Guard against environment variables @@ -234,24 +234,6 @@ endif export PERL_PATH -FLEX = flex -BISON= bison - -$(OUTPUT)util/parse-events-flex.c: util/parse-events.l - $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c - -$(OUTPUT)util/parse-events-bison.c: util/parse-events.y - $(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o $(OUTPUT)util/parse-events-bison.c - -$(OUTPUT)util/pmu-flex.c: util/pmu.l - $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c - -$(OUTPUT)util/pmu-bison.c: util/pmu.y - $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c - -$(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c -$(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c - LIB_FILE=$(OUTPUT)libperf.a LIB_H += ../../include/linux/perf_event.h @@ -267,7 +249,7 @@ LIB_H += util/include/linux/const.h LIB_H += util/include/linux/ctype.h LIB_H += util/include/linux/kernel.h LIB_H += util/include/linux/list.h -LIB_H += util/include/linux/export.h +LIB_H += util/include/linux/module.h LIB_H += util/include/linux/poison.h LIB_H += util/include/linux/prefetch.h LIB_H += util/include/linux/rbtree.h @@ -294,7 +276,6 @@ LIB_H += util/build-id.h LIB_H += util/debug.h LIB_H += util/debugfs.h LIB_H += util/sysfs.h -LIB_H += util/pmu.h LIB_H += util/event.h LIB_H += util/evsel.h LIB_H += util/evlist.h @@ -342,7 +323,6 @@ LIB_OBJS += $(OUTPUT)util/config.o LIB_OBJS += $(OUTPUT)util/ctype.o LIB_OBJS += $(OUTPUT)util/debugfs.o LIB_OBJS += $(OUTPUT)util/sysfs.o -LIB_OBJS += $(OUTPUT)util/pmu.o LIB_OBJS += $(OUTPUT)util/environment.o LIB_OBJS += $(OUTPUT)util/event.o LIB_OBJS += $(OUTPUT)util/evlist.o @@ -379,10 +359,6 @@ LIB_OBJS += $(OUTPUT)util/session.o LIB_OBJS += $(OUTPUT)util/thread.o LIB_OBJS += $(OUTPUT)util/thread_map.o LIB_OBJS += $(OUTPUT)util/trace-event-parse.o -LIB_OBJS += $(OUTPUT)util/parse-events-flex.o -LIB_OBJS += $(OUTPUT)util/parse-events-bison.o -LIB_OBJS += $(OUTPUT)util/pmu-flex.o -LIB_OBJS += $(OUTPUT)util/pmu-bison.o LIB_OBJS += $(OUTPUT)util/trace-event-read.o LIB_OBJS += $(OUTPUT)util/trace-event-info.o LIB_OBJS += $(OUTPUT)util/trace-event-scripting.o @@ -525,20 +501,6 @@ else endif endif -ifdef NO_GTK2 - BASIC_CFLAGS += -DNO_GTK2_SUPPORT -else - FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0) - ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2)),y) - msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev); - BASIC_CFLAGS += -DNO_GTK2_SUPPORT - else - BASIC_CFLAGS += $(shell pkg-config --cflags gtk+-2.0) - EXTLIBS += $(shell pkg-config --libs gtk+-2.0) - LIB_OBJS += $(OUTPUT)util/gtk/browser.o - endif -endif - ifdef NO_LIBPERL BASIC_CFLAGS += -DNO_LIBPERL else @@ -685,8 +647,6 @@ ifndef V QUIET_LINK = @echo ' ' LINK $@; QUIET_MKDIR = @echo ' ' MKDIR $@; QUIET_GEN = @echo ' ' GEN $@; - QUIET_FLEX = @echo ' ' FLEX $@; - QUIET_BISON = @echo ' ' BISON $@; endif endif @@ -767,28 +727,12 @@ $(OUTPUT)perf.o perf.spec \ $(SCRIPTS) \ : $(OUTPUT)PERF-VERSION-FILE -.SUFFIXES: -.SUFFIXES: .o .c .S .s - -# These two need to be here so that when O= is not used they take precedence -# over the general rule for .o - -$(OUTPUT)util/%-flex.o: $(OUTPUT)util/%-flex.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Iutil/ -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $< - -$(OUTPUT)util/%-bison.o: $(OUTPUT)util/%-bison.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -Iutil/ -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $< - $(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< -$(OUTPUT)%.i: %.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -E $(ALL_CFLAGS) $< $(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS - $(QUIET_CC)$(CC) -o $@ -S $(ALL_CFLAGS) $< + $(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $< $(OUTPUT)%.o: %.S $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< -$(OUTPUT)%.s: %.S - $(QUIET_CC)$(CC) -o $@ -E $(ALL_CFLAGS) $< $(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ @@ -987,7 +931,6 @@ clean: $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(MAKE) -C Documentation/ clean $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS - $(RM) $(OUTPUT)util/*-{bison,flex}* $(python-clean) .PHONY: all install clean strip diff --git a/trunk/tools/perf/builtin-diff.c b/trunk/tools/perf/builtin-diff.c index d29d350fb2b7..4f19513d7dda 100644 --- a/trunk/tools/perf/builtin-diff.c +++ b/trunk/tools/perf/builtin-diff.c @@ -24,11 +24,6 @@ static char diff__default_sort_order[] = "dso,symbol"; static bool force; static bool show_displacement; -struct perf_diff { - struct perf_tool tool; - struct perf_session *session; -}; - static int hists__add_entry(struct hists *self, struct addr_location *al, u64 period) { @@ -37,14 +32,12 @@ static int hists__add_entry(struct hists *self, return -ENOMEM; } -static int diff__process_sample_event(struct perf_tool *tool, +static int diff__process_sample_event(struct perf_tool *tool __used, union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel __used, struct machine *machine) { - struct perf_diff *_diff = container_of(tool, struct perf_diff, tool); - struct perf_session *session = _diff->session; struct addr_location al; if (perf_event__preprocess_sample(event, machine, &al, sample, NULL) < 0) { @@ -56,26 +49,24 @@ static int diff__process_sample_event(struct perf_tool *tool, if (al.filtered || al.sym == NULL) return 0; - if (hists__add_entry(&session->hists, &al, sample->period)) { + if (hists__add_entry(&evsel->hists, &al, sample->period)) { pr_warning("problem incrementing symbol period, skipping event\n"); return -1; } - session->hists.stats.total_period += sample->period; + evsel->hists.stats.total_period += sample->period; return 0; } -static struct perf_diff diff = { - .tool = { - .sample = diff__process_sample_event, - .mmap = perf_event__process_mmap, - .comm = perf_event__process_comm, - .exit = perf_event__process_task, - .fork = perf_event__process_task, - .lost = perf_event__process_lost, - .ordered_samples = true, - .ordering_requires_timestamps = true, - }, +static struct perf_tool perf_diff = { + .sample = diff__process_sample_event, + .mmap = perf_event__process_mmap, + .comm = perf_event__process_comm, + .exit = perf_event__process_task, + .fork = perf_event__process_task, + .lost = perf_event__process_lost, + .ordered_samples = true, + .ordering_requires_timestamps = true, }; static void perf_session__insert_hist_entry_by_name(struct rb_root *root, @@ -116,6 +107,12 @@ static void hists__resort_entries(struct hists *self) self->entries = tmp; } +static void hists__set_positions(struct hists *self) +{ + hists__output_resort(self); + hists__resort_entries(self); +} + static struct hist_entry *hists__find_entry(struct hists *self, struct hist_entry *he) { @@ -149,37 +146,30 @@ static void hists__match(struct hists *older, struct hists *newer) static int __cmd_diff(void) { int ret, i; -#define older (session[0]) -#define newer (session[1]) struct perf_session *session[2]; - older = perf_session__new(input_old, O_RDONLY, force, false, - &diff.tool); - newer = perf_session__new(input_new, O_RDONLY, force, false, - &diff.tool); + session[0] = perf_session__new(input_old, O_RDONLY, force, false, &perf_diff); + session[1] = perf_session__new(input_new, O_RDONLY, force, false, &perf_diff); if (session[0] == NULL || session[1] == NULL) return -ENOMEM; for (i = 0; i < 2; ++i) { - diff.session = session[i]; - ret = perf_session__process_events(session[i], &diff.tool); + ret = perf_session__process_events(session[i], &perf_diff); if (ret) goto out_delete; - hists__output_resort(&session[i]->hists); } + hists__output_resort(&session[1]->hists); if (show_displacement) - hists__resort_entries(&older->hists); + hists__set_positions(&session[0]->hists); - hists__match(&older->hists, &newer->hists); - hists__fprintf(&newer->hists, &older->hists, + hists__match(&session[0]->hists, &session[1]->hists); + hists__fprintf(&session[1]->hists, &session[0]->hists, show_displacement, true, 0, 0, stdout); out_delete: for (i = 0; i < 2; ++i) perf_session__delete(session[i]); return ret; -#undef older -#undef newer } static const char * const diff_usage[] = { diff --git a/trunk/tools/perf/builtin-report.c b/trunk/tools/perf/builtin-report.c index cdae9b2db1cc..8e91c6eba18a 100644 --- a/trunk/tools/perf/builtin-report.c +++ b/trunk/tools/perf/builtin-report.c @@ -40,7 +40,7 @@ struct perf_report { struct perf_tool tool; struct perf_session *session; char const *input_name; - bool force, use_tui, use_gtk, use_stdio; + bool force, use_tui, use_stdio; bool hide_unresolved; bool dont_use_callchains; bool show_full_info; @@ -50,7 +50,6 @@ struct perf_report { const char *pretty_printing_style; symbol_filter_t annotate_init; const char *cpu_list; - const char *symbol_filter_str; DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); }; @@ -374,23 +373,16 @@ static int __cmd_report(struct perf_report *rep) (kernel_map->dso->hit && (kernel_kmap->ref_reloc_sym == NULL || kernel_kmap->ref_reloc_sym->addr == 0))) { - const char *desc = - "As no suitable kallsyms nor vmlinux was found, kernel samples\n" - "can't be resolved."; - - if (kernel_map) { - const struct dso *kdso = kernel_map->dso; - if (!RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION])) { - desc = "If some relocation was applied (e.g. " - "kexec) symbols may be misresolved."; - } - } + const struct dso *kdso = kernel_map->dso; ui__warning( "Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n" "Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n" "Samples in kernel modules can't be resolved as well.\n\n", - desc); + RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION]) ? +"As no suitable kallsyms nor vmlinux was found, kernel samples\n" +"can't be resolved." : +"If some relocation was applied (e.g. kexec) symbols may be misresolved."); } if (dump_trace) { @@ -408,9 +400,6 @@ static int __cmd_report(struct perf_report *rep) list_for_each_entry(pos, &session->evlist->entries, node) { struct hists *hists = &pos->hists; - if (pos->idx == 0) - hists->symbol_filter_str = rep->symbol_filter_str; - hists__collapse_resort(hists); hists__output_resort(hists); nr_samples += hists->stats.nr_events[PERF_RECORD_SAMPLE]; @@ -422,13 +411,8 @@ static int __cmd_report(struct perf_report *rep) } if (use_browser > 0) { - if (use_browser == 1) { - perf_evlist__tui_browse_hists(session->evlist, help, - NULL, NULL, 0); - } else if (use_browser == 2) { - perf_evlist__gtk_browse_hists(session->evlist, help, - NULL, NULL, 0); - } + perf_evlist__tui_browse_hists(session->evlist, help, + NULL, NULL, 0); } else perf_evlist__tty_browse_hists(session->evlist, rep, help); @@ -585,7 +569,6 @@ int cmd_report(int argc, const char **argv, const char *prefix __used) OPT_STRING(0, "pretty", &report.pretty_printing_style, "key", "pretty printing style key: normal raw"), OPT_BOOLEAN(0, "tui", &report.use_tui, "Use the TUI interface"), - OPT_BOOLEAN(0, "gtk", &report.use_gtk, "Use the GTK2 interface"), OPT_BOOLEAN(0, "stdio", &report.use_stdio, "Use the stdio interface"), OPT_STRING('s', "sort", &sort_order, "key[,key2...]", @@ -608,8 +591,6 @@ int cmd_report(int argc, const char **argv, const char *prefix __used) "only consider symbols in these comms"), OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", "only consider these symbols"), - OPT_STRING(0, "symbol-filter", &report.symbol_filter_str, "filter", - "only show symbols that (partially) match with this filter"), OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str, "width[,width...]", "don't try to adjust column width, use these fixed values"), @@ -643,8 +624,6 @@ int cmd_report(int argc, const char **argv, const char *prefix __used) use_browser = 0; else if (report.use_tui) use_browser = 1; - else if (report.use_gtk) - use_browser = 2; if (report.inverted_callchain) callchain_param.order = ORDER_CALLER; @@ -681,10 +660,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __used) } if (strcmp(report.input_name, "-") != 0) { - if (report.use_gtk) - perf_gtk_setup_browser(argc, argv, true); - else - setup_browser(true); + setup_browser(true); } else { use_browser = 0; } @@ -733,16 +709,11 @@ int cmd_report(int argc, const char **argv, const char *prefix __used) } else symbol_conf.exclude_other = false; - if (argc) { - /* - * Special case: if there's an argument left then assume that - * it's a symbol filter: - */ - if (argc > 1) - usage_with_options(report_usage, options); - - report.symbol_filter_str = argv[0]; - } + /* + * Any (unrecognized) arguments left? + */ + if (argc) + usage_with_options(report_usage, options); sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout); diff --git a/trunk/tools/perf/builtin-sched.c b/trunk/tools/perf/builtin-sched.c index 1cad3af4bf4c..fb8b5f83b4a0 100644 --- a/trunk/tools/perf/builtin-sched.c +++ b/trunk/tools/perf/builtin-sched.c @@ -17,7 +17,6 @@ #include "util/debug.h" #include -#include #include #include diff --git a/trunk/tools/perf/builtin-stat.c b/trunk/tools/perf/builtin-stat.c index c941bb640f49..ea40e4e8b227 100644 --- a/trunk/tools/perf/builtin-stat.c +++ b/trunk/tools/perf/builtin-stat.c @@ -296,7 +296,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel, if (system_wide) return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, group, group_fd); - if (!target_pid && !target_tid && (!group || evsel == first)) { + if (!target_pid && !target_tid) { attr->disabled = 1; attr->enable_on_exec = 1; } diff --git a/trunk/tools/perf/builtin-test.c b/trunk/tools/perf/builtin-test.c index 223ffdcc0fd8..3e087ce8daa6 100644 --- a/trunk/tools/perf/builtin-test.c +++ b/trunk/tools/perf/builtin-test.c @@ -13,7 +13,6 @@ #include "util/parse-events.h" #include "util/symbol.h" #include "util/thread_map.h" -#include "util/pmu.h" #include "../../include/linux/hw_breakpoint.h" #include @@ -651,7 +650,7 @@ static int test__checkevent_raw(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 0x1a == evsel->attr.config); + TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); return 0; } @@ -678,24 +677,6 @@ static int test__checkevent_symbolic_name(struct perf_evlist *evlist) return 0; } -static int test__checkevent_symbolic_name_config(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = list_entry(evlist->entries.next, - struct perf_evsel, node); - - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong period", - 100000 == evsel->attr.sample_period); - TEST_ASSERT_VAL("wrong config1", - 0 == evsel->attr.config1); - TEST_ASSERT_VAL("wrong config2", - 1 == evsel->attr.config2); - return 0; -} - static int test__checkevent_symbolic_alias(struct perf_evlist *evlist) { struct perf_evsel *evsel = list_entry(evlist->entries.next, @@ -851,28 +832,6 @@ static int test__checkevent_symbolic_name_modifier(struct perf_evlist *evlist) return test__checkevent_symbolic_name(evlist); } -static int test__checkevent_exclude_host_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = list_entry(evlist->entries.next, - struct perf_evsel, node); - - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - - return test__checkevent_symbolic_name(evlist); -} - -static int test__checkevent_exclude_guest_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = list_entry(evlist->entries.next, - struct perf_evsel, node); - - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - - return test__checkevent_symbolic_name(evlist); -} - static int test__checkevent_symbolic_alias_modifier(struct perf_evlist *evlist) { struct perf_evsel *evsel = list_entry(evlist->entries.next, @@ -899,115 +858,6 @@ static int test__checkevent_genhw_modifier(struct perf_evlist *evlist) return test__checkevent_genhw(evlist); } -static int test__checkevent_breakpoint_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = list_entry(evlist->entries.next, - struct perf_evsel, node); - - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - - return test__checkevent_breakpoint(evlist); -} - -static int test__checkevent_breakpoint_x_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = list_entry(evlist->entries.next, - struct perf_evsel, node); - - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - - return test__checkevent_breakpoint_x(evlist); -} - -static int test__checkevent_breakpoint_r_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = list_entry(evlist->entries.next, - struct perf_evsel, node); - - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); - - return test__checkevent_breakpoint_r(evlist); -} - -static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = list_entry(evlist->entries.next, - struct perf_evsel, node); - - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); - - return test__checkevent_breakpoint_w(evlist); -} - -static int test__checkevent_pmu(struct perf_evlist *evlist) -{ - - struct perf_evsel *evsel = list_entry(evlist->entries.next, - struct perf_evsel, node); - - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 10 == evsel->attr.config); - TEST_ASSERT_VAL("wrong config1", 1 == evsel->attr.config1); - TEST_ASSERT_VAL("wrong config2", 3 == evsel->attr.config2); - TEST_ASSERT_VAL("wrong period", 1000 == evsel->attr.sample_period); - - return 0; -} - -static int test__checkevent_list(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel; - - TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries); - - /* r1 */ - evsel = list_entry(evlist->entries.next, struct perf_evsel, node); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); - TEST_ASSERT_VAL("wrong config1", 0 == evsel->attr.config1); - TEST_ASSERT_VAL("wrong config2", 0 == evsel->attr.config2); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - - /* syscalls:sys_enter_open:k */ - evsel = list_entry(evsel->node.next, struct perf_evsel, node); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); - TEST_ASSERT_VAL("wrong sample_type", - (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) == - evsel->attr.sample_type); - TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - - /* 1:1:hp */ - evsel = list_entry(evsel->node.next, struct perf_evsel, node); - TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); - - return 0; -} - static struct test__event_st { const char *name; __u32 type; @@ -1022,7 +872,7 @@ static struct test__event_st { .check = test__checkevent_tracepoint_multi, }, { - .name = "r1a", + .name = "r1", .check = test__checkevent_raw, }, { @@ -1033,10 +883,6 @@ static struct test__event_st { .name = "instructions", .check = test__checkevent_symbolic_name, }, - { - .name = "cycles/period=100000,config2/", - .check = test__checkevent_symbolic_name_config, - }, { .name = "faults", .check = test__checkevent_symbolic_alias, @@ -1070,7 +916,7 @@ static struct test__event_st { .check = test__checkevent_tracepoint_multi_modifier, }, { - .name = "r1a:kp", + .name = "r1:kp", .check = test__checkevent_raw_modifier, }, { @@ -1089,38 +935,6 @@ static struct test__event_st { .name = "L1-dcache-load-miss:kp", .check = test__checkevent_genhw_modifier, }, - { - .name = "mem:0:u", - .check = test__checkevent_breakpoint_modifier, - }, - { - .name = "mem:0:x:k", - .check = test__checkevent_breakpoint_x_modifier, - }, - { - .name = "mem:0:r:hp", - .check = test__checkevent_breakpoint_r_modifier, - }, - { - .name = "mem:0:w:up", - .check = test__checkevent_breakpoint_w_modifier, - }, - { - .name = "cpu/config=10,config1,config2=3,period=1000/u", - .check = test__checkevent_pmu, - }, - { - .name = "r1,syscalls:sys_enter_open:k,1:1:hp", - .check = test__checkevent_list, - }, - { - .name = "instructions:G", - .check = test__checkevent_exclude_host_modifier, - }, - { - .name = "instructions:H", - .check = test__checkevent_exclude_guest_modifier, - }, }; #define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st)) @@ -1146,9 +960,10 @@ static int test__parse_events(void) } ret = e->check(evlist); - perf_evlist__delete(evlist); if (ret) break; + + perf_evlist__delete(evlist); } return ret; @@ -1647,11 +1462,6 @@ static int test__rdpmc(void) #endif -static int test__perf_pmu(void) -{ - return perf_pmu__test(); -} - static struct test { const char *desc; int (*func)(void); @@ -1686,10 +1496,6 @@ static struct test { .desc = "Validate PERF_RECORD_* events & perf_sample fields", .func = test__PERF_RECORD, }, - { - .desc = "Test perf pmu format parsing", - .func = test__perf_pmu, - }, { .func = NULL, }, diff --git a/trunk/tools/perf/builtin-top.c b/trunk/tools/perf/builtin-top.c index 8ef59f8262bb..e3c63aef8efc 100644 --- a/trunk/tools/perf/builtin-top.c +++ b/trunk/tools/perf/builtin-top.c @@ -42,7 +42,6 @@ #include "util/debug.h" #include -#include #include #include @@ -60,7 +59,6 @@ #include #include #include -#include #include #include @@ -164,40 +162,12 @@ static void __zero_source_counters(struct hist_entry *he) symbol__annotate_zero_histograms(sym); } -static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip) -{ - struct utsname uts; - int err = uname(&uts); - - ui__warning("Out of bounds address found:\n\n" - "Addr: %" PRIx64 "\n" - "DSO: %s %c\n" - "Map: %" PRIx64 "-%" PRIx64 "\n" - "Symbol: %" PRIx64 "-%" PRIx64 " %c %s\n" - "Arch: %s\n" - "Kernel: %s\n" - "Tools: %s\n\n" - "Not all samples will be on the annotation output.\n\n" - "Please report to linux-kernel@vger.kernel.org\n", - ip, map->dso->long_name, dso__symtab_origin(map->dso), - map->start, map->end, sym->start, sym->end, - sym->binding == STB_GLOBAL ? 'g' : - sym->binding == STB_LOCAL ? 'l' : 'w', sym->name, - err ? "[unknown]" : uts.machine, - err ? "[unknown]" : uts.release, perf_version_string); - if (use_browser <= 0) - sleep(5); - - map->erange_warned = true; -} - static void perf_top__record_precise_ip(struct perf_top *top, struct hist_entry *he, int counter, u64 ip) { struct annotation *notes; struct symbol *sym; - int err; if (he == NULL || he->ms.sym == NULL || ((top->sym_filter_entry == NULL || @@ -219,12 +189,9 @@ static void perf_top__record_precise_ip(struct perf_top *top, } ip = he->ms.map->map_ip(he->ms.map, ip); - err = symbol__inc_addr_samples(sym, he->ms.map, counter, ip); + symbol__inc_addr_samples(sym, he->ms.map, counter, ip); pthread_mutex_unlock(¬es->lock); - - if (err == -ERANGE && !he->ms.map->erange_warned) - ui__warn_map_erange(he->ms.map, sym, ip); } static void perf_top__show_details(struct perf_top *top) @@ -648,7 +615,6 @@ static void *display_thread(void *arg) /* Tag samples to be skipped. */ static const char *skip_symbols[] = { - "intel_idle", "default_idle", "native_safe_halt", "cpu_idle", diff --git a/trunk/tools/perf/config/feature-tests.mak b/trunk/tools/perf/config/feature-tests.mak index d9084e03ce56..6170fd2531b5 100644 --- a/trunk/tools/perf/config/feature-tests.mak +++ b/trunk/tools/perf/config/feature-tests.mak @@ -65,21 +65,6 @@ int main(void) endef endif -ifndef NO_GTK2 -define SOURCE_GTK2 -#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" -#include -#pragma GCC diagnostic error \"-Wstrict-prototypes\" - -int main(int argc, char *argv[]) -{ - gtk_init(&argc, &argv); - - return 0; -} -endef -endif - ifndef NO_LIBPERL define SOURCE_PERL_EMBED #include diff --git a/trunk/tools/perf/perf-archive.sh b/trunk/tools/perf/perf-archive.sh index 95b6f8b6177a..677e59d62a8d 100644 --- a/trunk/tools/perf/perf-archive.sh +++ b/trunk/tools/perf/perf-archive.sh @@ -29,14 +29,13 @@ if [ ! -s $BUILDIDS ] ; then fi MANIFEST=$(mktemp /tmp/perf-archive-manifest.XXXXXX) -PERF_BUILDID_LINKDIR=$(readlink -f $PERF_BUILDID_DIR)/ cut -d ' ' -f 1 $BUILDIDS | \ while read build_id ; do linkname=$PERF_BUILDID_DIR.build-id/${build_id:0:2}/${build_id:2} filename=$(readlink -f $linkname) echo ${linkname#$PERF_BUILDID_DIR} >> $MANIFEST - echo ${filename#$PERF_BUILDID_LINKDIR} >> $MANIFEST + echo ${filename#$PERF_BUILDID_DIR} >> $MANIFEST done tar cfj $PERF_DATA.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST diff --git a/trunk/tools/perf/util/annotate.c b/trunk/tools/perf/util/annotate.c index 08c6d138a655..e5a462f1d07c 100644 --- a/trunk/tools/perf/util/annotate.c +++ b/trunk/tools/perf/util/annotate.c @@ -28,8 +28,8 @@ int symbol__annotate_init(struct map *map __used, struct symbol *sym) int symbol__alloc_hist(struct symbol *sym) { struct annotation *notes = symbol__annotation(sym); - const size_t size = sym->end - sym->start + 1; - size_t sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(u64)); + size_t sizeof_sym_hist = (sizeof(struct sym_hist) + + (sym->end - sym->start) * sizeof(u64)); notes->src = zalloc(sizeof(*notes->src) + symbol_conf.nr_events * sizeof_sym_hist); if (notes->src == NULL) @@ -64,8 +64,8 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map, pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); - if (addr < sym->start || addr > sym->end) - return -ERANGE; + if (addr >= sym->end) + return 0; offset = addr - sym->start; h = annotation__histogram(notes, evidx); @@ -408,7 +408,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, if (!notes->src->lines) return -1; - start = map__rip_2objdump(map, sym->start); + start = map->unmap_ip(map, sym->start); for (i = 0; i < len; i++) { char *path = NULL; @@ -561,12 +561,16 @@ void symbol__annotate_decay_histogram(struct symbol *sym, int evidx) { struct annotation *notes = symbol__annotation(sym); struct sym_hist *h = annotation__histogram(notes, evidx); - int len = sym->end - sym->start, offset; + struct objdump_line *pos; + int len = sym->end - sym->start; h->sum = 0; - for (offset = 0; offset < len; ++offset) { - h->addr[offset] = h->addr[offset] * 7 / 8; - h->sum += h->addr[offset]; + + list_for_each_entry(pos, ¬es->src->source, node) { + if (pos->offset != -1 && pos->offset < len) { + h->addr[pos->offset] = h->addr[pos->offset] * 7 / 8; + h->sum += h->addr[pos->offset]; + } } } diff --git a/trunk/tools/perf/util/cache.h b/trunk/tools/perf/util/cache.h index 8dd224df3e54..fc5e5a09d5b9 100644 --- a/trunk/tools/perf/util/cache.h +++ b/trunk/tools/perf/util/cache.h @@ -45,18 +45,6 @@ void setup_browser(bool fallback_to_pager); void exit_browser(bool wait_for_ok); #endif -#ifdef NO_GTK2_SUPPORT -static inline void perf_gtk_setup_browser(int argc __used, const char *argv[] __used, bool fallback_to_pager) -{ - if (fallback_to_pager) - setup_pager(); -} -static inline void perf_gtk_exit_browser(bool wait_for_ok __used) {} -#else -void perf_gtk_setup_browser(int argc, const char *argv[], bool fallback_to_pager); -void perf_gtk_exit_browser(bool wait_for_ok); -#endif - char *alias_lookup(const char *alias); int split_cmdline(char *cmdline, const char ***argv); diff --git a/trunk/tools/perf/util/evlist.c b/trunk/tools/perf/util/evlist.c index 1986d8051bd1..159263d17c2d 100644 --- a/trunk/tools/perf/util/evlist.c +++ b/trunk/tools/perf/util/evlist.c @@ -51,15 +51,13 @@ struct perf_evlist *perf_evlist__new(struct cpu_map *cpus, void perf_evlist__config_attrs(struct perf_evlist *evlist, struct perf_record_opts *opts) { - struct perf_evsel *evsel, *first; + struct perf_evsel *evsel; if (evlist->cpus->map[0] < 0) opts->no_inherit = true; - first = list_entry(evlist->entries.next, struct perf_evsel, node); - list_for_each_entry(evsel, &evlist->entries, node) { - perf_evsel__config(evsel, opts, first); + perf_evsel__config(evsel, opts); if (evlist->nr_entries > 1) evsel->attr.sample_type |= PERF_SAMPLE_ID; diff --git a/trunk/tools/perf/util/evsel.c b/trunk/tools/perf/util/evsel.c index 8c13dbcb84b9..f421f7cbc0d3 100644 --- a/trunk/tools/perf/util/evsel.c +++ b/trunk/tools/perf/util/evsel.c @@ -34,7 +34,7 @@ int __perf_evsel__sample_size(u64 sample_type) return size; } -void hists__init(struct hists *hists) +static void hists__init(struct hists *hists) { memset(hists, 0, sizeof(*hists)); hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT; @@ -63,8 +63,7 @@ struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx) return evsel; } -void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, - struct perf_evsel *first) +void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts) { struct perf_event_attr *attr = &evsel->attr; int track = !evsel->idx; /* only the first counter needs these */ @@ -135,8 +134,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, attr->mmap = track; attr->comm = track; - if (!opts->target_pid && !opts->target_tid && !opts->system_wide && - (!opts->group || evsel == first)) { + if (!opts->target_pid && !opts->target_tid && !opts->system_wide) { attr->disabled = 1; attr->enable_on_exec = 1; } @@ -580,8 +578,6 @@ int perf_event__parse_sample(const union perf_event *event, u64 type, return -EFAULT; data->raw_data = (void *) pdata; - - array = (void *)array + data->raw_size + sizeof(u32); } if (type & PERF_SAMPLE_BRANCH_STACK) { diff --git a/trunk/tools/perf/util/evsel.h b/trunk/tools/perf/util/evsel.h index 3d6b3e4cb66b..326b8e4d5035 100644 --- a/trunk/tools/perf/util/evsel.h +++ b/trunk/tools/perf/util/evsel.h @@ -80,8 +80,7 @@ void perf_evsel__exit(struct perf_evsel *evsel); void perf_evsel__delete(struct perf_evsel *evsel); void perf_evsel__config(struct perf_evsel *evsel, - struct perf_record_opts *opts, - struct perf_evsel *first); + struct perf_record_opts *opts); int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads); @@ -170,6 +169,4 @@ static inline int perf_evsel__sample_size(struct perf_evsel *evsel) return __perf_evsel__sample_size(evsel->attr.sample_type); } -void hists__init(struct hists *hists); - #endif /* __PERF_EVSEL_H */ diff --git a/trunk/tools/perf/util/gtk/browser.c b/trunk/tools/perf/util/gtk/browser.c deleted file mode 100644 index 258352a2356c..000000000000 --- a/trunk/tools/perf/util/gtk/browser.c +++ /dev/null @@ -1,189 +0,0 @@ -#include "../evlist.h" -#include "../cache.h" -#include "../evsel.h" -#include "../sort.h" -#include "../hist.h" -#include "gtk.h" - -#include - -#define MAX_COLUMNS 32 - -void perf_gtk_setup_browser(int argc, const char *argv[], - bool fallback_to_pager __used) -{ - gtk_init(&argc, (char ***)&argv); -} - -void perf_gtk_exit_browser(bool wait_for_ok __used) -{ - gtk_main_quit(); -} - -static void perf_gtk_signal(int sig) -{ - psignal(sig, "perf"); - gtk_main_quit(); -} - -static void perf_gtk_resize_window(GtkWidget *window) -{ - GdkRectangle rect; - GdkScreen *screen; - int monitor; - int height; - int width; - - screen = gtk_widget_get_screen(window); - - monitor = gdk_screen_get_monitor_at_window(screen, window->window); - - gdk_screen_get_monitor_geometry(screen, monitor, &rect); - - width = rect.width * 3 / 4; - height = rect.height * 3 / 4; - - gtk_window_resize(GTK_WINDOW(window), width, height); -} - -static void perf_gtk_show_hists(GtkWidget *window, struct hists *hists) -{ - GType col_types[MAX_COLUMNS]; - GtkCellRenderer *renderer; - struct sort_entry *se; - GtkListStore *store; - struct rb_node *nd; - u64 total_period; - GtkWidget *view; - int col_idx; - int nr_cols; - - nr_cols = 0; - - /* The percentage column */ - col_types[nr_cols++] = G_TYPE_STRING; - - list_for_each_entry(se, &hist_entry__sort_list, list) { - if (se->elide) - continue; - - col_types[nr_cols++] = G_TYPE_STRING; - } - - store = gtk_list_store_newv(nr_cols, col_types); - - view = gtk_tree_view_new(); - - renderer = gtk_cell_renderer_text_new(); - - col_idx = 0; - - /* The percentage column */ - gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), - -1, "Overhead (%)", - renderer, "text", - col_idx++, NULL); - - list_for_each_entry(se, &hist_entry__sort_list, list) { - if (se->elide) - continue; - - gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), - -1, se->se_header, - renderer, "text", - col_idx++, NULL); - } - - gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store)); - - g_object_unref(GTK_TREE_MODEL(store)); - - total_period = hists->stats.total_period; - - for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { - struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); - GtkTreeIter iter; - double percent; - char s[512]; - - if (h->filtered) - continue; - - gtk_list_store_append(store, &iter); - - col_idx = 0; - - percent = (h->period * 100.0) / total_period; - - snprintf(s, ARRAY_SIZE(s), "%.2f", percent); - - gtk_list_store_set(store, &iter, col_idx++, s, -1); - - list_for_each_entry(se, &hist_entry__sort_list, list) { - if (se->elide) - continue; - - se->se_snprintf(h, s, ARRAY_SIZE(s), - hists__col_len(hists, se->se_width_idx)); - - gtk_list_store_set(store, &iter, col_idx++, s, -1); - } - } - - gtk_container_add(GTK_CONTAINER(window), view); -} - -int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, - const char *help __used, - void (*timer) (void *arg)__used, - void *arg __used, int delay_secs __used) -{ - struct perf_evsel *pos; - GtkWidget *notebook; - GtkWidget *window; - - signal(SIGSEGV, perf_gtk_signal); - signal(SIGFPE, perf_gtk_signal); - signal(SIGINT, perf_gtk_signal); - signal(SIGQUIT, perf_gtk_signal); - signal(SIGTERM, perf_gtk_signal); - - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - - gtk_window_set_title(GTK_WINDOW(window), "perf report"); - - g_signal_connect(window, "delete_event", gtk_main_quit, NULL); - - notebook = gtk_notebook_new(); - - list_for_each_entry(pos, &evlist->entries, node) { - struct hists *hists = &pos->hists; - const char *evname = event_name(pos); - GtkWidget *scrolled_window; - GtkWidget *tab_label; - - scrolled_window = gtk_scrolled_window_new(NULL, NULL); - - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - - perf_gtk_show_hists(scrolled_window, hists); - - tab_label = gtk_label_new(evname); - - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_window, tab_label); - } - - gtk_container_add(GTK_CONTAINER(window), notebook); - - gtk_widget_show_all(window); - - perf_gtk_resize_window(window); - - gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); - - gtk_main(); - - return 0; -} diff --git a/trunk/tools/perf/util/gtk/gtk.h b/trunk/tools/perf/util/gtk/gtk.h deleted file mode 100644 index 75177ee04032..000000000000 --- a/trunk/tools/perf/util/gtk/gtk.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _PERF_GTK_H_ -#define _PERF_GTK_H_ 1 - -#pragma GCC diagnostic ignored "-Wstrict-prototypes" -#include -#pragma GCC diagnostic error "-Wstrict-prototypes" - -#endif /* _PERF_GTK_H_ */ diff --git a/trunk/tools/perf/util/header.c b/trunk/tools/perf/util/header.c index 4c7c2d73251f..fcd9cf3ea63e 100644 --- a/trunk/tools/perf/util/header.c +++ b/trunk/tools/perf/util/header.c @@ -1177,7 +1177,7 @@ static void print_event_desc(struct perf_header *ph, int fd, FILE *fp) goto error; msz = sizeof(attr); - if (sz < msz) + if (sz < (ssize_t)msz) msz = sz; for (i = 0 ; i < nre; i++) { diff --git a/trunk/tools/perf/util/hist.c b/trunk/tools/perf/util/hist.c index 9f6d630d5316..3dc99a9b71f5 100644 --- a/trunk/tools/perf/util/hist.c +++ b/trunk/tools/perf/util/hist.c @@ -10,14 +10,11 @@ static bool hists__filter_entry_by_dso(struct hists *hists, struct hist_entry *he); static bool hists__filter_entry_by_thread(struct hists *hists, struct hist_entry *he); -static bool hists__filter_entry_by_symbol(struct hists *hists, - struct hist_entry *he); enum hist_filter { HIST_FILTER__DSO, HIST_FILTER__THREAD, HIST_FILTER__PARENT, - HIST_FILTER__SYMBOL, }; struct callchain_param callchain_param = { @@ -256,18 +253,6 @@ static struct hist_entry *add_hist_entry(struct hists *hists, if (!cmp) { he->period += period; ++he->nr_events; - - /* If the map of an existing hist_entry has - * become out-of-date due to an exec() or - * similar, update it. Otherwise we will - * mis-adjust symbol addresses when computing - * the history counter to increment. - */ - if (he->ms.map != entry->ms.map) { - he->ms.map = entry->ms.map; - if (he->ms.map) - he->ms.map->referenced = true; - } goto out; } @@ -435,7 +420,6 @@ static void hists__apply_filters(struct hists *hists, struct hist_entry *he) { hists__filter_entry_by_dso(hists, he); hists__filter_entry_by_thread(hists, he); - hists__filter_entry_by_symbol(hists, he); } static void __hists__collapse_resort(struct hists *hists, bool threaded) @@ -619,7 +603,7 @@ static void init_rem_hits(void) rem_hits.ms.sym = rem_sq_bracket; } -static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root, +static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self, u64 total_samples, int depth, int depth_mask, int left_margin) { @@ -627,16 +611,21 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root, struct callchain_node *child; struct callchain_list *chain; int new_depth_mask = depth_mask; + u64 new_total; u64 remaining; size_t ret = 0; int i; uint entries_printed = 0; - remaining = total_samples; + if (callchain_param.mode == CHAIN_GRAPH_REL) + new_total = self->children_hit; + else + new_total = total_samples; + + remaining = new_total; - node = rb_first(root); + node = rb_first(&self->rb_root); while (node) { - u64 new_total; u64 cumul; child = rb_entry(node, struct callchain_node, rb_node); @@ -664,17 +653,11 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root, list_for_each_entry(chain, &child->val, list) { ret += ipchain__fprintf_graph(fp, chain, depth, new_depth_mask, i++, - total_samples, + new_total, cumul, left_margin); } - - if (callchain_param.mode == CHAIN_GRAPH_REL) - new_total = child->children_hit; - else - new_total = total_samples; - - ret += __callchain__fprintf_graph(fp, &child->rb_root, new_total, + ret += __callchain__fprintf_graph(fp, child, new_total, depth + 1, new_depth_mask | (1 << depth), left_margin); @@ -684,75 +667,61 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root, } if (callchain_param.mode == CHAIN_GRAPH_REL && - remaining && remaining != total_samples) { + remaining && remaining != new_total) { if (!rem_sq_bracket) return ret; new_depth_mask &= ~(1 << (depth - 1)); + ret += ipchain__fprintf_graph(fp, &rem_hits, depth, - new_depth_mask, 0, total_samples, + new_depth_mask, 0, new_total, remaining, left_margin); } return ret; } -static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root, +static size_t callchain__fprintf_graph(FILE *fp, struct callchain_node *self, u64 total_samples, int left_margin) { - struct callchain_node *cnode; struct callchain_list *chain; - u32 entries_printed = 0; bool printed = false; - struct rb_node *node; int i = 0; - int ret; + int ret = 0; + u32 entries_printed = 0; - /* - * If have one single callchain root, don't bother printing - * its percentage (100 % in fractal mode and the same percentage - * than the hist in graph mode). This also avoid one level of column. - */ - node = rb_first(root); - if (node && !rb_next(node)) { - cnode = rb_entry(node, struct callchain_node, rb_node); - list_for_each_entry(chain, &cnode->val, list) { - /* - * If we sort by symbol, the first entry is the same than - * the symbol. No need to print it otherwise it appears as - * displayed twice. - */ - if (!i++ && sort__first_dimension == SORT_SYM) - continue; - if (!printed) { - ret += callchain__fprintf_left_margin(fp, left_margin); - ret += fprintf(fp, "|\n"); - ret += callchain__fprintf_left_margin(fp, left_margin); - ret += fprintf(fp, "---"); - left_margin += 3; - printed = true; - } else - ret += callchain__fprintf_left_margin(fp, left_margin); - - if (chain->ms.sym) - ret += fprintf(fp, " %s\n", chain->ms.sym->name); - else - ret += fprintf(fp, " %p\n", (void *)(long)chain->ip); + list_for_each_entry(chain, &self->val, list) { + if (!i++ && sort__first_dimension == SORT_SYM) + continue; - if (++entries_printed == callchain_param.print_limit) - break; - } - root = &cnode->rb_root; + if (!printed) { + ret += callchain__fprintf_left_margin(fp, left_margin); + ret += fprintf(fp, "|\n"); + ret += callchain__fprintf_left_margin(fp, left_margin); + ret += fprintf(fp, "---"); + + left_margin += 3; + printed = true; + } else + ret += callchain__fprintf_left_margin(fp, left_margin); + + if (chain->ms.sym) + ret += fprintf(fp, " %s\n", chain->ms.sym->name); + else + ret += fprintf(fp, " %p\n", (void *)(long)chain->ip); + + if (++entries_printed == callchain_param.print_limit) + break; } - return __callchain__fprintf_graph(fp, root, total_samples, - 1, 1, left_margin); + ret += __callchain__fprintf_graph(fp, self, total_samples, 1, 1, left_margin); + + return ret; } -static size_t __callchain__fprintf_flat(FILE *fp, - struct callchain_node *self, - u64 total_samples) +static size_t callchain__fprintf_flat(FILE *fp, struct callchain_node *self, + u64 total_samples) { struct callchain_list *chain; size_t ret = 0; @@ -760,7 +729,7 @@ static size_t __callchain__fprintf_flat(FILE *fp, if (!self) return 0; - ret += __callchain__fprintf_flat(fp, self->parent, total_samples); + ret += callchain__fprintf_flat(fp, self->parent, total_samples); list_for_each_entry(chain, &self->val, list) { @@ -776,58 +745,44 @@ static size_t __callchain__fprintf_flat(FILE *fp, return ret; } -static size_t callchain__fprintf_flat(FILE *fp, struct rb_root *self, - u64 total_samples) +static size_t hist_entry_callchain__fprintf(struct hist_entry *he, + u64 total_samples, int left_margin, + FILE *fp) { - size_t ret = 0; - u32 entries_printed = 0; struct rb_node *rb_node; struct callchain_node *chain; + size_t ret = 0; + u32 entries_printed = 0; - rb_node = rb_first(self); + rb_node = rb_first(&he->sorted_chain); while (rb_node) { double percent; chain = rb_entry(rb_node, struct callchain_node, rb_node); percent = chain->hit * 100.0 / total_samples; - - ret = percent_color_fprintf(fp, " %6.2f%%\n", percent); - ret += __callchain__fprintf_flat(fp, chain, total_samples); + switch (callchain_param.mode) { + case CHAIN_FLAT: + ret += percent_color_fprintf(fp, " %6.2f%%\n", + percent); + ret += callchain__fprintf_flat(fp, chain, total_samples); + break; + case CHAIN_GRAPH_ABS: /* Falldown */ + case CHAIN_GRAPH_REL: + ret += callchain__fprintf_graph(fp, chain, total_samples, + left_margin); + case CHAIN_NONE: + default: + break; + } ret += fprintf(fp, "\n"); if (++entries_printed == callchain_param.print_limit) break; - rb_node = rb_next(rb_node); } return ret; } -static size_t hist_entry_callchain__fprintf(struct hist_entry *he, - u64 total_samples, int left_margin, - FILE *fp) -{ - switch (callchain_param.mode) { - case CHAIN_GRAPH_REL: - return callchain__fprintf_graph(fp, &he->sorted_chain, he->period, - left_margin); - break; - case CHAIN_GRAPH_ABS: - return callchain__fprintf_graph(fp, &he->sorted_chain, total_samples, - left_margin); - break; - case CHAIN_FLAT: - return callchain__fprintf_flat(fp, &he->sorted_chain, total_samples); - break; - case CHAIN_NONE: - break; - default: - pr_err("Bad callchain mode\n"); - } - - return 0; -} - void hists__output_recalc_col_len(struct hists *hists, int max_rows) { struct rb_node *next = rb_first(&hists->entries); @@ -932,9 +887,9 @@ static int hist_entry__pcnt_snprintf(struct hist_entry *he, char *s, diff = new_percent - old_percent; if (fabs(diff) >= 0.01) - scnprintf(bf, sizeof(bf), "%+4.2F%%", diff); + ret += scnprintf(bf, sizeof(bf), "%+4.2F%%", diff); else - scnprintf(bf, sizeof(bf), " "); + ret += scnprintf(bf, sizeof(bf), " "); if (sep) ret += scnprintf(s + ret, size - ret, "%c%s", *sep, bf); @@ -943,9 +898,9 @@ static int hist_entry__pcnt_snprintf(struct hist_entry *he, char *s, if (show_displacement) { if (displacement) - scnprintf(bf, sizeof(bf), "%+4ld", displacement); + ret += scnprintf(bf, sizeof(bf), "%+4ld", displacement); else - scnprintf(bf, sizeof(bf), " "); + ret += scnprintf(bf, sizeof(bf), " "); if (sep) ret += scnprintf(s + ret, size - ret, "%c%s", *sep, bf); @@ -1292,37 +1247,6 @@ void hists__filter_by_thread(struct hists *hists) } } -static bool hists__filter_entry_by_symbol(struct hists *hists, - struct hist_entry *he) -{ - if (hists->symbol_filter_str != NULL && - (!he->ms.sym || strstr(he->ms.sym->name, - hists->symbol_filter_str) == NULL)) { - he->filtered |= (1 << HIST_FILTER__SYMBOL); - return true; - } - - return false; -} - -void hists__filter_by_symbol(struct hists *hists) -{ - struct rb_node *nd; - - hists->nr_entries = hists->stats.total_period = 0; - hists->stats.nr_events[PERF_RECORD_SAMPLE] = 0; - hists__reset_col_len(hists); - - for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { - struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); - - if (hists__filter_entry_by_symbol(hists, h)) - continue; - - hists__remove_entry_filter(hists, h, HIST_FILTER__SYMBOL); - } -} - int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip) { return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip); diff --git a/trunk/tools/perf/util/hist.h b/trunk/tools/perf/util/hist.h index 2cae9df40e04..9413f3e31fea 100644 --- a/trunk/tools/perf/util/hist.h +++ b/trunk/tools/perf/util/hist.h @@ -62,7 +62,6 @@ struct hists { const struct thread *thread_filter; const struct dso *dso_filter; const char *uid_filter_str; - const char *symbol_filter_str; pthread_mutex_t lock; struct events_stats stats; u64 event_stream; @@ -108,7 +107,6 @@ int hist_entry__annotate(struct hist_entry *self, size_t privsize); void hists__filter_by_dso(struct hists *hists); void hists__filter_by_thread(struct hists *hists); -void hists__filter_by_symbol(struct hists *hists); u16 hists__col_len(struct hists *self, enum hist_column col); void hists__set_col_len(struct hists *self, enum hist_column col, u16 len); @@ -147,23 +145,6 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, int refresh); #endif -#ifdef NO_GTK2_SUPPORT -static inline -int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __used, - const char *help __used, - void(*timer)(void *arg) __used, - void *arg __used, - int refresh __used) -{ - return 0; -} - -#else -int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help, - void(*timer)(void *arg), void *arg, - int refresh); -#endif - unsigned int hists__sort_list_width(struct hists *self); #endif /* __PERF_HIST_H */ diff --git a/trunk/tools/perf/util/include/linux/export.h b/trunk/tools/perf/util/include/linux/module.h similarity index 100% rename from trunk/tools/perf/util/include/linux/export.h rename to trunk/tools/perf/util/include/linux/module.h diff --git a/trunk/tools/perf/util/map.c b/trunk/tools/perf/util/map.c index 35ae56864e4f..dea6d1c1a954 100644 --- a/trunk/tools/perf/util/map.c +++ b/trunk/tools/perf/util/map.c @@ -38,7 +38,6 @@ void map__init(struct map *self, enum map_type type, RB_CLEAR_NODE(&self->rb_node); self->groups = NULL; self->referenced = false; - self->erange_warned = false; } struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, diff --git a/trunk/tools/perf/util/map.h b/trunk/tools/perf/util/map.h index 81371bad4ef0..b100c20b7f94 100644 --- a/trunk/tools/perf/util/map.h +++ b/trunk/tools/perf/util/map.h @@ -33,7 +33,6 @@ struct map { u64 end; u8 /* enum map_type */ type; bool referenced; - bool erange_warned; u32 priv; u64 pgoff; diff --git a/trunk/tools/perf/util/parse-events.c b/trunk/tools/perf/util/parse-events.c index 5b3a0ef4e232..c7a6f6faf91e 100644 --- a/trunk/tools/perf/util/parse-events.c +++ b/trunk/tools/perf/util/parse-events.c @@ -11,10 +11,6 @@ #include "cache.h" #include "header.h" #include "debugfs.h" -#include "parse-events-flex.h" -#include "pmu.h" - -#define MAX_NAME_LEN 100 struct event_symbol { u8 type; @@ -23,8 +19,11 @@ struct event_symbol { const char *alias; }; -int parse_events_parse(struct list_head *list, struct list_head *list_tmp, - int *idx); +enum event_result { + EVT_FAILED, + EVT_HANDLED, + EVT_HANDLED_ALL +}; #define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x #define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x @@ -355,24 +354,7 @@ const char *__event_name(int type, u64 config) return "unknown"; } -static int add_event(struct list_head *list, int *idx, - struct perf_event_attr *attr, char *name) -{ - struct perf_evsel *evsel; - - event_attr_init(attr); - - evsel = perf_evsel__new(attr, (*idx)++); - if (!evsel) - return -ENOMEM; - - list_add_tail(&evsel->node, list); - - evsel->name = strdup(name); - return 0; -} - -static int parse_aliases(char *str, const char *names[][MAX_ALIASES], int size) +static int parse_aliases(const char **str, const char *names[][MAX_ALIASES], int size) { int i, j; int n, longest = -1; @@ -380,57 +362,58 @@ static int parse_aliases(char *str, const char *names[][MAX_ALIASES], int size) for (i = 0; i < size; i++) { for (j = 0; j < MAX_ALIASES && names[i][j]; j++) { n = strlen(names[i][j]); - if (n > longest && !strncasecmp(str, names[i][j], n)) + if (n > longest && !strncasecmp(*str, names[i][j], n)) longest = n; } - if (longest > 0) + if (longest > 0) { + *str += longest; return i; + } } return -1; } -int parse_events_add_cache(struct list_head *list, int *idx, - char *type, char *op_result1, char *op_result2) +static enum event_result +parse_generic_hw_event(const char **str, struct perf_event_attr *attr) { - struct perf_event_attr attr; - char name[MAX_NAME_LEN]; + const char *s = *str; int cache_type = -1, cache_op = -1, cache_result = -1; - char *op_result[2] = { op_result1, op_result2 }; - int i, n; + cache_type = parse_aliases(&s, hw_cache, PERF_COUNT_HW_CACHE_MAX); /* * No fallback - if we cannot get a clear cache type * then bail out: */ - cache_type = parse_aliases(type, hw_cache, - PERF_COUNT_HW_CACHE_MAX); if (cache_type == -1) - return -EINVAL; + return EVT_FAILED; - n = snprintf(name, MAX_NAME_LEN, "%s", type); - - for (i = 0; (i < 2) && (op_result[i]); i++) { - char *str = op_result[i]; - - snprintf(name + n, MAX_NAME_LEN - n, "-%s\n", str); + while ((cache_op == -1 || cache_result == -1) && *s == '-') { + ++s; if (cache_op == -1) { - cache_op = parse_aliases(str, hw_cache_op, - PERF_COUNT_HW_CACHE_OP_MAX); + cache_op = parse_aliases(&s, hw_cache_op, + PERF_COUNT_HW_CACHE_OP_MAX); if (cache_op >= 0) { if (!is_cache_op_valid(cache_type, cache_op)) - return -EINVAL; + return EVT_FAILED; continue; } } if (cache_result == -1) { - cache_result = parse_aliases(str, hw_cache_result, + cache_result = parse_aliases(&s, hw_cache_result, PERF_COUNT_HW_CACHE_RESULT_MAX); if (cache_result >= 0) continue; } + + /* + * Can't parse this as a cache op or result, so back up + * to the '-'. + */ + --s; + break; } /* @@ -445,17 +428,20 @@ int parse_events_add_cache(struct list_head *list, int *idx, if (cache_result == -1) cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS; - memset(&attr, 0, sizeof(attr)); - attr.config = cache_type | (cache_op << 8) | (cache_result << 16); - attr.type = PERF_TYPE_HW_CACHE; - return add_event(list, idx, &attr, name); + attr->config = cache_type | (cache_op << 8) | (cache_result << 16); + attr->type = PERF_TYPE_HW_CACHE; + + *str = s; + return EVT_HANDLED; } -static int add_tracepoint(struct list_head *list, int *idx, - char *sys_name, char *evt_name) +static enum event_result +parse_single_tracepoint_event(char *sys_name, + const char *evt_name, + unsigned int evt_length, + struct perf_event_attr *attr, + const char **strp) { - struct perf_event_attr attr; - char name[MAX_NAME_LEN]; char evt_path[MAXPATHLEN]; char id_buf[4]; u64 id; @@ -466,80 +452,130 @@ static int add_tracepoint(struct list_head *list, int *idx, fd = open(evt_path, O_RDONLY); if (fd < 0) - return -1; + return EVT_FAILED; if (read(fd, id_buf, sizeof(id_buf)) < 0) { close(fd); - return -1; + return EVT_FAILED; } close(fd); id = atoll(id_buf); + attr->config = id; + attr->type = PERF_TYPE_TRACEPOINT; + *strp += strlen(sys_name) + evt_length + 1; /* + 1 for the ':' */ + + attr->sample_type |= PERF_SAMPLE_RAW; + attr->sample_type |= PERF_SAMPLE_TIME; + attr->sample_type |= PERF_SAMPLE_CPU; + + attr->sample_period = 1; - memset(&attr, 0, sizeof(attr)); - attr.config = id; - attr.type = PERF_TYPE_TRACEPOINT; - attr.sample_type |= PERF_SAMPLE_RAW; - attr.sample_type |= PERF_SAMPLE_TIME; - attr.sample_type |= PERF_SAMPLE_CPU; - attr.sample_period = 1; - snprintf(name, MAX_NAME_LEN, "%s:%s", sys_name, evt_name); - return add_event(list, idx, &attr, name); + return EVT_HANDLED; } -static int add_tracepoint_multi(struct list_head *list, int *idx, - char *sys_name, char *evt_name) +/* sys + ':' + event + ':' + flags*/ +#define MAX_EVOPT_LEN (MAX_EVENT_LENGTH * 2 + 2 + 128) +static enum event_result +parse_multiple_tracepoint_event(struct perf_evlist *evlist, char *sys_name, + const char *evt_exp, char *flags) { char evt_path[MAXPATHLEN]; struct dirent *evt_ent; DIR *evt_dir; - int ret = 0; snprintf(evt_path, MAXPATHLEN, "%s/%s", tracing_events_path, sys_name); evt_dir = opendir(evt_path); + if (!evt_dir) { perror("Can't open event dir"); - return -1; + return EVT_FAILED; } - while (!ret && (evt_ent = readdir(evt_dir))) { + while ((evt_ent = readdir(evt_dir))) { + char event_opt[MAX_EVOPT_LEN + 1]; + int len; + if (!strcmp(evt_ent->d_name, ".") || !strcmp(evt_ent->d_name, "..") || !strcmp(evt_ent->d_name, "enable") || !strcmp(evt_ent->d_name, "filter")) continue; - if (!strglobmatch(evt_ent->d_name, evt_name)) + if (!strglobmatch(evt_ent->d_name, evt_exp)) continue; - ret = add_tracepoint(list, idx, sys_name, evt_ent->d_name); + len = snprintf(event_opt, MAX_EVOPT_LEN, "%s:%s%s%s", sys_name, + evt_ent->d_name, flags ? ":" : "", + flags ?: ""); + if (len < 0) + return EVT_FAILED; + + if (parse_events(evlist, event_opt, 0)) + return EVT_FAILED; } - return ret; + return EVT_HANDLED_ALL; } -int parse_events_add_tracepoint(struct list_head *list, int *idx, - char *sys, char *event) +static enum event_result +parse_tracepoint_event(struct perf_evlist *evlist, const char **strp, + struct perf_event_attr *attr) { - int ret; + const char *evt_name; + char *flags = NULL, *comma_loc; + char sys_name[MAX_EVENT_LENGTH]; + unsigned int sys_length, evt_length; + + if (debugfs_valid_mountpoint(tracing_events_path)) + return 0; + + evt_name = strchr(*strp, ':'); + if (!evt_name) + return EVT_FAILED; + + sys_length = evt_name - *strp; + if (sys_length >= MAX_EVENT_LENGTH) + return 0; - ret = debugfs_valid_mountpoint(tracing_events_path); - if (ret) - return ret; + strncpy(sys_name, *strp, sys_length); + sys_name[sys_length] = '\0'; + evt_name = evt_name + 1; - return strpbrk(event, "*?") ? - add_tracepoint_multi(list, idx, sys, event) : - add_tracepoint(list, idx, sys, event); + comma_loc = strchr(evt_name, ','); + if (comma_loc) { + /* take the event name up to the comma */ + evt_name = strndup(evt_name, comma_loc - evt_name); + } + flags = strchr(evt_name, ':'); + if (flags) { + /* split it out: */ + evt_name = strndup(evt_name, flags - evt_name); + flags++; + } + + evt_length = strlen(evt_name); + if (evt_length >= MAX_EVENT_LENGTH) + return EVT_FAILED; + if (strpbrk(evt_name, "*?")) { + *strp += strlen(sys_name) + evt_length + 1; /* 1 == the ':' */ + return parse_multiple_tracepoint_event(evlist, sys_name, + evt_name, flags); + } else { + return parse_single_tracepoint_event(sys_name, evt_name, + evt_length, attr, strp); + } } -static int -parse_breakpoint_type(const char *type, struct perf_event_attr *attr) +static enum event_result +parse_breakpoint_type(const char *type, const char **strp, + struct perf_event_attr *attr) { int i; for (i = 0; i < 3; i++) { - if (!type || !type[i]) + if (!type[i]) break; switch (type[i]) { @@ -553,146 +589,164 @@ parse_breakpoint_type(const char *type, struct perf_event_attr *attr) attr->bp_type |= HW_BREAKPOINT_X; break; default: - return -EINVAL; + return EVT_FAILED; } } - if (!attr->bp_type) /* Default */ attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; - return 0; + *strp = type + i; + + return EVT_HANDLED; } -int parse_events_add_breakpoint(struct list_head *list, int *idx, - void *ptr, char *type) +static enum event_result +parse_breakpoint_event(const char **strp, struct perf_event_attr *attr) { - struct perf_event_attr attr; - char name[MAX_NAME_LEN]; + const char *target; + const char *type; + char *endaddr; + u64 addr; + enum event_result err; - memset(&attr, 0, sizeof(attr)); - attr.bp_addr = (unsigned long) ptr; + target = strchr(*strp, ':'); + if (!target) + return EVT_FAILED; - if (parse_breakpoint_type(type, &attr)) - return -EINVAL; + if (strncmp(*strp, "mem", target - *strp) != 0) + return EVT_FAILED; + + target++; + + addr = strtoull(target, &endaddr, 0); + if (target == endaddr) + return EVT_FAILED; + + attr->bp_addr = addr; + *strp = endaddr; + + type = strchr(target, ':'); + + /* If no type is defined, just rw as default */ + if (!type) { + attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; + } else { + err = parse_breakpoint_type(++type, strp, attr); + if (err == EVT_FAILED) + return EVT_FAILED; + } /* * We should find a nice way to override the access length * Provide some defaults for now */ - if (attr.bp_type == HW_BREAKPOINT_X) - attr.bp_len = sizeof(long); + if (attr->bp_type == HW_BREAKPOINT_X) + attr->bp_len = sizeof(long); else - attr.bp_len = HW_BREAKPOINT_LEN_4; + attr->bp_len = HW_BREAKPOINT_LEN_4; - attr.type = PERF_TYPE_BREAKPOINT; + attr->type = PERF_TYPE_BREAKPOINT; - snprintf(name, MAX_NAME_LEN, "mem:%p:%s", ptr, type ? type : "rw"); - return add_event(list, idx, &attr, name); + return EVT_HANDLED; } -static int config_term(struct perf_event_attr *attr, - struct parse_events__term *term) +static int check_events(const char *str, unsigned int i) { - switch (term->type) { - case PARSE_EVENTS__TERM_TYPE_CONFIG: - attr->config = term->val.num; - break; - case PARSE_EVENTS__TERM_TYPE_CONFIG1: - attr->config1 = term->val.num; - break; - case PARSE_EVENTS__TERM_TYPE_CONFIG2: - attr->config2 = term->val.num; - break; - case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: - attr->sample_period = term->val.num; - break; - case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: - /* - * TODO uncomment when the field is available - * attr->branch_sample_type = term->val.num; - */ - break; - default: - return -EINVAL; - } - return 0; -} + int n; -static int config_attr(struct perf_event_attr *attr, - struct list_head *head, int fail) -{ - struct parse_events__term *term; + n = strlen(event_symbols[i].symbol); + if (!strncasecmp(str, event_symbols[i].symbol, n)) + return n; - list_for_each_entry(term, head, list) - if (config_term(attr, term) && fail) - return -EINVAL; + n = strlen(event_symbols[i].alias); + if (n) { + if (!strncasecmp(str, event_symbols[i].alias, n)) + return n; + } return 0; } -int parse_events_add_numeric(struct list_head *list, int *idx, - unsigned long type, unsigned long config, - struct list_head *head_config) +static enum event_result +parse_symbolic_event(const char **strp, struct perf_event_attr *attr) { - struct perf_event_attr attr; - - memset(&attr, 0, sizeof(attr)); - attr.type = type; - attr.config = config; - - if (head_config && - config_attr(&attr, head_config, 1)) - return -EINVAL; - - return add_event(list, idx, &attr, - (char *) __event_name(type, config)); + const char *str = *strp; + unsigned int i; + int n; + + for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { + n = check_events(str, i); + if (n > 0) { + attr->type = event_symbols[i].type; + attr->config = event_symbols[i].config; + *strp = str + n; + return EVT_HANDLED; + } + } + return EVT_FAILED; } -int parse_events_add_pmu(struct list_head *list, int *idx, - char *name, struct list_head *head_config) +static enum event_result +parse_raw_event(const char **strp, struct perf_event_attr *attr) { - struct perf_event_attr attr; - struct perf_pmu *pmu; - - pmu = perf_pmu__find(name); - if (!pmu) - return -EINVAL; - - memset(&attr, 0, sizeof(attr)); - - /* - * Configure hardcoded terms first, no need to check - * return value when called with fail == 0 ;) - */ - config_attr(&attr, head_config, 0); - - if (perf_pmu__config(pmu, &attr, head_config)) - return -EINVAL; - - return add_event(list, idx, &attr, (char *) "pmu"); + const char *str = *strp; + u64 config; + int n; + + if (*str != 'r') + return EVT_FAILED; + n = hex2u64(str + 1, &config); + if (n > 0) { + const char *end = str + n + 1; + if (*end != '\0' && *end != ',' && *end != ':') + return EVT_FAILED; + + *strp = end; + attr->type = PERF_TYPE_RAW; + attr->config = config; + return EVT_HANDLED; + } + return EVT_FAILED; } -void parse_events_update_lists(struct list_head *list_event, - struct list_head *list_all) +static enum event_result +parse_numeric_event(const char **strp, struct perf_event_attr *attr) { - /* - * Called for single event definition. Update the - * 'all event' list, and reinit the 'signle event' - * list, for next event definition. - */ - list_splice_tail(list_event, list_all); - INIT_LIST_HEAD(list_event); + const char *str = *strp; + char *endp; + unsigned long type; + u64 config; + + type = strtoul(str, &endp, 0); + if (endp > str && type < PERF_TYPE_MAX && *endp == ':') { + str = endp + 1; + config = strtoul(str, &endp, 0); + if (endp > str) { + attr->type = type; + attr->config = config; + *strp = endp; + return EVT_HANDLED; + } + } + return EVT_FAILED; } -int parse_events_modifier(struct list_head *list, char *str) +static int +parse_event_modifier(const char **strp, struct perf_event_attr *attr) { - struct perf_evsel *evsel; + const char *str = *strp; int exclude = 0, exclude_GH = 0; int eu = 0, ek = 0, eh = 0, eH = 0, eG = 0, precise = 0; - if (str == NULL) + if (!*str) return 0; + if (*str == ',') + return 0; + + if (*str++ != ':') + return -1; + while (*str) { if (*str == 'u') { if (!exclude) @@ -721,62 +775,111 @@ int parse_events_modifier(struct list_head *list, char *str) ++str; } + if (str < *strp + 2) + return -1; - /* - * precise ip: - * - * 0 - SAMPLE_IP can have arbitrary skid - * 1 - SAMPLE_IP must have constant skid - * 2 - SAMPLE_IP requested to have 0 skid - * 3 - SAMPLE_IP must have 0 skid - * - * See also PERF_RECORD_MISC_EXACT_IP - */ - if (precise > 3) - return -EINVAL; + *strp = str; - list_for_each_entry(evsel, list, node) { - evsel->attr.exclude_user = eu; - evsel->attr.exclude_kernel = ek; - evsel->attr.exclude_hv = eh; - evsel->attr.precise_ip = precise; - evsel->attr.exclude_host = eH; - evsel->attr.exclude_guest = eG; - } + attr->exclude_user = eu; + attr->exclude_kernel = ek; + attr->exclude_hv = eh; + attr->precise_ip = precise; + attr->exclude_host = eH; + attr->exclude_guest = eG; return 0; } -int parse_events(struct perf_evlist *evlist, const char *str, int unset __used) +/* + * Each event can have multiple symbolic names. + * Symbolic names are (almost) exactly matched. + */ +static enum event_result +parse_event_symbols(struct perf_evlist *evlist, const char **str, + struct perf_event_attr *attr) { - LIST_HEAD(list); - LIST_HEAD(list_tmp); - YY_BUFFER_STATE buffer; - int ret, idx = evlist->nr_entries; + enum event_result ret; - buffer = parse_events__scan_string(str); + ret = parse_tracepoint_event(evlist, str, attr); + if (ret != EVT_FAILED) + goto modifier; - ret = parse_events_parse(&list, &list_tmp, &idx); + ret = parse_raw_event(str, attr); + if (ret != EVT_FAILED) + goto modifier; - parse_events__flush_buffer(buffer); - parse_events__delete_buffer(buffer); + ret = parse_numeric_event(str, attr); + if (ret != EVT_FAILED) + goto modifier; - if (!ret) { - int entries = idx - evlist->nr_entries; - perf_evlist__splice_list_tail(evlist, &list, entries); - return 0; - } + ret = parse_symbolic_event(str, attr); + if (ret != EVT_FAILED) + goto modifier; - /* - * There are 2 users - builtin-record and builtin-test objects. - * Both call perf_evlist__delete in case of error, so we dont - * need to bother. - */ - fprintf(stderr, "invalid or unsupported event: '%s'\n", str); + ret = parse_generic_hw_event(str, attr); + if (ret != EVT_FAILED) + goto modifier; + + ret = parse_breakpoint_event(str, attr); + if (ret != EVT_FAILED) + goto modifier; + + fprintf(stderr, "invalid or unsupported event: '%s'\n", *str); fprintf(stderr, "Run 'perf list' for a list of valid events\n"); + return EVT_FAILED; + +modifier: + if (parse_event_modifier(str, attr) < 0) { + fprintf(stderr, "invalid event modifier: '%s'\n", *str); + fprintf(stderr, "Run 'perf list' for a list of valid events and modifiers\n"); + + return EVT_FAILED; + } + return ret; } +int parse_events(struct perf_evlist *evlist , const char *str, int unset __used) +{ + struct perf_event_attr attr; + enum event_result ret; + const char *ostr; + + for (;;) { + ostr = str; + memset(&attr, 0, sizeof(attr)); + event_attr_init(&attr); + ret = parse_event_symbols(evlist, &str, &attr); + if (ret == EVT_FAILED) + return -1; + + if (!(*str == 0 || *str == ',' || isspace(*str))) + return -1; + + if (ret != EVT_HANDLED_ALL) { + struct perf_evsel *evsel; + evsel = perf_evsel__new(&attr, evlist->nr_entries); + if (evsel == NULL) + return -1; + perf_evlist__add(evlist, evsel); + + evsel->name = calloc(str - ostr + 1, 1); + if (!evsel->name) + return -1; + strncpy(evsel->name, ostr, str - ostr); + } + + if (*str == 0) + break; + if (*str == ',') + ++str; + while (isspace(*str)) + ++str; + } + + return 0; +} + int parse_events_option(const struct option *opt, const char *str, int unset __used) { @@ -949,6 +1052,8 @@ int print_hwcache_events(const char *event_glob) return printed; } +#define MAX_NAME_LEN 100 + /* * Print the help text for the event symbols: */ @@ -997,12 +1102,8 @@ void print_events(const char *event_glob) printf("\n"); printf(" %-50s [%s]\n", - "rNNN", + "rNNN (see 'perf list --help' on how to encode it)", event_type_descriptors[PERF_TYPE_RAW]); - printf(" %-50s [%s]\n", - "cpu/t1=v1[,t2=v2,t3 ...]/modifier", - event_type_descriptors[PERF_TYPE_RAW]); - printf(" (see 'perf list --help' on how to encode it)\n"); printf("\n"); printf(" %-50s [%s]\n", @@ -1012,51 +1113,3 @@ void print_events(const char *event_glob) print_tracepoint_events(NULL, NULL); } - -int parse_events__is_hardcoded_term(struct parse_events__term *term) -{ - return term->type <= PARSE_EVENTS__TERM_TYPE_HARDCODED_MAX; -} - -int parse_events__new_term(struct parse_events__term **_term, int type, - char *config, char *str, long num) -{ - struct parse_events__term *term; - - term = zalloc(sizeof(*term)); - if (!term) - return -ENOMEM; - - INIT_LIST_HEAD(&term->list); - term->type = type; - term->config = config; - - switch (type) { - case PARSE_EVENTS__TERM_TYPE_CONFIG: - case PARSE_EVENTS__TERM_TYPE_CONFIG1: - case PARSE_EVENTS__TERM_TYPE_CONFIG2: - case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: - case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: - case PARSE_EVENTS__TERM_TYPE_NUM: - term->val.num = num; - break; - case PARSE_EVENTS__TERM_TYPE_STR: - term->val.str = str; - break; - default: - return -EINVAL; - } - - *_term = term; - return 0; -} - -void parse_events__free_terms(struct list_head *terms) -{ - struct parse_events__term *term, *h; - - list_for_each_entry_safe(term, h, terms, list) - free(term); - - free(terms); -} diff --git a/trunk/tools/perf/util/parse-events.h b/trunk/tools/perf/util/parse-events.h index ca069f893381..7e0cbe75d5f1 100644 --- a/trunk/tools/perf/util/parse-events.h +++ b/trunk/tools/perf/util/parse-events.h @@ -33,55 +33,6 @@ extern int parse_filter(const struct option *opt, const char *str, int unset); #define EVENTS_HELP_MAX (128*1024) -enum { - PARSE_EVENTS__TERM_TYPE_CONFIG, - PARSE_EVENTS__TERM_TYPE_CONFIG1, - PARSE_EVENTS__TERM_TYPE_CONFIG2, - PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD, - PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE, - PARSE_EVENTS__TERM_TYPE_NUM, - PARSE_EVENTS__TERM_TYPE_STR, - - PARSE_EVENTS__TERM_TYPE_HARDCODED_MAX = - PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE, -}; - -struct parse_events__term { - char *config; - union { - char *str; - long num; - } val; - int type; - - struct list_head list; -}; - -int parse_events__is_hardcoded_term(struct parse_events__term *term); -int parse_events__new_term(struct parse_events__term **term, int type, - char *config, char *str, long num); -void parse_events__free_terms(struct list_head *terms); -int parse_events_modifier(struct list_head *list __used, char *str __used); -int parse_events_add_tracepoint(struct list_head *list, int *idx, - char *sys, char *event); -int parse_events_add_raw(struct perf_evlist *evlist, unsigned long config, - unsigned long config1, unsigned long config2, - char *mod); -int parse_events_add_numeric(struct list_head *list, int *idx, - unsigned long type, unsigned long config, - struct list_head *head_config); -int parse_events_add_cache(struct list_head *list, int *idx, - char *type, char *op_result1, char *op_result2); -int parse_events_add_breakpoint(struct list_head *list, int *idx, - void *ptr, char *type); -int parse_events_add_pmu(struct list_head *list, int *idx, - char *pmu , struct list_head *head_config); -void parse_events_update_lists(struct list_head *list_event, - struct list_head *list_all); -void parse_events_error(struct list_head *list_all, - struct list_head *list_event, - int *idx, char const *msg); - void print_events(const char *event_glob); void print_events_type(u8 type); void print_tracepoint_events(const char *subsys_glob, const char *event_glob); diff --git a/trunk/tools/perf/util/parse-events.l b/trunk/tools/perf/util/parse-events.l deleted file mode 100644 index 1fcf1bbc5458..000000000000 --- a/trunk/tools/perf/util/parse-events.l +++ /dev/null @@ -1,127 +0,0 @@ - -%option prefix="parse_events_" - -%{ -#include -#include "../perf.h" -#include "parse-events-bison.h" -#include "parse-events.h" - -static int __value(char *str, int base, int token) -{ - long num; - - errno = 0; - num = strtoul(str, NULL, base); - if (errno) - return PE_ERROR; - - parse_events_lval.num = num; - return token; -} - -static int value(int base) -{ - return __value(parse_events_text, base, PE_VALUE); -} - -static int raw(void) -{ - return __value(parse_events_text + 1, 16, PE_RAW); -} - -static int str(int token) -{ - parse_events_lval.str = strdup(parse_events_text); - return token; -} - -static int sym(int type, int config) -{ - parse_events_lval.num = (type << 16) + config; - return PE_VALUE_SYM; -} - -static int term(int type) -{ - parse_events_lval.num = type; - return PE_TERM; -} - -%} - -num_dec [0-9]+ -num_hex 0x[a-fA-F0-9]+ -num_raw_hex [a-fA-F0-9]+ -name [a-zA-Z_*?][a-zA-Z0-9_*?]* -modifier_event [ukhpGH]{1,8} -modifier_bp [rwx] - -%% -cpu-cycles|cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); } -stalled-cycles-frontend|idle-cycles-frontend { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } -stalled-cycles-backend|idle-cycles-backend { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); } -instructions { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS); } -cache-references { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES); } -cache-misses { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES); } -branch-instructions|branches { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); } -branch-misses { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES); } -bus-cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES); } -ref-cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); } -cpu-clock { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK); } -task-clock { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK); } -page-faults|faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS); } -minor-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN); } -major-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ); } -context-switches|cs { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES); } -cpu-migrations|migrations { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS); } -alignment-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); } -emulation-faults { return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } - -L1-dcache|l1-d|l1d|L1-data | -L1-icache|l1-i|l1i|L1-instruction | -LLC|L2 | -dTLB|d-tlb|Data-TLB | -iTLB|i-tlb|Instruction-TLB | -branch|branches|bpu|btb|bpc | -node { return str(PE_NAME_CACHE_TYPE); } - -load|loads|read | -store|stores|write | -prefetch|prefetches | -speculative-read|speculative-load | -refs|Reference|ops|access | -misses|miss { return str(PE_NAME_CACHE_OP_RESULT); } - - /* - * These are event config hardcoded term names to be specified - * within xxx/.../ syntax. So far we dont clash with other names, - * so we can put them here directly. In case the we have a conflict - * in future, this needs to go into '//' condition block. - */ -config { return term(PARSE_EVENTS__TERM_TYPE_CONFIG); } -config1 { return term(PARSE_EVENTS__TERM_TYPE_CONFIG1); } -config2 { return term(PARSE_EVENTS__TERM_TYPE_CONFIG2); } -period { return term(PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); } -branch_type { return term(PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); } - -mem: { return PE_PREFIX_MEM; } -r{num_raw_hex} { return raw(); } -{num_dec} { return value(10); } -{num_hex} { return value(16); } - -{modifier_event} { return str(PE_MODIFIER_EVENT); } -{modifier_bp} { return str(PE_MODIFIER_BP); } -{name} { return str(PE_NAME); } -"/" { return '/'; } -- { return '-'; } -, { return ','; } -: { return ':'; } -= { return '='; } - -%% - -int parse_events_wrap(void) -{ - return 1; -} diff --git a/trunk/tools/perf/util/parse-events.y b/trunk/tools/perf/util/parse-events.y deleted file mode 100644 index d9637da7333c..000000000000 --- a/trunk/tools/perf/util/parse-events.y +++ /dev/null @@ -1,229 +0,0 @@ - -%name-prefix "parse_events_" -%parse-param {struct list_head *list_all} -%parse-param {struct list_head *list_event} -%parse-param {int *idx} - -%{ - -#define YYDEBUG 1 - -#include -#include -#include "types.h" -#include "util.h" -#include "parse-events.h" - -extern int parse_events_lex (void); - -#define ABORT_ON(val) \ -do { \ - if (val) \ - YYABORT; \ -} while (0) - -%} - -%token PE_VALUE PE_VALUE_SYM PE_RAW PE_TERM -%token PE_NAME -%token PE_MODIFIER_EVENT PE_MODIFIER_BP -%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT -%token PE_PREFIX_MEM PE_PREFIX_RAW -%token PE_ERROR -%type PE_VALUE -%type PE_VALUE_SYM -%type PE_RAW -%type PE_TERM -%type PE_NAME -%type PE_NAME_CACHE_TYPE -%type PE_NAME_CACHE_OP_RESULT -%type PE_MODIFIER_EVENT -%type PE_MODIFIER_BP -%type event_config -%type event_term - -%union -{ - char *str; - unsigned long num; - struct list_head *head; - struct parse_events__term *term; -} -%% - -events: -events ',' event | event - -event: -event_def PE_MODIFIER_EVENT -{ - /* - * Apply modifier on all events added by single event definition - * (there could be more events added for multiple tracepoint - * definitions via '*?'. - */ - ABORT_ON(parse_events_modifier(list_event, $2)); - parse_events_update_lists(list_event, list_all); -} -| -event_def -{ - parse_events_update_lists(list_event, list_all); -} - -event_def: event_pmu | - event_legacy_symbol | - event_legacy_cache sep_dc | - event_legacy_mem | - event_legacy_tracepoint sep_dc | - event_legacy_numeric sep_dc | - event_legacy_raw sep_dc - -event_pmu: -PE_NAME '/' event_config '/' -{ - ABORT_ON(parse_events_add_pmu(list_event, idx, $1, $3)); - parse_events__free_terms($3); -} - -event_legacy_symbol: -PE_VALUE_SYM '/' event_config '/' -{ - int type = $1 >> 16; - int config = $1 & 255; - - ABORT_ON(parse_events_add_numeric(list_event, idx, type, config, $3)); - parse_events__free_terms($3); -} -| -PE_VALUE_SYM sep_slash_dc -{ - int type = $1 >> 16; - int config = $1 & 255; - - ABORT_ON(parse_events_add_numeric(list_event, idx, type, config, NULL)); -} - -event_legacy_cache: -PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT -{ - ABORT_ON(parse_events_add_cache(list_event, idx, $1, $3, $5)); -} -| -PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT -{ - ABORT_ON(parse_events_add_cache(list_event, idx, $1, $3, NULL)); -} -| -PE_NAME_CACHE_TYPE -{ - ABORT_ON(parse_events_add_cache(list_event, idx, $1, NULL, NULL)); -} - -event_legacy_mem: -PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc -{ - ABORT_ON(parse_events_add_breakpoint(list_event, idx, (void *) $2, $4)); -} -| -PE_PREFIX_MEM PE_VALUE sep_dc -{ - ABORT_ON(parse_events_add_breakpoint(list_event, idx, (void *) $2, NULL)); -} - -event_legacy_tracepoint: -PE_NAME ':' PE_NAME -{ - ABORT_ON(parse_events_add_tracepoint(list_event, idx, $1, $3)); -} - -event_legacy_numeric: -PE_VALUE ':' PE_VALUE -{ - ABORT_ON(parse_events_add_numeric(list_event, idx, $1, $3, NULL)); -} - -event_legacy_raw: -PE_RAW -{ - ABORT_ON(parse_events_add_numeric(list_event, idx, PERF_TYPE_RAW, $1, NULL)); -} - -event_config: -event_config ',' event_term -{ - struct list_head *head = $1; - struct parse_events__term *term = $3; - - ABORT_ON(!head); - list_add_tail(&term->list, head); - $$ = $1; -} -| -event_term -{ - struct list_head *head = malloc(sizeof(*head)); - struct parse_events__term *term = $1; - - ABORT_ON(!head); - INIT_LIST_HEAD(head); - list_add_tail(&term->list, head); - $$ = head; -} - -event_term: -PE_NAME '=' PE_NAME -{ - struct parse_events__term *term; - - ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_STR, - $1, $3, 0)); - $$ = term; -} -| -PE_NAME '=' PE_VALUE -{ - struct parse_events__term *term; - - ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_NUM, - $1, NULL, $3)); - $$ = term; -} -| -PE_NAME -{ - struct parse_events__term *term; - - ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_NUM, - $1, NULL, 1)); - $$ = term; -} -| -PE_TERM '=' PE_VALUE -{ - struct parse_events__term *term; - - ABORT_ON(parse_events__new_term(&term, $1, NULL, NULL, $3)); - $$ = term; -} -| -PE_TERM -{ - struct parse_events__term *term; - - ABORT_ON(parse_events__new_term(&term, $1, NULL, NULL, 1)); - $$ = term; -} - -sep_dc: ':' | - -sep_slash_dc: '/' | ':' | - -%% - -void parse_events_error(struct list_head *list_all __used, - struct list_head *list_event __used, - int *idx __used, - char const *msg __used) -{ -} diff --git a/trunk/tools/perf/util/pmu.c b/trunk/tools/perf/util/pmu.c deleted file mode 100644 index cb08a118e811..000000000000 --- a/trunk/tools/perf/util/pmu.c +++ /dev/null @@ -1,469 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include "sysfs.h" -#include "util.h" -#include "pmu.h" -#include "parse-events.h" - -int perf_pmu_parse(struct list_head *list, char *name); -extern FILE *perf_pmu_in; - -static LIST_HEAD(pmus); - -/* - * Parse & process all the sysfs attributes located under - * the directory specified in 'dir' parameter. - */ -static int pmu_format_parse(char *dir, struct list_head *head) -{ - struct dirent *evt_ent; - DIR *format_dir; - int ret = 0; - - format_dir = opendir(dir); - if (!format_dir) - return -EINVAL; - - while (!ret && (evt_ent = readdir(format_dir))) { - char path[PATH_MAX]; - char *name = evt_ent->d_name; - FILE *file; - - if (!strcmp(name, ".") || !strcmp(name, "..")) - continue; - - snprintf(path, PATH_MAX, "%s/%s", dir, name); - - ret = -EINVAL; - file = fopen(path, "r"); - if (!file) - break; - - perf_pmu_in = file; - ret = perf_pmu_parse(head, name); - fclose(file); - } - - closedir(format_dir); - return ret; -} - -/* - * Reading/parsing the default pmu format definition, which should be - * located at: - * /sys/bus/event_source/devices//format as sysfs group attributes. - */ -static int pmu_format(char *name, struct list_head *format) -{ - struct stat st; - char path[PATH_MAX]; - const char *sysfs; - - sysfs = sysfs_find_mountpoint(); - if (!sysfs) - return -1; - - snprintf(path, PATH_MAX, - "%s/bus/event_source/devices/%s/format", sysfs, name); - - if (stat(path, &st) < 0) - return -1; - - if (pmu_format_parse(path, format)) - return -1; - - return 0; -} - -/* - * Reading/parsing the default pmu type value, which should be - * located at: - * /sys/bus/event_source/devices//type as sysfs attribute. - */ -static int pmu_type(char *name, __u32 *type) -{ - struct stat st; - char path[PATH_MAX]; - const char *sysfs; - FILE *file; - int ret = 0; - - sysfs = sysfs_find_mountpoint(); - if (!sysfs) - return -1; - - snprintf(path, PATH_MAX, - "%s/bus/event_source/devices/%s/type", sysfs, name); - - if (stat(path, &st) < 0) - return -1; - - file = fopen(path, "r"); - if (!file) - return -EINVAL; - - if (1 != fscanf(file, "%u", type)) - ret = -1; - - fclose(file); - return ret; -} - -static struct perf_pmu *pmu_lookup(char *name) -{ - struct perf_pmu *pmu; - LIST_HEAD(format); - __u32 type; - - /* - * The pmu data we store & need consists of the pmu - * type value and format definitions. Load both right - * now. - */ - if (pmu_format(name, &format)) - return NULL; - - if (pmu_type(name, &type)) - return NULL; - - pmu = zalloc(sizeof(*pmu)); - if (!pmu) - return NULL; - - INIT_LIST_HEAD(&pmu->format); - list_splice(&format, &pmu->format); - pmu->name = strdup(name); - pmu->type = type; - return pmu; -} - -static struct perf_pmu *pmu_find(char *name) -{ - struct perf_pmu *pmu; - - list_for_each_entry(pmu, &pmus, list) - if (!strcmp(pmu->name, name)) - return pmu; - - return NULL; -} - -struct perf_pmu *perf_pmu__find(char *name) -{ - struct perf_pmu *pmu; - - /* - * Once PMU is loaded it stays in the list, - * so we keep us from multiple reading/parsing - * the pmu format definitions. - */ - pmu = pmu_find(name); - if (pmu) - return pmu; - - return pmu_lookup(name); -} - -static struct perf_pmu__format* -pmu_find_format(struct list_head *formats, char *name) -{ - struct perf_pmu__format *format; - - list_for_each_entry(format, formats, list) - if (!strcmp(format->name, name)) - return format; - - return NULL; -} - -/* - * Returns value based on the format definition (format parameter) - * and unformated value (value parameter). - * - * TODO maybe optimize a little ;) - */ -static __u64 pmu_format_value(unsigned long *format, __u64 value) -{ - unsigned long fbit, vbit; - __u64 v = 0; - - for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) { - - if (!test_bit(fbit, format)) - continue; - - if (!(value & (1llu << vbit++))) - continue; - - v |= (1llu << fbit); - } - - return v; -} - -/* - * Setup one of config[12] attr members based on the - * user input data - temr parameter. - */ -static int pmu_config_term(struct list_head *formats, - struct perf_event_attr *attr, - struct parse_events__term *term) -{ - struct perf_pmu__format *format; - __u64 *vp; - - /* - * Support only for hardcoded and numnerial terms. - * Hardcoded terms should be already in, so nothing - * to be done for them. - */ - if (parse_events__is_hardcoded_term(term)) - return 0; - - if (term->type != PARSE_EVENTS__TERM_TYPE_NUM) - return -EINVAL; - - format = pmu_find_format(formats, term->config); - if (!format) - return -EINVAL; - - switch (format->value) { - case PERF_PMU_FORMAT_VALUE_CONFIG: - vp = &attr->config; - break; - case PERF_PMU_FORMAT_VALUE_CONFIG1: - vp = &attr->config1; - break; - case PERF_PMU_FORMAT_VALUE_CONFIG2: - vp = &attr->config2; - break; - default: - return -EINVAL; - } - - *vp |= pmu_format_value(format->bits, term->val.num); - return 0; -} - -static int pmu_config(struct list_head *formats, struct perf_event_attr *attr, - struct list_head *head_terms) -{ - struct parse_events__term *term, *h; - - list_for_each_entry_safe(term, h, head_terms, list) - if (pmu_config_term(formats, attr, term)) - return -EINVAL; - - return 0; -} - -/* - * Configures event's 'attr' parameter based on the: - * 1) users input - specified in terms parameter - * 2) pmu format definitions - specified by pmu parameter - */ -int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, - struct list_head *head_terms) -{ - attr->type = pmu->type; - return pmu_config(&pmu->format, attr, head_terms); -} - -int perf_pmu__new_format(struct list_head *list, char *name, - int config, unsigned long *bits) -{ - struct perf_pmu__format *format; - - format = zalloc(sizeof(*format)); - if (!format) - return -ENOMEM; - - format->name = strdup(name); - format->value = config; - memcpy(format->bits, bits, sizeof(format->bits)); - - list_add_tail(&format->list, list); - return 0; -} - -void perf_pmu__set_format(unsigned long *bits, long from, long to) -{ - long b; - - if (!to) - to = from; - - memset(bits, 0, BITS_TO_LONGS(PERF_PMU_FORMAT_BITS)); - for (b = from; b <= to; b++) - set_bit(b, bits); -} - -/* Simulated format definitions. */ -static struct test_format { - const char *name; - const char *value; -} test_formats[] = { - { "krava01", "config:0-1,62-63\n", }, - { "krava02", "config:10-17\n", }, - { "krava03", "config:5\n", }, - { "krava11", "config1:0,2,4,6,8,20-28\n", }, - { "krava12", "config1:63\n", }, - { "krava13", "config1:45-47\n", }, - { "krava21", "config2:0-3,10-13,20-23,30-33,40-43,50-53,60-63\n", }, - { "krava22", "config2:8,18,48,58\n", }, - { "krava23", "config2:28-29,38\n", }, -}; - -#define TEST_FORMATS_CNT (sizeof(test_formats) / sizeof(struct test_format)) - -/* Simulated users input. */ -static struct parse_events__term test_terms[] = { - { - .config = (char *) "krava01", - .val.num = 15, - .type = PARSE_EVENTS__TERM_TYPE_NUM, - }, - { - .config = (char *) "krava02", - .val.num = 170, - .type = PARSE_EVENTS__TERM_TYPE_NUM, - }, - { - .config = (char *) "krava03", - .val.num = 1, - .type = PARSE_EVENTS__TERM_TYPE_NUM, - }, - { - .config = (char *) "krava11", - .val.num = 27, - .type = PARSE_EVENTS__TERM_TYPE_NUM, - }, - { - .config = (char *) "krava12", - .val.num = 1, - .type = PARSE_EVENTS__TERM_TYPE_NUM, - }, - { - .config = (char *) "krava13", - .val.num = 2, - .type = PARSE_EVENTS__TERM_TYPE_NUM, - }, - { - .config = (char *) "krava21", - .val.num = 119, - .type = PARSE_EVENTS__TERM_TYPE_NUM, - }, - { - .config = (char *) "krava22", - .val.num = 11, - .type = PARSE_EVENTS__TERM_TYPE_NUM, - }, - { - .config = (char *) "krava23", - .val.num = 2, - .type = PARSE_EVENTS__TERM_TYPE_NUM, - }, -}; -#define TERMS_CNT (sizeof(test_terms) / sizeof(struct parse_events__term)) - -/* - * Prepare format directory data, exported by kernel - * at /sys/bus/event_source/devices//format. - */ -static char *test_format_dir_get(void) -{ - static char dir[PATH_MAX]; - unsigned int i; - - snprintf(dir, PATH_MAX, "/tmp/perf-pmu-test-format-XXXXXX"); - if (!mkdtemp(dir)) - return NULL; - - for (i = 0; i < TEST_FORMATS_CNT; i++) { - static char name[PATH_MAX]; - struct test_format *format = &test_formats[i]; - FILE *file; - - snprintf(name, PATH_MAX, "%s/%s", dir, format->name); - - file = fopen(name, "w"); - if (!file) - return NULL; - - if (1 != fwrite(format->value, strlen(format->value), 1, file)) - break; - - fclose(file); - } - - return dir; -} - -/* Cleanup format directory. */ -static int test_format_dir_put(char *dir) -{ - char buf[PATH_MAX]; - snprintf(buf, PATH_MAX, "rm -f %s/*\n", dir); - if (system(buf)) - return -1; - - snprintf(buf, PATH_MAX, "rmdir %s\n", dir); - return system(buf); -} - -static struct list_head *test_terms_list(void) -{ - static LIST_HEAD(terms); - unsigned int i; - - for (i = 0; i < TERMS_CNT; i++) - list_add_tail(&test_terms[i].list, &terms); - - return &terms; -} - -#undef TERMS_CNT - -int perf_pmu__test(void) -{ - char *format = test_format_dir_get(); - LIST_HEAD(formats); - struct list_head *terms = test_terms_list(); - int ret; - - if (!format) - return -EINVAL; - - do { - struct perf_event_attr attr; - - memset(&attr, 0, sizeof(attr)); - - ret = pmu_format_parse(format, &formats); - if (ret) - break; - - ret = pmu_config(&formats, &attr, terms); - if (ret) - break; - - ret = -EINVAL; - - if (attr.config != 0xc00000000002a823) - break; - if (attr.config1 != 0x8000400000000145) - break; - if (attr.config2 != 0x0400000020041d07) - break; - - ret = 0; - } while (0); - - test_format_dir_put(format); - return ret; -} diff --git a/trunk/tools/perf/util/pmu.h b/trunk/tools/perf/util/pmu.h deleted file mode 100644 index 68c0db965e1f..000000000000 --- a/trunk/tools/perf/util/pmu.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __PMU_H -#define __PMU_H - -#include -#include "../../../include/linux/perf_event.h" - -enum { - PERF_PMU_FORMAT_VALUE_CONFIG, - PERF_PMU_FORMAT_VALUE_CONFIG1, - PERF_PMU_FORMAT_VALUE_CONFIG2, -}; - -#define PERF_PMU_FORMAT_BITS 64 - -struct perf_pmu__format { - char *name; - int value; - DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS); - struct list_head list; -}; - -struct perf_pmu { - char *name; - __u32 type; - struct list_head format; - struct list_head list; -}; - -struct perf_pmu *perf_pmu__find(char *name); -int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, - struct list_head *head_terms); - -int perf_pmu_wrap(void); -void perf_pmu_error(struct list_head *list, char *name, char const *msg); - -int perf_pmu__new_format(struct list_head *list, char *name, - int config, unsigned long *bits); -void perf_pmu__set_format(unsigned long *bits, long from, long to); - -int perf_pmu__test(void); -#endif /* __PMU_H */ diff --git a/trunk/tools/perf/util/pmu.l b/trunk/tools/perf/util/pmu.l deleted file mode 100644 index a15d9fbd7c0e..000000000000 --- a/trunk/tools/perf/util/pmu.l +++ /dev/null @@ -1,43 +0,0 @@ -%option prefix="perf_pmu_" - -%{ -#include -#include -#include "pmu.h" -#include "pmu-bison.h" - -static int value(int base) -{ - long num; - - errno = 0; - num = strtoul(perf_pmu_text, NULL, base); - if (errno) - return PP_ERROR; - - perf_pmu_lval.num = num; - return PP_VALUE; -} - -%} - -num_dec [0-9]+ - -%% - -{num_dec} { return value(10); } -config { return PP_CONFIG; } -config1 { return PP_CONFIG1; } -config2 { return PP_CONFIG2; } -- { return '-'; } -: { return ':'; } -, { return ','; } -. { ; } -\n { ; } - -%% - -int perf_pmu_wrap(void) -{ - return 1; -} diff --git a/trunk/tools/perf/util/pmu.y b/trunk/tools/perf/util/pmu.y deleted file mode 100644 index 20ea77e93169..000000000000 --- a/trunk/tools/perf/util/pmu.y +++ /dev/null @@ -1,93 +0,0 @@ - -%name-prefix "perf_pmu_" -%parse-param {struct list_head *format} -%parse-param {char *name} - -%{ - -#include -#include -#include -#include -#include "pmu.h" - -extern int perf_pmu_lex (void); - -#define ABORT_ON(val) \ -do { \ - if (val) \ - YYABORT; \ -} while (0) - -%} - -%token PP_CONFIG PP_CONFIG1 PP_CONFIG2 -%token PP_VALUE PP_ERROR -%type PP_VALUE -%type bit_term -%type bits - -%union -{ - unsigned long num; - DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS); -} - -%% - -format: -format format_term -| -format_term - -format_term: -PP_CONFIG ':' bits -{ - ABORT_ON(perf_pmu__new_format(format, name, - PERF_PMU_FORMAT_VALUE_CONFIG, - $3)); -} -| -PP_CONFIG1 ':' bits -{ - ABORT_ON(perf_pmu__new_format(format, name, - PERF_PMU_FORMAT_VALUE_CONFIG1, - $3)); -} -| -PP_CONFIG2 ':' bits -{ - ABORT_ON(perf_pmu__new_format(format, name, - PERF_PMU_FORMAT_VALUE_CONFIG2, - $3)); -} - -bits: -bits ',' bit_term -{ - bitmap_or($$, $1, $3, 64); -} -| -bit_term -{ - memcpy($$, $1, sizeof($1)); -} - -bit_term: -PP_VALUE '-' PP_VALUE -{ - perf_pmu__set_format($$, $1, $3); -} -| -PP_VALUE -{ - perf_pmu__set_format($$, $1, 0); -} - -%% - -void perf_pmu_error(struct list_head *list __used, - char *name __used, - char const *msg __used) -{ -} diff --git a/trunk/tools/perf/util/probe-finder.c b/trunk/tools/perf/util/probe-finder.c index d448984ed789..2cc162d3b78c 100644 --- a/trunk/tools/perf/util/probe-finder.c +++ b/trunk/tools/perf/util/probe-finder.c @@ -972,12 +972,10 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) struct dwarf_callback_param *param = data; struct probe_finder *pf = param->data; struct perf_probe_point *pp = &pf->pev->point; - Dwarf_Attribute attr; /* Check tag and diename */ if (dwarf_tag(sp_die) != DW_TAG_subprogram || - !die_compare_name(sp_die, pp->function) || - dwarf_attr(sp_die, DW_AT_declaration, &attr)) + !die_compare_name(sp_die, pp->function)) return DWARF_CB_OK; /* Check declared file */ diff --git a/trunk/tools/perf/util/session.c b/trunk/tools/perf/util/session.c index 1efd3bee6336..002ebbf59f48 100644 --- a/trunk/tools/perf/util/session.c +++ b/trunk/tools/perf/util/session.c @@ -140,7 +140,6 @@ struct perf_session *perf_session__new(const char *filename, int mode, INIT_LIST_HEAD(&self->ordered_samples.sample_cache); INIT_LIST_HEAD(&self->ordered_samples.to_free); machine__init(&self->host_machine, "", HOST_KERNEL_ID); - hists__init(&self->hists); if (mode == O_RDONLY) { if (perf_session__open(self, force) < 0) @@ -826,16 +825,8 @@ static struct machine * { const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { - u32 pid; - - if (event->header.type == PERF_RECORD_MMAP) - pid = event->mmap.pid; - else - pid = event->ip.pid; - - return perf_session__find_machine(session, pid); - } + if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) + return perf_session__find_machine(session, event->ip.pid); return perf_session__find_host_machine(session); } @@ -876,11 +867,11 @@ static int perf_session_deliver_event(struct perf_session *session, dump_sample(session, event, sample); if (evsel == NULL) { ++session->hists.stats.nr_unknown_id; - return 0; + return -1; } if (machine == NULL) { ++session->hists.stats.nr_unprocessable_samples; - return 0; + return -1; } return tool->sample(tool, event, sample, evsel, machine); case PERF_RECORD_MMAP: diff --git a/trunk/tools/perf/util/symbol.c b/trunk/tools/perf/util/symbol.c index ab9867b2b433..5dd83c3e2c0c 100644 --- a/trunk/tools/perf/util/symbol.c +++ b/trunk/tools/perf/util/symbol.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -50,8 +51,6 @@ struct symbol_conf symbol_conf = { int dso__name_len(const struct dso *dso) { - if (!dso) - return strlen("[unknown]"); if (verbose) return dso->long_name_len; @@ -977,9 +976,8 @@ static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, * And always look at the original dso, not at debuginfo packages, that * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS). */ -static int -dso__synthesize_plt_symbols(struct dso *dso, char *name, struct map *map, - symbol_filter_t filter) +static int dso__synthesize_plt_symbols(struct dso *dso, struct map *map, + symbol_filter_t filter) { uint32_t nr_rel_entries, idx; GElf_Sym sym; @@ -994,7 +992,10 @@ dso__synthesize_plt_symbols(struct dso *dso, char *name, struct map *map, char sympltname[1024]; Elf *elf; int nr = 0, symidx, fd, err = 0; + char name[PATH_MAX]; + snprintf(name, sizeof(name), "%s%s", + symbol_conf.symfs, dso->long_name); fd = open(name, O_RDONLY); if (fd < 0) goto out; @@ -1701,9 +1702,8 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) continue; if (ret > 0) { - int nr_plt; - - nr_plt = dso__synthesize_plt_symbols(dso, name, map, filter); + int nr_plt = dso__synthesize_plt_symbols(dso, map, + filter); if (nr_plt > 0) ret += nr_plt; break; diff --git a/trunk/tools/perf/util/trace-event-parse.c b/trunk/tools/perf/util/trace-event-parse.c index dfd1bd8371a4..a4088ced1e64 100644 --- a/trunk/tools/perf/util/trace-event-parse.c +++ b/trunk/tools/perf/util/trace-event-parse.c @@ -722,7 +722,7 @@ static char *event_read_name(void) static int event_read_id(void) { char *token; - int id = -1; + int id; if (read_expected_item(EVENT_ITEM, "ID") < 0) return -1; @@ -731,13 +731,15 @@ static int event_read_id(void) return -1; if (read_expect_type(EVENT_ITEM, &token) < 0) - goto free; + goto fail; id = strtoul(token, NULL, 0); - - free: free_token(token); return id; + + fail: + free_token(token); + return -1; } static int field_is_string(struct format_field *field) diff --git a/trunk/tools/perf/util/ui/browser.h b/trunk/tools/perf/util/ui/browser.h index 6ee82f60feaf..84d761b730c1 100644 --- a/trunk/tools/perf/util/ui/browser.h +++ b/trunk/tools/perf/util/ui/browser.h @@ -49,8 +49,6 @@ int ui_browser__warning(struct ui_browser *browser, int timeout, const char *format, ...); int ui_browser__help_window(struct ui_browser *browser, const char *text); bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text); -int ui_browser__input_window(const char *title, const char *text, char *input, - const char *exit_msg, int delay_sec); void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence); unsigned int ui_browser__argv_refresh(struct ui_browser *browser); diff --git a/trunk/tools/perf/util/ui/browsers/hists.c b/trunk/tools/perf/util/ui/browsers/hists.c index 2f83e5dc9967..fa530fcc764a 100644 --- a/trunk/tools/perf/util/ui/browsers/hists.c +++ b/trunk/tools/perf/util/ui/browsers/hists.c @@ -125,9 +125,6 @@ static int callchain__count_rows(struct rb_root *chain) static bool map_symbol__toggle_fold(struct map_symbol *self) { - if (!self) - return false; - if (!self->has_children) return false; @@ -882,7 +879,6 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, char *options[16]; int nr_options = 0; int key = -1; - char buf[64]; if (browser == NULL) return -1; @@ -937,16 +933,6 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, goto zoom_dso; case 't': goto zoom_thread; - case 's': - if (ui_browser__input_window("Symbol to show", - "Please enter the name of symbol you want to see", - buf, "ENTER: OK, ESC: Cancel", - delay_secs * 2) == K_ENTER) { - self->symbol_filter_str = *buf ? buf : NULL; - hists__filter_by_symbol(self); - hist_browser__reset(browser); - } - continue; case K_F1: case 'h': case '?': @@ -964,8 +950,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, "C Collapse all callchains\n" "E Expand all callchains\n" "d Zoom into current DSO\n" - "t Zoom into current Thread\n" - "s Filter symbol by name"); + "t Zoom into current Thread"); continue; case K_ENTER: case K_RIGHT: diff --git a/trunk/tools/perf/util/ui/keysyms.h b/trunk/tools/perf/util/ui/keysyms.h index 809eca5707fa..3458b1985761 100644 --- a/trunk/tools/perf/util/ui/keysyms.h +++ b/trunk/tools/perf/util/ui/keysyms.h @@ -16,8 +16,6 @@ #define K_TAB '\t' #define K_UNTAB SL_KEY_UNTAB #define K_UP SL_KEY_UP -#define K_BKSPC 0x7f -#define K_DEL SL_KEY_DELETE /* Not really keys */ #define K_TIMER -1 diff --git a/trunk/tools/perf/util/ui/util.c b/trunk/tools/perf/util/ui/util.c index ad4374a16bb0..45daa7c41dad 100644 --- a/trunk/tools/perf/util/ui/util.c +++ b/trunk/tools/perf/util/ui/util.c @@ -69,88 +69,6 @@ int ui__popup_menu(int argc, char * const argv[]) return popup_menu__run(&menu); } -int ui_browser__input_window(const char *title, const char *text, char *input, - const char *exit_msg, int delay_secs) -{ - int x, y, len, key; - int max_len = 60, nr_lines = 0; - static char buf[50]; - const char *t; - - t = text; - while (1) { - const char *sep = strchr(t, '\n'); - - if (sep == NULL) - sep = strchr(t, '\0'); - len = sep - t; - if (max_len < len) - max_len = len; - ++nr_lines; - if (*sep == '\0') - break; - t = sep + 1; - } - - max_len += 2; - nr_lines += 8; - y = SLtt_Screen_Rows / 2 - nr_lines / 2; - x = SLtt_Screen_Cols / 2 - max_len / 2; - - SLsmg_set_color(0); - SLsmg_draw_box(y, x++, nr_lines, max_len); - if (title) { - SLsmg_gotorc(y, x + 1); - SLsmg_write_string((char *)title); - } - SLsmg_gotorc(++y, x); - nr_lines -= 7; - max_len -= 2; - SLsmg_write_wrapped_string((unsigned char *)text, y, x, - nr_lines, max_len, 1); - y += nr_lines; - len = 5; - while (len--) { - SLsmg_gotorc(y + len - 1, x); - SLsmg_write_nstring((char *)" ", max_len); - } - SLsmg_draw_box(y++, x + 1, 3, max_len - 2); - - SLsmg_gotorc(y + 3, x); - SLsmg_write_nstring((char *)exit_msg, max_len); - SLsmg_refresh(); - - x += 2; - len = 0; - key = ui__getch(delay_secs); - while (key != K_TIMER && key != K_ENTER && key != K_ESC) { - if (key == K_BKSPC) { - if (len == 0) - goto next_key; - SLsmg_gotorc(y, x + --len); - SLsmg_write_char(' '); - } else { - buf[len] = key; - SLsmg_gotorc(y, x + len++); - SLsmg_write_char(key); - } - SLsmg_refresh(); - - /* XXX more graceful overflow handling needed */ - if (len == sizeof(buf) - 1) { - ui_helpline__push("maximum size of symbol name reached!"); - key = K_ENTER; - break; - } -next_key: - key = ui__getch(delay_secs); - } - - buf[len] = '\0'; - strncpy(input, buf, len+1); - return key; -} - int ui__question_window(const char *title, const char *text, const char *exit_msg, int delay_secs) { diff --git a/trunk/tools/power/x86/turbostat/turbostat.8 b/trunk/tools/power/x86/turbostat/turbostat.8 index adf175f61496..555c69a5592a 100644 --- a/trunk/tools/power/x86/turbostat/turbostat.8 +++ b/trunk/tools/power/x86/turbostat/turbostat.8 @@ -4,13 +4,11 @@ turbostat \- Report processor frequency and idle statistics .SH SYNOPSIS .ft B .B turbostat -.RB [ "\-s" ] .RB [ "\-v" ] .RB [ "\-M MSR#" ] .RB command .br .B turbostat -.RB [ "\-s" ] .RB [ "\-v" ] .RB [ "\-M MSR#" ] .RB [ "\-i interval_sec" ] @@ -27,8 +25,6 @@ supports an "invariant" TSC, plus the APERF and MPERF MSRs. on processors that additionally support C-state residency counters. .SS Options -The \fB-s\fP option prints only a 1-line summary for each sample interval. -.PP The \fB-v\fP option increases verbosity. .PP The \fB-M MSR#\fP option dumps the specified MSR, @@ -43,14 +39,13 @@ displays the statistics gathered since it was forked. .SH FIELD DESCRIPTIONS .nf \fBpk\fP processor package number. -\fBcor\fP processor core number. +\fBcr\fP processor core number. \fBCPU\fP Linux CPU (logical processor) number. -Note that multiple CPUs per core indicate support for Intel(R) Hyper-Threading Technology. \fB%c0\fP percent of the interval that the CPU retired instructions. \fBGHz\fP average clock rate while the CPU was in c0 state. \fBTSC\fP average GHz that the TSC ran during the entire interval. -\fB%c1, %c3, %c6, %c7\fP show the percentage residency in hardware core idle states. -\fB%pc2, %pc3, %pc6, %pc7\fP percentage residency in hardware package idle states. +\fB%c1, %c3, %c6\fP show the percentage residency in hardware core idle states. +\fB%pc3, %pc6\fP percentage residency in hardware package idle states. .fi .PP .SH EXAMPLE @@ -58,37 +53,25 @@ Without any parameters, turbostat prints out counters ever 5 seconds. (override interval with "-i sec" option, or specify a command for turbostat to fork). -The first row of statistics is a summary for the entire system. -Note that the summary is a weighted average. +The first row of statistics reflect the average for the entire system. Subsequent rows show per-CPU statistics. .nf [root@x980]# ./turbostat -cor CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 - 0.60 1.63 3.38 2.91 0.00 96.49 0.00 76.64 - 0 0 0.59 1.62 3.38 4.51 0.00 94.90 0.00 76.64 - 0 6 1.13 1.64 3.38 3.97 0.00 94.90 0.00 76.64 - 1 2 0.08 1.62 3.38 0.07 0.00 99.85 0.00 76.64 - 1 8 0.03 1.62 3.38 0.12 0.00 99.85 0.00 76.64 - 2 4 0.01 1.62 3.38 0.06 0.00 99.93 0.00 76.64 - 2 10 0.04 1.62 3.38 0.02 0.00 99.93 0.00 76.64 - 8 1 2.85 1.62 3.38 11.71 0.00 85.44 0.00 76.64 - 8 7 1.98 1.62 3.38 12.58 0.00 85.44 0.00 76.64 - 9 3 0.36 1.62 3.38 0.71 0.00 98.93 0.00 76.64 - 9 9 0.09 1.62 3.38 0.98 0.00 98.93 0.00 76.64 - 10 5 0.03 1.62 3.38 0.09 0.00 99.87 0.00 76.64 - 10 11 0.07 1.62 3.38 0.06 0.00 99.87 0.00 76.64 -.fi -.SH SUMMARY EXAMPLE -The "-s" option prints the column headers just once, -and then the one line system summary for each sample interval. - -.nf -[root@x980]# ./turbostat -s - %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 - 0.61 1.89 3.38 5.95 0.00 93.44 0.00 66.33 - 0.52 1.62 3.38 6.83 0.00 92.65 0.00 61.11 - 0.62 1.92 3.38 5.47 0.00 93.91 0.00 67.31 +cr CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 + 0.04 1.62 3.38 0.11 0.00 99.85 0.00 95.07 + 0 0 0.04 1.62 3.38 0.06 0.00 99.90 0.00 95.07 + 0 6 0.02 1.62 3.38 0.08 0.00 99.90 0.00 95.07 + 1 2 0.10 1.62 3.38 0.29 0.00 99.61 0.00 95.07 + 1 8 0.11 1.62 3.38 0.28 0.00 99.61 0.00 95.07 + 2 4 0.01 1.62 3.38 0.01 0.00 99.98 0.00 95.07 + 2 10 0.01 1.61 3.38 0.02 0.00 99.98 0.00 95.07 + 8 1 0.07 1.62 3.38 0.15 0.00 99.78 0.00 95.07 + 8 7 0.03 1.62 3.38 0.19 0.00 99.78 0.00 95.07 + 9 3 0.01 1.62 3.38 0.02 0.00 99.98 0.00 95.07 + 9 9 0.01 1.62 3.38 0.02 0.00 99.98 0.00 95.07 + 10 5 0.01 1.62 3.38 0.13 0.00 99.86 0.00 95.07 + 10 11 0.08 1.62 3.38 0.05 0.00 99.86 0.00 95.07 .fi .SH VERBOSE EXAMPLE The "-v" option adds verbosity to the output: @@ -118,33 +101,33 @@ until ^C while the other CPUs are mostly idle: .nf [root@x980 lenb]# ./turbostat cat /dev/zero > /dev/null -^C -cor CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 - 8.63 3.64 3.38 14.46 0.49 76.42 0.00 0.00 - 0 0 0.34 3.36 3.38 99.66 0.00 0.00 0.00 0.00 - 0 6 99.96 3.64 3.38 0.04 0.00 0.00 0.00 0.00 - 1 2 0.14 3.50 3.38 1.75 2.04 96.07 0.00 0.00 - 1 8 0.38 3.57 3.38 1.51 2.04 96.07 0.00 0.00 - 2 4 0.01 2.65 3.38 0.06 0.00 99.93 0.00 0.00 - 2 10 0.03 2.12 3.38 0.04 0.00 99.93 0.00 0.00 - 8 1 0.91 3.59 3.38 35.27 0.92 62.90 0.00 0.00 - 8 7 1.61 3.63 3.38 34.57 0.92 62.90 0.00 0.00 - 9 3 0.04 3.38 3.38 0.20 0.00 99.76 0.00 0.00 - 9 9 0.04 3.29 3.38 0.20 0.00 99.76 0.00 0.00 - 10 5 0.03 3.08 3.38 0.12 0.00 99.85 0.00 0.00 - 10 11 0.05 3.07 3.38 0.10 0.00 99.85 0.00 0.00 -4.907015 sec + +^Ccr CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 + 8.49 3.63 3.38 16.23 0.66 74.63 0.00 0.00 + 0 0 1.22 3.62 3.38 32.18 0.00 66.60 0.00 0.00 + 0 6 0.40 3.61 3.38 33.00 0.00 66.60 0.00 0.00 + 1 2 0.11 3.14 3.38 0.19 3.95 95.75 0.00 0.00 + 1 8 0.05 2.88 3.38 0.25 3.95 95.75 0.00 0.00 + 2 4 0.00 3.13 3.38 0.02 0.00 99.98 0.00 0.00 + 2 10 0.00 3.09 3.38 0.02 0.00 99.98 0.00 0.00 + 8 1 0.04 3.50 3.38 14.43 0.00 85.54 0.00 0.00 + 8 7 0.03 2.98 3.38 14.43 0.00 85.54 0.00 0.00 + 9 3 0.00 3.16 3.38 100.00 0.00 0.00 0.00 0.00 + 9 9 99.93 3.63 3.38 0.06 0.00 0.00 0.00 0.00 + 10 5 0.01 2.82 3.38 0.08 0.00 99.91 0.00 0.00 + 10 11 0.02 3.36 3.38 0.06 0.00 99.91 0.00 0.00 +6.950866 sec .fi -Above the cycle soaker drives cpu6 up 3.6 Ghz turbo limit +Above the cycle soaker drives cpu9 up 3.6 Ghz turbo limit while the other processors are generally in various states of idle. -Note that cpu0 is an HT sibling sharing core0 -with cpu6, and thus it is unable to get to an idle state -deeper than c1 while cpu6 is busy. +Note that cpu3 is an HT sibling sharing core9 +with cpu9, and thus it is unable to get to an idle state +deeper than c1 while cpu9 is busy. -Note that turbostat reports average GHz of 3.64, while -the arithmetic average of the GHz column above is lower. +Note that turbostat reports average GHz of 3.61, while +the arithmetic average of the GHz column above is 3.24. This is a weighted average, where the weight is %c0. ie. it is the total number of un-halted cycles elapsed per time divided by the number of CPUs. .SH NOTES @@ -184,6 +167,6 @@ http://www.intel.com/products/processor/manuals/ .SH "SEE ALSO" msr(4), vmstat(8) .PP -.SH AUTHOR +.SH AUTHORS .nf Written by Len Brown diff --git a/trunk/tools/power/x86/turbostat/turbostat.c b/trunk/tools/power/x86/turbostat/turbostat.c index ab2f682fd44c..310d3dd5e547 100644 --- a/trunk/tools/power/x86/turbostat/turbostat.c +++ b/trunk/tools/power/x86/turbostat/turbostat.c @@ -2,7 +2,7 @@ * turbostat -- show CPU frequency and C-state residency * on modern Intel turbo-capable processors. * - * Copyright (c) 2012 Intel Corporation. + * Copyright (c) 2010, Intel Corporation. * Len Brown * * This program is free software; you can redistribute it and/or modify it @@ -19,7 +19,6 @@ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. */ -#define _GNU_SOURCE #include #include #include @@ -33,7 +32,6 @@ #include #include #include -#include #define MSR_TSC 0x10 #define MSR_NEHALEM_PLATFORM_INFO 0xCE @@ -51,7 +49,6 @@ char *proc_stat = "/proc/stat"; unsigned int interval_sec = 5; /* set with -i interval_sec */ unsigned int verbose; /* set with -v */ -unsigned int summary_only; /* set with -s */ unsigned int skip_c0; unsigned int skip_c1; unsigned int do_nhm_cstates; @@ -71,10 +68,9 @@ unsigned int show_cpu; int aperf_mperf_unstable; int backwards_count; char *progname; +int need_reinitialize; int num_cpus; -cpu_set_t *cpu_mask; -size_t cpu_mask_size; struct counters { unsigned long long tsc; /* per thread */ @@ -103,76 +99,44 @@ struct timeval tv_even; struct timeval tv_odd; struct timeval tv_delta; -/* - * cpu_mask_init(ncpus) - * - * allocate and clear cpu_mask - * set cpu_mask_size - */ -void cpu_mask_init(int ncpus) -{ - cpu_mask = CPU_ALLOC(ncpus); - if (cpu_mask == NULL) { - perror("CPU_ALLOC"); - exit(3); - } - cpu_mask_size = CPU_ALLOC_SIZE(ncpus); - CPU_ZERO_S(cpu_mask_size, cpu_mask); -} - -void cpu_mask_uninit() -{ - CPU_FREE(cpu_mask); - cpu_mask = NULL; - cpu_mask_size = 0; -} - -int cpu_migrate(int cpu) -{ - CPU_ZERO_S(cpu_mask_size, cpu_mask); - CPU_SET_S(cpu, cpu_mask_size, cpu_mask); - if (sched_setaffinity(0, cpu_mask_size, cpu_mask) == -1) - return -1; - else - return 0; -} - -int get_msr(int cpu, off_t offset, unsigned long long *msr) +unsigned long long get_msr(int cpu, off_t offset) { ssize_t retval; + unsigned long long msr; char pathname[32]; int fd; sprintf(pathname, "/dev/cpu/%d/msr", cpu); fd = open(pathname, O_RDONLY); - if (fd < 0) - return -1; - - retval = pread(fd, msr, sizeof *msr, offset); - close(fd); + if (fd < 0) { + perror(pathname); + need_reinitialize = 1; + return 0; + } - if (retval != sizeof *msr) - return -1; + retval = pread(fd, &msr, sizeof msr, offset); + if (retval != sizeof msr) { + fprintf(stderr, "cpu%d pread(..., 0x%zx) = %jd\n", + cpu, offset, retval); + exit(-2); + } - return 0; + close(fd); + return msr; } void print_header(void) { if (show_pkg) fprintf(stderr, "pk"); - if (show_pkg) - fprintf(stderr, " "); if (show_core) - fprintf(stderr, "cor"); + fprintf(stderr, " cr"); if (show_cpu) fprintf(stderr, " CPU"); - if (show_pkg || show_core || show_cpu) - fprintf(stderr, " "); if (do_nhm_cstates) - fprintf(stderr, " %%c0"); + fprintf(stderr, " %%c0 "); if (has_aperf) - fprintf(stderr, " GHz"); + fprintf(stderr, " GHz"); fprintf(stderr, " TSC"); if (do_nhm_cstates) fprintf(stderr, " %%c1"); @@ -183,13 +147,13 @@ void print_header(void) if (do_snb_cstates) fprintf(stderr, " %%c7"); if (do_snb_cstates) - fprintf(stderr, " %%pc2"); + fprintf(stderr, " %%pc2"); if (do_nhm_cstates) - fprintf(stderr, " %%pc3"); + fprintf(stderr, " %%pc3"); if (do_nhm_cstates) - fprintf(stderr, " %%pc6"); + fprintf(stderr, " %%pc6"); if (do_snb_cstates) - fprintf(stderr, " %%pc7"); + fprintf(stderr, " %%pc7"); if (extra_msr_offset) fprintf(stderr, " MSR 0x%x ", extra_msr_offset); @@ -223,15 +187,6 @@ void dump_list(struct counters *cnt) dump_cnt(cnt); } -/* - * column formatting convention & formats - * package: "pk" 2 columns %2d - * core: "cor" 3 columns %3d - * CPU: "CPU" 3 columns %3d - * GHz: "GHz" 3 columns %3.2 - * TSC: "TSC" 3 columns %3.2 - * percentage " %pc3" %6.2 - */ void print_cnt(struct counters *p) { double interval_float; @@ -241,45 +196,39 @@ void print_cnt(struct counters *p) /* topology columns, print blanks on 1st (average) line */ if (p == cnt_average) { if (show_pkg) - fprintf(stderr, " "); - if (show_pkg && show_core) fprintf(stderr, " "); if (show_core) - fprintf(stderr, " "); + fprintf(stderr, " "); if (show_cpu) - fprintf(stderr, " " " "); + fprintf(stderr, " "); } else { if (show_pkg) - fprintf(stderr, "%2d", p->pkg); - if (show_pkg && show_core) - fprintf(stderr, " "); + fprintf(stderr, "%d", p->pkg); if (show_core) - fprintf(stderr, "%3d", p->core); + fprintf(stderr, "%4d", p->core); if (show_cpu) - fprintf(stderr, " %3d", p->cpu); + fprintf(stderr, "%4d", p->cpu); } /* %c0 */ if (do_nhm_cstates) { - if (show_pkg || show_core || show_cpu) - fprintf(stderr, " "); if (!skip_c0) - fprintf(stderr, "%6.2f", 100.0 * p->mperf/p->tsc); + fprintf(stderr, "%7.2f", 100.0 * p->mperf/p->tsc); else - fprintf(stderr, " ****"); + fprintf(stderr, " ****"); } /* GHz */ if (has_aperf) { if (!aperf_mperf_unstable) { - fprintf(stderr, " %3.2f", + fprintf(stderr, "%5.2f", 1.0 * p->tsc / units * p->aperf / p->mperf / interval_float); } else { if (p->aperf > p->tsc || p->mperf > p->tsc) { - fprintf(stderr, " ***"); + fprintf(stderr, " ****"); } else { - fprintf(stderr, "%3.1f*", + fprintf(stderr, "%4.1f*", 1.0 * p->tsc / units * p->aperf / p->mperf / interval_float); @@ -292,7 +241,7 @@ void print_cnt(struct counters *p) if (do_nhm_cstates) { if (!skip_c1) - fprintf(stderr, " %6.2f", 100.0 * p->c1/p->tsc); + fprintf(stderr, "%7.2f", 100.0 * p->c1/p->tsc); else fprintf(stderr, " ****"); } @@ -303,13 +252,13 @@ void print_cnt(struct counters *p) if (do_snb_cstates) fprintf(stderr, " %6.2f", 100.0 * p->c7/p->tsc); if (do_snb_cstates) - fprintf(stderr, " %6.2f", 100.0 * p->pc2/p->tsc); + fprintf(stderr, " %5.2f", 100.0 * p->pc2/p->tsc); if (do_nhm_cstates) - fprintf(stderr, " %6.2f", 100.0 * p->pc3/p->tsc); + fprintf(stderr, " %5.2f", 100.0 * p->pc3/p->tsc); if (do_nhm_cstates) - fprintf(stderr, " %6.2f", 100.0 * p->pc6/p->tsc); + fprintf(stderr, " %5.2f", 100.0 * p->pc6/p->tsc); if (do_snb_cstates) - fprintf(stderr, " %6.2f", 100.0 * p->pc7/p->tsc); + fprintf(stderr, " %5.2f", 100.0 * p->pc7/p->tsc); if (extra_msr_offset) fprintf(stderr, " 0x%016llx", p->extra_msr); putc('\n', stderr); @@ -318,20 +267,12 @@ void print_cnt(struct counters *p) void print_counters(struct counters *counters) { struct counters *cnt; - static int printed; - - if (!printed || !summary_only) - print_header(); + print_header(); if (num_cpus > 1) print_cnt(cnt_average); - printed = 1; - - if (summary_only) - return; - for (cnt = counters; cnt != NULL; cnt = cnt->next) print_cnt(cnt); @@ -499,51 +440,31 @@ void compute_average(struct counters *delta, struct counters *avg) free(sum); } -int get_counters(struct counters *cnt) +void get_counters(struct counters *cnt) { for ( ; cnt; cnt = cnt->next) { - - if (cpu_migrate(cnt->cpu)) - return -1; - - if (get_msr(cnt->cpu, MSR_TSC, &cnt->tsc)) - return -1; - - if (has_aperf) { - if (get_msr(cnt->cpu, MSR_APERF, &cnt->aperf)) - return -1; - if (get_msr(cnt->cpu, MSR_MPERF, &cnt->mperf)) - return -1; - } - - if (do_nhm_cstates) { - if (get_msr(cnt->cpu, MSR_CORE_C3_RESIDENCY, &cnt->c3)) - return -1; - if (get_msr(cnt->cpu, MSR_CORE_C6_RESIDENCY, &cnt->c6)) - return -1; - } - + cnt->tsc = get_msr(cnt->cpu, MSR_TSC); + if (do_nhm_cstates) + cnt->c3 = get_msr(cnt->cpu, MSR_CORE_C3_RESIDENCY); + if (do_nhm_cstates) + cnt->c6 = get_msr(cnt->cpu, MSR_CORE_C6_RESIDENCY); if (do_snb_cstates) - if (get_msr(cnt->cpu, MSR_CORE_C7_RESIDENCY, &cnt->c7)) - return -1; - - if (do_nhm_cstates) { - if (get_msr(cnt->cpu, MSR_PKG_C3_RESIDENCY, &cnt->pc3)) - return -1; - if (get_msr(cnt->cpu, MSR_PKG_C6_RESIDENCY, &cnt->pc6)) - return -1; - } - if (do_snb_cstates) { - if (get_msr(cnt->cpu, MSR_PKG_C2_RESIDENCY, &cnt->pc2)) - return -1; - if (get_msr(cnt->cpu, MSR_PKG_C7_RESIDENCY, &cnt->pc7)) - return -1; - } + cnt->c7 = get_msr(cnt->cpu, MSR_CORE_C7_RESIDENCY); + if (has_aperf) + cnt->aperf = get_msr(cnt->cpu, MSR_APERF); + if (has_aperf) + cnt->mperf = get_msr(cnt->cpu, MSR_MPERF); + if (do_snb_cstates) + cnt->pc2 = get_msr(cnt->cpu, MSR_PKG_C2_RESIDENCY); + if (do_nhm_cstates) + cnt->pc3 = get_msr(cnt->cpu, MSR_PKG_C3_RESIDENCY); + if (do_nhm_cstates) + cnt->pc6 = get_msr(cnt->cpu, MSR_PKG_C6_RESIDENCY); + if (do_snb_cstates) + cnt->pc7 = get_msr(cnt->cpu, MSR_PKG_C7_RESIDENCY); if (extra_msr_offset) - if (get_msr(cnt->cpu, extra_msr_offset, &cnt->extra_msr)) - return -1; + cnt->extra_msr = get_msr(cnt->cpu, extra_msr_offset); } - return 0; } void print_nehalem_info(void) @@ -554,7 +475,7 @@ void print_nehalem_info(void) if (!do_nehalem_platform_info) return; - get_msr(0, MSR_NEHALEM_PLATFORM_INFO, &msr); + msr = get_msr(0, MSR_NEHALEM_PLATFORM_INFO); ratio = (msr >> 40) & 0xFF; fprintf(stderr, "%d * %.0f = %.0f MHz max efficiency\n", @@ -570,7 +491,7 @@ void print_nehalem_info(void) if (!do_nehalem_turbo_ratio_limit) return; - get_msr(0, MSR_NEHALEM_TURBO_RATIO_LIMIT, &msr); + msr = get_msr(0, MSR_NEHALEM_TURBO_RATIO_LIMIT); ratio = (msr >> 24) & 0xFF; if (ratio) @@ -636,8 +557,7 @@ void insert_counters(struct counters **list, return; } - if (!summary_only) - show_cpu = 1; /* there is more than one CPU */ + show_cpu = 1; /* there is more than one CPU */ /* * insert on front of list. @@ -655,15 +575,13 @@ void insert_counters(struct counters **list, while (prev->next && (prev->next->pkg < new->pkg)) { prev = prev->next; - if (!summary_only) - show_pkg = 1; /* there is more than 1 package */ + show_pkg = 1; /* there is more than 1 package */ } while (prev->next && (prev->next->pkg == new->pkg) && (prev->next->core < new->core)) { prev = prev->next; - if (!summary_only) - show_core = 1; /* there is more than 1 core */ + show_core = 1; /* there is more than 1 core */ } while (prev->next && (prev->next->pkg == new->pkg) @@ -763,7 +681,7 @@ int get_core_id(int cpu) } /* - * run func(pkg, core, cpu) on every cpu in /proc/stat + * run func(index, cpu) on every cpu in /proc/stat */ int for_all_cpus(void (func)(int, int, int)) @@ -799,18 +717,18 @@ int for_all_cpus(void (func)(int, int, int)) void re_initialize(void) { + printf("turbostat: topology changed, re-initializing.\n"); free_all_counters(); num_cpus = for_all_cpus(alloc_new_counters); - cpu_mask_uninit(); - cpu_mask_init(num_cpus); - printf("turbostat: re-initialized with num_cpus %d\n", num_cpus); + need_reinitialize = 0; + printf("num_cpus is now %d\n", num_cpus); } void dummy(int pkg, int core, int cpu) { return; } /* * check to see if a cpu came on-line */ -int verify_num_cpus(void) +void verify_num_cpus(void) { int new_num_cpus; @@ -820,9 +738,8 @@ int verify_num_cpus(void) if (verbose) printf("num_cpus was %d, is now %d\n", num_cpus, new_num_cpus); - return -1; + need_reinitialize = 1; } - return 0; } void turbostat_loop() @@ -832,25 +749,25 @@ void turbostat_loop() gettimeofday(&tv_even, (struct timezone *)NULL); while (1) { - if (verify_num_cpus()) { + verify_num_cpus(); + if (need_reinitialize) { re_initialize(); goto restart; } sleep(interval_sec); - if (get_counters(cnt_odd)) { - re_initialize(); - goto restart; - } + get_counters(cnt_odd); gettimeofday(&tv_odd, (struct timezone *)NULL); + compute_delta(cnt_odd, cnt_even, cnt_delta); timersub(&tv_odd, &tv_even, &tv_delta); compute_average(cnt_delta, cnt_average); print_counters(cnt_delta); - sleep(interval_sec); - if (get_counters(cnt_even)) { + if (need_reinitialize) { re_initialize(); goto restart; } + sleep(interval_sec); + get_counters(cnt_even); gettimeofday(&tv_even, (struct timezone *)NULL); compute_delta(cnt_even, cnt_odd, cnt_delta); timersub(&tv_even, &tv_odd, &tv_delta); @@ -1036,7 +953,6 @@ void turbostat_init() check_super_user(); num_cpus = for_all_cpus(alloc_new_counters); - cpu_mask_init(num_cpus); if (verbose) print_nehalem_info(); @@ -1089,11 +1005,8 @@ void cmdline(int argc, char **argv) progname = argv[0]; - while ((opt = getopt(argc, argv, "+svi:M:")) != -1) { + while ((opt = getopt(argc, argv, "+vi:M:")) != -1) { switch (opt) { - case 's': - summary_only++; - break; case 'v': verbose++; break; diff --git a/trunk/tools/testing/ktest/ktest.pl b/trunk/tools/testing/ktest/ktest.pl index 4915408f6a98..95d6a6f7c33a 100755 --- a/trunk/tools/testing/ktest/ktest.pl +++ b/trunk/tools/testing/ktest/ktest.pl @@ -183,9 +183,6 @@ # do not force reboots on config problems my $no_reboot = 1; -# reboot on success -my $reboot_success = 0; - my %option_map = ( "MACHINE" => \$machine, "SSH_USER" => \$ssh_user, @@ -2195,7 +2192,7 @@ sub run_bisect { } # Are we looking for where it worked, not failed? - if ($reverse_bisect && $ret >= 0) { + if ($reverse_bisect) { $ret = !$ret; } @@ -3472,7 +3469,6 @@ sub set_test_option { # Do not reboot on failing test options $no_reboot = 1; - $reboot_success = 0; $iteration = $i; @@ -3558,11 +3554,9 @@ sub set_test_option { die "failed to checkout $checkout"; } - $no_reboot = 0; - # A test may opt to not reboot the box if ($reboot_on_success) { - $reboot_success = 1; + $no_reboot = 0; } if ($test_type eq "bisect") { @@ -3606,7 +3600,7 @@ sub set_test_option { if ($opt{"POWEROFF_ON_SUCCESS"}) { halt; -} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) { +} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) { reboot_to_good; } elsif (defined($switch_to_good)) { # still need to get to the good kernel diff --git a/trunk/virt/kvm/iommu.c b/trunk/virt/kvm/iommu.c index e9fff9830bf0..a457d2138f49 100644 --- a/trunk/virt/kvm/iommu.c +++ b/trunk/virt/kvm/iommu.c @@ -240,13 +240,9 @@ int kvm_iommu_map_guest(struct kvm *kvm) return -ENODEV; } - mutex_lock(&kvm->slots_lock); - kvm->arch.iommu_domain = iommu_domain_alloc(&pci_bus_type); - if (!kvm->arch.iommu_domain) { - r = -ENOMEM; - goto out_unlock; - } + if (!kvm->arch.iommu_domain) + return -ENOMEM; if (!allow_unsafe_assigned_interrupts && !iommu_domain_has_cap(kvm->arch.iommu_domain, @@ -257,16 +253,17 @@ int kvm_iommu_map_guest(struct kvm *kvm) " module option.\n", __func__); iommu_domain_free(kvm->arch.iommu_domain); kvm->arch.iommu_domain = NULL; - r = -EPERM; - goto out_unlock; + return -EPERM; } r = kvm_iommu_map_memslots(kvm); if (r) - kvm_iommu_unmap_memslots(kvm); + goto out_unmap; -out_unlock: - mutex_unlock(&kvm->slots_lock); + return 0; + +out_unmap: + kvm_iommu_unmap_memslots(kvm); return r; } @@ -313,11 +310,6 @@ static void kvm_iommu_put_pages(struct kvm *kvm, } } -void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot) -{ - kvm_iommu_put_pages(kvm, slot->base_gfn, slot->npages); -} - static int kvm_iommu_unmap_memslots(struct kvm *kvm) { int idx; @@ -328,7 +320,7 @@ static int kvm_iommu_unmap_memslots(struct kvm *kvm) slots = kvm_memslots(kvm); kvm_for_each_memslot(memslot, slots) - kvm_iommu_unmap_pages(kvm, memslot); + kvm_iommu_put_pages(kvm, memslot->base_gfn, memslot->npages); srcu_read_unlock(&kvm->srcu, idx); @@ -343,11 +335,7 @@ int kvm_iommu_unmap_guest(struct kvm *kvm) if (!domain) return 0; - mutex_lock(&kvm->slots_lock); kvm_iommu_unmap_memslots(kvm); - kvm->arch.iommu_domain = NULL; - mutex_unlock(&kvm->slots_lock); - iommu_domain_free(domain); return 0; } diff --git a/trunk/virt/kvm/kvm_main.c b/trunk/virt/kvm/kvm_main.c index 9739b533ca2e..42b73930a6de 100644 --- a/trunk/virt/kvm/kvm_main.c +++ b/trunk/virt/kvm/kvm_main.c @@ -808,13 +808,12 @@ int __kvm_set_memory_region(struct kvm *kvm, if (r) goto out_free; - /* map/unmap the pages in iommu page table */ + /* map the pages in iommu page table */ if (npages) { r = kvm_iommu_map_pages(kvm, &new); if (r) goto out_free; - } else - kvm_iommu_unmap_pages(kvm, &old); + } r = -ENOMEM; slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots),