]> err.no Git - linux-2.6/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Sun, 22 Jul 2007 18:45:17 +0000 (11:45 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Sun, 22 Jul 2007 18:45:17 +0000 (11:45 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband:
  IB/ehca: Support small QP queues
  IB/ehca: Make internal_create/destroy_qp() static
  IB/ehca: Move ehca2ib_return_code() out of line
  IB/ehca: Generate async event when SRQ limit reached
  IB/ehca: Support large page MRs
  IB/mlx4: Fix error path in create_qp_common()
  mlx4_core: Change command token on timeout
  IB/mthca: Change command token on timeout
  IB/ipath: Remove ipath_layer dead code
  IB/mlx4: Fix leaks in __mlx4_ib_modify_qp

635 files changed:
Documentation/DocBook/libata.tmpl
Documentation/feature-removal-schedule.txt
Documentation/kernel-parameters.txt
Documentation/power/freezing-of-tasks.txt
Documentation/thinkpad-acpi.txt
Documentation/x86_64/boot-options.txt
Documentation/x86_64/machinecheck
MAINTAINERS
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/Makefile
arch/arm/boot/Makefile
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/head.S
arch/arm/configs/em_x270_defconfig [new file with mode: 0644]
arch/arm/configs/s3c2410_defconfig
arch/arm/mach-at91/at91rm9200_devices.c
arch/arm/mach-davinci/time.c
arch/arm/mach-imx/time.c
arch/arm/mach-iop32x/Kconfig
arch/arm/mach-iop32x/Makefile
arch/arm/mach-iop32x/em7210.c [new file with mode: 0644]
arch/arm/mach-iop32x/irq.c
arch/arm/mach-ixp4xx/common.c
arch/arm/mach-ks8695/irq.c
arch/arm/mach-mx3/Kconfig [new file with mode: 0644]
arch/arm/mach-mx3/Makefile [new file with mode: 0644]
arch/arm/mach-mx3/Makefile.boot [new file with mode: 0644]
arch/arm/mach-mx3/mm.c [new file with mode: 0644]
arch/arm/mach-mx3/mx31ads.c [new file with mode: 0644]
arch/arm/mach-mx3/time.c [new file with mode: 0644]
arch/arm/mach-ns9xxx/Makefile
arch/arm/mach-ns9xxx/board-a9m9750dev.c
arch/arm/mach-ns9xxx/generic.c
arch/arm/mach-ns9xxx/irq.c
arch/arm/mach-ns9xxx/mach-cc9p9360js.c
arch/arm/mach-omap1/time.c
arch/arm/mach-pxa/Kconfig
arch/arm/mach-pxa/Makefile
arch/arm/mach-pxa/devices.h
arch/arm/mach-pxa/em-x270.c [new file with mode: 0644]
arch/arm/mach-pxa/generic.c
arch/arm/mach-pxa/pm.c
arch/arm/mach-pxa/pxa25x.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-pxa/sleep.S
arch/arm/mach-pxa/time.c
arch/arm/mach-rpc/riscpc.c
arch/arm/mach-s3c2410/Kconfig
arch/arm/mach-s3c2410/clock.c
arch/arm/mach-s3c2410/dma.c
arch/arm/mach-s3c2410/mach-amlm5900.c
arch/arm/mach-s3c2410/mach-bast.c
arch/arm/mach-s3c2410/mach-h1940.c
arch/arm/mach-s3c2410/mach-n30.c
arch/arm/mach-s3c2410/mach-otom.c
arch/arm/mach-s3c2410/mach-qt2410.c
arch/arm/mach-s3c2410/mach-smdk2410.c
arch/arm/mach-s3c2410/mach-vr1000.c
arch/arm/mach-s3c2410/s3c2410.c
arch/arm/mach-s3c2410/sleep.S
arch/arm/mach-s3c2412/Kconfig
arch/arm/mach-s3c2412/clock.c
arch/arm/mach-s3c2412/dma.c
arch/arm/mach-s3c2412/mach-smdk2413.c
arch/arm/mach-s3c2412/mach-vstms.c
arch/arm/mach-s3c2412/s3c2412.c
arch/arm/mach-s3c2440/Kconfig
arch/arm/mach-s3c2440/dma.c
arch/arm/mach-s3c2440/mach-anubis.c
arch/arm/mach-s3c2440/mach-nexcoder.c
arch/arm/mach-s3c2440/mach-osiris.c
arch/arm/mach-s3c2440/mach-rx3715.c
arch/arm/mach-s3c2440/mach-smdk2440.c
arch/arm/mach-s3c2442/Kconfig
arch/arm/mach-s3c2443/Kconfig
arch/arm/mach-s3c2443/dma.c
arch/arm/mach-s3c2443/mach-smdk2443.c
arch/arm/mach-sa1100/Kconfig
arch/arm/mach-sa1100/Makefile
arch/arm/mach-sa1100/jornada720_ssp.c [new file with mode: 0644]
arch/arm/mach-sa1100/neponset.c
arch/arm/mm/Kconfig
arch/arm/mm/cache-l2x0.c
arch/arm/mm/mmu.c
arch/arm/mm/proc-syms.c
arch/arm/mm/proc-v7.S
arch/arm/plat-iop/time.c
arch/arm/plat-mxc/Kconfig [new file with mode: 0644]
arch/arm/plat-mxc/Makefile [new file with mode: 0644]
arch/arm/plat-mxc/irq.c [new file with mode: 0644]
arch/arm/plat-omap/timer32k.c
arch/arm/plat-s3c/Kconfig [new file with mode: 0644]
arch/arm/plat-s3c24xx/Kconfig
arch/arm/plat-s3c24xx/common-smdk.c
arch/arm/plat-s3c24xx/cpu.c
arch/arm/plat-s3c24xx/devs.c
arch/arm/plat-s3c24xx/pm.c
arch/arm/plat-s3c24xx/s3c244x.c
arch/arm/plat-s3c24xx/sleep.S
arch/arm/plat-s3c24xx/time.c
arch/arm/vfp/vfphw.S
arch/arm/vfp/vfpmodule.c
arch/arm26/kernel/armksyms.c
arch/arm26/kernel/irq.c
arch/avr32/boards/atngw100/setup.c
arch/avr32/configs/atngw100_defconfig
arch/i386/Kconfig
arch/i386/defconfig
arch/i386/kernel/Makefile
arch/i386/kernel/acpi/boot.c
arch/i386/kernel/alternative.c
arch/i386/kernel/apic.c
arch/i386/kernel/cpu/Makefile
arch/i386/kernel/cpu/amd.c
arch/i386/kernel/cpu/common.c
arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
arch/i386/kernel/cpu/cyrix.c
arch/i386/kernel/cpu/intel_cacheinfo.c
arch/i386/kernel/cpu/mcheck/mce.c
arch/i386/kernel/cpu/mcheck/non-fatal.c
arch/i386/kernel/cpu/mtrr/cyrix.c
arch/i386/kernel/cpu/mtrr/generic.c
arch/i386/kernel/cpu/mtrr/main.c
arch/i386/kernel/cpu/mtrr/state.c
arch/i386/kernel/cpu/perfctr-watchdog.c
arch/i386/kernel/cpu/rise.c [deleted file]
arch/i386/kernel/e820.c
arch/i386/kernel/geode.c [new file with mode: 0644]
arch/i386/kernel/hpet.c
arch/i386/kernel/i8253.c
arch/i386/kernel/io_apic.c
arch/i386/kernel/irq.c
arch/i386/kernel/kprobes.c
arch/i386/kernel/nmi.c
arch/i386/kernel/paravirt.c
arch/i386/kernel/process.c
arch/i386/kernel/reboot.c
arch/i386/kernel/setup.c
arch/i386/kernel/signal.c
arch/i386/kernel/smpboot.c
arch/i386/kernel/sysenter.c
arch/i386/kernel/time.c
arch/i386/kernel/traps.c
arch/i386/kernel/vmiclock.c
arch/i386/lib/Makefile
arch/i386/lib/string.c [new file with mode: 0644]
arch/i386/mm/fault.c
arch/i386/mm/init.c
arch/i386/mm/ioremap.c
arch/i386/mm/pageattr.c
arch/i386/mm/pgtable.c
arch/i386/pci/acpi.c
arch/i386/pci/common.c
arch/i386/pci/mmconfig-shared.c
arch/i386/xen/time.c
arch/i386/xen/xen-head.S
arch/ia64/ia32/binfmt_elf32.c
arch/m68k/kernel/ints.c
arch/powerpc/boot/ps3-head.S
arch/powerpc/boot/ps3-hvcall.S
arch/powerpc/configs/prpmc2800_defconfig
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/smp.c
arch/powerpc/mm/fault.c
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/tlb_32.c
arch/powerpc/platforms/Kconfig.cputype
arch/powerpc/platforms/cell/spufs/file.c
arch/powerpc/platforms/embedded6xx/Kconfig
arch/powerpc/platforms/ps3/Kconfig
arch/powerpc/platforms/pseries/firmware.c
arch/powerpc/platforms/pseries/pseries.h
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/sysdev/mpic.c
arch/powerpc/xmon/nonstdio.c
arch/powerpc/xmon/nonstdio.h
arch/powerpc/xmon/start.c
arch/powerpc/xmon/xmon.c
arch/ppc/syslib/mv64x60.c
arch/sh/kernel/timers/timer-tmu.c
arch/sparc/kernel/entry.S
arch/sparc/kernel/irq.c
arch/sparc/kernel/irq.h [new file with mode: 0644]
arch/sparc/kernel/pcic.c
arch/sparc/kernel/smp.c
arch/sparc/kernel/sparc_ksyms.c
arch/sparc/kernel/sun4c_irq.c
arch/sparc/kernel/sun4d_irq.c
arch/sparc/kernel/sun4d_smp.c
arch/sparc/kernel/sun4m_irq.c
arch/sparc/kernel/sun4m_smp.c
arch/sparc/kernel/tick14.c
arch/sparc/kernel/time.c
arch/sparc/mm/init.c
arch/sparc/mm/srmmu.c
arch/sparc/mm/sun4c.c
arch/sparc64/Kconfig
arch/sparc64/kernel/sparc64_ksyms.c
arch/sparc64/kernel/time.c
arch/x86_64/Kconfig
arch/x86_64/Makefile
arch/x86_64/boot/compressed/Makefile
arch/x86_64/defconfig
arch/x86_64/ia32/ia32_binfmt.c
arch/x86_64/ia32/ia32entry.S
arch/x86_64/kernel/aperture.c
arch/x86_64/kernel/apic.c
arch/x86_64/kernel/e820.c
arch/x86_64/kernel/early-quirks.c
arch/x86_64/kernel/entry.S
arch/x86_64/kernel/head.S
arch/x86_64/kernel/hpet.c
arch/x86_64/kernel/i8259.c
arch/x86_64/kernel/io_apic.c
arch/x86_64/kernel/kprobes.c
arch/x86_64/kernel/mce.c
arch/x86_64/kernel/mce_amd.c
arch/x86_64/kernel/mpparse.c
arch/x86_64/kernel/nmi.c
arch/x86_64/kernel/pci-calgary.c
arch/x86_64/kernel/pci-dma.c
arch/x86_64/kernel/pci-gart.c
arch/x86_64/kernel/pci-nommu.c
arch/x86_64/kernel/pci-swiotlb.c
arch/x86_64/kernel/process.c
arch/x86_64/kernel/reboot.c
arch/x86_64/kernel/setup.c
arch/x86_64/kernel/signal.c
arch/x86_64/kernel/smp.c
arch/x86_64/kernel/suspend.c
arch/x86_64/kernel/tce.c
arch/x86_64/kernel/time.c
arch/x86_64/kernel/traps.c
arch/x86_64/kernel/tsc.c
arch/x86_64/kernel/vmlinux.lds.S
arch/x86_64/kernel/vsyscall.c
arch/x86_64/mm/fault.c
arch/x86_64/mm/init.c
arch/x86_64/mm/k8topology.c
arch/x86_64/mm/numa.c
arch/x86_64/mm/pageattr.c
arch/x86_64/mm/srat.c
arch/x86_64/pci/k8-bus.c
arch/x86_64/vdso/Makefile [new file with mode: 0644]
arch/x86_64/vdso/vclock_gettime.c [new file with mode: 0644]
arch/x86_64/vdso/vdso-note.S [new file with mode: 0644]
arch/x86_64/vdso/vdso-start.S [new file with mode: 0644]
arch/x86_64/vdso/vdso.S [new file with mode: 0644]
arch/x86_64/vdso/vdso.lds.S [new file with mode: 0644]
arch/x86_64/vdso/vextern.h [new file with mode: 0644]
arch/x86_64/vdso/vgetcpu.c [new file with mode: 0644]
arch/x86_64/vdso/vma.c [new file with mode: 0644]
arch/x86_64/vdso/voffset.h [new file with mode: 0644]
arch/x86_64/vdso/vvar.c [new file with mode: 0644]
block/Kconfig
block/bsg.c
block/scsi_ioctl.c
drivers/acpi/Kconfig
drivers/acpi/battery.c
drivers/acpi/bay.c
drivers/acpi/bus.c
drivers/acpi/dock.c
drivers/acpi/ec.c
drivers/acpi/event.c
drivers/acpi/events/evgpeblk.c
drivers/acpi/events/evrgnini.c
drivers/acpi/glue.c
drivers/acpi/numa.c
drivers/acpi/osl.c
drivers/acpi/pci_link.c
drivers/acpi/processor_core.c
drivers/acpi/processor_idle.c
drivers/acpi/processor_throttling.c
drivers/acpi/sbs.c
drivers/acpi/sleep/main.c
drivers/acpi/system.c
drivers/acpi/tables/tbfadt.c
drivers/acpi/utilities/uteval.c
drivers/acpi/video.c
drivers/base/power/trace.c
drivers/block/Makefile
drivers/block/ps3disk.c [new file with mode: 0644]
drivers/char/Makefile
drivers/char/hvc_iseries.c
drivers/char/hvc_rtas.c
drivers/char/hvcs.c
drivers/char/hw_random/Kconfig
drivers/char/ps3flash.c [new file with mode: 0644]
drivers/char/rtc.c
drivers/char/watchdog/Kconfig
drivers/char/watchdog/Makefile
drivers/char/watchdog/iop_wdt.c [new file with mode: 0644]
drivers/clocksource/acpi_pm.c
drivers/firewire/fw-sbp2.c
drivers/input/misc/pcspkr.c
drivers/isdn/Kconfig
drivers/isdn/act2000/Kconfig
drivers/isdn/gigaset/Kconfig
drivers/isdn/hisax/Kconfig
drivers/isdn/i4l/Kconfig
drivers/isdn/icn/Kconfig
drivers/isdn/pcbit/Kconfig
drivers/isdn/sc/Kconfig
drivers/kvm/Kconfig
drivers/kvm/mmu.c
drivers/leds/Kconfig
drivers/leds/Makefile
drivers/leds/led-class.c
drivers/leds/led-triggers.c
drivers/leds/leds-gpio.c [new file with mode: 0644]
drivers/leds/leds-locomo.c
drivers/leds/leds.h
drivers/leds/ledtrig-timer.c
drivers/lguest/lguest.c
drivers/macintosh/rack-meter.c
drivers/md/dm-crypt.c
drivers/message/fusion/Kconfig
drivers/message/fusion/mptbase.c
drivers/message/fusion/mptbase.h
drivers/message/fusion/mptfc.c
drivers/message/fusion/mptsas.c
drivers/message/fusion/mptscsih.c
drivers/message/fusion/mptscsih.h
drivers/message/fusion/mptspi.c
drivers/misc/Kconfig
drivers/misc/sony-laptop.c
drivers/misc/thinkpad_acpi.c
drivers/misc/thinkpad_acpi.h
drivers/mmc/host/at91_mci.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h
drivers/net/Kconfig
drivers/net/arm/ether1.c
drivers/net/arm/ether3.c
drivers/net/arm/etherh.c
drivers/net/irda/Kconfig
drivers/net/irda/Makefile
drivers/net/irda/ep7211-sir.c [new file with mode: 0644]
drivers/pcmcia/m8xx_pcmcia.c
drivers/rtc/Kconfig
drivers/rtc/Makefile
drivers/rtc/rtc-ds1553.c
drivers/rtc/rtc-ds1742.c
drivers/rtc/rtc-max6900.c
drivers/rtc/rtc-stk17ta8.c [new file with mode: 0644]
drivers/s390/scsi/zfcp_aux.c
drivers/s390/scsi/zfcp_def.h
drivers/s390/scsi/zfcp_erp.c
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_qdio.c
drivers/scsi/3w-9xxx.c
drivers/scsi/3w-9xxx.h
drivers/scsi/Kconfig
drivers/scsi/Makefile
drivers/scsi/a4000t.c
drivers/scsi/aacraid/aachba.c
drivers/scsi/aacraid/aacraid.h
drivers/scsi/aacraid/commsup.c
drivers/scsi/aic94xx/aic94xx_dev.c
drivers/scsi/aic94xx/aic94xx_init.c
drivers/scsi/aic94xx/aic94xx_task.c
drivers/scsi/arm/cumana_1.c
drivers/scsi/arm/ecoscsi.c
drivers/scsi/arm/oak.c
drivers/scsi/bvme6000_scsi.c
drivers/scsi/esp_scsi.h
drivers/scsi/libsas/Kconfig
drivers/scsi/libsas/Makefile
drivers/scsi/libsas/sas_ata.c [new file with mode: 0644]
drivers/scsi/libsas/sas_discover.c
drivers/scsi/libsas/sas_expander.c
drivers/scsi/libsas/sas_init.c
drivers/scsi/libsas/sas_internal.h
drivers/scsi/libsas/sas_scsi_host.c
drivers/scsi/mvme16x_scsi.c
drivers/scsi/pcmcia/Kconfig
drivers/scsi/ps3rom.c [new file with mode: 0644]
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_dbg.c
drivers/scsi/qla2xxx/qla_dbg.h
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_fw.h
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_gs.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_inline.h
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_sup.c
drivers/scsi/qla2xxx/qla_version.h
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_sysctl.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_transport_fc.c
drivers/scsi/scsi_transport_sas.c
drivers/scsi/seagate.c
drivers/scsi/sim710.c
drivers/scsi/sr.c
drivers/scsi/wd33c93.c
drivers/scsi/zorro7xx.c
drivers/serial/imx.c
drivers/serial/s3c2410.c
drivers/spi/spi.c
drivers/usb/misc/appledisplay.c
drivers/video/Kconfig
drivers/video/Makefile
drivers/video/atmel_lcdfb.c
drivers/video/aty/aty128fb.c
drivers/video/aty/atyfb_base.c
drivers/video/aty/radeon_backlight.c
drivers/video/backlight/Kconfig
drivers/video/backlight/backlight.c
drivers/video/backlight/cr_bllcd.c
drivers/video/backlight/lcd.c
drivers/video/console/vgacon.c
drivers/video/nvidia/nv_backlight.c
drivers/video/ps3fb.c
drivers/video/riva/fbdev.c
fs/binfmt_elf.c
fs/coda/dir.c
fs/coda/file.c
fs/coda/upcall.c
fs/nfs/super.c
fs/nfsd/export.c
fs/proc/proc_misc.c
fs/udf/balloc.c
fs/udf/crc.c
fs/udf/dir.c
fs/udf/directory.c
fs/udf/ecma_167.h
fs/udf/file.c
fs/udf/fsync.c
fs/udf/ialloc.c
fs/udf/inode.c
fs/udf/lowlevel.c
fs/udf/misc.c
fs/udf/namei.c
fs/udf/osta_udf.h
fs/udf/partition.c
fs/udf/super.c
fs/udf/symlink.c
fs/udf/truncate.c
fs/udf/udf_i.h
fs/udf/udf_sb.h
fs/udf/udfdecl.h
fs/udf/udfend.h
fs/udf/udftime.c
fs/udf/unicode.c
include/acpi/acmacros.h
include/acpi/acoutput.h
include/acpi/acpi_bus.h
include/acpi/acpi_numa.h
include/acpi/platform/acenv.h
include/acpi/platform/aclinux.h
include/acpi/processor.h
include/asm-alpha/irq.h
include/asm-arm/arch-at91/at91_mci.h
include/asm-arm/arch-iop13xx/iop13xx.h
include/asm-arm/arch-iop13xx/system.h
include/asm-arm/arch-iop13xx/uncompress.h
include/asm-arm/arch-iop32x/uncompress.h
include/asm-arm/arch-mxc/board-mx31ads.h [new file with mode: 0644]
include/asm-arm/arch-mxc/common.h [new file with mode: 0644]
include/asm-arm/arch-mxc/dma.h [new file with mode: 0644]
include/asm-arm/arch-mxc/entry-macro.S [new file with mode: 0644]
include/asm-arm/arch-mxc/hardware.h [new file with mode: 0644]
include/asm-arm/arch-mxc/io.h [new file with mode: 0644]
include/asm-arm/arch-mxc/irqs.h [new file with mode: 0644]
include/asm-arm/arch-mxc/memory.h [new file with mode: 0644]
include/asm-arm/arch-mxc/mx31.h [new file with mode: 0644]
include/asm-arm/arch-mxc/mxc.h [new file with mode: 0644]
include/asm-arm/arch-mxc/system.h [new file with mode: 0644]
include/asm-arm/arch-mxc/timex.h [new file with mode: 0644]
include/asm-arm/arch-mxc/uncompress.h [new file with mode: 0644]
include/asm-arm/arch-mxc/vmalloc.h [new file with mode: 0644]
include/asm-arm/arch-ns9xxx/regs-bbu.h
include/asm-arm/arch-ns9xxx/regs-mem.h
include/asm-arm/arch-ns9xxx/regs-sys.h
include/asm-arm/arch-pxa/pm.h
include/asm-arm/arch-s3c2400/map.h [new file with mode: 0644]
include/asm-arm/arch-s3c2400/memory.h [new file with mode: 0644]
include/asm-arm/arch-s3c2410/debug-macro.S
include/asm-arm/arch-s3c2410/map.h
include/asm-arm/arch-s3c2410/memory.h
include/asm-arm/arch-s3c2410/regs-lcd.h
include/asm-arm/arch-s3c2410/system.h
include/asm-arm/arch-s3c2410/uncompress.h
include/asm-arm/arch-sa1100/jornada720.h [new file with mode: 0644]
include/asm-arm/elf.h
include/asm-arm/floppy.h
include/asm-arm/hardware/iop3xx.h
include/asm-arm/pgtable-nommu.h
include/asm-arm/plat-s3c/debug-macro.S [new file with mode: 0644]
include/asm-arm/plat-s3c/iic.h [moved from include/asm-arm/arch-s3c2410/iic.h with 100% similarity]
include/asm-arm/plat-s3c/map.h [new file with mode: 0644]
include/asm-arm/plat-s3c/nand.h [moved from include/asm-arm/arch-s3c2410/nand.h with 100% similarity]
include/asm-arm/plat-s3c/regs-ac97.h [moved from include/asm-arm/arch-s3c2410/regs-ac97.h with 100% similarity]
include/asm-arm/plat-s3c/regs-adc.h [moved from include/asm-arm/arch-s3c2410/regs-adc.h with 100% similarity]
include/asm-arm/plat-s3c/regs-iic.h [moved from include/asm-arm/arch-s3c2410/regs-iic.h with 100% similarity]
include/asm-arm/plat-s3c/regs-nand.h [moved from include/asm-arm/arch-s3c2410/regs-nand.h with 100% similarity]
include/asm-arm/plat-s3c/regs-rtc.h [moved from include/asm-arm/arch-s3c2410/regs-rtc.h with 100% similarity]
include/asm-arm/plat-s3c/regs-serial.h [moved from include/asm-arm/arch-s3c2410/regs-serial.h with 96% similarity]
include/asm-arm/plat-s3c/regs-timer.h [moved from include/asm-arm/arch-s3c2410/regs-timer.h with 86% similarity]
include/asm-arm/plat-s3c/regs-watchdog.h [moved from include/asm-arm/arch-s3c2410/regs-watchdog.h with 83% similarity]
include/asm-arm/plat-s3c/uncompress.h [new file with mode: 0644]
include/asm-arm/plat-s3c24xx/regs-iis.h [moved from include/asm-arm/arch-s3c2410/regs-iis.h with 100% similarity]
include/asm-arm/plat-s3c24xx/regs-spi.h [moved from include/asm-arm/arch-s3c2410/regs-spi.h with 100% similarity]
include/asm-arm/plat-s3c24xx/regs-udc.h [moved from include/asm-arm/arch-s3c2410/regs-udc.h with 100% similarity]
include/asm-arm/plat-s3c24xx/udc.h [moved from include/asm-arm/arch-s3c2410/udc.h with 100% similarity]
include/asm-arm/thread_info.h
include/asm-arm/unistd.h
include/asm-arm/vfp.h
include/asm-arm26/irq.h
include/asm-h8300/irq.h
include/asm-i386/alternative.h
include/asm-i386/cmpxchg.h
include/asm-i386/e820.h
include/asm-i386/geode.h [new file with mode: 0644]
include/asm-i386/hpet.h
include/asm-i386/i8253.h
include/asm-i386/mach-default/do_timer.h
include/asm-i386/mach-default/io_ports.h
include/asm-i386/mach-default/mach_reboot.h
include/asm-i386/mach-voyager/do_timer.h
include/asm-i386/mc146818rtc.h
include/asm-i386/mce.h
include/asm-i386/nmi.h
include/asm-i386/page.h
include/asm-i386/pci.h
include/asm-i386/processor-cyrix.h [new file with mode: 0644]
include/asm-i386/processor.h
include/asm-i386/resume-trace.h [new file with mode: 0644]
include/asm-i386/string.h
include/asm-i386/timer.h
include/asm-i386/tlbflush.h
include/asm-i386/topology.h
include/asm-i386/uaccess.h
include/asm-ia64/irq.h
include/asm-m68k/irq.h
include/asm-powerpc/mpic.h
include/asm-powerpc/prom.h
include/asm-ppc/system.h
include/asm-sh64/irq.h
include/asm-sparc/irq.h
include/asm-sparc/pgtable.h
include/asm-v850/irq.h
include/asm-x86_64/acpi.h
include/asm-x86_64/alternative.h
include/asm-x86_64/apic.h
include/asm-x86_64/auxvec.h
include/asm-x86_64/calgary.h
include/asm-x86_64/cmpxchg.h
include/asm-x86_64/dmi.h
include/asm-x86_64/elf.h
include/asm-x86_64/fixmap.h
include/asm-x86_64/hpet.h
include/asm-x86_64/hw_irq.h
include/asm-x86_64/hypertransport.h
include/asm-x86_64/i8253.h [new file with mode: 0644]
include/asm-x86_64/iommu.h [new file with mode: 0644]
include/asm-x86_64/mce.h
include/asm-x86_64/mmu.h
include/asm-x86_64/msidef.h
include/asm-x86_64/nmi.h
include/asm-x86_64/pci.h
include/asm-x86_64/pgalloc.h
include/asm-x86_64/pgtable.h
include/asm-x86_64/processor.h
include/asm-x86_64/proto.h
include/asm-x86_64/ptrace.h
include/asm-x86_64/resume-trace.h [new file with mode: 0644]
include/asm-x86_64/string.h
include/asm-x86_64/system.h
include/asm-x86_64/thread_info.h
include/asm-x86_64/timex.h
include/asm-x86_64/tlbflush.h
include/asm-x86_64/topology.h
include/asm-x86_64/vgtod.h [new file with mode: 0644]
include/asm-x86_64/vsyscall.h
include/linux/acpi.h
include/linux/audit.h
include/linux/backlight.h
include/linux/blkdev.h
include/linux/bsg.h
include/linux/clockchips.h
include/linux/coda_linux.h
include/linux/coda_psdev.h
include/linux/compiler-gcc4.h
include/linux/compiler.h
include/linux/init.h
include/linux/interrupt.h
include/linux/irda.h
include/linux/kernel.h
include/linux/lcd.h
include/linux/leds.h
include/linux/libata.h
include/linux/netdevice.h
include/linux/of_platform.h
include/linux/pci_ids.h
include/linux/resume-trace.h
include/linux/signal.h
include/linux/time.h
include/linux/vmalloc.h
include/scsi/libsas.h
include/scsi/sas_ata.h [new file with mode: 0644]
include/scsi/scsi_host.h
include/scsi/scsi_transport_sas.h
kernel/auditfilter.c
kernel/auditsc.c
kernel/hrtimer.c
kernel/irq/proc.c
kernel/power/Kconfig
kernel/signal.c
kernel/sysctl.c
kernel/time/ntp.c
kernel/time/tick-broadcast.c
kernel/time/tick-common.c
kernel/time/tick-oneshot.c
kernel/time/tick-sched.c
lib/swiotlb.c
mm/memory.c
mm/nommu.c
mm/slob.c
mm/sparse.c
net/core/dev.c
net/core/sock.c
net/ipv4/inetpeer.c
net/ipv6/ip6_tunnel.c
net/irda/irnetlink.c
security/selinux/avc.c

index e2e24b4778d447b8335e3f447f51883b618c306b..ba997577150369c5d7bc655c82704e01567e685d 100644 (file)
@@ -456,8 +456,9 @@ void (*irq_clear) (struct ata_port *);
 
        <sect2><title>SATA phy read/write</title>
        <programlisting>
-u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
-void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
+int (*scr_read) (struct ata_port *ap, unsigned int sc_reg,
+                u32 *val);
+int (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
                    u32 val);
        </programlisting>
 
index a5cb7839a679eadc040c71a6db06d33af5083ffc..c175eedadb5fb358f589d93da61720e9453b73ad 100644 (file)
@@ -180,24 +180,11 @@ Who:   Adrian Bunk <bunk@stusta.de>
 
 ---------------------------
 
-What:  /sys/firmware/acpi/namespace
-When:  2.6.21
-Why:   The ACPI namespace is effectively the symbol list for
-       the BIOS.  The device names are completely arbitrary
-       and have no place being exposed to user-space.
-
-       For those interested in the BIOS ACPI namespace,
-       the BIOS can be extracted and disassembled with acpidump
-       and iasl as documented in the pmtools package here:
-       http://ftp.kernel.org/pub/linux/kernel/people/lenb/acpi/utils
-Who:   Len Brown <len.brown@intel.com>
-
----------------------------
-
 What:  ACPI procfs interface
-When:  July 2007
-Why:   After ACPI sysfs conversion, ACPI attributes will be duplicated
-       in sysfs and the ACPI procfs interface should be removed.
+When:  July 2008
+Why:   ACPI sysfs conversion should be finished by January 2008.
+       ACPI procfs interface will be removed in July 2008 so that
+       there is enough time for the user space to catch up.
 Who:   Zhang Rui <rui.zhang@intel.com>
 
 ---------------------------
index 5fbe07706ae9eedae14c1582004a0fc52e4daa40..fb80e9ffea68b7a0f8d1bbcd0229957276cfe747 100644 (file)
@@ -1882,7 +1882,7 @@ and is between 256 and 4096 characters. It is defined in the file
        usbhid.mousepoll=
                        [USBHID] The interval which mice are to be polled at.
 
-       vdso=           [IA-32,SH]
+       vdso=           [IA-32,SH,x86-64]
                        vdso=2: enable compat VDSO (default with COMPAT_VDSO)
                        vdso=1: enable VDSO (default)
                        vdso=0: disable VDSO mapping
index af1a282c71a3135e0e0c7999c6db280dde74766a..04dc1cf9d2155a3488d2fe557d7f82b76a06ecc8 100644 (file)
@@ -155,6 +155,8 @@ Suppose, however, that the firmware file is located on a filesystem accessible
 only through another device that hasn't been resumed yet.  In that case,
 request_firmware() will fail regardless of whether or not the freezing of tasks
 is used.  Consequently, the problem is not really related to the freezing of
-tasks, since it generally exists anyway.  [The solution to this particular
-problem is to keep the firmware in memory after it's loaded for the first time
-and upload if from memory to the device whenever necessary.]
+tasks, since it generally exists anyway.
+
+A driver must have all firmwares it may need in RAM before suspend() is called.
+If keeping them is not practical, for example due to their size, they must be
+requested early enough using the suspend notifier API described in notifiers.txt.
index 9e6b94face4bb2a11f0ea743246f0b85adbbd105..6711fbcf408078644bf237b2f46466b69b7040ff 100644 (file)
@@ -1,11 +1,11 @@
                     ThinkPad ACPI Extras Driver
 
-                            Version 0.14
-                          April 21st, 2007
+                            Version 0.15
+                           July 1st, 2007
 
                Borislav Deianov <borislav@users.sf.net>
-            Henrique de Moraes Holschuh <hmh@hmh.eng.br>
-                     http://ibm-acpi.sf.net/
+             Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+                      http://ibm-acpi.sf.net/
 
 
 This is a Linux driver for the IBM and Lenovo ThinkPad laptops. It
@@ -134,54 +134,68 @@ end of this document.  Changes to the sysfs interface done by the kernel
 subsystems are not documented here, nor are they tracked by this
 attribute.
 
+Changes to the thinkpad-acpi sysfs interface are only considered
+non-experimental when they are submitted to Linux mainline, at which
+point the changes in this interface are documented and interface_version
+may be updated.  If you are using any thinkpad-acpi features not yet
+sent to mainline for merging, you do so on your own risk: these features
+may disappear, or be implemented in a different and incompatible way by
+the time they are merged in Linux mainline.
+
+Changes that are backwards-compatible by nature (e.g. the addition of
+attributes that do not change the way the other attributes work) do not
+always warrant an update of interface_version.  Therefore, one must
+expect that an attribute might not be there, and deal with it properly
+(an attribute not being there *is* a valid way to make it clear that a
+feature is not available in sysfs).
+
 Hot keys
 --------
 
 procfs: /proc/acpi/ibm/hotkey
 sysfs device attribute: hotkey_*
 
-Without this driver, only the Fn-F4 key (sleep button) generates an
-ACPI event. With the driver loaded, the hotkey feature enabled and the
-mask set (see below), the various hot keys generate ACPI events in the
+In a ThinkPad, the ACPI HKEY handler is responsible for comunicating
+some important events and also keyboard hot key presses to the operating
+system.  Enabling the hotkey functionality of thinkpad-acpi signals the
+firmware that such a driver is present, and modifies how the ThinkPad
+firmware will behave in many situations.
+
+When the hotkey feature is enabled and the hot key mask is set (see
+below), the various hot keys either generate ACPI events in the
 following format:
 
        ibm/hotkey HKEY 00000080 0000xxxx
 
-The last four digits vary depending on the key combination pressed.
-All labeled Fn-Fx key combinations generate distinct events. In
-addition, the lid microswitch and some docking station buttons may
-also generate such events.
-
-The bit mask allows some control over which hot keys generate ACPI
-events. Not all bits in the mask can be modified. Not all bits that
-can be modified do anything. Not all hot keys can be individually
-controlled by the mask. Most recent ThinkPad models honor the
-following bits (assuming the hot keys feature has been enabled):
-
-       key     bit     behavior when set       behavior when unset
-
-       Fn-F3                   always generates ACPI event
-       Fn-F4                   always generates ACPI event
-       Fn-F5   0010    generate ACPI event     enable/disable Bluetooth
-       Fn-F7   0040    generate ACPI event     switch LCD and external display
-       Fn-F8   0080    generate ACPI event     expand screen or none
-       Fn-F9   0100    generate ACPI event     none
-       Fn-F12                  always generates ACPI event
-
-Some models do not support all of the above. For example, the T30 does
-not support Fn-F5 and Fn-F9. Other models do not support the mask at
-all. On those models, hot keys cannot be controlled individually.
-
-Note that enabling ACPI events for some keys prevents their default
-behavior. For example, if events for Fn-F5 are enabled, that key will
-no longer enable/disable Bluetooth by itself. This can still be done
-from an acpid handler for the ibm/hotkey event.
-
-Note also that not all Fn key combinations are supported through
-ACPI. For example, on the X40, the brightness, volume and "Access IBM"
-buttons do not generate ACPI events even with this driver. They *can*
-be used through the "ThinkPad Buttons" utility, see
-http://www.nongnu.org/tpb/
+or events over the input layer.  The input layer support accepts the
+standard IOCTLs to remap the keycodes assigned to each hotkey.
+
+When the input device is open, the driver will suppress any ACPI hot key
+events that get translated into a meaningful input layer event, in order
+to avoid sending duplicate events to userspace.  Hot keys that are
+mapped to KEY_RESERVED in the keymap are not translated, and will always
+generate an ACPI ibm/hotkey HKEY event, and no input layer events.
+
+The hot key bit mask allows some control over which hot keys generate
+events.  If a key is "masked" (bit set to 0 in the mask), the firmware
+will handle it.  If it is "unmasked", it signals the firmware that
+thinkpad-acpi would prefer to handle it, if the firmware would be so
+kind to allow it (and it often doesn't!).
+
+Not all bits in the mask can be modified.  Not all bits that can be
+modified do anything.  Not all hot keys can be individually controlled
+by the mask.  Some models do not support the mask at all, and in those
+models, hot keys cannot be controlled individually.  The behaviour of
+the mask is, therefore, higly dependent on the ThinkPad model.
+
+Note that unmasking some keys prevents their default behavior.  For
+example, if Fn+F5 is unmasked, that key will no longer enable/disable
+Bluetooth by itself.
+
+Note also that not all Fn key combinations are supported through ACPI.
+For example, on the X40, the brightness, volume and "Access IBM" buttons
+do not generate ACPI events even with this driver.  They *can* be used
+through the "ThinkPad Buttons" utility, see http://www.nongnu.org/tpb/
 
 procfs notes:
 
@@ -189,9 +203,9 @@ The following commands can be written to the /proc/acpi/ibm/hotkey file:
 
        echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature
        echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature
-       echo 0xffff > /proc/acpi/ibm/hotkey -- enable all possible hot keys
-       echo 0x0000 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
-       ... any other 4-hex-digit mask ...
+       echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys
+       echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
+       ... any other 8-hex-digit mask ...
        echo reset > /proc/acpi/ibm/hotkey -- restore the original mask
 
 sysfs notes:
@@ -202,7 +216,7 @@ sysfs notes:
                key feature status will be restored to this value.
 
                0: hot keys were disabled
-               1: hot keys were enabled
+               1: hot keys were enabled (unusual)
 
        hotkey_bios_mask:
                Returns the hot keys mask when thinkpad-acpi was loaded.
@@ -217,9 +231,182 @@ sysfs notes:
                1: enables the hot keys feature / feature enabled
 
        hotkey_mask:
-               bit mask to enable ACPI event generation for each hot
-               key (see above).  Returns the current status of the hot
-               keys mask, and allows one to modify it.
+               bit mask to enable driver-handling and ACPI event
+               generation for each hot key (see above).  Returns the
+               current status of the hot keys mask, and allows one to
+               modify it.
+
+       hotkey_all_mask:
+               bit mask that should enable event reporting for all
+               supported hot keys, when echoed to hotkey_mask above.
+               Unless you know which events need to be handled
+               passively (because the firmware *will* handle them
+               anyway), do *not* use hotkey_all_mask.  Use
+               hotkey_recommended_mask, instead. You have been warned.
+
+       hotkey_recommended_mask:
+               bit mask that should enable event reporting for all
+               supported hot keys, except those which are always
+               handled by the firmware anyway.  Echo it to
+               hotkey_mask above, to use.
+
+       hotkey_radio_sw:
+               if the ThinkPad has a hardware radio switch, this
+               attribute will read 0 if the switch is in the "radios
+               disabled" postition, and 1 if the switch is in the
+               "radios enabled" position.
+
+input layer notes:
+
+A Hot key is mapped to a single input layer EV_KEY event, possibly
+followed by an EV_MSC MSC_SCAN event that shall contain that key's scan
+code.  An EV_SYN event will always be generated to mark the end of the
+event block.
+
+Do not use the EV_MSC MSC_SCAN events to process keys.  They are to be
+used as a helper to remap keys, only.  They are particularly useful when
+remapping KEY_UNKNOWN keys.
+
+The events are available in an input device, with the following id:
+
+       Bus:            BUS_HOST
+       vendor:         0x1014 (PCI_VENDOR_ID_IBM)  or
+                       0x17aa (PCI_VENDOR_ID_LENOVO)
+       product:        0x5054 ("TP")
+       version:        0x4101
+
+The version will have its LSB incremented if the keymap changes in a
+backwards-compatible way.  The MSB shall always be 0x41 for this input
+device.  If the MSB is not 0x41, do not use the device as described in
+this section, as it is either something else (e.g. another input device
+exported by a thinkpad driver, such as HDAPS) or its functionality has
+been changed in a non-backwards compatible way.
+
+Adding other event types for other functionalities shall be considered a
+backwards-compatible change for this input device.
+
+Thinkpad-acpi Hot Key event map (version 0x4101):
+
+ACPI   Scan
+event  code    Key             Notes
+
+0x1001 0x00    FN+F1           -
+0x1002 0x01    FN+F2           IBM: battery (rare)
+                               Lenovo: Screen lock
+
+0x1003 0x02    FN+F3           Many IBM models always report
+                               this hot key, even with hot keys
+                               disabled or with Fn+F3 masked
+                               off
+                               IBM: screen lock
+                               Lenovo: battery
+
+0x1004 0x03    FN+F4           Sleep button (ACPI sleep button
+                               semanthics, i.e. sleep-to-RAM).
+                               It is always generate some kind
+                               of event, either the hot key
+                               event or a ACPI sleep button
+                               event. The firmware may
+                               refuse to generate further FN+F4
+                               key presses until a S3 or S4 ACPI
+                               sleep cycle is performed or some
+                               time passes.
+
+0x1005 0x04    FN+F5           Radio.  Enables/disables
+                               the internal BlueTooth hardware
+                               and W-WAN card if left in control
+                               of the firmware.  Does not affect
+                               the WLAN card.
+                               Should be used to turn on/off all
+                               radios (bluetooth+W-WAN+WLAN),
+                               really.
+
+0x1006 0x05    FN+F6           -
+
+0x1007 0x06    FN+F7           Video output cycle.
+                               Do you feel lucky today?
+
+0x1008 0x07    FN+F8           IBM: toggle screen expand
+                               Lenovo: configure ultranav
+
+0x1009 0x08    FN+F9           -
+       ..      ..              ..
+0x100B 0x0A    FN+F11          -
+
+0x100C 0x0B    FN+F12          Sleep to disk.  You are always
+                               supposed to handle it yourself,
+                               either through the ACPI event,
+                               or through a hotkey event.
+                               The firmware may refuse to
+                               generate further FN+F4 key
+                               press events until a S3 or S4
+                               ACPI sleep cycle is performed,
+                               or some time passes.
+
+0x100D 0x0C    FN+BACKSPACE    -
+0x100E 0x0D    FN+INSERT       -
+0x100F 0x0E    FN+DELETE       -
+
+0x1010 0x0F    FN+HOME         Brightness up.  This key is
+                               always handled by the firmware
+                               in IBM ThinkPads, even when
+                               unmasked.  Just leave it alone.
+                               For Lenovo ThinkPads with a new
+                               BIOS, it has to be handled either
+                               by the ACPI OSI, or by userspace.
+0x1011 0x10    FN+END          Brightness down.  See brightness
+                               up for details.
+
+0x1012 0x11    FN+PGUP         Thinklight toggle.  This key is
+                               always handled by the firmware,
+                               even when unmasked.
+
+0x1013 0x12    FN+PGDOWN       -
+
+0x1014 0x13    FN+SPACE        Zoom key
+
+0x1015 0x14    VOLUME UP       Internal mixer volume up. This
+                               key is always handled by the
+                               firmware, even when unmasked.
+                               NOTE: Lenovo seems to be changing
+                               this.
+0x1016 0x15    VOLUME DOWN     Internal mixer volume up. This
+                               key is always handled by the
+                               firmware, even when unmasked.
+                               NOTE: Lenovo seems to be changing
+                               this.
+0x1017 0x16    MUTE            Mute internal mixer. This
+                               key is always handled by the
+                               firmware, even when unmasked.
+
+0x1018 0x17    THINKPAD        Thinkpad/Access IBM/Lenovo key
+
+0x1019 0x18    unknown
+..     ..      ..
+0x1020 0x1F    unknown
+
+The ThinkPad firmware does not allow one to differentiate when most hot
+keys are pressed or released (either that, or we don't know how to, yet).
+For these keys, the driver generates a set of events for a key press and
+immediately issues the same set of events for a key release.  It is
+unknown by the driver if the ThinkPad firmware triggered these events on
+hot key press or release, but the firmware will do it for either one, not
+both.
+
+If a key is mapped to KEY_RESERVED, it generates no input events at all,
+and it may generate a legacy thinkpad-acpi ACPI hotkey event.
+
+If a key is mapped to KEY_UNKNOWN, it generates an input event that
+includes an scan code, and it may also generate a legacy thinkpad-acpi
+ACPI hotkey event.
+
+If a key is mapped to anything else, it will only generate legacy
+thinkpad-acpi ACPI hotkey events if nobody has opened the input device.
+
+Non hot-key ACPI HKEY event map:
+0x5001         Lid closed
+0x5002         Lid opened
+0x7000         Radio Switch may have changed state
 
 
 Bluetooth
@@ -437,27 +624,34 @@ CMOS control
 procfs: /proc/acpi/ibm/cmos
 sysfs device attribute: cmos_command
 
-This feature is used internally by the ACPI firmware to control the
-ThinkLight on most newer ThinkPad models. It may also control LCD
-brightness, sounds volume and more, but only on some models.
+This feature is mostly used internally by the ACPI firmware to keep the legacy
+CMOS NVRAM bits in sync with the current machine state, and to record this
+state so that the ThinkPad will retain such settings across reboots.
+
+Some of these commands actually perform actions in some ThinkPad models, but
+this is expected to disappear more and more in newer models.  As an example, in
+a T43 and in a X40, commands 12 and 13 still control the ThinkLight state for
+real, but commands 0 to 2 don't control the mixer anymore (they have been
+phased out) and just update the NVRAM.
 
 The range of valid cmos command numbers is 0 to 21, but not all have an
 effect and the behavior varies from model to model.  Here is the behavior
 on the X40 (tpb is the ThinkPad Buttons utility):
 
-       0 - no effect but tpb reports "Volume down"
-       1 - no effect but tpb reports "Volume up"
-       2 - no effect but tpb reports "Mute on"
-       3 - simulate pressing the "Access IBM" button
-       4 - LCD brightness up
-       5 - LCD brightness down
-       11 - toggle screen expansion
-       12 - ThinkLight on
-       13 - ThinkLight off
-       14 - no effect but tpb reports ThinkLight status change
+       0 - Related to "Volume down" key press
+       1 - Related to "Volume up" key press
+       2 - Related to "Mute on" key press
+       3 - Related to "Access IBM" key press
+       4 - Related to "LCD brightness up" key pess
+       5 - Related to "LCD brightness down" key press
+       11 - Related to "toggle screen expansion" key press/function
+       12 - Related to "ThinkLight on"
+       13 - Related to "ThinkLight off"
+       14 - Related to "ThinkLight" key press (toggle thinklight)
 
 The cmos command interface is prone to firmware split-brain problems, as
-in newer ThinkPads it is just a compatibility layer.
+in newer ThinkPads it is just a compatibility layer.  Do not use it, it is
+exported just as a debug tool.
 
 LED control -- /proc/acpi/ibm/led
 ---------------------------------
@@ -516,23 +710,15 @@ Temperature sensors
 procfs: /proc/acpi/ibm/thermal
 sysfs device attributes: (hwmon) temp*_input
 
-Most ThinkPads include six or more separate temperature sensors but
-only expose the CPU temperature through the standard ACPI methods.
-This feature shows readings from up to eight different sensors on older
-ThinkPads, and it has experimental support for up to sixteen different
-sensors on newer ThinkPads.
-
-EXPERIMENTAL: The 16-sensors feature is marked EXPERIMENTAL because the
-implementation directly accesses hardware registers and may not work as
-expected. USE WITH CAUTION! To use this feature, you need to supply the
-experimental=1 parameter when loading the module.  When EXPERIMENTAL
-mode is enabled, reading the first 8 sensors on newer ThinkPads will
-also use an new experimental thermal sensor access mode.
+Most ThinkPads include six or more separate temperature sensors but only
+expose the CPU temperature through the standard ACPI methods.  This
+feature shows readings from up to eight different sensors on older
+ThinkPads, and up to sixteen different sensors on newer ThinkPads.
 
 For example, on the X40, a typical output may be:
 temperatures:   42 42 45 41 36 -128 33 -128
 
-EXPERIMENTAL: On the T43/p, a typical output may be:
+On the T43/p, a typical output may be:
 temperatures:   48 48 36 52 38 -128 31 -128 48 52 48 -128 -128 -128 -128 -128
 
 The mapping of thermal sensors to physical locations varies depending on
@@ -562,7 +748,8 @@ http://thinkwiki.org/wiki/Thermal_Sensors#ThinkPad_T43.2C_T43p
 2:  System board, left side (near PCMCIA slot), reported as HDAPS temp
 3:  PCMCIA slot
 9:  MCH (northbridge) to DRAM Bus
-10: ICH (southbridge), under Mini-PCI card, under touchpad
+10: Clock-generator, mini-pci card and ICH (southbridge), under Mini-PCI
+    card, under touchpad
 11: Power regulator, underside of system board, below F2 key
 
 The A31 has a very atypical layout for the thermal sensors
@@ -681,6 +868,12 @@ cannot be controlled.
 The backlight control has eight levels, ranging from 0 to 7.  Some of the
 levels may not be distinct.
 
+There are two interfaces to the firmware for brightness control, EC and CMOS.
+To select which one should be used, use the brightness_mode module parameter:
+brightness_mode=1 selects EC mode, brightness_mode=2 selects CMOS mode,
+brightness_mode=3 selects both EC and CMOS.  The driver tries to autodetect
+which interface to use.
+
 Procfs notes:
 
        The available commands are:
@@ -976,3 +1169,9 @@ Sysfs interface changelog:
 
 0x000100:      Initial sysfs support, as a single platform driver and
                device.
+0x000200:      Hot key support for 32 hot keys, and radio slider switch
+               support.
+0x010000:      Hot keys are now handled by default over the input
+               layer, the radio switch generates input event EV_RADIO,
+               and the driver enables hot key handling by default in
+               the firmware.
index 6177d881983fa701f4df08f9ad55c6b21db6a02e..945311840a10d29be3f8c680f1124a01e8cd4bed 100644 (file)
@@ -14,9 +14,11 @@ Machine check
    mce=nobootlog
                Disable boot machine check logging.
    mce=tolerancelevel (number)
-               0: always panic, 1: panic if deadlock possible,
-               2: try to avoid panic, 3: never panic or exit (for testing)
-               default is 1
+               0: always panic on uncorrected errors, log corrected errors
+               1: panic or SIGBUS on uncorrected errors, log corrected errors
+               2: SIGBUS or log uncorrected errors, log corrected errors
+               3: never panic or SIGBUS, log all errors (for testing only)
+               Default is 1
                Can be also set using sysfs which is preferable.
 
    nomce (for compatibility with i386): same as mce=off
@@ -134,12 +136,6 @@ Non Executable Mappings
 
 SMP
 
-  nosmp        Only use a single CPU
-
-  maxcpus=NUMBER only use upto NUMBER CPUs
-
-  cpumask=MASK   only use cpus with bits set in mask
-
   additional_cpus=NUM Allow NUM more CPUs for hotplug
                 (defaults are specified by the BIOS, see Documentation/x86_64/cpu-hotplug-spec)
 
index feaeaf6f6e4dd45dc03028886764d35477d2b3b9..a05e58e7b159b4dda2910eab39b6372b648f3c19 100644 (file)
@@ -49,12 +49,14 @@ tolerant
        Since machine check exceptions can happen any time it is sometimes
        risky for the kernel to kill a process because it defies
        normal kernel locking rules. The tolerance level configures
-       how hard the kernel tries to recover even at some risk of deadlock.
-
-       0: always panic,
-       1: panic if deadlock possible,
-       2: try to avoid panic,
-       3: never panic or exit (for testing only)
+       how hard the kernel tries to recover even at some risk of
+       deadlock.  Higher tolerant values trade potentially better uptime
+       with the risk of a crash or even corruption (for tolerant >= 3).
+
+       0: always panic on uncorrected errors, log corrected errors
+       1: panic or SIGBUS on uncorrected errors, log corrected errors
+       2: SIGBUS or log uncorrected errors, log corrected errors
+       3: never panic or SIGBUS, log all errors (for testing only)
 
        Default: 1
 
index f49c5563f060d723b9789451cef25e12bcdf83bb..01f222e51871ba1ed86465119e2329ba74e7afb1 100644 (file)
@@ -225,15 +225,15 @@ T:        git kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
 S:     Supported
 
 ACPI BATTERY DRIVERS
-P:     Vladimir P. Lebedev
-M:     vladimir.p.lebedev@intel.com
+P:     Alexey Starikovskiy
+M:     astarikovskiy@suse.de
 L:     linux-acpi@vger.kernel.org
 W:     http://acpi.sourceforge.net/
 S:     Supported
 
 ACPI EC DRIVER
 P:     Alexey Starikovskiy
-M:     alexey.y.starikovskiy@linux.intel.com
+M:     astarikovskiy@suse.de
 L:     linux-acpi@vger.kernel.org
 W:     http://acpi.sourceforge.net/
 S:     Supported
@@ -463,7 +463,7 @@ S:  Maintained
 
 ARM/HP JORNADA 7XX MACHINE SUPPORT
 P:      Kristoffer Ericson
-M:      kristoffer_e1@hotmail.com
+M:      kristoffer.ericson@gmail.com
 W:      www.jlime.com
 S:      Maintained
 
@@ -651,7 +651,12 @@ W: http://linux-atm.sourceforge.net
 S:     Maintained
 
 ATMEL AT91 MCI DRIVER
-S:     Orphan
+P:     Nicolas Ferre
+M:     nicolas.ferre@rfo.atmel.com
+L:     linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+W:     http://www.atmel.com/products/AT91/
+W:     http://www.at91.com/
+S:     Maintained
 
 ATMEL MACB ETHERNET DRIVER
 P:     Haavard Skinnemoen
index a44c6da9bf8363d21169eecb1521ef8f16144e7a..85016313bd1175779772fbfe45d1c798780e064e 100644 (file)
@@ -324,6 +324,12 @@ config ARCH_NS9XXX
 
          <http://www.digi.com/products/microprocessors/index.jsp>
 
+config ARCH_MXC
+       bool "Freescale MXC/iMX-based"
+       select ARCH_MTD_XIP
+       help
+         Support for Freescale MXC/iMX-based family of processors
+
 config ARCH_PNX4008
        bool "Philips Nexperia PNX4008 Mobile"
        help
@@ -432,6 +438,7 @@ source "arch/arm/mach-omap1/Kconfig"
 source "arch/arm/mach-omap2/Kconfig"
 
 source "arch/arm/plat-s3c24xx/Kconfig"
+source "arch/arm/plat-s3c/Kconfig"
 
 if ARCH_S3C2410
 source "arch/arm/mach-s3c2400/Kconfig"
@@ -456,6 +463,8 @@ source "arch/arm/mach-realview/Kconfig"
 
 source "arch/arm/mach-at91/Kconfig"
 
+source "arch/arm/plat-mxc/Kconfig"
+
 source "arch/arm/mach-netx/Kconfig"
 
 source "arch/arm/mach-ns9xxx/Kconfig"
index 40c5eb1f55c7e3572f02ebdc39e12d9020bc1936..18101f5f5f249b0377c1fe4299c9094f6db16af7 100644 (file)
@@ -82,24 +82,24 @@ config DEBUG_CLPS711X_UART2
          output to the second serial port on these devices.  Saying N will
          cause the debug messages to appear on the first serial port.
 
-config DEBUG_S3C2410_PORT
-       depends on DEBUG_LL && ARCH_S3C2410
-       bool "Kernel low-level debugging messages via S3C2410 UART"
+config DEBUG_S3C_PORT
+       depends on DEBUG_LL && PLAT_S3C
+       bool "Kernel low-level debugging messages via S3C UART"
        help
          Say Y here if you want debug print routines to go to one of the
-         S3C2410 internal UARTs. The chosen UART must have been configured
+         S3C internal UARTs. The chosen UART must have been configured
          before it is used.
 
-config DEBUG_S3C2410_UART
-       depends on ARCH_S3C2410
-       int "S3C2410 UART to use for low-level debug"
+config DEBUG_S3C_UART
+       depends on PLAT_S3C
+       int "S3C UART to use for low-level debug"
        default "0"
        help
-         Choice for UART for kernel low-level using S3C2410 UARTS,
+         Choice for UART for kernel low-level using S3C UARTS,
          should be between zero and two. The port must have been
          initialised by the boot-loader before use.
 
          The uncompressor code port configuration is now handled
-         by CONFIG_S3C2410_LOWLEVEL_UART_PORT.
+         by CONFIG_S3C_LOWLEVEL_UART_PORT.
 
 endmenu
index cbd5010d3bc3acb5b64dc99ad5ba380e2f97f409..fa4ea9ff0797b9ff94144b2b69bee97524dd09a0 100644 (file)
@@ -137,6 +137,8 @@ endif
  textofs-$(CONFIG_ARCH_NS9XXX)    := 0x00108000
  machine-$(CONFIG_ARCH_DAVINCI)           := davinci
  machine-$(CONFIG_ARCH_KS8695)     := ks8695
+  incdir-$(CONFIG_ARCH_MXC)       := mxc
+ machine-$(CONFIG_ARCH_MX3)       := mx3
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
 # This is what happens if you forget the IOCS16 line.
@@ -183,6 +185,7 @@ core-$(CONFIG_VFP)          += arch/arm/vfp/
 core-$(CONFIG_PLAT_IOP)                += arch/arm/plat-iop/
 core-$(CONFIG_ARCH_OMAP)       += arch/arm/plat-omap/
 core-$(CONFIG_PLAT_S3C24XX)            += arch/arm/plat-s3c24xx/
+core-$(CONFIG_ARCH_MXC)                += arch/arm/plat-mxc/
 
 drivers-$(CONFIG_OPROFILE)      += arch/arm/oprofile/
 drivers-$(CONFIG_ARCH_CLPS7500)        += drivers/acorn/char/
index ec9c400c7f82d171ba9ccf6e52cdb055bf1a50cb..25f12303b1062d163fcbb846b7e8709e609a640b 100644 (file)
@@ -91,4 +91,12 @@ zinstall: $(obj)/zImage
        $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
        $(obj)/zImage System.map "$(INSTALL_PATH)"
 
+zi:
+       $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
+       $(obj)/zImage System.map "$(INSTALL_PATH)"
+
+i:
+       $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
+       $(obj)/Image System.map "$(INSTALL_PATH)"
+
 subdir-            := bootp compressed
index a1f1691b67fe212f01c11a5e20f0f5fc78087fd3..6b8cbd69f2490d89b12344a3af53ca162307633d 100644 (file)
@@ -73,7 +73,7 @@ SEDFLAGS      = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
 
 targets       := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c \
                 head.o misc.o $(OBJS)
-EXTRA_CFLAGS  := -fpic
+EXTRA_CFLAGS  := -fpic -fno-builtin
 EXTRA_AFLAGS  :=
 
 # Supply ZRELADDR, INITRD_PHYS and PARAMS_PHYS to the decompressor via
index d7fb5ee1637e8f25e23edcd69b7acbeca019b539..b9b03eda70e5a370b02b3c276cd9db69405af3d7 100644 (file)
@@ -55,7 +55,7 @@
 #elif defined(CONFIG_ARCH_S3C2410)
                .macro loadsp, rb
                mov     \rb, #0x50000000
-               add     \rb, \rb, #0x4000 * CONFIG_S3C2410_LOWLEVEL_UART_PORT
+               add     \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
                .endm
 #else
                .macro  loadsp, rb
diff --git a/arch/arm/configs/em_x270_defconfig b/arch/arm/configs/em_x270_defconfig
new file mode 100644 (file)
index 0000000..6bea090
--- /dev/null
@@ -0,0 +1,1265 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.22
+# Mon Jul  9 15:18:20 2007
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION="-em-x270"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_PNX4008 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Intel PXA2xx Implementations
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_MACH_TRIZEPS4 is not set
+CONFIG_MACH_EM_X270=y
+CONFIG_PXA27x=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
+CONFIG_XSCALE_PMU=y
+
+#
+# Bus support
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_PM_SYSFS_DEPRECATED is not set
+CONFIG_APM_EMULATION=m
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+# CONFIG_BT_RFCOMM_TTY is not set
+CONFIG_BT_BNEP=m
+# CONFIG_BT_BNEP_MC_FILTER is not set
+# CONFIG_BT_BNEP_PROTO_FILTER is not set
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+# CONFIG_BT_HCIUSB_SCO is not set
+CONFIG_BT_HCIUART=m
+# CONFIG_BT_HCIUART_H4 is not set
+# CONFIG_BT_HCIUART_BCSP is not set
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
+# CONFIG_IEEE80211_SOFTMAC is not set
+# CONFIG_RFKILL is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+# CONFIG_MTD_CFI_NOSWAP is not set
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_SHARP_SL is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_H1900 is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_SHARPSL is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+CONFIG_MTD_NAND_PLATFORM=y
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=12000
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_SMC91X is not set
+CONFIG_DM9000=y
+# CONFIG_SMC911X is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_PXA27x=m
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+# CONFIG_HWMON is not set
+
+#
+# Misc devices
+#
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_PXA=y
+# CONFIG_FB_PXA_PARAMETERS is not set
+# CONFIG_FB_MBX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+CONFIG_SND_PXA2XX_PCM=m
+CONFIG_SND_PXA2XX_AC97=m
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+
+#
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_MON is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+
+#
+# MMC/SD Host Controller Drivers
+#
+CONFIG_MMC_PXA=m
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_V3020=m
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SA1100=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=y
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_MANAGER=m
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
index 1d5150e4d6b3e97cd568e33e21bc1229e45407ad..f8a1645b3d4affd925eb2dfaaf85cd1d1db995a4 100644 (file)
@@ -138,11 +138,11 @@ CONFIG_ARCH_S3C2410=y
 CONFIG_PLAT_S3C24XX=y
 CONFIG_CPU_S3C244X=y
 CONFIG_PM_SIMTEC=y
-# CONFIG_S3C2410_BOOT_WATCHDOG is not set
-# CONFIG_S3C2410_BOOT_ERROR_RESET is not set
+# CONFIG_S3C_BOOT_WATCHDOG is not set
+# CONFIG_S3C_BOOT_ERROR_RESET is not set
 # CONFIG_S3C2410_PM_DEBUG is not set
 # CONFIG_S3C2410_PM_CHECK is not set
-CONFIG_S3C2410_LOWLEVEL_UART_PORT=0
+CONFIG_S3C_LOWLEVEL_UART_PORT=0
 CONFIG_S3C2410_DMA=y
 # CONFIG_S3C2410_DMA_DEBUG is not set
 CONFIG_MACH_SMDK=y
@@ -1392,8 +1392,8 @@ CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_ERRORS is not set
 CONFIG_DEBUG_LL=y
 # CONFIG_DEBUG_ICEDCC is not set
-CONFIG_DEBUG_S3C2410_PORT=y
-CONFIG_DEBUG_S3C2410_UART=0
+CONFIG_DEBUG_S3C_PORT=y
+CONFIG_DEBUG_S3C_UART=0
 
 #
 # Security options
index 70599bcf451cf9c64000f71f2af29a6f849db02a..0417c165d50d0a8e732b60b5ad767cddbe757851 100644 (file)
@@ -477,7 +477,7 @@ void __init at91_add_device_i2c(void) {}
  *  SPI
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_SPI_AT91) || defined(CONFIG_SPI_AT91_MODULE) || defined(CONFIG_AT91_SPI) || defined(CONFIG_AT91_SPI_MODULE)
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
 static u64 spi_dmamask = 0xffffffffUL;
 
 static struct resource spi_resources[] = {
@@ -494,7 +494,7 @@ static struct resource spi_resources[] = {
 };
 
 static struct platform_device at91rm9200_spi_device = {
-       .name           = "at91_spi",
+       .name           = "atmel_spi",
        .id             = 0,
        .dev            = {
                                .dma_mask               = &spi_dmamask,
@@ -522,18 +522,14 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
                else
                        cs_pin = spi_standard_cs[devices[i].chip_select];
 
-#ifdef CONFIG_SPI_AT91_MANUAL_CS
+               /* enable chip-select pin */
                at91_set_gpio_output(cs_pin, 1);
-#else
-               at91_set_A_periph(cs_pin, 0);
-#endif
 
                /* pass chip-select pin to driver */
                devices[i].controller_data = (void *) cs_pin;
        }
 
        spi_register_board_info(devices, nr_devices);
-       at91_clock_associate("spi_clk", &at91rm9200_spi_device.dev, "spi");
        platform_device_register(&at91rm9200_spi_device);
 }
 #else
index 4d8425de6922ff6bdaef0074af01086b34a53d99..e96a3dcdc1a7720cb7385775ca334945a1d3352e 100644 (file)
@@ -285,6 +285,8 @@ static void davinci_set_mode(enum clock_event_mode mode,
        case CLOCK_EVT_MODE_SHUTDOWN:
                t->opts = TIMER_OPTS_DISABLED;
                break;
+       case CLOCK_EVT_MODE_RESUME:
+               break;
        }
 }
 
index 010f6fa984a65e7f05262fa5ec70edda8ee8b34b..d86d124aea2290791afabf17cc579a757a6fb19d 100644 (file)
@@ -159,6 +159,7 @@ static void imx_set_mode(enum clock_event_mode mode, struct clock_event_device *
                break;
        case CLOCK_EVT_MODE_SHUTDOWN:
        case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_RESUME:
                /* Left event sources disabled, no more interrupts appears */
                break;
        }
index 9bb02b6d7ae1622fbfb002fedc98bdfb9f1857fc..dbe07c9472edcc41130d0ba0a523cdf3e8e31fac 100644 (file)
@@ -42,6 +42,13 @@ config IOP3XX_ATU
           Say N if the IOP is an add in card, the host system owns the PCI
           bus in this case.
 
+config MACH_EM7210
+       bool "Enable support for the Lanner EM7210"
+       help
+         Say Y here if you want to run your kernel on the Lanner EM7210
+         board. Say also Y here if you have a SS4000e Baxter Creek NAS
+         appliance."
+
 endmenu
 
 endif
index 7b05b37e1f94c5ea6d4b49f1e8e9786990864473..cfdf8a137c2b9f8911771d87859b0edb4934019b 100644 (file)
@@ -11,3 +11,4 @@ obj-$(CONFIG_MACH_GLANTANK) += glantank.o
 obj-$(CONFIG_ARCH_IQ80321) += iq80321.o
 obj-$(CONFIG_ARCH_IQ31244) += iq31244.o
 obj-$(CONFIG_MACH_N2100) += n2100.o
+obj-$(CONFIG_MACH_EM7210) += em7210.o
diff --git a/arch/arm/mach-iop32x/em7210.c b/arch/arm/mach-iop32x/em7210.c
new file mode 100644 (file)
index 0000000..c947152
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * arch/arm/mach-iop32x/em7210.c
+ *
+ * Board support code for the Lanner EM7210 platforms.
+ *
+ * Based on arch/arm/mach-iop32x/iq31244.c file.
+ *
+ * Copyright (C) 2007 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/pm.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <asm/hardware.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+#include <asm/arch/time.h>
+
+static void __init em7210_timer_init(void)
+{
+       /* http://www.kwaak.net/fotos/fotos-nas/slide_24.html */
+       /* 33.333 MHz crystal.                                */
+       iop_init_time(200000000);
+}
+
+static struct sys_timer em7210_timer = {
+       .init           = em7210_timer_init,
+       .offset         = iop_gettimeoffset,
+};
+
+/*
+ * EM7210 RTC
+ */
+static struct i2c_board_info __initdata em7210_i2c_devices[] = {
+       {
+               I2C_BOARD_INFO("rtc-rs5c372", 0x32),
+               .type = "rs5c372a",
+       },
+};
+
+/*
+ * EM7210 I/O
+ */
+static struct map_desc em7210_io_desc[] __initdata = {
+       {       /* on-board devices */
+               .virtual        = IQ31244_UART,
+               .pfn            = __phys_to_pfn(IQ31244_UART),
+               .length         = 0x00100000,
+               .type           = MT_DEVICE,
+       },
+};
+
+void __init em7210_map_io(void)
+{
+       iop3xx_map_io();
+       iotable_init(em7210_io_desc, ARRAY_SIZE(em7210_io_desc));
+}
+
+
+/*
+ * EM7210 PCI
+ */
+#define INTA   IRQ_IOP32X_XINT0
+#define INTB   IRQ_IOP32X_XINT1
+#define INTC   IRQ_IOP32X_XINT2
+#define INTD   IRQ_IOP32X_XINT3
+
+static int __init
+em7210_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+       static int pci_irq_table[][4] = {
+               /*
+                * PCI IDSEL/INTPIN->INTLINE
+                * A       B       C       D
+                */
+               {INTB, INTB, INTB, INTB}, /* console / uart */
+               {INTA, INTA, INTA, INTA}, /* 1st 82541      */
+               {INTD, INTD, INTD, INTD}, /* 2nd 82541      */
+               {INTC, INTC, INTC, INTC}, /* GD31244        */
+               {INTD, INTA, INTA, INTA}, /* mini-PCI       */
+               {INTD, INTC, INTA, INTA}, /* NEC USB        */
+       };
+
+       if (pin < 1 || pin > 4)
+               return -1;
+
+       return pci_irq_table[slot % 6][pin - 1];
+}
+
+static struct hw_pci em7210_pci __initdata = {
+       .swizzle        = pci_std_swizzle,
+       .nr_controllers = 1,
+       .setup          = iop3xx_pci_setup,
+       .preinit        = iop3xx_pci_preinit,
+       .scan           = iop3xx_pci_scan_bus,
+       .map_irq        = em7210_pci_map_irq,
+};
+
+static int __init em7210_pci_init(void)
+{
+       if (machine_is_em7210())
+               pci_common_init(&em7210_pci);
+
+       return 0;
+}
+
+subsys_initcall(em7210_pci_init);
+
+
+/*
+ * EM7210 Flash
+ */
+static struct physmap_flash_data em7210_flash_data = {
+       .width          = 2,
+};
+
+static struct resource em7210_flash_resource = {
+       .start          = 0xf0000000,
+       .end            = 0xf1ffffff,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device em7210_flash_device = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &em7210_flash_data,
+       },
+       .num_resources  = 1,
+       .resource       = &em7210_flash_resource,
+};
+
+
+/*
+ * EM7210 UART
+ * The physical address of the serial port is 0xfe800000,
+ * so it can be used for physical and virtual address.
+ */
+static struct plat_serial8250_port em7210_serial_port[] = {
+       {
+               .mapbase        = IQ31244_UART,
+               .membase        = (char *)IQ31244_UART,
+               .irq            = IRQ_IOP32X_XINT1,
+               .flags          = UPF_SKIP_TEST,
+               .iotype         = UPIO_MEM,
+               .regshift       = 0,
+               .uartclk        = 1843200,
+       },
+       { },
+};
+
+static struct resource em7210_uart_resource = {
+       .start          = IQ31244_UART,
+       .end            = IQ31244_UART + 7,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device em7210_serial_device = {
+       .name           = "serial8250",
+       .id             = PLAT8250_DEV_PLATFORM,
+       .dev            = {
+               .platform_data          = em7210_serial_port,
+       },
+       .num_resources  = 1,
+       .resource       = &em7210_uart_resource,
+};
+
+void em7210_power_off(void)
+{
+       *IOP3XX_GPOE &= 0xfe;
+       *IOP3XX_GPOD |= 0x01;
+}
+
+static void __init em7210_init_machine(void)
+{
+       platform_device_register(&em7210_serial_device);
+       platform_device_register(&iop3xx_i2c0_device);
+       platform_device_register(&iop3xx_i2c1_device);
+       platform_device_register(&em7210_flash_device);
+       platform_device_register(&iop3xx_dma_0_channel);
+       platform_device_register(&iop3xx_dma_1_channel);
+
+       i2c_register_board_info(0, em7210_i2c_devices,
+               ARRAY_SIZE(em7210_i2c_devices));
+
+
+       pm_power_off = em7210_power_off;
+}
+
+MACHINE_START(EM7210, "Lanner EM7210")
+       .phys_io        = IQ31244_UART,
+       .io_pg_offst    = ((IQ31244_UART) >> 18) & 0xfffc,
+       .boot_params    = 0xa0000100,
+       .map_io         = em7210_map_io,
+       .init_irq       = iop32x_init_irq,
+       .timer          = &em7210_timer,
+       .init_machine   = em7210_init_machine,
+MACHINE_END
index c971171c2905a359bc06a4d32280a859ae1bfeca..55cf0162e8c1acca575ca0b46d82db8774b61dbb 100644 (file)
@@ -63,7 +63,8 @@ void __init iop32x_init_irq(void)
        if (machine_is_glantank() ||
            machine_is_iq80321() ||
            machine_is_iq31244() ||
-           machine_is_n2100())
+           machine_is_n2100() ||
+           machine_is_em7210())
                *IOP3XX_PCIIRSR = 0x0f;
 
        for (i = 0; i < NR_IRQS; i++) {
index 8112f726ffa0885e2edd505b3a0e17ad5e925b0f..c1271c449246ecf743d6bdce0e77e052ad1e74a1 100644 (file)
@@ -188,7 +188,7 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
        *int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
 
        /* Configure the line as an input */
-       gpio_line_config(line, IXP4XX_GPIO_IN);
+       gpio_line_config(irq2gpio[irq], IXP4XX_GPIO_IN);
 
        return 0;
 }
@@ -459,6 +459,8 @@ static void ixp4xx_set_mode(enum clock_event_mode mode,
        default:
                osrt = opts = 0;
                break;
+       case CLOCK_EVT_MODE_RESUME:
+               break;
        }
 
        *IXP4XX_OSRT1 = osrt | opts;
index 2407bba00547bb9b8c338955ab113016c6a60d98..4c3ab43e1046b5f36ecd9c27447b31d33e05003a 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
-#include <linux/ptrace.h>
 #include <linux/sysdev.h>
 
 #include <asm/hardware.h>
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig
new file mode 100644 (file)
index 0000000..5fe8606
--- /dev/null
@@ -0,0 +1,12 @@
+menu "MX3 Options"
+       depends on ARCH_MX3
+
+config MACH_MX31ADS
+       bool "Support MX31ADS platforms"
+       default y
+       help
+         Include support for MX31ADS platform. This includes specific
+         configurations for the board and its peripherals.
+
+endmenu
+
diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile
new file mode 100644 (file)
index 0000000..cbec997
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y                  := mm.o time.o
+obj-$(CONFIG_MACH_MX31ADS)     += mx31ads.o
diff --git a/arch/arm/mach-mx3/Makefile.boot b/arch/arm/mach-mx3/Makefile.boot
new file mode 100644 (file)
index 0000000..e1dd366
--- /dev/null
@@ -0,0 +1,3 @@
+   zreladdr-y  := 0x80008000
+params_phys-y  := 0x80000100
+initrd_phys-y  := 0x80800000
diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c
new file mode 100644 (file)
index 0000000..41dad48
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ *  Copyright (C) 1999,2000 Arm Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *    - add MX31 specific definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <asm/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+#include <asm/arch/common.h>
+
+/*!
+ * @file mm.c
+ *
+ * @brief This file creates static virtual to physical mappings, common to all MX3 boards.
+ *
+ * @ingroup Memory
+ */
+
+/*!
+ * This table defines static virtual address mappings for I/O regions.
+ * These are the mappings common across all MX3 boards.
+ */
+static struct map_desc mxc_io_desc[] __initdata = {
+       {
+               .virtual        = X_MEMC_BASE_ADDR_VIRT,
+               .pfn            = __phys_to_pfn(X_MEMC_BASE_ADDR),
+               .length         = X_MEMC_SIZE,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        = AVIC_BASE_ADDR_VIRT,
+               .pfn            = __phys_to_pfn(AVIC_BASE_ADDR),
+               .length         = AVIC_SIZE,
+               .type           = MT_NONSHARED_DEVICE
+       },
+};
+
+/*!
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mxc_map_io(void)
+{
+       iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
+}
diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c
new file mode 100644 (file)
index 0000000..7e89bdc
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright 2005-2007 Freescale Semiconductor, Inc. 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/serial_8250.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/memory.h>
+#include <asm/mach/map.h>
+#include <asm/arch/common.h>
+
+/*!
+ * @file mx31ads.c
+ *
+ * @brief This file contains the board-specific initialization routines.
+ *
+ * @ingroup System
+ */
+
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+/*!
+ * The serial port definition structure.
+ */
+static struct plat_serial8250_port serial_platform_data[] = {
+       {
+               .membase  = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTA),
+               .mapbase  = (unsigned long)(CS4_BASE_ADDR + PBC_SC16C652_UARTA),
+               .irq      = EXPIO_INT_XUART_INTA,
+               .uartclk  = 14745600,
+               .regshift = 0,
+               .iotype   = UPIO_MEM,
+               .flags    = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,
+       }, {
+               .membase  = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTB),
+               .mapbase  = (unsigned long)(CS4_BASE_ADDR + PBC_SC16C652_UARTB),
+               .irq      = EXPIO_INT_XUART_INTB,
+               .uartclk  = 14745600,
+               .regshift = 0,
+               .iotype   = UPIO_MEM,
+               .flags    = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,
+       },
+       {},
+};
+
+static struct platform_device serial_device = {
+       .name   = "serial8250",
+       .id     = 0,
+       .dev    = {
+               .platform_data = serial_platform_data,
+       },
+};
+
+static int __init mxc_init_extuart(void)
+{
+       return platform_device_register(&serial_device);
+}
+#else
+static inline int mxc_init_extuart(void)
+{
+       return 0;
+}
+#endif
+
+/*!
+ * This structure defines static mappings for the i.MX31ADS board.
+ */
+static struct map_desc mx31ads_io_desc[] __initdata = {
+       {
+               .virtual        = AIPS1_BASE_ADDR_VIRT,
+               .pfn            = __phys_to_pfn(AIPS1_BASE_ADDR),
+               .length         = AIPS1_SIZE,
+               .type           = MT_NONSHARED_DEVICE
+       }, {
+               .virtual        = SPBA0_BASE_ADDR_VIRT,
+               .pfn            = __phys_to_pfn(SPBA0_BASE_ADDR),
+               .length         = SPBA0_SIZE,
+               .type           = MT_NONSHARED_DEVICE
+       }, {
+               .virtual        = AIPS2_BASE_ADDR_VIRT,
+               .pfn            = __phys_to_pfn(AIPS2_BASE_ADDR),
+               .length         = AIPS2_SIZE,
+               .type           = MT_NONSHARED_DEVICE
+       }, {
+               .virtual        = CS4_BASE_ADDR_VIRT,
+               .pfn            = __phys_to_pfn(CS4_BASE_ADDR),
+               .length         = CS4_SIZE / 2,
+               .type           = MT_DEVICE
+       },
+};
+
+/*!
+ * Set up static virtual mappings.
+ */
+void __init mx31ads_map_io(void)
+{
+       mxc_map_io();
+       iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc));
+}
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+       mxc_init_extuart();
+}
+
+/*
+ * The following uses standard kernel macros defined in arch.h in order to
+ * initialize __mach_desc_MX31ADS data structure.
+ */
+MACHINE_START(MX31ADS, "Freescale MX31ADS")
+       /* Maintainer: Freescale Semiconductor, Inc. */
+       .phys_io        = AIPS1_BASE_ADDR,
+       .io_pg_offst    = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+       .boot_params    = PHYS_OFFSET + 0x100,
+       .map_io         = mx31ads_map_io,
+       .init_irq       = mxc_init_irq,
+       .init_machine   = mxc_board_init,
+       .timer          = &mxc_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx3/time.c b/arch/arm/mach-mx3/time.c
new file mode 100644 (file)
index 0000000..e81fb5c
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * System Timer Interrupt reconfigured to run in free-run mode.
+ * Author: Vitaly Wool
+ * Copyright 2004 MontaVista Software Inc.
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. 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 as
+ * published by the Free Software Foundation.
+ */
+
+/*!
+ * @file time.c
+ * @brief This file contains OS tick and wdog timer implementations.
+ *
+ * This file contains OS tick and wdog timer implementations.
+ *
+ * @ingroup Timers
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/hardware.h>
+#include <asm/mach/time.h>
+#include <asm/io.h>
+#include <asm/arch/common.h>
+
+/*!
+ * This is the timer interrupt service routine to do required tasks.
+ * It also services the WDOG timer at the frequency of twice per WDOG
+ * timeout value. For example, if the WDOG's timeout value is 4 (2
+ * seconds since the WDOG runs at 0.5Hz), it will be serviced once
+ * every 2/2=1 second.
+ *
+ * @param  irq          GPT interrupt source number (not used)
+ * @param  dev_id       this parameter is not used
+ * @return always returns \b IRQ_HANDLED as defined in
+ *         include/linux/interrupt.h.
+ */
+static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
+{
+       unsigned int next_match;
+
+       write_seqlock(&xtime_lock);
+
+       if (__raw_readl(MXC_GPT_GPTSR) & GPTSR_OF1) {
+               do {
+                       timer_tick();
+                       next_match = __raw_readl(MXC_GPT_GPTOCR1) + LATCH;
+                       __raw_writel(GPTSR_OF1, MXC_GPT_GPTSR);
+                       __raw_writel(next_match, MXC_GPT_GPTOCR1);
+               } while ((signed long)(next_match -
+                                      __raw_readl(MXC_GPT_GPTCNT)) <= 0);
+       }
+
+       write_sequnlock(&xtime_lock);
+
+       return IRQ_HANDLED;
+}
+
+/*!
+ * This function is used to obtain the number of microseconds since the last
+ * timer interrupt. Note that interrupts is disabled by do_gettimeofday().
+ *
+ * @return the number of microseconds since the last timer interrupt.
+ */
+static unsigned long mxc_gettimeoffset(void)
+{
+       unsigned long ticks_to_match, elapsed, usec, tick_usec, i;
+
+       /* Get ticks before next timer match */
+       ticks_to_match =
+           __raw_readl(MXC_GPT_GPTOCR1) - __raw_readl(MXC_GPT_GPTCNT);
+
+       /* We need elapsed ticks since last match */
+       elapsed = LATCH - ticks_to_match;
+
+       /* Now convert them to usec */
+       /* Insure no overflow when calculating the usec below */
+       for (i = 1, tick_usec = tick_nsec / 1000;; i *= 2) {
+               tick_usec /= i;
+               if ((0xFFFFFFFF / tick_usec) > elapsed)
+                       break;
+       }
+       usec = (unsigned long)(elapsed * tick_usec) / (LATCH / i);
+
+       return usec;
+}
+
+/*!
+ * The OS tick timer interrupt structure.
+ */
+static struct irqaction timer_irq = {
+       .name = "MXC Timer Tick",
+       .flags = IRQF_DISABLED | IRQF_TIMER,
+       .handler = mxc_timer_interrupt
+};
+
+/*!
+ * This function is used to initialize the GPT to produce an interrupt
+ * based on HZ.  It is called by start_kernel() during system startup.
+ */
+void __init mxc_init_time(void)
+{
+       u32 reg, v;
+       reg = __raw_readl(MXC_GPT_GPTCR);
+       reg &= ~GPTCR_ENABLE;
+       __raw_writel(reg, MXC_GPT_GPTCR);
+       reg |= GPTCR_SWR;
+       __raw_writel(reg, MXC_GPT_GPTCR);
+
+       while ((__raw_readl(MXC_GPT_GPTCR) & GPTCR_SWR) != 0)
+               cpu_relax();
+
+       reg = GPTCR_FRR | GPTCR_CLKSRC_HIGHFREQ;
+       __raw_writel(reg, MXC_GPT_GPTCR);
+
+       /* TODO: get timer rate from clk driver */
+       v = 66500000;
+
+       __raw_writel((v / CLOCK_TICK_RATE) - 1, MXC_GPT_GPTPR);
+
+       if ((v % CLOCK_TICK_RATE) != 0) {
+               pr_info("\nWARNING: Can't generate CLOCK_TICK_RATE at %d Hz\n",
+                       CLOCK_TICK_RATE);
+       }
+       pr_info("Actual CLOCK_TICK_RATE is %d Hz\n",
+               v / ((__raw_readl(MXC_GPT_GPTPR) & 0xFFF) + 1));
+
+       reg = __raw_readl(MXC_GPT_GPTCNT);
+       reg += LATCH;
+       __raw_writel(reg, MXC_GPT_GPTOCR1);
+
+       setup_irq(MXC_INT_GPT, &timer_irq);
+
+       reg = __raw_readl(MXC_GPT_GPTCR);
+       reg =
+           GPTCR_FRR | GPTCR_CLKSRC_HIGHFREQ | GPTCR_STOPEN | GPTCR_DOZEN |
+           GPTCR_WAITEN | GPTCR_ENMOD | GPTCR_ENABLE;
+       __raw_writel(reg, MXC_GPT_GPTCR);
+
+       __raw_writel(GPTIR_OF1IE, MXC_GPT_GPTIR);
+}
+
+struct sys_timer mxc_timer = {
+       .init = mxc_init_time,
+       .offset = mxc_gettimeoffset,
+};
index 53213a69f601593e37dd5366280e4872b8ccbbb1..4476411b81408704f9d430e51715d1232f95c2d5 100644 (file)
@@ -1,6 +1,7 @@
 obj-y := irq.o time.o generic.o
 
 obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o
+obj-$(CONFIG_MACH_CC9P9360JS) += mach-cc9p9360js.o
 
 obj-$(CONFIG_BOARD_A9M9750DEV) += board-a9m9750dev.o
 obj-$(CONFIG_BOARD_JSCC9P9360) += board-jscc9p9360.o
index 25289884a6079d45a4df8b7ae7461865e251bde4..925048e7adfe9c9d048a14cb9914562e8e11cc49 100644 (file)
@@ -77,7 +77,7 @@ static void a9m9750dev_fpga_demux_handler(unsigned int irq,
 
                desc = irq_desc + FPGA_IRQ(irqno);
 
-               desc_handle_irq(irqno, desc);
+               desc_handle_irq(FPGA_IRQ(irqno), desc);
        }
 }
 
@@ -91,7 +91,7 @@ void __init board_a9m9750dev_init_irq(void)
         * use GPIO 11, because GPIO 32 is used for the LCD
         */
        /* XXX: proper GPIO handling */
-       BBU_GC(2) &= ~0x2000;
+       BBU_GCONFb1(1) &= ~0x2000;
 
        for (i = FPGA_IRQ(0); i <= FPGA_IRQ(7); ++i) {
                set_irq_chip(i, &a9m9750dev_fpga_chip);
@@ -178,7 +178,7 @@ void __init board_a9m9750dev_init_machine(void)
 
        /* setup static CS0: memory configuration */
        reg = MEM_SMC(0);
-       REGSET(reg, MEM_SMC, WSMC, OFF);
+       REGSET(reg, MEM_SMC, PSMC, OFF);
        REGSET(reg, MEM_SMC, BSMC, OFF);
        REGSET(reg, MEM_SMC, EW, OFF);
        REGSET(reg, MEM_SMC, PB, 1);
@@ -196,4 +196,3 @@ void __init board_a9m9750dev_init_machine(void)
        platform_add_devices(board_a9m9750dev_devices,
                        ARRAY_SIZE(board_a9m9750dev_devices));
 }
-
index 83e2b6532b2243749d1c02e60dcdac28e1ae6334..d742c921e34dabb42ed10948c32599c4d12dcedb 100644 (file)
@@ -18,6 +18,8 @@
 #include <asm/arch-ns9xxx/regs-mem.h>
 #include <asm/arch-ns9xxx/board.h>
 
+#include "generic.h"
+
 static struct map_desc standard_io_desc[] __initdata = {
        { /* BBus */
                .virtual = io_p2v(0x90000000),
index 83d92724a971cb383c7141968148ddcccf3a9119..b8c7b00522e677d0ee8d5f0ebc72faa1a7ed9a98 100644 (file)
@@ -21,6 +21,15 @@ static void ns9xxx_ack_irq_timer(unsigned int irq)
 {
        u32 tc = SYS_TC(irq - IRQ_TIMER0);
 
+       /*
+        * If the timer is programmed to halt on terminal count, the
+        * timer must be disabled before clearing the interrupt.
+        */
+       if (REGGET(tc, SYS_TCx, REN) == 0) {
+               REGSET(tc, SYS_TCx, TEN, DIS);
+               SYS_TC(irq - IRQ_TIMER0) = tc;
+       }
+
        REGSET(tc, SYS_TCx, INTC, SET);
        SYS_TC(irq - IRQ_TIMER0) = tc;
 
@@ -28,7 +37,7 @@ static void ns9xxx_ack_irq_timer(unsigned int irq)
        SYS_TC(irq - IRQ_TIMER0) = tc;
 }
 
-void (*ns9xxx_ack_irq_functions[NR_IRQS])(unsigned int) = {
+static void (*ns9xxx_ack_irq_functions[NR_IRQS])(unsigned int) = {
        [IRQ_TIMER0] = ns9xxx_ack_irq_timer,
        [IRQ_TIMER1] = ns9xxx_ack_irq_timer,
        [IRQ_TIMER2] = ns9xxx_ack_irq_timer,
index d09d5fa5620a4df9b6767baa1e54f6531150ee20..85c8b41105c915818d430ba52c0654817f3fb167 100644 (file)
@@ -20,7 +20,7 @@ static void __init mach_cc9p9360js_init_machine(void)
        board_jscc9p9360_init_machine();
 }
 
-MACHINE_START(CC9P9360DEV, "Digi ConnectCore 9P 9360 on an JSCC9P9360 Devboard")
+MACHINE_START(CC9P9360JS, "Digi ConnectCore 9P 9360 on an JSCC9P9360 Devboard")
        .map_io = ns9xxx_map_io,
        .init_irq = ns9xxx_init_irq,
        .init_machine = mach_cc9p9360js_init_machine,
index 3705d20c4e5c9b69a8c9c4d01dc2ee7b1c72e1c7..237651ebae5da555be9e346b36f154400d9acaa7 100644 (file)
@@ -156,6 +156,7 @@ static void omap_mpu_set_mode(enum clock_event_mode mode,
                break;
        case CLOCK_EVT_MODE_UNUSED:
        case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_RESUME:
                break;
        }
 }
index 5c0a10041cd17c1fc7c9ae97a442d266b4dd8c05..5ebec6d88b5161d0ec3c5d05076a6ff21389d664 100644 (file)
@@ -37,6 +37,10 @@ config MACH_TRIZEPS4
        bool "Keith und Koep Trizeps4 DIMM-Module"
        select PXA27x
 
+config MACH_EM_X270
+       bool "CompuLab EM-x270 platform"
+       select PXA27x
+
 endchoice
 
 if PXA_SHARPSL
index 9093eb1c94ebdfae3a94611a1d586c493ad01d9a..7d6ab5c59ab9757829cd72849d229265ca2cc0d7 100644 (file)
@@ -18,6 +18,7 @@ obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o sp
 obj-$(CONFIG_MACH_AKITA)       += akita-ioexp.o
 obj-$(CONFIG_MACH_POODLE)      += poodle.o corgi_ssp.o
 obj-$(CONFIG_MACH_TOSA)         += tosa.o
+obj-$(CONFIG_MACH_EM_X270) += em-x270.o
 
 # Support for blinky lights
 led-y := leds.o
index 9a6faff8e5a71f17a4097ced0536e7798f43f91d..636fdb1c049cd6bfac477d203753f09b8aa75e6f 100644 (file)
@@ -1,11 +1,11 @@
-extern struct platform_device pxamci_device;
-extern struct platform_device pxaudc_device;
-extern struct platform_device pxafb_device;
-extern struct platform_device ffuart_device;
-extern struct platform_device btuart_device;
-extern struct platform_device stuart_device;
-extern struct platform_device hwuart_device;
-extern struct platform_device pxai2c_device;
-extern struct platform_device pxai2s_device;
-extern struct platform_device pxaficp_device;
-extern struct platform_device pxartc_device;
+extern struct platform_device pxa_device_mci;
+extern struct platform_device pxa_device_udc;
+extern struct platform_device pxa_device_fb;
+extern struct platform_device pxa_device_ffuart;
+extern struct platform_device pxa_device_btuart;
+extern struct platform_device pxa_device_stuart;
+extern struct platform_device pxa_device_hwuart;
+extern struct platform_device pxa_device_i2c;
+extern struct platform_device pxa_device_i2s;
+extern struct platform_device pxa_device_ficp;
+extern struct platform_device pxa_device_rtc;
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
new file mode 100644 (file)
index 0000000..3d0ad50
--- /dev/null
@@ -0,0 +1,354 @@
+/*
+ * Support for CompuLab EM-x270 platform
+ *
+ * Copyright (C) 2007 CompuLab, Ltd.
+ * Author: Mike Rapoport <mike@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+
+#include <linux/dm9000.h>
+#include <linux/rtc-v3020.h>
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/ohci.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/bitfield.h>
+
+#include "generic.h"
+
+/* GPIO IRQ usage */
+#define EM_X270_MMC_PD         (105)
+#define EM_X270_ETHIRQ         IRQ_GPIO(41)
+#define EM_X270_MMC_IRQ                IRQ_GPIO(13)
+
+static struct resource em_x270_dm9k_resource[] = {
+       [0] = {
+               .start = PXA_CS2_PHYS,
+               .end   = PXA_CS2_PHYS + 3,
+               .flags = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start = PXA_CS2_PHYS + 8,
+               .end   = PXA_CS2_PHYS + 8 + 0x3f,
+               .flags = IORESOURCE_MEM,
+       },
+       [2] = {
+               .start = EM_X270_ETHIRQ,
+               .end   = EM_X270_ETHIRQ,
+               .flags = IORESOURCE_IRQ,
+       }
+};
+
+/* for the moment we limit ourselves to 32bit IO until some
+ * better IO routines can be written and tested
+ */
+static struct dm9000_plat_data em_x270_dm9k_platdata = {
+       .flags          = DM9000_PLATF_32BITONLY,
+};
+
+/* Ethernet device */
+static struct platform_device em_x270_dm9k = {
+       .name           = "dm9000",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(em_x270_dm9k_resource),
+       .resource       = em_x270_dm9k_resource,
+       .dev            = {
+               .platform_data = &em_x270_dm9k_platdata,
+       }
+};
+
+/* audio device */
+static struct platform_device em_x270_audio = {
+       .name           = "pxa2xx-ac97",
+       .id             = -1,
+};
+
+/* WM9712 touchscreen controller. Hopefully the driver will make it to
+ * the mainstream sometime */
+static struct platform_device em_x270_ts = {
+       .name           = "wm97xx-ts",
+       .id             = -1,
+};
+
+/* RTC */
+static struct resource em_x270_v3020_resource[] = {
+       [0] = {
+               .start = PXA_CS4_PHYS,
+               .end   = PXA_CS4_PHYS + 3,
+               .flags = IORESOURCE_MEM,
+       },
+};
+
+static struct v3020_platform_data em_x270_v3020_platdata = {
+       .leftshift = 0,
+};
+
+static struct platform_device em_x270_rtc = {
+       .name           = "v3020",
+       .num_resources  = ARRAY_SIZE(em_x270_v3020_resource),
+       .resource       = em_x270_v3020_resource,
+       .id             = -1,
+       .dev            = {
+               .platform_data = &em_x270_v3020_platdata,
+       }
+};
+
+/* NAND flash */
+#define GPIO_NAND_CS   (11)
+#define GPIO_NAND_RB   (56)
+
+static inline void nand_cs_on(void)
+{
+       GPCR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS);
+}
+
+static void nand_cs_off(void)
+{
+       dsb();
+
+       GPSR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS);
+}
+
+/* hardware specific access to control-lines */
+static void em_x270_nand_cmd_ctl(struct mtd_info *mtd, int dat,
+                                unsigned int ctrl)
+{
+       struct nand_chip *this = mtd->priv;
+       unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
+
+       dsb();
+
+       if (ctrl & NAND_CTRL_CHANGE) {
+               if (ctrl & NAND_ALE)
+                       nandaddr |=  (1 << 3);
+               else
+                       nandaddr &= ~(1 << 3);
+               if (ctrl & NAND_CLE)
+                       nandaddr |=  (1 << 2);
+               else
+                       nandaddr &= ~(1 << 2);
+               if (ctrl & NAND_NCE)
+                       nand_cs_on();
+               else
+                       nand_cs_off();
+       }
+
+       dsb();
+       this->IO_ADDR_W = (void __iomem *)nandaddr;
+       if (dat != NAND_CMD_NONE)
+               writel(dat, this->IO_ADDR_W);
+
+       dsb();
+}
+
+/* read device ready pin */
+static int em_x270_nand_device_ready(struct mtd_info *mtd)
+{
+       dsb();
+
+       return GPLR(GPIO_NAND_RB) & GPIO_bit(GPIO_NAND_RB);
+}
+
+static struct mtd_partition em_x270_partition_info[] = {
+       [0] = {
+               .name   = "em_x270-0",
+               .offset = 0,
+               .size   = SZ_4M,
+       },
+       [1] = {
+               .name   = "em_x270-1",
+               .offset = MTDPART_OFS_APPEND,
+               .size   = MTDPART_SIZ_FULL
+       },
+};
+
+static const char *em_x270_part_probes[] = { "cmdlinepart", NULL };
+
+struct platform_nand_data em_x270_nand_platdata = {
+       .chip = {
+               .nr_chips = 1,
+               .chip_offset = 0,
+               .nr_partitions = ARRAY_SIZE(em_x270_partition_info),
+               .partitions = em_x270_partition_info,
+               .chip_delay = 20,
+               .part_probe_types = em_x270_part_probes,
+       },
+       .ctrl = {
+               .hwcontrol = 0,
+               .dev_ready = em_x270_nand_device_ready,
+               .select_chip = 0,
+               .cmd_ctrl = em_x270_nand_cmd_ctl,
+       },
+};
+
+static struct resource em_x270_nand_resource[] = {
+       [0] = {
+               .start = PXA_CS1_PHYS,
+               .end   = PXA_CS1_PHYS + 12,
+               .flags = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device em_x270_nand = {
+       .name           = "gen_nand",
+       .num_resources  = ARRAY_SIZE(em_x270_nand_resource),
+       .resource       = em_x270_nand_resource,
+       .id             = -1,
+       .dev            = {
+               .platform_data = &em_x270_nand_platdata,
+       }
+};
+
+/* platform devices */
+static struct platform_device *platform_devices[] __initdata = {
+       &em_x270_dm9k,
+       &em_x270_audio,
+       &em_x270_ts,
+       &em_x270_rtc,
+       &em_x270_nand,
+};
+
+
+/* PXA27x OHCI controller setup */
+static int em_x270_ohci_init(struct device *dev)
+{
+       /* Set the Power Control Polarity Low */
+       UHCHR = (UHCHR | UHCHR_PCPL) &
+               ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE);
+
+       /* enable port 2 transiever */
+       UP2OCR = UP2OCR_HXS | UP2OCR_HXOE;
+
+       return 0;
+}
+
+static struct pxaohci_platform_data em_x270_ohci_platform_data = {
+       .port_mode      = PMM_PERPORT_MODE,
+       .init           = em_x270_ohci_init,
+};
+
+
+static int em_x270_mci_init(struct device *dev,
+                           irq_handler_t em_x270_detect_int,
+                           void *data)
+{
+       int err;
+
+       /* setup GPIO for PXA27x MMC controller */
+       pxa_gpio_mode(GPIO32_MMCCLK_MD);
+       pxa_gpio_mode(GPIO112_MMCCMD_MD);
+       pxa_gpio_mode(GPIO92_MMCDAT0_MD);
+       pxa_gpio_mode(GPIO109_MMCDAT1_MD);
+       pxa_gpio_mode(GPIO110_MMCDAT2_MD);
+       pxa_gpio_mode(GPIO111_MMCDAT3_MD);
+
+       /* EM-X270 uses GPIO13 as SD power enable */
+       pxa_gpio_mode(EM_X270_MMC_PD | GPIO_OUT);
+
+       err = request_irq(EM_X270_MMC_IRQ, em_x270_detect_int,
+                         IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+                         "MMC card detect", data);
+       if (err) {
+               printk(KERN_ERR "%s: can't request MMC card detect IRQ: %d\n",
+                      __FUNCTION__, err);
+               return err;
+       }
+
+       return 0;
+}
+
+static void em_x270_mci_setpower(struct device *dev, unsigned int vdd)
+{
+       /*
+          FIXME: current hardware implementation does not allow to
+          enable/disable MMC power. This will be fixed in next HW releases,
+          and we'll need to add implmentation here.
+       */
+       return;
+}
+
+static void em_x270_mci_exit(struct device *dev, void *data)
+{
+       free_irq(EM_X270_MMC_IRQ, data);
+}
+
+static struct pxamci_platform_data em_x270_mci_platform_data = {
+       .ocr_mask       = MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31,
+       .init           = em_x270_mci_init,
+       .setpower       = em_x270_mci_setpower,
+       .exit           = em_x270_mci_exit,
+};
+
+/* LCD 480x640 */
+static struct pxafb_mode_info em_x270_lcd_mode = {
+       .pixclock       = 50000,
+       .bpp            = 16,
+       .xres           = 480,
+       .yres           = 640,
+       .hsync_len      = 8,
+       .vsync_len      = 2,
+       .left_margin    = 8,
+       .upper_margin   = 0,
+       .right_margin   = 24,
+       .lower_margin   = 4,
+       .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info em_x270_lcd = {
+       .modes          = &em_x270_lcd_mode,
+       .num_modes      = 1,
+       .cmap_inverse   = 0,
+       .cmap_static    = 0,
+       .lccr0          = LCCR0_PAS,
+       .lccr3          = LCCR3_PixClkDiv(0x01) | LCCR3_Acb(0xff),
+};
+
+static void __init em_x270_init(void)
+{
+       /* setup LCD */
+       set_pxa_fb_info(&em_x270_lcd);
+
+       /* register EM-X270 platform devices */
+       platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+       /* set MCI and OHCI platform parameters */
+       pxa_set_mci_info(&em_x270_mci_platform_data);
+       pxa_set_ohci_info(&em_x270_ohci_platform_data);
+
+       /* setup STUART GPIOs */
+       pxa_gpio_mode(GPIO46_STRXD_MD);
+       pxa_gpio_mode(GPIO47_STTXD_MD);
+
+       /* setup BTUART GPIOs */
+       pxa_gpio_mode(GPIO42_BTRXD_MD);
+       pxa_gpio_mode(GPIO43_BTTXD_MD);
+       pxa_gpio_mode(GPIO44_BTCTS_MD);
+       pxa_gpio_mode(GPIO45_BTRTS_MD);
+
+       /* Setup interrupt for dm9000 */
+       set_irq_type(EM_X270_ETHIRQ, IRQT_RISING);
+}
+
+MACHINE_START(EM_X270, "Compulab EM-x270")
+       .boot_params    = 0xa0000100,
+       .phys_io        = 0x40000000,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa27x_init_irq,
+       .timer          = &pxa_timer,
+       .init_machine   = em_x270_init,
+MACHINE_END
index 296539b6359ca43af779f59e5fa078351c14195b..5510f6fdce55e4dc8b2f55f93359e1b245da619a 100644 (file)
@@ -243,7 +243,7 @@ static struct resource pxamci_resources[] = {
 
 static u64 pxamci_dmamask = 0xffffffffUL;
 
-struct platform_device pxamci_device = {
+struct platform_device pxa_device_mci = {
        .name           = "pxa2xx-mci",
        .id             = -1,
        .dev            = {
@@ -256,7 +256,7 @@ struct platform_device pxamci_device = {
 
 void __init pxa_set_mci_info(struct pxamci_platform_data *info)
 {
-       pxamci_device.dev.platform_data = info;
+       pxa_device_mci.dev.platform_data = info;
 }
 
 
@@ -282,7 +282,7 @@ static struct resource pxa2xx_udc_resources[] = {
 
 static u64 udc_dma_mask = ~(u32)0;
 
-struct platform_device pxaudc_device = {
+struct platform_device pxa_device_udc = {
        .name           = "pxa2xx-udc",
        .id             = -1,
        .resource       = pxa2xx_udc_resources,
@@ -308,7 +308,7 @@ static struct resource pxafb_resources[] = {
 
 static u64 fb_dma_mask = ~(u64)0;
 
-struct platform_device pxafb_device = {
+struct platform_device pxa_device_fb = {
        .name           = "pxa2xx-fb",
        .id             = -1,
        .dev            = {
@@ -321,27 +321,27 @@ struct platform_device pxafb_device = {
 
 void __init set_pxa_fb_info(struct pxafb_mach_info *info)
 {
-       pxafb_device.dev.platform_data = info;
+       pxa_device_fb.dev.platform_data = info;
 }
 
 void __init set_pxa_fb_parent(struct device *parent_dev)
 {
-       pxafb_device.dev.parent = parent_dev;
+       pxa_device_fb.dev.parent = parent_dev;
 }
 
-struct platform_device ffuart_device = {
+struct platform_device pxa_device_ffuart= {
        .name           = "pxa2xx-uart",
        .id             = 0,
 };
-struct platform_device btuart_device = {
+struct platform_device pxa_device_btuart = {
        .name           = "pxa2xx-uart",
        .id             = 1,
 };
-struct platform_device stuart_device = {
+struct platform_device pxa_device_stuart = {
        .name           = "pxa2xx-uart",
        .id             = 2,
 };
-struct platform_device hwuart_device = {
+struct platform_device pxa_device_hwuart = {
        .name           = "pxa2xx-uart",
        .id             = 3,
 };
@@ -358,7 +358,7 @@ static struct resource pxai2c_resources[] = {
        },
 };
 
-struct platform_device pxai2c_device = {
+struct platform_device pxa_device_i2c = {
        .name           = "pxa2xx-i2c",
        .id             = 0,
        .resource       = pxai2c_resources,
@@ -367,7 +367,7 @@ struct platform_device pxai2c_device = {
 
 void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
 {
-       pxai2c_device.dev.platform_data = info;
+       pxa_device_i2c.dev.platform_data = info;
 }
 
 static struct resource pxai2s_resources[] = {
@@ -382,7 +382,7 @@ static struct resource pxai2s_resources[] = {
        },
 };
 
-struct platform_device pxai2s_device = {
+struct platform_device pxa_device_i2s = {
        .name           = "pxa2xx-i2s",
        .id             = -1,
        .resource       = pxai2s_resources,
@@ -391,7 +391,7 @@ struct platform_device pxai2s_device = {
 
 static u64 pxaficp_dmamask = ~(u32)0;
 
-struct platform_device pxaficp_device = {
+struct platform_device pxa_device_ficp = {
        .name           = "pxa2xx-ir",
        .id             = -1,
        .dev            = {
@@ -402,10 +402,10 @@ struct platform_device pxaficp_device = {
 
 void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
 {
-       pxaficp_device.dev.platform_data = info;
+       pxa_device_ficp.dev.platform_data = info;
 }
 
-struct platform_device pxartc_device = {
+struct platform_device pxa_device_rtc = {
        .name           = "sa1100-rtc",
        .id             = -1,
 };
index e66dbc26add1f1f8291e4461b3b2f9a000e86d3c..b59a81a8e7d32d35d1ad9c3b1ce4cc833bf7eb7b 100644 (file)
 #include <asm/arch/lubbock.h>
 #include <asm/mach/time.h>
 
-
-/*
- * Debug macros
- */
-#undef DEBUG
-
-#define SAVE(x)                sleep_save[SLEEP_SAVE_##x] = x
-#define RESTORE(x)     x = sleep_save[SLEEP_SAVE_##x]
-
-#define RESTORE_GPLEVEL(n) do { \
-       GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \
-       GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \
-} while (0)
-
-/*
- * List of global PXA peripheral registers to preserve.
- * More ones like CP and general purpose register values are preserved
- * with the stack pointer in sleep.S.
- */
-enum { SLEEP_SAVE_START = 0,
-
-       SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, SLEEP_SAVE_GPLR3,
-       SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, SLEEP_SAVE_GPDR3,
-       SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, SLEEP_SAVE_GRER3,
-       SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, SLEEP_SAVE_GFER3,
-       SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3,
-
-       SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
-       SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U,
-       SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U,
-       SLEEP_SAVE_GAFR3_L, SLEEP_SAVE_GAFR3_U,
-
-       SLEEP_SAVE_PSTR,
-
-       SLEEP_SAVE_ICMR,
-       SLEEP_SAVE_CKEN,
-
-#ifdef CONFIG_PXA27x
-       SLEEP_SAVE_MDREFR,
-       SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER,
-       SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR,
-#endif
-
-       SLEEP_SAVE_CKSUM,
-
-       SLEEP_SAVE_SIZE
-};
-
+struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
+static unsigned long *sleep_save;
 
 int pxa_pm_enter(suspend_state_t state)
 {
-       unsigned long sleep_save[SLEEP_SAVE_SIZE];
-       unsigned long checksum = 0;
+       unsigned long sleep_save_checksum = 0, checksum = 0;
        int i;
-       extern void pxa_cpu_pm_enter(suspend_state_t state);
 
 #ifdef CONFIG_IWMMXT
        /* force any iWMMXt context to ram **/
@@ -86,100 +38,35 @@ int pxa_pm_enter(suspend_state_t state)
                iwmmxt_task_disable(NULL);
 #endif
 
-       SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2);
-       SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2);
-       SAVE(GRER0); SAVE(GRER1); SAVE(GRER2);
-       SAVE(GFER0); SAVE(GFER1); SAVE(GFER2);
-       SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2);
-
-       SAVE(GAFR0_L); SAVE(GAFR0_U);
-       SAVE(GAFR1_L); SAVE(GAFR1_U);
-       SAVE(GAFR2_L); SAVE(GAFR2_U);
-
-#ifdef CONFIG_PXA27x
-       SAVE(MDREFR);
-       SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3);
-       SAVE(GAFR3_L); SAVE(GAFR3_U);
-       SAVE(PWER); SAVE(PCFR); SAVE(PRER);
-       SAVE(PFER); SAVE(PKWR);
-#endif
-
-       SAVE(ICMR);
-       ICMR = 0;
-
-       SAVE(CKEN);
-       SAVE(PSTR);
-
-       /* Note: wake up source are set up in each machine specific files */
-
-       /* clear GPIO transition detect  bits */
-       GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2;
-#ifdef CONFIG_PXA27x
-       GEDR3 = GEDR3;
-#endif
+       pxa_cpu_pm_fns->save(sleep_save);
 
        /* Clear sleep reset status */
        RCSR = RCSR_SMR;
 
        /* before sleeping, calculate and save a checksum */
-       for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
-               checksum += sleep_save[i];
-       sleep_save[SLEEP_SAVE_CKSUM] = checksum;
+       for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
+               sleep_save_checksum += sleep_save[i];
 
        /* *** go zzz *** */
-       pxa_cpu_pm_enter(state);
-
+       pxa_cpu_pm_fns->enter(state);
        cpu_init();
 
        /* after sleeping, validate the checksum */
-       checksum = 0;
-       for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
+       for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
                checksum += sleep_save[i];
 
        /* if invalid, display message and wait for a hardware reset */
-       if (checksum != sleep_save[SLEEP_SAVE_CKSUM]) {
+       if (checksum != sleep_save_checksum) {
 #ifdef CONFIG_ARCH_LUBBOCK
                LUB_HEXLED = 0xbadbadc5;
 #endif
                while (1)
-                       pxa_cpu_pm_enter(state);
+                       pxa_cpu_pm_fns->enter(state);
        }
 
-       /* ensure not to come back here if it wasn't intended */
-       PSPR = 0;
-
-       /* restore registers */
-       RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2);
-       RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2);
-       RESTORE(GAFR0_L); RESTORE(GAFR0_U);
-       RESTORE(GAFR1_L); RESTORE(GAFR1_U);
-       RESTORE(GAFR2_L); RESTORE(GAFR2_U);
-       RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2);
-       RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2);
-       RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
-
-#ifdef CONFIG_PXA27x
-       RESTORE(MDREFR);
-       RESTORE_GPLEVEL(3); RESTORE(GPDR3);
-       RESTORE(GAFR3_L); RESTORE(GAFR3_U);
-       RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3);
-       RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER);
-       RESTORE(PFER); RESTORE(PKWR);
-#endif
-
-       PSSR = PSSR_RDH | PSSR_PH;
-
-       RESTORE(CKEN);
-
-       ICLR = 0;
-       ICCR = 1;
-       RESTORE(ICMR);
+       pxa_cpu_pm_fns->restore(sleep_save);
 
-       RESTORE(PSTR);
-
-#ifdef DEBUG
-       printk(KERN_DEBUG "*** made it back from resume\n");
-#endif
+       pr_debug("*** made it back from resume\n");
 
        return 0;
 }
@@ -190,3 +77,35 @@ unsigned long sleep_phys_sp(void *sp)
 {
        return virt_to_phys(sp);
 }
+
+static int pxa_pm_valid(suspend_state_t state)
+{
+       if (pxa_cpu_pm_fns)
+               return pxa_cpu_pm_fns->valid(state);
+
+       return -EINVAL;
+}
+
+static struct pm_ops pxa_pm_ops = {
+       .valid          = pxa_pm_valid,
+       .enter          = pxa_pm_enter,
+};
+
+static int __init pxa_pm_init(void)
+{
+       if (!pxa_cpu_pm_fns) {
+               printk(KERN_ERR "no valid pxa_cpu_pm_fns defined\n");
+               return -EINVAL;
+       }
+
+       sleep_save = kmalloc(pxa_cpu_pm_fns->save_size, GFP_KERNEL);
+       if (!sleep_save) {
+               printk(KERN_ERR "failed to alloc memory for pm save\n");
+               return -ENOMEM;
+       }
+
+       pm_set_ops(&pxa_pm_ops);
+       return 0;
+}
+
+device_initcall(pxa_pm_init);
index f36ca448338e380ff76cef2764193a7d83e4949c..6dfcca72e90f65602f8d58140329cc6e2f3273ff 100644 (file)
@@ -110,26 +110,99 @@ EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
 
 #ifdef CONFIG_PM
 
-void pxa_cpu_pm_enter(suspend_state_t state)
+#define SAVE(x)                sleep_save[SLEEP_SAVE_##x] = x
+#define RESTORE(x)     x = sleep_save[SLEEP_SAVE_##x]
+
+#define RESTORE_GPLEVEL(n) do { \
+       GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \
+       GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \
+} while (0)
+
+/*
+ * List of global PXA peripheral registers to preserve.
+ * More ones like CP and general purpose register values are preserved
+ * with the stack pointer in sleep.S.
+ */
+enum { SLEEP_SAVE_START = 0,
+
+       SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2,
+       SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2,
+       SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2,
+       SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2,
+       SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2,
+
+       SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
+       SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U,
+       SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U,
+
+       SLEEP_SAVE_PSTR,
+
+       SLEEP_SAVE_ICMR,
+       SLEEP_SAVE_CKEN,
+
+       SLEEP_SAVE_SIZE
+};
+
+
+static void pxa25x_cpu_pm_save(unsigned long *sleep_save)
+{
+       SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2);
+       SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2);
+       SAVE(GRER0); SAVE(GRER1); SAVE(GRER2);
+       SAVE(GFER0); SAVE(GFER1); SAVE(GFER2);
+       SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2);
+
+       SAVE(GAFR0_L); SAVE(GAFR0_U);
+       SAVE(GAFR1_L); SAVE(GAFR1_U);
+       SAVE(GAFR2_L); SAVE(GAFR2_U);
+
+       SAVE(ICMR);
+       SAVE(CKEN);
+       SAVE(PSTR);
+}
+
+static void pxa25x_cpu_pm_restore(unsigned long *sleep_save)
 {
-       extern void pxa_cpu_suspend(unsigned int);
-       extern void pxa_cpu_resume(void);
+       /* restore registers */
+       RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2);
+       RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2);
+       RESTORE(GAFR0_L); RESTORE(GAFR0_U);
+       RESTORE(GAFR1_L); RESTORE(GAFR1_U);
+       RESTORE(GAFR2_L); RESTORE(GAFR2_U);
+       RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2);
+       RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2);
+       RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
+
+       RESTORE(CKEN);
+       RESTORE(ICMR);
+       RESTORE(PSTR);
+}
 
+static void pxa25x_cpu_pm_enter(suspend_state_t state)
+{
        CKEN = 0;
 
        switch (state) {
        case PM_SUSPEND_MEM:
                /* set resume return address */
                PSPR = virt_to_phys(pxa_cpu_resume);
-               pxa_cpu_suspend(PWRMODE_SLEEP);
+               pxa25x_cpu_suspend(PWRMODE_SLEEP);
                break;
        }
 }
 
-static struct pm_ops pxa25x_pm_ops = {
-       .enter          = pxa_pm_enter,
+static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = {
+       .save_size      = SLEEP_SAVE_SIZE,
        .valid          = pm_valid_only_mem,
+       .save           = pxa25x_cpu_pm_save,
+       .restore        = pxa25x_cpu_pm_restore,
+       .enter          = pxa25x_cpu_pm_enter,
 };
+
+static void __init pxa25x_init_pm(void)
+{
+       pxa_cpu_pm_fns = &pxa25x_cpu_pm_fns;
+}
 #endif
 
 void __init pxa25x_init_irq(void)
@@ -139,16 +212,16 @@ void __init pxa25x_init_irq(void)
 }
 
 static struct platform_device *pxa25x_devices[] __initdata = {
-       &pxamci_device,
-       &pxaudc_device,
-       &pxafb_device,
-       &ffuart_device,
-       &btuart_device,
-       &stuart_device,
-       &pxai2c_device,
-       &pxai2s_device,
-       &pxaficp_device,
-       &pxartc_device,
+       &pxa_device_mci,
+       &pxa_device_udc,
+       &pxa_device_fb,
+       &pxa_device_ffuart,
+       &pxa_device_btuart,
+       &pxa_device_stuart,
+       &pxa_device_i2c,
+       &pxa_device_i2s,
+       &pxa_device_ficp,
+       &pxa_device_rtc,
 };
 
 static int __init pxa25x_init(void)
@@ -159,14 +232,14 @@ static int __init pxa25x_init(void)
                if ((ret = pxa_init_dma(16)))
                        return ret;
 #ifdef CONFIG_PM
-               pm_set_ops(&pxa25x_pm_ops);
+               pxa25x_init_pm();
 #endif
                ret = platform_add_devices(pxa25x_devices,
                                           ARRAY_SIZE(pxa25x_devices));
        }
        /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
        if (cpu_is_pxa25x())
-               ret = platform_device_register(&hwuart_device);
+               ret = platform_device_register(&pxa_device_hwuart);
 
        return ret;
 }
index aa5bb02c897bd331c59ce29b1bcbc10c2be83e81..203371ab19db2b87c97359a12eb8d6defabab649 100644 (file)
@@ -126,14 +126,107 @@ EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
 
 #ifdef CONFIG_PM
 
-void pxa_cpu_pm_enter(suspend_state_t state)
+#define SAVE(x)                sleep_save[SLEEP_SAVE_##x] = x
+#define RESTORE(x)     x = sleep_save[SLEEP_SAVE_##x]
+
+#define RESTORE_GPLEVEL(n) do { \
+       GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \
+       GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \
+} while (0)
+
+/*
+ * List of global PXA peripheral registers to preserve.
+ * More ones like CP and general purpose register values are preserved
+ * with the stack pointer in sleep.S.
+ */
+enum { SLEEP_SAVE_START = 0,
+
+       SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, SLEEP_SAVE_GPLR3,
+       SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, SLEEP_SAVE_GPDR3,
+       SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, SLEEP_SAVE_GRER3,
+       SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, SLEEP_SAVE_GFER3,
+       SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3,
+
+       SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
+       SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U,
+       SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U,
+       SLEEP_SAVE_GAFR3_L, SLEEP_SAVE_GAFR3_U,
+
+       SLEEP_SAVE_PSTR,
+
+       SLEEP_SAVE_ICMR,
+       SLEEP_SAVE_CKEN,
+
+       SLEEP_SAVE_MDREFR,
+       SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER,
+       SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR,
+
+       SLEEP_SAVE_SIZE
+};
+
+void pxa27x_cpu_pm_save(unsigned long *sleep_save)
+{
+       SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); SAVE(GPLR3);
+       SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); SAVE(GPDR3);
+       SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); SAVE(GRER3);
+       SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); SAVE(GFER3);
+       SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3);
+
+       SAVE(GAFR0_L); SAVE(GAFR0_U);
+       SAVE(GAFR1_L); SAVE(GAFR1_U);
+       SAVE(GAFR2_L); SAVE(GAFR2_U);
+       SAVE(GAFR3_L); SAVE(GAFR3_U);
+
+       SAVE(MDREFR);
+       SAVE(PWER); SAVE(PCFR); SAVE(PRER);
+       SAVE(PFER); SAVE(PKWR);
+
+       SAVE(ICMR); ICMR = 0;
+       SAVE(CKEN);
+       SAVE(PSTR);
+
+       /* Clear GPIO transition detect bits */
+       GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; GEDR3 = GEDR3;
+}
+
+void pxa27x_cpu_pm_restore(unsigned long *sleep_save)
+{
+       /* ensure not to come back here if it wasn't intended */
+       PSPR = 0;
+
+       /* restore registers */
+       RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1);
+       RESTORE_GPLEVEL(2); RESTORE_GPLEVEL(3);
+       RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); RESTORE(GPDR3);
+       RESTORE(GAFR0_L); RESTORE(GAFR0_U);
+       RESTORE(GAFR1_L); RESTORE(GAFR1_U);
+       RESTORE(GAFR2_L); RESTORE(GAFR2_U);
+       RESTORE(GAFR3_L); RESTORE(GAFR3_U);
+       RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); RESTORE(GRER3);
+       RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); RESTORE(GFER3);
+       RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3);
+
+       RESTORE(MDREFR);
+       RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER);
+       RESTORE(PFER); RESTORE(PKWR);
+
+       PSSR = PSSR_RDH | PSSR_PH;
+
+       RESTORE(CKEN);
+
+       ICLR = 0;
+       ICCR = 1;
+       RESTORE(ICMR);
+       RESTORE(PSTR);
+}
+
+void pxa27x_cpu_pm_enter(suspend_state_t state)
 {
        extern void pxa_cpu_standby(void);
-       extern void pxa_cpu_suspend(unsigned int);
-       extern void pxa_cpu_resume(void);
 
        if (state == PM_SUSPEND_STANDBY)
-               CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER) | (1 << CKEN_LCD) | (1 << CKEN_PWM0);
+               CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER) |
+                       (1 << CKEN_LCD) | (1 << CKEN_PWM0);
        else
                CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER);
 
@@ -150,20 +243,28 @@ void pxa_cpu_pm_enter(suspend_state_t state)
        case PM_SUSPEND_MEM:
                /* set resume return address */
                PSPR = virt_to_phys(pxa_cpu_resume);
-               pxa_cpu_suspend(PWRMODE_SLEEP);
+               pxa27x_cpu_suspend(PWRMODE_SLEEP);
                break;
        }
 }
 
-static int pxa27x_pm_valid(suspend_state_t state)
+static int pxa27x_cpu_pm_valid(suspend_state_t state)
 {
        return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY;
 }
 
-static struct pm_ops pxa27x_pm_ops = {
-       .enter          = pxa_pm_enter,
-       .valid          = pxa27x_pm_valid,
+static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = {
+       .save_size      = SLEEP_SAVE_SIZE,
+       .save           = pxa27x_cpu_pm_save,
+       .restore        = pxa27x_cpu_pm_restore,
+       .valid          = pxa27x_cpu_pm_valid,
+       .enter          = pxa27x_cpu_pm_enter,
 };
+
+static void __init pxa27x_init_pm(void)
+{
+       pxa_cpu_pm_fns = &pxa27x_cpu_pm_fns;
+}
 #endif
 
 /*
@@ -185,7 +286,7 @@ static struct resource pxa27x_ohci_resources[] = {
        },
 };
 
-static struct platform_device pxaohci_device = {
+static struct platform_device pxa27x_device_ohci = {
        .name           = "pxa27x-ohci",
        .id             = -1,
        .dev            = {
@@ -198,7 +299,7 @@ static struct platform_device pxaohci_device = {
 
 void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
 {
-       pxaohci_device.dev.platform_data = info;
+       pxa27x_device_ohci.dev.platform_data = info;
 }
 
 static struct resource i2c_power_resources[] = {
@@ -213,7 +314,7 @@ static struct resource i2c_power_resources[] = {
        },
 };
 
-static struct platform_device pxai2c_power_device = {
+static struct platform_device pxa27x_device_i2c_power = {
        .name           = "pxa2xx-i2c",
        .id             = 1,
        .resource       = i2c_power_resources,
@@ -221,18 +322,18 @@ static struct platform_device pxai2c_power_device = {
 };
 
 static struct platform_device *devices[] __initdata = {
-       &pxamci_device,
-       &pxaudc_device,
-       &pxafb_device,
-       &ffuart_device,
-       &btuart_device,
-       &stuart_device,
-       &pxai2c_device,
-       &pxai2c_power_device,
-       &pxai2s_device,
-       &pxaficp_device,
-       &pxartc_device,
-       &pxaohci_device,
+       &pxa_device_mci,
+       &pxa_device_udc,
+       &pxa_device_fb,
+       &pxa_device_ffuart,
+       &pxa_device_btuart,
+       &pxa_device_stuart,
+       &pxa_device_i2c,
+       &pxa_device_i2s,
+       &pxa_device_ficp,
+       &pxa_device_rtc,
+       &pxa27x_device_i2c_power,
+       &pxa27x_device_ohci,
 };
 
 void __init pxa27x_init_irq(void)
@@ -249,7 +350,7 @@ static int __init pxa27x_init(void)
                if ((ret = pxa_init_dma(32)))
                        return ret;
 #ifdef CONFIG_PM
-               pm_set_ops(&pxa27x_pm_ops);
+               pxa27x_init_pm();
 #endif
                ret = platform_add_devices(devices, ARRAY_SIZE(devices));
        }
index 15874b360e519dd93c3e1f674b464fadb91210e3..aff71fec618ac7468cd3aca861873d86edb578a1 100644 (file)
 
 #include <asm/arch/pxa-regs.h>
 
-#ifdef CONFIG_PXA27x                   // workaround for Errata 50
 #define MDREFR_KDIV    0x200a4000      // all banks
 #define CCCR_SLEEP     0x00000107      // L=7 2N=2 A=0 PPDIS=0 CPDIS=0
-#endif
 
                .text
 
-/*
- * pxa_cpu_suspend()
- *
- * Forces CPU into sleep state.
- *
- * r0 = value for PWRMODE M field for desired sleep state
- */
-
-ENTRY(pxa_cpu_suspend)
-
-#ifndef CONFIG_IWMMXT
-       mra     r2, r3, acc0
-#endif
-       stmfd   sp!, {r2 - r12, lr}             @ save registers on stack
-
+pxa_cpu_save_cp:
        @ get coprocessor registers
        mrc     p14, 0, r3, c6, c0, 0           @ clock configuration, for turbo mode
        mrc     p15, 0, r4, c15, c1, 0          @ CP access reg
@@ -54,12 +38,36 @@ ENTRY(pxa_cpu_suspend)
        mov     r10, sp
        stmfd   sp!, {r3 - r10}
 
-       mov r5, r0                              @ save sleep mode
+       mov     pc, lr
+
+pxa_cpu_save_sp:
        @ preserve phys address of stack
        mov     r0, sp
+       mov     r2, lr
        bl      sleep_phys_sp
        ldr     r1, =sleep_save_sp
        str     r0, [r1]
+       mov     pc, r2
+
+/*
+ * pxa27x_cpu_suspend()
+ *
+ * Forces CPU into sleep state.
+ *
+ * r0 = value for PWRMODE M field for desired sleep state
+ */
+
+ENTRY(pxa27x_cpu_suspend)
+
+#ifndef CONFIG_IWMMXT
+       mra     r2, r3, acc0
+#endif
+       stmfd   sp!, {r2 - r12, lr}             @ save registers on stack
+
+       bl      pxa_cpu_save_cp
+
+       mov     r5, r0                          @ save sleep mode
+       bl      pxa_cpu_save_sp
 
        @ clean data cache
        bl      xscale_flush_kern_cache_all
@@ -80,13 +88,55 @@ ENTRY(pxa_cpu_suspend)
        @ enable SDRAM self-refresh mode
        orr     r5, r5, #MDREFR_SLFRSH
 
-#ifdef CONFIG_PXA27x
        @ set SDCLKx divide-by-2 bits (this is part of a workaround for Errata 50)
        ldr     r6, =MDREFR_KDIV
        orr     r5, r5, r6
-#endif
 
-#ifdef CONFIG_PXA25x
+       @ Intel PXA270 Specification Update notes problems sleeping
+       @ with core operating above 91 MHz
+       @ (see Errata 50, ...processor does not exit from sleep...)
+
+       ldr     r6, =CCCR
+       ldr     r8, [r6]                @ keep original value for resume
+
+       ldr     r7, =CCCR_SLEEP         @ prepare CCCR sleep value
+       mov     r0, #0x2                @ prepare value for CLKCFG
+
+       @ align execution to a cache line
+       b       pxa_cpu_do_suspend
+
+/*
+ * pxa27x_cpu_suspend()
+ *
+ * Forces CPU into sleep state.
+ *
+ * r0 = value for PWRMODE M field for desired sleep state
+ */
+
+ENTRY(pxa25x_cpu_suspend)
+       stmfd   sp!, {r2 - r12, lr}             @ save registers on stack
+
+       bl      pxa_cpu_save_cp
+
+       mov     r5, r0                          @ save sleep mode
+       bl      pxa_cpu_save_sp
+
+       @ clean data cache
+       bl      xscale_flush_kern_cache_all
+
+       @ prepare value for sleep mode
+       mov     r1, r5                          @ sleep mode
+
+       @ prepare pointer to physical address 0 (virtual mapping in generic.c)
+       mov     r2, #UNCACHED_PHYS_0
+
+       @ prepare SDRAM refresh settings
+       ldr     r4, =MDREFR
+       ldr     r5, [r4]
+
+       @ enable SDRAM self-refresh mode
+       orr     r5, r5, #MDREFR_SLFRSH
+
        @ Intel PXA255 Specification Update notes problems
        @ about suspending with PXBus operating above 133MHz
        @ (see Errata 31, GPIO output signals, ... unpredictable in sleep
@@ -118,30 +168,15 @@ ENTRY(pxa_cpu_suspend)
        mov     r0, #0
        mcr     p14, 0, r0, c6, c0, 0
        orr     r0, r0, #2                      @ initiate change bit
-#endif
-#ifdef CONFIG_PXA27x
-       @ Intel PXA270 Specification Update notes problems sleeping
-       @ with core operating above 91 MHz
-       @ (see Errata 50, ...processor does not exit from sleep...)
-
-       ldr     r6, =CCCR
-       ldr     r8, [r6]                @ keep original value for resume
-
-       ldr     r7, =CCCR_SLEEP         @ prepare CCCR sleep value
-       mov     r0, #0x2                @ prepare value for CLKCFG
-#endif
-
-       @ align execution to a cache line
-       b       1f
+       b       pxa_cpu_do_suspend
 
        .ltorg
        .align  5
-1:
+pxa_cpu_do_suspend:
 
        @ All needed values are now in registers.
        @ These last instructions should be in cache
 
-#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
        @ initiate the frequency change...
        str     r7, [r6]
        mcr     p14, 0, r0, c6, c0, 0
@@ -155,7 +190,6 @@ ENTRY(pxa_cpu_suspend)
        mov     r0, #42
 10:    subs    r0, r0, #1
        bne     10b
-#endif
 
        @ Do not reorder...
        @ Intel PXA270 Specification Update notes problems performing
index 6f91fd2d061ab0b9dc5062d5db3c551e03f6198e..98d27e646b0925a2266eb6fe63f9c29361a4c109 100644 (file)
@@ -1,9 +1,11 @@
 /*
  * arch/arm/mach-pxa/time.c
  *
- * Author:     Nicolas Pitre
- * Created:    Jun 15, 2001
- * Copyright:  MontaVista Software Inc.
+ * PXA clocksource, clockevents, and OST interrupt handlers.
+ * Copyright (c) 2007 by Bill Gatliff <bgat@billgatliff.com>.
+ *
+ * Derived from Nicolas Pitre's PXA timer handler Copyright (c) 2001
+ * by MontaVista Software, Inc.  (Nico, your code rocks!)
  *
  * 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
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/delay.h>
 #include <linux/interrupt.h>
-#include <linux/time.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/clocksource.h>
-
-#include <asm/system.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/leds.h>
-#include <asm/irq.h>
+#include <linux/clockchips.h>
+
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 #include <asm/arch/pxa-regs.h>
 
-
-static int pxa_set_rtc(void)
-{
-       unsigned long current_time = xtime.tv_sec;
-
-       if (RTSR & RTSR_ALE) {
-               /* make sure not to forward the clock over an alarm */
-               unsigned long alarm = RTAR;
-               if (current_time >= alarm && alarm >= RCNR)
-                       return -ERESTARTSYS;
-       }
-       RCNR = current_time;
-       return 0;
-}
-
-#ifdef CONFIG_NO_IDLE_HZ
-static unsigned long initial_match;
-static int match_posponed;
-#endif
-
 static irqreturn_t
-pxa_timer_interrupt(int irq, void *dev_id)
+pxa_ost0_interrupt(int irq, void *dev_id)
 {
        int next_match;
-
-       write_seqlock(&xtime_lock);
-
-#ifdef CONFIG_NO_IDLE_HZ
-       if (match_posponed) {
-               match_posponed = 0;
-               OSMR0 = initial_match;
-       }
-#endif
-
-       /* Loop until we get ahead of the free running timer.
-        * This ensures an exact clock tick count and time accuracy.
-        * Since IRQs are disabled at this point, coherence between
-        * lost_ticks(updated in do_timer()) and the match reg value is
-        * ensured, hence we can use do_gettimeofday() from interrupt
-        * handlers.
-        *
-        * HACK ALERT: it seems that the PXA timer regs aren't updated right
-        * away in all cases when a write occurs.  We therefore compare with
-        * 8 instead of 0 in the while() condition below to avoid missing a
-        * match if OSCR has already reached the next OSMR value.
-        * Experience has shown that up to 6 ticks are needed to work around
-        * this problem, but let's use 8 to be conservative.  Note that this
-        * affect things only when the timer IRQ has been delayed by nearly
-        * exactly one tick period which should be a pretty rare event.
+       struct clock_event_device *c = dev_id;
+
+       if (c->mode == CLOCK_EVT_MODE_ONESHOT) {
+               /* Disarm the compare/match, signal the event. */
+               OIER &= ~OIER_E0;
+               c->event_handler(c);
+       } else if (c->mode == CLOCK_EVT_MODE_PERIODIC) {
+               /* Call the event handler as many times as necessary
+                * to recover missed events, if any (if we update
+                * OSMR0 and OSCR0 is still ahead of us, we've missed
+                * the event).  As we're dealing with that, re-arm the
+                * compare/match for the next event.
+                *
+                * HACK ALERT:
+                *
+                * There's a latency between the instruction that
+                * writes to OSMR0 and the actual commit to the
+                * physical hardware, because the CPU doesn't (have
+                * to) run at bus speed, there's a write buffer
+                * between the CPU and the bus, etc. etc.  So if the
+                * target OSCR0 is "very close", to the OSMR0 load
+                * value, the update to OSMR0 might not get to the
+                * hardware in time and we'll miss that interrupt.
+                *
+                * To be safe, if the new OSMR0 is "very close" to the
+                * target OSCR0 value, we call the event_handler as
+                * though the event actually happened.  According to
+                * Nico's comment in the previous version of this
+                * code, experience has shown that 6 OSCR ticks is
+                * "very close" but he went with 8.  We will use 16,
+                * based on the results of testing on PXA270.
+                *
+                * To be doubly sure, we also tell clkevt via
+                * clockevents_register_device() not to ask for
+                * anything that might put us "very close".
         */
+#define MIN_OSCR_DELTA 16
        do {
-               timer_tick();
-               OSSR = OSSR_M0;  /* Clear match on timer 0 */
+                       OSSR = OSSR_M0;
                next_match = (OSMR0 += LATCH);
-       } while( (signed long)(next_match - OSCR) <= 8 );
-
-       write_sequnlock(&xtime_lock);
+                       c->event_handler(c);
+               } while (((signed long)(next_match - OSCR) <= MIN_OSCR_DELTA)
+                        && (c->mode == CLOCK_EVT_MODE_PERIODIC));
+       }
 
        return IRQ_HANDLED;
 }
 
-static struct irqaction pxa_timer_irq = {
-       .name           = "PXA Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-       .handler        = pxa_timer_interrupt,
+static int
+pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev)
+{
+       unsigned long irqflags;
+
+       raw_local_irq_save(irqflags);
+       OSMR0 = OSCR + delta;
+       OSSR = OSSR_M0;
+       OIER |= OIER_E0;
+       raw_local_irq_restore(irqflags);
+       return 0;
+}
+
+static void
+pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
+{
+       unsigned long irqflags;
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               raw_local_irq_save(irqflags);
+               OSMR0 = OSCR + LATCH;
+               OSSR = OSSR_M0;
+               OIER |= OIER_E0;
+               raw_local_irq_restore(irqflags);
+               break;
+
+       case CLOCK_EVT_MODE_ONESHOT:
+               raw_local_irq_save(irqflags);
+               OIER &= ~OIER_E0;
+               raw_local_irq_restore(irqflags);
+               break;
+
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_SHUTDOWN:
+               /* initializing, released, or preparing for suspend */
+               raw_local_irq_save(irqflags);
+               OIER &= ~OIER_E0;
+               raw_local_irq_restore(irqflags);
+               break;
+       }
+}
+
+static struct clock_event_device ckevt_pxa_osmr0 = {
+       .name           = "osmr0",
+       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+       .shift          = 32,
+       .rating         = 200,
+       .cpumask        = CPU_MASK_CPU0,
+       .set_next_event = pxa_osmr0_set_next_event,
+       .set_mode       = pxa_osmr0_set_mode,
 };
 
-static cycle_t pxa_get_cycles(void)
+static cycle_t pxa_read_oscr(void)
 {
        return OSCR;
 }
 
-static struct clocksource clocksource_pxa = {
-       .name           = "pxa_timer",
+static struct clocksource cksrc_pxa_oscr0 = {
+       .name           = "oscr0",
        .rating         = 200,
-       .read           = pxa_get_cycles,
+       .read           = pxa_read_oscr,
        .mask           = CLOCKSOURCE_MASK(32),
        .shift          = 20,
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+static struct irqaction pxa_ost0_irq = {
+       .name           = "ost0",
+       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .handler        = pxa_ost0_interrupt,
+       .dev_id         = &ckevt_pxa_osmr0,
+};
+
 static void __init pxa_timer_init(void)
 {
-       struct timespec tv;
-       unsigned long flags;
+       OIER = 0;
+       OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;
 
-       set_rtc = pxa_set_rtc;
+       ckevt_pxa_osmr0.mult =
+               div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt_pxa_osmr0.shift);
+       ckevt_pxa_osmr0.max_delta_ns =
+               clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0);
+       ckevt_pxa_osmr0.min_delta_ns =
+               clockevent_delta2ns(MIN_OSCR_DELTA, &ckevt_pxa_osmr0) + 1;
 
-       OIER = 0;               /* disable any timer interrupts */
-       OSSR = 0xf;             /* clear status on all timers */
-       setup_irq(IRQ_OST0, &pxa_timer_irq);
-       local_irq_save(flags);
-       OIER = OIER_E0;         /* enable match on timer 0 to cause interrupts */
-       OSMR0 = OSCR + LATCH;   /* set initial match */
-       local_irq_restore(flags);
-
-       /*
-        * OSCR runs continuously on PXA and is not written to,
-        * so we can use it as clock source directly.
-        */
-       clocksource_pxa.mult =
-               clocksource_hz2mult(CLOCK_TICK_RATE, clocksource_pxa.shift);
-       clocksource_register(&clocksource_pxa);
-}
-
-#ifdef CONFIG_NO_IDLE_HZ
-static int pxa_dyn_tick_enable_disable(void)
-{
-       /* nothing to do */
-       return 0;
-}
+       cksrc_pxa_oscr0.mult =
+               clocksource_hz2mult(CLOCK_TICK_RATE, cksrc_pxa_oscr0.shift);
 
-static void pxa_dyn_tick_reprogram(unsigned long ticks)
-{
-       if (ticks > 1) {
-               initial_match = OSMR0;
-               OSMR0 = initial_match + ticks * LATCH;
-               match_posponed = 1;
-       }
-}
+       setup_irq(IRQ_OST0, &pxa_ost0_irq);
 
-static irqreturn_t
-pxa_dyn_tick_handler(int irq, void *dev_id)
-{
-       if (match_posponed) {
-               match_posponed = 0;
-               OSMR0 = initial_match;
-               if ( (signed long)(initial_match - OSCR) <= 8 )
-                       return pxa_timer_interrupt(irq, dev_id);
-       }
-       return IRQ_NONE;
+       clocksource_register(&cksrc_pxa_oscr0);
+       clockevents_register_device(&ckevt_pxa_osmr0);
 }
 
-static struct dyn_tick_timer pxa_dyn_tick = {
-       .enable         = pxa_dyn_tick_enable_disable,
-       .disable        = pxa_dyn_tick_enable_disable,
-       .reprogram      = pxa_dyn_tick_reprogram,
-       .handler        = pxa_dyn_tick_handler,
-};
-#endif
-
 #ifdef CONFIG_PM
 static unsigned long osmr[4], oier;
 
@@ -191,7 +189,10 @@ static void pxa_timer_resume(void)
        OIER = oier;
 
        /*
-        * OSMR0 is the system timer: make sure OSCR is sufficiently behind
+        * OSCR0 is the system timer, which has to increase
+        * monotonically until it rolls over in hardware.  The value
+        * (OSMR0 - LATCH) is OSCR0 at the most recent system tick,
+        * which is a handy value to restore to OSCR0.
         */
        OSCR = OSMR0 - LATCH;
 }
@@ -204,7 +205,4 @@ struct sys_timer pxa_timer = {
        .init           = pxa_timer_init,
        .suspend        = pxa_timer_suspend,
        .resume         = pxa_timer_resume,
-#ifdef CONFIG_NO_IDLE_HZ
-       .dyn_tick       = &pxa_dyn_tick,
-#endif
 };
index 570cf937e73b378ea4cecbf91c17d547b16017ad..a454451c97c36ea77ee9abb2a74e6b9f99ff0f6e 100644 (file)
@@ -87,7 +87,7 @@ static void __init rpc_map_io(void)
        /*
         * Turn off floppy.
         */
-       outb(0xc, 0x3f2);
+       writeb(0xc, PCIO_BASE + (0x3f2 << 2));
 
        /*
         * RiscPC can't handle half-word loads and stores
index d4b013b283c3680f63be0b9b8b05b4120ebf3777..e2079cf9266fd44c5f2bff2ab81826585cd65f9b 100644 (file)
@@ -9,6 +9,7 @@ config CPU_S3C2410
        depends on ARCH_S3C2410
        select S3C2410_CLOCK
        select S3C2410_GPIO
+       select CPU_LLSERIAL_S3C2410
        select S3C2410_PM if PM
        help
          Support for S3C2410 and S3C2410A family from the S3C24XX line
index 5b4831c4c1d8dccb556c35a6502c92b238933672..cab9d6265e9ee513d37cae781a89e068721df398 100644 (file)
@@ -37,7 +37,7 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-clock.h>
 #include <asm/arch/regs-gpio.h>
 
index 67d1ad36397344715a1c085a0abe0ce9b82632ea..80d83739ab9f6c0185eac554b4208c9b7ffb056c 100644 (file)
 #include <asm/plat-s3c24xx/cpu.h>
 #include <asm/plat-s3c24xx/dma.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-ac97.h>
+#include <asm/plat-s3c/regs-ac97.h>
 #include <asm/arch/regs-mem.h>
 #include <asm/arch/regs-lcd.h>
 #include <asm/arch/regs-sdi.h>
-#include <asm/arch/regs-iis.h>
-#include <asm/arch/regs-spi.h>
+#include <asm/plat-s3c24xx/regs-iis.h>
+#include <asm/plat-s3c24xx/regs-spi.h>
 
 static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
        [DMACH_XD0] = {
index 435adcce6482a369e5898de40bfc4bdfb690a6e1..43bb5e1063020fa112cdb9d5e6a2f6c8b7845eca 100644 (file)
@@ -48,7 +48,7 @@
 #include <asm/mach-types.h>
 #include <asm/arch/fb.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-lcd.h>
 #include <asm/arch/regs-gpio.h>
 
index 8b52ea95d4f68523f72782aee1c8ca368a7ddb35..bc926992b4e447de12b0504ff7a3bbfed48bd923 100644 (file)
 #include <asm/mach-types.h>
 
 //#include <asm/debug-ll.h>
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-mem.h>
 #include <asm/arch/regs-lcd.h>
 
-#include <asm/arch/nand.h>
-#include <asm/arch/iic.h>
+#include <asm/plat-s3c/nand.h>
+#include <asm/plat-s3c/iic.h>
 #include <asm/arch/fb.h>
 
 #include <linux/mtd/mtd.h>
index 5c9bcea7476732d77e6f3081b86956ec9db3f947..9a172b4ad720f51980ab10c928eb2611970f253e 100644 (file)
@@ -30,7 +30,7 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-lcd.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-clock.h>
@@ -38,7 +38,7 @@
 #include <asm/arch/h1940.h>
 #include <asm/arch/h1940-latch.h>
 #include <asm/arch/fb.h>
-#include <asm/arch/udc.h>
+#include <asm/plat-s3c24xx/udc.h>
 
 #include <asm/plat-s3c24xx/clock.h>
 #include <asm/plat-s3c24xx/devs.h>
index 412e50c3d28ac0d518941f77d387971bc2a72324..621f548da610fd297f1d590e898b85d98063e520 100644 (file)
@@ -33,9 +33,9 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
-#include <asm/arch/iic.h>
+#include <asm/plat-s3c/iic.h>
 
 #include <asm/plat-s3c24xx/s3c2410.h>
 #include <asm/plat-s3c24xx/clock.h>
index 1f899fa588dfdcaef21d531f3360447366f334b6..717af40e4477d62fcae8a1da4178f159517b57a4 100644 (file)
@@ -29,7 +29,7 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 
 #include <asm/plat-s3c24xx/s3c2410.h>
index d86e6f18bac9f736ddd7beca0ae9e3a4e88eb88f..e670b1e1631bd2619deb3189e7358bdeeb3ff185 100644 (file)
 
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/leds-gpio.h>
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/fb.h>
-#include <asm/arch/nand.h>
-#include <asm/arch/udc.h>
+#include <asm/plat-s3c/nand.h>
+#include <asm/plat-s3c24xx/udc.h>
 #include <asm/arch/spi.h>
 #include <asm/arch/spi-gpio.h>
 
index 5852d300d52f67c5a0997b2993083264779f22b2..226550504c85fd05142ed1d7830ae215ce0953f3 100644 (file)
@@ -47,7 +47,7 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 
 #include <asm/plat-s3c24xx/devs.h>
 #include <asm/plat-s3c24xx/cpu.h>
index 7b624bb0049060c06c41c5c7b7d39fa76ec437d7..9f43f3f124f561eeec3efa9b5bbc16a9c083b5e1 100644 (file)
@@ -39,7 +39,7 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/leds-gpio.h>
 
index 1a86a9803753470acb87ea3476d30c9ece2a87d8..e580303cb0abbd86d1e97429ea21fceaeeb0efec 100644 (file)
@@ -29,7 +29,7 @@
 #include <asm/irq.h>
 
 #include <asm/arch/regs-clock.h>
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 
 #include <asm/plat-s3c24xx/s3c2410.h>
 #include <asm/plat-s3c24xx/cpu.h>
@@ -40,7 +40,6 @@
 
 static struct map_desc s3c2410_iodesc[] __initdata = {
        IODESC_ENT(CLKPWR),
-       IODESC_ENT(LCD),
        IODESC_ENT(TIMER),
        IODESC_ENT(WATCHDOG),
 };
index d1eeed2ad47c79f5ed1d94209233957001690f5f..8a9c5a2bb2523295b01c919ad98088da2c415ca7 100644 (file)
@@ -32,7 +32,7 @@
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-clock.h>
 #include <asm/arch/regs-mem.h>
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 
        /* s3c2410_cpu_suspend
         *
index d5be5d053264da3079782e6abe8436e43759daec..8e8fe48ea47f24f9deb1419f5a0ed7c48693a5a3 100644 (file)
@@ -7,6 +7,7 @@
 config CPU_S3C2412
        bool
        depends on ARCH_S3C2410
+       select CPU_LLSERIAL_S3C2440
        select S3C2412_PM if PM
        select S3C2412_DMA if S3C2410_DMA
        help
index 6a8e4448770bdce38870138b780db90477932bcf..8543dd6df391e17cbeb895beef52af22b0091fb9 100644 (file)
@@ -37,7 +37,7 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-clock.h>
 #include <asm/arch/regs-gpio.h>
 
index 668cccefe7b066aa4472a91b18469d4b80904617..4b9425c1bf722b8eb25dc4ecf2d15126b0637181 100644 (file)
 #include <asm/plat-s3c24xx/dma.h>
 #include <asm/plat-s3c24xx/cpu.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-ac97.h>
+#include <asm/plat-s3c/regs-ac97.h>
 #include <asm/arch/regs-mem.h>
 #include <asm/arch/regs-lcd.h>
 #include <asm/arch/regs-sdi.h>
-#include <asm/arch/regs-iis.h>
-#include <asm/arch/regs-spi.h>
+#include <asm/plat-s3c24xx/regs-iis.h>
+#include <asm/plat-s3c24xx/regs-spi.h>
 
 #define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID }
 
index 063af09f899d865a253376304980c4bb634a01c3..b126a530daa661f993304d68a8d6e619852e73af 100644 (file)
 #include <asm/mach-types.h>
 
 //#include <asm/debug-ll.h>
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-lcd.h>
 
 #include <asm/arch/idle.h>
-#include <asm/arch/udc.h>
+#include <asm/plat-s3c24xx/udc.h>
 #include <asm/arch/fb.h>
 
 #include <asm/plat-s3c24xx/s3c2410.h>
index f2fbd65956acd0db2d823c99e82ff3d641349290..32982547cd633fa8f065b18cc601534b783ff51c 100644 (file)
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-lcd.h>
 
 #include <asm/arch/idle.h>
 #include <asm/arch/fb.h>
 
-#include <asm/arch/nand.h>
+#include <asm/plat-s3c/nand.h>
 
 #include <asm/plat-s3c24xx/s3c2410.h>
 #include <asm/plat-s3c24xx/s3c2412.h>
index 782b5814ced24411f356a4566c8f19265de3601b..e0ccb404623f738b373ee3eb227dc987e0b17808 100644 (file)
 #include <asm/arch/idle.h>
 
 #include <asm/arch/regs-clock.h>
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-power.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-gpioj.h>
 #include <asm/arch/regs-dsc.h>
-#include <asm/arch/regs-spi.h>
+#include <asm/plat-s3c24xx/regs-spi.h>
 #include <asm/arch/regs-s3c2412.h>
 
 #include <asm/plat-s3c24xx/s3c2412.h>
@@ -63,7 +63,6 @@ static inline void s3c2412_init_gpio2(void)
 
 static struct map_desc s3c2412_iodesc[] __initdata = {
        IODESC_ENT(CLKPWR),
-       IODESC_ENT(LCD),
        IODESC_ENT(TIMER),
        IODESC_ENT(WATCHDOG),
 };
index e3bfda098c0f440a52ef2fbc4200857fab0d48c6..f1915bd61d15b862e4198c110a0a499a0f40e378 100644 (file)
@@ -12,6 +12,7 @@ config CPU_S3C2440
        select S3C2410_GPIO
        select S3C2440_DMA if S3C2410_DMA
        select CPU_S3C244X
+       select CPU_LLSERIAL_S3C2440
        help
          Support for S3C2440 Samsung Mobile CPU based systems.
 
index cd035a3ec878be42d8d75b53229db416d04a274a..f509f062e749bcd0b6357921058e4139d76c6ee3 100644 (file)
 #include <asm/plat-s3c24xx/dma.h>
 #include <asm/plat-s3c24xx/cpu.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-ac97.h>
+#include <asm/plat-s3c/regs-ac97.h>
 #include <asm/arch/regs-mem.h>
 #include <asm/arch/regs-lcd.h>
 #include <asm/arch/regs-sdi.h>
-#include <asm/arch/regs-iis.h>
-#include <asm/arch/regs-spi.h>
+#include <asm/plat-s3c24xx/regs-iis.h>
+#include <asm/plat-s3c24xx/regs-spi.h>
 
 static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = {
        [DMACH_XD0] = {
index 29c163d300d4cc9f78a4f35654e3559b92497efc..3d3dfa95db8ef7dcfcd668150e7fb4959638213f 100644 (file)
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-mem.h>
 #include <asm/arch/regs-lcd.h>
-#include <asm/arch/nand.h>
+#include <asm/plat-s3c/nand.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
index 5e61f2166c76f6583cb923ed6472afbb713f6e97..afe0d7b7e389003235722326ea4a4fa700bd81d6 100644 (file)
@@ -36,7 +36,7 @@
 
 //#include <asm/debug-ll.h>
 #include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 
 #include <asm/plat-s3c24xx/s3c2410.h>
 #include <asm/plat-s3c24xx/s3c2440.h>
index 89f4c9c5777b324ca4f603f4fdeb5ed6dabb2473..0ba7e9060c7bba3ece0df5d9eacbdbeb86d71eac 100644 (file)
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-mem.h>
 #include <asm/arch/regs-lcd.h>
-#include <asm/arch/nand.h>
+#include <asm/plat-s3c/nand.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
index 866ff71c01ddf27861192763270f72cf51dac212..b59e6d39f2f267f8cd09508c729665437df2e424 100644 (file)
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-lcd.h>
 
 #include <asm/arch/h1940.h>
-#include <asm/arch/nand.h>
+#include <asm/plat-s3c/nand.h>
 #include <asm/arch/fb.h>
 
 #include <asm/plat-s3c24xx/clock.h>
index e167254e232eb8155156ba994dbed62d1e388229..670115b8a12ea49c3592fa3bdbde0b6dc4f4e875 100644 (file)
@@ -31,7 +31,7 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-lcd.h>
 
index bf8d87abfab39def97a8c805bef77e142ac38319..88d5fd34fe3bca320a4146feb314ccc5c21163a1 100644 (file)
@@ -11,6 +11,7 @@ config CPU_S3C2442
        select S3C2410_GPIO
        select S3C2410_PM if PM
        select CPU_S3C244X
+       select CPU_LLSERIAL_S3C2440
        help
          Support for S3C2442 Samsung Mobile CPU based systems.
 
index c649bb2e7ce84ef7bddd9761d212480975dcfefa..14252f57375468d4d9809fe5e6475550962a688d 100644 (file)
@@ -8,6 +8,7 @@ config CPU_S3C2443
        bool
        depends on ARCH_S3C2410
        select S3C2443_DMA if S3C2410_DMA
+       select CPU_LLSERIAL_S3C2440
        help
          Support for the S3C2443 SoC from the S3C24XX line
 
index f70e8ccffc3d6e457f7625a8d5a9e1ab16233ab4..fc3ede82af8f77360fef59d0a1e3200d3c60bd5c 100644 (file)
 #include <asm/plat-s3c24xx/dma.h>
 #include <asm/plat-s3c24xx/cpu.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-ac97.h>
+#include <asm/plat-s3c/regs-ac97.h>
 #include <asm/arch/regs-mem.h>
 #include <asm/arch/regs-lcd.h>
 #include <asm/arch/regs-sdi.h>
-#include <asm/arch/regs-iis.h>
-#include <asm/arch/regs-spi.h>
+#include <asm/plat-s3c24xx/regs-iis.h>
+#include <asm/plat-s3c24xx/regs-spi.h>
 
 #define MAP(x) { \
                [0]     = (x) | DMA_CH_VALID,   \
index b1eb709ee65a3d7a7acb87a3bbbf614b788f7c24..8cd93130ef36bb5434bd4c001cf3388a421195f2 100644 (file)
@@ -31,7 +31,7 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-lcd.h>
 
index cd67ab1b217b7d9ae1478af363aaa7e646d8c866..f99d9013905fea6ecaad0fd36c965696b5145fe1 100644 (file)
@@ -101,6 +101,16 @@ config SA1100_JORNADA720
          handheld computer.  See <http://www.hp.com/jornada/products/720>
          for details.
 
+config SA1100_JORNADA720_SSP
+       bool "HP Jornada 720 Extended SSP driver"
+       select SA1100_SSP
+       depends on SA1100_JORNADA720
+       help
+         Say Y here if you have a HP Jornada 7xx handheld computer and you
+         want to access devices connected to the MCU. Those include the
+         keyboard, touchscreen, backlight and battery. This driver also activates
+         the generic SSP which it extends.
+
 config SA1100_HACKKIT
        bool "HackKit Core CPU Board"
        help
@@ -145,8 +155,7 @@ config SA1100_SSP
        help
          Say Y here to enable support for the generic PIO SSP driver.
          This isn't for audio support, but for attached sensors and
-         other devices, eg for BadgePAD 4 sensor support, or Jornada
-         720 touchscreen support.
+         other devices, eg for BadgePAD 4 sensor support.
 
 config H3600_SLEEVE
        tristate "Compaq iPAQ Handheld sleeve support"
index e27f15042a22dfec7e492f0fa6d965fec139cf5d..7a61e8d33ab7527240ec74d6cc50812b72a57c71 100644 (file)
@@ -31,6 +31,7 @@ obj-$(CONFIG_SA1100_HACKKIT)          += hackkit.o
 led-$(CONFIG_SA1100_HACKKIT)           += leds-hackkit.o
 
 obj-$(CONFIG_SA1100_JORNADA720)                += jornada720.o
+obj-$(CONFIG_SA1100_JORNADA720_SSP)    += jornada720_ssp.o
 
 obj-$(CONFIG_SA1100_LART)              += lart.o
 led-$(CONFIG_SA1100_LART)              += leds-lart.o
@@ -51,3 +52,4 @@ obj-$(CONFIG_LEDS) += $(led-y)
 # Miscelaneous functions
 obj-$(CONFIG_PM)                       += pm.o sleep.o
 obj-$(CONFIG_SA1100_SSP)               += ssp.o
+
diff --git a/arch/arm/mach-sa1100/jornada720_ssp.c b/arch/arm/mach-sa1100/jornada720_ssp.c
new file mode 100644 (file)
index 0000000..0a45e1a
--- /dev/null
@@ -0,0 +1,201 @@
+/**
+ *  arch/arm/mac-sa1100/jornada720_ssp.c
+ *
+ *  Copyright (C) 2006/2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
+ *   Copyright (C) 2006 Filip Zyzniewski <filip.zyzniewski@tefnet.pl>
+ *
+ * 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.
+ *
+ *  SSP driver for the HP Jornada 710/720/728
+ */
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include <asm/hardware.h>
+#include <asm/hardware/ssp.h>
+#include <asm/arch/jornada720.h>
+
+static DEFINE_SPINLOCK(jornada_ssp_lock);
+static unsigned long jornada_ssp_flags;
+
+/**
+ * jornada_ssp_reverse - reverses input byte
+ *
+ * we need to reverse all data we recieve from the mcu due to its physical location
+ * returns : 01110111 -> 11101110
+ */
+u8 inline jornada_ssp_reverse(u8 byte)
+{
+       return
+               ((0x80 & byte) >> 7) |
+               ((0x40 & byte) >> 5) |
+               ((0x20 & byte) >> 3) |
+               ((0x10 & byte) >> 1) |
+               ((0x08 & byte) << 1) |
+               ((0x04 & byte) << 3) |
+               ((0x02 & byte) << 5) |
+               ((0x01 & byte) << 7);
+};
+EXPORT_SYMBOL(jornada_ssp_reverse);
+
+/**
+ * jornada_ssp_byte - waits for ready ssp bus and sends byte
+ *
+ * waits for fifo buffer to clear and then transmits, if it doesn't then we will
+ * timeout after <timeout> rounds. Needs mcu running before its called.
+ *
+ * returns : %mcu output on success
+ *        : %-ETIMEOUT on timeout
+ */
+int jornada_ssp_byte(u8 byte)
+{
+       int timeout = 400000;
+       u16 ret;
+
+       while ((GPLR & GPIO_GPIO10)) {
+               if (!--timeout) {
+                       printk(KERN_WARNING "SSP: timeout while waiting for transmit\n");
+                       return -ETIMEDOUT;
+               }
+               cpu_relax();
+       }
+
+       ret = jornada_ssp_reverse(byte) << 8;
+
+       ssp_write_word(ret);
+       ssp_read_word(&ret);
+
+       return jornada_ssp_reverse(ret);
+};
+EXPORT_SYMBOL(jornada_ssp_byte);
+
+/**
+ * jornada_ssp_inout - decide if input is command or trading byte
+ *
+ * returns : (jornada_ssp_byte(byte)) on success
+ *         : %-ETIMEOUT on timeout failure
+ */
+int jornada_ssp_inout(u8 byte)
+{
+       int ret, i;
+
+       /* true means command byte */
+       if (byte != TXDUMMY) {
+               ret = jornada_ssp_byte(byte);
+               /* Proper return to commands is TxDummy */
+               if (ret != TXDUMMY) {
+                       for (i = 0; i < 256; i++)/* flushing bus */
+                               if (jornada_ssp_byte(TXDUMMY) == -1)
+                                       break;
+                       return -ETIMEDOUT;
+               }
+       } else /* Exchange TxDummy for data */
+               ret = jornada_ssp_byte(TXDUMMY);
+
+       return ret;
+};
+EXPORT_SYMBOL(jornada_ssp_inout);
+
+/**
+ * jornada_ssp_start - enable mcu
+ *
+ */
+int jornada_ssp_start()
+{
+       spin_lock_irqsave(&jornada_ssp_lock, jornada_ssp_flags);
+       GPCR = GPIO_GPIO25;
+       udelay(50);
+       return 0;
+};
+EXPORT_SYMBOL(jornada_ssp_start);
+
+/**
+ * jornada_ssp_end - disable mcu and turn off lock
+ *
+ */
+int jornada_ssp_end()
+{
+       GPSR = GPIO_GPIO25;
+       spin_unlock_irqrestore(&jornada_ssp_lock, jornada_ssp_flags);
+       return 0;
+};
+EXPORT_SYMBOL(jornada_ssp_end);
+
+static int __init jornada_ssp_probe(struct platform_device *dev)
+{
+       int ret;
+
+       GPSR = GPIO_GPIO25;
+
+       ret = ssp_init();
+
+       /* worked fine, lets not bother with anything else */
+       if (!ret) {
+               printk(KERN_INFO "SSP: device initialized with irq\n");
+               return ret;
+       }
+
+       printk(KERN_WARNING "SSP: initialization failed, trying non-irq solution \n");
+
+       /* init of Serial 4 port */
+       Ser4MCCR0 = 0;
+       Ser4SSCR0 = 0x0387;
+       Ser4SSCR1 = 0x18;
+
+       /* clear out any left over data */
+       ssp_flush();
+
+       /* enable MCU */
+       jornada_ssp_start();
+
+       /* see if return value makes sense */
+       ret = jornada_ssp_inout(GETBRIGHTNESS);
+
+       /* seems like it worked, just feed it with TxDummy to get rid of data */
+       if (ret == TxDummy)
+               jornada_ssp_inout(TXDUMMY);
+
+       jornada_ssp_end();
+
+       /* failed, lets just kill everything */
+       if (ret == -ETIMEDOUT) {
+               printk(KERN_WARNING "SSP: attempts failed, bailing\n");
+               ssp_exit();
+               return -ENODEV;
+       }
+
+       /* all fine */
+       printk(KERN_INFO "SSP: device initialized\n");
+       return 0;
+};
+
+static int jornada_ssp_remove(struct platform_device *dev)
+{
+       /* Note that this doesnt actually remove the driver, since theres nothing to remove
+        * It just makes sure everything is turned off */
+       GPSR = GPIO_GPIO25;
+       ssp_exit();
+       return 0;
+};
+
+struct platform_driver jornadassp_driver = {
+       .probe  = jornada_ssp_probe,
+       .remove = jornada_ssp_remove,
+       .driver = {
+               .name   = "jornada_ssp",
+       },
+};
+
+static int __init jornada_ssp_init(void)
+{
+       return platform_driver_register(&jornadassp_driver);
+}
index 3a0a1ee2542d05535c860f3d0cadb78e0a9a736d..9f1ed15093016b3ebd88a204795efca7d026946b 100644 (file)
@@ -292,6 +292,8 @@ static struct platform_device *devices[] __initdata = {
        &smc91x_device,
 };
 
+extern void sa1110_mb_disable(void);
+
 static int __init neponset_init(void)
 {
        platform_driver_register(&neponset_device_driver);
index e7904bc92c73f846abda2b872f3c3e86139c0cfd..12161ae445dadecae15361fbd5e68a7241b7f1b1 100644 (file)
@@ -345,13 +345,14 @@ config CPU_XSC3
 # ARMv6
 config CPU_V6
        bool "Support ARM V6 processor"
-       depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2
+       depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3
+       default y if ARCH_MX3
        select CPU_32v6
        select CPU_ABRT_EV6
        select CPU_CACHE_V6
        select CPU_CACHE_VIPT
        select CPU_CP15_MMU
-       select CPU_HAS_ASID
+       select CPU_HAS_ASID if MMU
        select CPU_COPY_V6 if MMU
        select CPU_TLB_V6 if MMU
 
@@ -359,7 +360,7 @@ config CPU_V6
 config CPU_32v6K
        bool "Support ARM V6K processor extensions" if !SMP
        depends on CPU_V6
-       default y if SMP
+       default y if SMP && !ARCH_MX3
        help
          Say Y here if your ARMv6 processor supports the 'K' extension.
          This enables the kernel to use some instructions not present
@@ -377,7 +378,7 @@ config CPU_V7
        select CPU_CACHE_V7
        select CPU_CACHE_VIPT
        select CPU_CP15_MMU
-       select CPU_HAS_ASID
+       select CPU_HAS_ASID if MMU
        select CPU_COPY_V6 if MMU
        select CPU_TLB_V7 if MMU
 
@@ -405,6 +406,7 @@ config CPU_32v5
 
 config CPU_32v6
        bool
+       select TLS_REG_EMUL if !CPU_32v6K && !MMU
 
 config CPU_32v7
        bool
@@ -598,7 +600,7 @@ config CPU_DCACHE_SIZE
 
 config CPU_DCACHE_WRITETHROUGH
        bool "Force write through D-cache"
-       depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE
+       depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020) && !CPU_DCACHE_DISABLE
        default y if CPU_ARM925T
        help
          Say Y here to use the data cache in writethrough mode. Unless you
@@ -611,12 +613,6 @@ config CPU_CACHE_ROUND_ROBIN
          Say Y here to use the predictable round-robin cache replacement
          policy.  Unless you specifically require this or are unsure, say N.
 
-config CPU_L2CACHE_DISABLE
-       bool "Disable level 2 cache"
-       depends on CPU_V7
-       help
-         Say Y here to disable the level 2 cache.  If unsure, say N.
-
 config CPU_BPREDICT_DISABLE
        bool "Disable branch prediction"
        depends on CPU_ARM1020 || CPU_V6 || CPU_XSC3 || CPU_V7
index 08a36f1b35d29faf1d4f23b70b7ab96bea318801..b4e9b734e0bd939cddcdc392889368fe43f30846 100644 (file)
@@ -17,6 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 #include <linux/init.h>
+#include <linux/spinlock.h>
 
 #include <asm/cacheflush.h>
 #include <asm/io.h>
 #define CACHE_LINE_SIZE                32
 
 static void __iomem *l2x0_base;
+static DEFINE_SPINLOCK(l2x0_lock);
 
 static inline void sync_writel(unsigned long val, unsigned long reg,
                               unsigned long complete_mask)
 {
+       unsigned long flags;
+
+       spin_lock_irqsave(&l2x0_lock, flags);
        writel(val, l2x0_base + reg);
        /* wait for the operation to complete */
        while (readl(l2x0_base + reg) & complete_mask)
                ;
+       spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
 static inline void cache_sync(void)
index 3b5e47dc0c9737fe7e996769a45c416bb5201c1d..e5d61ee3d4a1bec9c309f3ba7b91de8ce4f9cb53 100644 (file)
@@ -114,6 +114,10 @@ static void __init early_cachepolicy(char **p)
        }
        if (i == ARRAY_SIZE(cache_policies))
                printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n");
+       if (cpu_architecture() >= CPU_ARCH_ARMv6) {
+               printk(KERN_WARNING "Only cachepolicy=writeback supported on ARMv6 and later\n");
+               cachepolicy = CPOLICY_WRITEBACK;
+       }
        flush_cache_all();
        set_cr(cr_alignment);
 }
@@ -252,13 +256,15 @@ static void __init build_mem_type_table(void)
        int cpu_arch = cpu_architecture();
        int i;
 
+       if (cpu_arch < CPU_ARCH_ARMv6) {
 #if defined(CONFIG_CPU_DCACHE_DISABLE)
-       if (cachepolicy > CPOLICY_BUFFERED)
-               cachepolicy = CPOLICY_BUFFERED;
+               if (cachepolicy > CPOLICY_BUFFERED)
+                       cachepolicy = CPOLICY_BUFFERED;
 #elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
-       if (cachepolicy > CPOLICY_WRITETHROUGH)
-               cachepolicy = CPOLICY_WRITETHROUGH;
+               if (cachepolicy > CPOLICY_WRITETHROUGH)
+                       cachepolicy = CPOLICY_WRITETHROUGH;
 #endif
+       }
        if (cpu_arch < CPU_ARCH_ARMv5) {
                if (cachepolicy >= CPOLICY_WRITEALLOC)
                        cachepolicy = CPOLICY_WRITEBACK;
index 9f396b4fa0b7c67f95de6deb5a6c2a684f264f60..2b5ba396e3a63ee455e6b73bfff9176c78aef029 100644 (file)
@@ -31,12 +31,14 @@ EXPORT_SYMBOL(__cpuc_coherent_kern_range);
 EXPORT_SYMBOL(cpu_cache);
 #endif
 
+#ifdef CONFIG_MMU
 #ifndef MULTI_USER
 EXPORT_SYMBOL(__cpu_clear_user_page);
 EXPORT_SYMBOL(__cpu_copy_user_page);
 #else
 EXPORT_SYMBOL(cpu_user);
 #endif
+#endif
 
 /*
  * No module should need to touch the TLB (and currently
index 718f4782ee8b943e14d6a4bb6dc9f515ff9c47b4..e0acc5ae6f6ff4a501ee1d74991cdd7b58f2f332 100644 (file)
@@ -77,6 +77,7 @@ ENTRY(cpu_v7_dcache_clean_area)
  *     - we are not using split page tables
  */
 ENTRY(cpu_v7_switch_mm)
+#ifdef CONFIG_MMU
        mov     r2, #0
        ldr     r1, [r1, #MM_CONTEXT_ID]        @ get mm->context.id
        orr     r0, r0, #TTB_RGN_OC_WB          @ mark PTWs outer cacheable, WB
@@ -86,6 +87,7 @@ ENTRY(cpu_v7_switch_mm)
        isb
        mcr     p15, 0, r1, c13, c0, 1          @ set context ID
        isb
+#endif
        mov     pc, lr
 
 /*
@@ -109,6 +111,7 @@ ENTRY(cpu_v7_switch_mm)
  *       1111   0   1   1      r/w     r/w
  */
 ENTRY(cpu_v7_set_pte_ext)
+#ifdef CONFIG_MMU
        str     r1, [r0], #-2048                @ linux version
 
        bic     r3, r1, #0x000003f0
@@ -136,6 +139,7 @@ ENTRY(cpu_v7_set_pte_ext)
 
        str     r3, [r0]
        mcr     p15, 0, r0, c7, c10, 1          @ flush_pte
+#endif
        mov     pc, lr
 
 cpu_v7_name:
@@ -169,6 +173,7 @@ __v7_setup:
        mcr     p15, 0, r10, c7, c5, 0          @ I+BTB cache invalidate
 #endif
        dsb
+#ifdef CONFIG_MMU
        mcr     p15, 0, r10, c8, c7, 0          @ invalidate I + D TLBs
        mcr     p15, 0, r10, c2, c0, 2          @ TTB control register
        orr     r4, r4, #TTB_RGN_OC_WB          @ mark PTWs outer cacheable, WB
@@ -176,21 +181,12 @@ __v7_setup:
        mcr     p15, 0, r4, c2, c0, 1           @ load TTB1
        mov     r10, #0x1f                      @ domains 0, 1 = manager
        mcr     p15, 0, r10, c3, c0, 0          @ load domain access register
-#ifndef CONFIG_CPU_L2CACHE_DISABLE
-       @ L2 cache configuration in the L2 aux control register
-       mrc     p15, 1, r10, c9, c0, 2
-       bic     r10, r10, #(1 << 16)            @ L2 outer cache
-       mcr     p15, 1, r10, c9, c0, 2
-       @ L2 cache is enabled in the aux control register
-       mrc     p15, 0, r10, c1, c0, 1
-       orr     r10, r10, #2
-       mcr     p15, 0, r10, c1, c0, 1
 #endif
-       mrc     p15, 0, r0, c1, c0, 0           @ read control register
-       ldr     r10, cr1_clear                  @ get mask for bits to clear
-       bic     r0, r0, r10                     @ clear bits them
-       ldr     r10, cr1_set                    @ get mask for bits to set
-       orr     r0, r0, r10                     @ set them
+       adr     r5, v7_crval
+       ldmia   r5, {r5, r6}
+       mrc     p15, 0, r0, c1, c0, 0           @ read control register
+       bic     r0, r0, r5                      @ clear bits them
+       orr     r0, r0, r                     @ set them
        mov     pc, lr                          @ return to head.S:__ret
 
        /*
@@ -199,12 +195,9 @@ __v7_setup:
         * rrrr rrrx xxx0 0101 xxxx xxxx x111 xxxx < forced
         *         0 110       0011 1.00 .111 1101 < we want
         */
-       .type   cr1_clear, #object
-       .type   cr1_set, #object
-cr1_clear:
-       .word   0x0120c302
-cr1_set:
-       .word   0x00c0387d
+       .type   v7_crval, #object
+v7_crval:
+       crval   clear=0x0120c302, mmuset=0x00c0387d, ucset=0x00c0187c
 
 __v7_setup_stack:
        .space  4 * 11                          @ 11 registers
index 100d57ad98ed82636c87282501e4adaaa73f70b1..ba3d21d8fba34c4c458a2d80b660e258ca06a2b3 100644 (file)
@@ -78,6 +78,13 @@ static struct irqaction iop_timer_irq = {
        .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
 };
 
+static unsigned long iop_tick_rate;
+unsigned long get_iop_tick_rate(void)
+{
+       return iop_tick_rate;
+}
+EXPORT_SYMBOL(get_iop_tick_rate);
+
 void __init iop_init_time(unsigned long tick_rate)
 {
        u32 timer_ctl;
@@ -85,6 +92,7 @@ void __init iop_init_time(unsigned long tick_rate)
        ticks_per_jiffy = (tick_rate + HZ/2) / HZ;
        ticks_per_usec = tick_rate / 1000000;
        next_jiffy_time = 0xffffffff;
+       iop_tick_rate = tick_rate;
 
        timer_ctl = IOP_TMR_EN | IOP_TMR_PRIVILEGED |
                        IOP_TMR_RELOAD | IOP_TMR_RATIO_1_1;
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
new file mode 100644 (file)
index 0000000..03a65c0
--- /dev/null
@@ -0,0 +1,20 @@
+if ARCH_MXC
+
+menu "Freescale MXC Implementations"
+
+choice
+       prompt "MXC/iMX System Type"
+       default 0
+
+config ARCH_MX3
+       bool "MX3-based"
+       help
+         This enables support for systems based on the Freescale i.MX3 family
+
+endchoice
+
+source "arch/arm/mach-mx3/Kconfig"
+
+endmenu
+
+endif
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
new file mode 100644 (file)
index 0000000..66ad9c2
--- /dev/null
@@ -0,0 +1,10 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := irq.o
+
+obj-m :=
+obj-n :=
+obj-  :=
diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c
new file mode 100644 (file)
index 0000000..87d253b
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  Copyright 2004-2007 Freescale Semiconductor, Inc. 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 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/common.h>
+
+/*!
+ * Disable interrupt number "irq" in the AVIC
+ *
+ * @param  irq          interrupt source number
+ */
+static void mxc_mask_irq(unsigned int irq)
+{
+       __raw_writel(irq, AVIC_INTDISNUM);
+}
+
+/*!
+ * Enable interrupt number "irq" in the AVIC
+ *
+ * @param  irq          interrupt source number
+ */
+static void mxc_unmask_irq(unsigned int irq)
+{
+       __raw_writel(irq, AVIC_INTENNUM);
+}
+
+static struct irq_chip mxc_avic_chip = {
+       .mask_ack = mxc_mask_irq,
+       .mask = mxc_mask_irq,
+       .unmask = mxc_unmask_irq,
+};
+
+/*!
+ * This function initializes the AVIC hardware and disables all the
+ * interrupts. It registers the interrupt enable and disable functions
+ * to the kernel for each interrupt source.
+ */
+void __init mxc_init_irq(void)
+{
+       int i;
+       u32 reg;
+
+       /* put the AVIC into the reset value with
+        * all interrupts disabled
+        */
+       __raw_writel(0, AVIC_INTCNTL);
+       __raw_writel(0x1f, AVIC_NIMASK);
+
+       /* disable all interrupts */
+       __raw_writel(0, AVIC_INTENABLEH);
+       __raw_writel(0, AVIC_INTENABLEL);
+
+       /* all IRQ no FIQ */
+       __raw_writel(0, AVIC_INTTYPEH);
+       __raw_writel(0, AVIC_INTTYPEL);
+       for (i = 0; i < MXC_MAX_INT_LINES; i++) {
+               set_irq_chip(i, &mxc_avic_chip);
+               set_irq_handler(i, handle_level_irq);
+               set_irq_flags(i, IRQF_VALID);
+       }
+
+       /* Set WDOG2's interrupt the highest priority level (bit 28-31) */
+       reg = __raw_readl(AVIC_NIPRIORITY6);
+       reg |= (0xF << 28);
+       __raw_writel(reg, AVIC_NIPRIORITY6);
+
+       printk(KERN_INFO "MXC IRQ initialized\n");
+}
index 2feceec8eccd0e639933c07b71bacf0a5e924ea4..b0af014b0e2c1c05d3d26c77f29f04bb0573e79d 100644 (file)
@@ -156,6 +156,8 @@ static void omap_32k_timer_set_mode(enum clock_event_mode mode,
        case CLOCK_EVT_MODE_SHUTDOWN:
                omap_32k_timer_stop();
                break;
+       case CLOCK_EVT_MODE_RESUME:
+               break;
        }
 }
 
diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig
new file mode 100644 (file)
index 0000000..31656c3
--- /dev/null
@@ -0,0 +1,104 @@
+# arch/arm/plat-s3c/Kconfig
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config PLAT_S3C
+       bool
+       depends on ARCH_S3C2410
+       default y if ARCH_S3C2410
+       select NO_IOPORT
+       help
+         Base platform code for any Samsung S3C device
+
+# low-level serial option nodes
+
+config CPU_LLSERIAL_S3C2410_ONLY
+       bool
+       depends on ARCH_S3C2410
+       default y if CPU_LLSERIAL_S3C2410 && !CPU_LLSERIAL_S3C2440
+
+config CPU_LLSERIAL_S3C2440_ONLY
+       bool
+       depends on ARCH_S3C2410
+       default y if CPU_LLSERIAL_S3C2440 && !CPU_LLSERIAL_S3C2410
+
+config CPU_LLSERIAL_S3C2410
+       bool
+       depends on ARCH_S3C2410
+       help
+         Selected if there is an S3C2410 (or register compatible) serial
+         low-level implementation needed
+
+config CPU_LLSERIAL_S3C2440
+       bool
+       depends on ARCH_S3C2410
+       help
+         Selected if there is an S3C2440 (or register compatible) serial
+         low-level implementation needed
+
+# boot configurations
+
+comment "Boot options"
+
+config S3C_BOOT_WATCHDOG
+       bool "S3C Initialisation watchdog"
+       depends on PLAT_S3C && S3C2410_WATCHDOG
+       help
+         Say y to enable the watchdog during the kernel decompression
+         stage. If the kernel fails to uncompress, then the watchdog
+         will trigger a reset and the system should restart.
+
+config S3C_BOOT_ERROR_RESET
+       bool "S3C Reboot on decompression error"
+       depends on PLAT_S3C
+       help
+         Say y here to use the watchdog to reset the system if the
+         kernel decompressor detects an error during decompression.
+
+comment "Power management"
+
+config S3C2410_PM_DEBUG
+       bool "S3C2410 PM Suspend debug"
+       depends on PLAT_S3C && PM
+       help
+         Say Y here if you want verbose debugging from the PM Suspend and
+         Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
+         for more information.
+
+config S3C2410_PM_CHECK
+       bool "S3C2410 PM Suspend Memory CRC"
+       depends on PLAT_S3C && PM && CRC32
+       help
+         Enable the PM code's memory area checksum over sleep. This option
+         will generate CRCs of all blocks of memory, and store them before
+         going to sleep. The blocks are then checked on resume for any
+         errors.
+
+         Note, this can take several seconds depending on memory size
+         and CPU speed.
+
+         See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
+
+config S3C2410_PM_CHECK_CHUNKSIZE
+       int "S3C2410 PM Suspend CRC Chunksize (KiB)"
+       depends on PLAT_S3C && PM && S3C2410_PM_CHECK
+       default 64
+       help
+         Set the chunksize in Kilobytes of the CRC for checking memory
+         corruption over suspend and resume. A smaller value will mean that
+         the CRC data block will take more memory, but wil identify any
+         faults with better precision.
+
+         See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
+
+config S3C_LOWLEVEL_UART_PORT
+       int "S3C UART to use for low-level messages"
+       depends on PLAT_S3C
+       default 0
+       help
+         Choice of which UART port to use for the low-level messages,
+         such as the `Uncompressing...` at start time. The value of
+         this configuration should be between zero and two. The port
+         must have been initialised by the boot-loader before use.
index b972f36d547ccd17190fd4cb698e1aa3e2656043..b66fb3c4e228c75852c7a159eeb986d11f6270b0 100644 (file)
@@ -10,7 +10,7 @@ config PLAT_S3C24XX
        default y if ARCH_S3C2410
        select NO_IOPORT
        help
-         Base platform code for any Samsung S3C device
+         Base platform code for any Samsung S3C24XX device
 
 if PLAT_S3C24XX
 
@@ -26,64 +26,6 @@ config PM_SIMTEC
          Common power management code for systems that are
          compatible with the Simtec style of power management
 
-config S3C2410_BOOT_WATCHDOG
-       bool "S3C2410 Initialisation watchdog"
-       depends on ARCH_S3C2410 && S3C2410_WATCHDOG
-       help
-         Say y to enable the watchdog during the kernel decompression
-         stage. If the kernel fails to uncompress, then the watchdog
-         will trigger a reset and the system should restart.
-
-config S3C2410_BOOT_ERROR_RESET
-       bool "S3C2410 Reboot on decompression error"
-       depends on ARCH_S3C2410
-       help
-         Say y here to use the watchdog to reset the system if the
-         kernel decompressor detects an error during decompression.
-
-config S3C2410_PM_DEBUG
-       bool "S3C2410 PM Suspend debug"
-       depends on ARCH_S3C2410 && PM
-       help
-         Say Y here if you want verbose debugging from the PM Suspend and
-         Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
-         for more information.
-
-config S3C2410_PM_CHECK
-       bool "S3C2410 PM Suspend Memory CRC"
-       depends on ARCH_S3C2410 && PM && CRC32
-       help
-         Enable the PM code's memory area checksum over sleep. This option
-         will generate CRCs of all blocks of memory, and store them before
-         going to sleep. The blocks are then checked on resume for any
-         errors.
-
-         Note, this can take several seconds depending on memory size
-         and CPU speed.
-
-         See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
-
-config S3C2410_PM_CHECK_CHUNKSIZE
-       int "S3C2410 PM Suspend CRC Chunksize (KiB)"
-       depends on ARCH_S3C2410 && PM && S3C2410_PM_CHECK
-       default 64
-       help
-         Set the chunksize in Kilobytes of the CRC for checking memory
-         corruption over suspend and resume. A smaller value will mean that
-         the CRC data block will take more memory, but wil identify any
-         faults with better precision.
-
-         See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
-
-config S3C2410_LOWLEVEL_UART_PORT
-       int "S3C2410 UART to use for low-level messages"
-       default 0
-       help
-         Choice of which UART port to use for the low-level messages,
-         such as the `Uncompressing...` at start time. The value of
-         this configuration should be between zero and two. The port
-         must have been initialised by the boot-loader before use.
-
 config S3C2410_DMA
        bool "S3C2410 DMA support"
        depends on ARCH_S3C2410
index 7ed19b23ce56bf40ce310947d78de15decf044fc..398c7ac25296bc8fb63c71354e7fb2384d759c41 100644 (file)
@@ -38,7 +38,7 @@
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/leds-gpio.h>
 
-#include <asm/arch/nand.h>
+#include <asm/plat-s3c/nand.h>
 
 #include <asm/plat-s3c24xx/common-smdk.h>
 #include <asm/plat-s3c24xx/devs.h>
index 8ce4904d313178e574188753416dc9750914083e..f513ab083b8f24c9106253b65c8fc185237cfad3 100644 (file)
@@ -38,7 +38,7 @@
 #include <asm/mach/map.h>
 
 #include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 
 #include <asm/plat-s3c24xx/cpu.h>
 #include <asm/plat-s3c24xx/devs.h>
index 5875da0ae0eb89b6cae7158a977b906b59222728..e546e933b3f7648204b9715e88066df1b1b93ffb 100644 (file)
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#include <asm/arch/regs-serial.h>
-#include <asm/arch/udc.h>
+#include <asm/plat-s3c/regs-serial.h>
+#include <asm/plat-s3c24xx/udc.h>
 
 #include <asm/plat-s3c24xx/devs.h>
 #include <asm/plat-s3c24xx/cpu.h>
-#include <asm/arch/regs-spi.h>
+#include <asm/plat-s3c24xx/regs-spi.h>
 
 /* Serial port registrations */
 
index 5692eccdf4d1dd036a056aa2fb22293131636976..eab1850616d860ef5488cbc4f5c489d0f763da49 100644 (file)
@@ -40,7 +40,7 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-clock.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-mem.h>
index 767f2e9a3a555beff2d3e05388ad1ac9800f7590..3444b13afac52ad0a9694785f204f50c71c32ade 100644 (file)
@@ -30,7 +30,7 @@
 #include <asm/irq.h>
 
 #include <asm/arch/regs-clock.h>
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-gpioj.h>
 #include <asm/arch/regs-dsc.h>
@@ -47,7 +47,6 @@ static struct map_desc s3c244x_iodesc[] __initdata = {
        IODESC_ENT(CLKPWR),
        IODESC_ENT(TIMER),
        IODESC_ENT(WATCHDOG),
-       IODESC_ENT(LCD),
 };
 
 /* uart initialisation */
index 7b7ae790b00da07ebfede651cd10d2bfa1706e89..d47113bbc34cee98eb8895f0475d7a1c278f46bc 100644 (file)
@@ -32,7 +32,7 @@
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-clock.h>
 #include <asm/arch/regs-mem.h>
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 
 /* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not
  * reset the UART configuration, only enable if you really need this!
index b7667375bcec891912682260cd62e855d968085c..2ec1daaa0e537a6aed01f4aa62f5d7551ad3e8b8 100644 (file)
@@ -33,7 +33,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/arch/map.h>
-#include <asm/arch/regs-timer.h>
+#include <asm/plat-s3c/regs-timer.h>
 #include <asm/arch/regs-irq.h>
 #include <asm/mach/time.h>
 
index d4b7b229631d5b3fe9db079a3aed284f656beadf..0ac022f800a13578d97db2a6236f2cc16e86ef03 100644 (file)
@@ -74,14 +74,14 @@ vfp_support_entry:
 
        VFPFMRX r1, FPEXC               @ Is the VFP enabled?
        DBGSTR1 "fpexc %08x", r1
-       tst     r1, #FPEXC_ENABLE
+       tst     r1, #FPEXC_EN
        bne     look_for_VFP_exceptions @ VFP is already enabled
 
        DBGSTR1 "enable %x", r10
        ldr     r3, last_VFP_context_address
-       orr     r1, r1, #FPEXC_ENABLE   @ user FPEXC has the enable bit set
+       orr     r1, r1, #FPEXC_EN       @ user FPEXC has the enable bit set
        ldr     r4, [r3, r11, lsl #2]   @ last_VFP_context pointer
-       bic     r5, r1, #FPEXC_EXCEPTION @ make sure exceptions are disabled
+       bic     r5, r1, #FPEXC_EX       @ make sure exceptions are disabled
        cmp     r4, r10
        beq     check_for_exception     @ we are returning to the same
                                        @ process, so the registers are
@@ -124,7 +124,7 @@ no_old_VFP_process:
        VFPFMXR FPSCR, r5               @ restore status
 
 check_for_exception:
-       tst     r1, #FPEXC_EXCEPTION
+       tst     r1, #FPEXC_EX
        bne     process_exception       @ might as well handle the pending
                                        @ exception before retrying branch
                                        @ out before setting an FPEXC that
@@ -136,10 +136,10 @@ check_for_exception:
 
 
 look_for_VFP_exceptions:
-       tst     r1, #FPEXC_EXCEPTION
+       tst     r1, #FPEXC_EX
        bne     process_exception
        VFPFMRX r5, FPSCR
-       tst     r5, #FPSCR_IXE          @ IXE doesn't set FPEXC_EXCEPTION !
+       tst     r5, #FPSCR_IXE          @ IXE doesn't set FPEXC_EX !
        bne     process_exception
 
        @ Fall into hand on to next handler - appropriate coproc instr
index 1106b5f9cf197bffda116df9562511374ffd7bd9..04ddab2bd876e3485a0857a124a740fa8f0550be 100644 (file)
@@ -53,7 +53,7 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
                 * case the thread migrates to a different CPU. The
                 * restoring is done lazily.
                 */
-               if ((fpexc & FPEXC_ENABLE) && last_VFP_context[cpu]) {
+               if ((fpexc & FPEXC_EN) && last_VFP_context[cpu]) {
                        vfp_save_state(last_VFP_context[cpu], fpexc);
                        last_VFP_context[cpu]->hard.cpu = cpu;
                }
@@ -70,7 +70,7 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
                 * Always disable VFP so we can lazily save/restore the
                 * old state.
                 */
-               fmxr(FPEXC, fpexc & ~FPEXC_ENABLE);
+               fmxr(FPEXC, fpexc & ~FPEXC_EN);
                return NOTIFY_DONE;
        }
 
@@ -81,13 +81,13 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
                 */
                memset(vfp, 0, sizeof(union vfp_state));
 
-               vfp->hard.fpexc = FPEXC_ENABLE;
+               vfp->hard.fpexc = FPEXC_EN;
                vfp->hard.fpscr = FPSCR_ROUND_NEAREST;
 
                /*
                 * Disable VFP to ensure we initialise it first.
                 */
-               fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE);
+               fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
        }
 
        /* flush and release case: Per-thread VFP cleanup. */
@@ -229,7 +229,7 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
        /*
         * Enable access to the VFP so we can handle the bounce.
         */
-       fmxr(FPEXC, fpexc & ~(FPEXC_EXCEPTION|FPEXC_INV|FPEXC_UFC|FPEXC_IOC));
+       fmxr(FPEXC, fpexc & ~(FPEXC_EX|FPEXC_INV|FPEXC_UFC|FPEXC_IOC));
 
        orig_fpscr = fpscr = fmrx(FPSCR);
 
@@ -248,7 +248,7 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
        /*
         * Modify fpscr to indicate the number of iterations remaining
         */
-       if (fpexc & FPEXC_EXCEPTION) {
+       if (fpexc & FPEXC_EX) {
                u32 len;
 
                len = fpexc + (1 << FPEXC_LENGTH_BIT);
index f735d7e018e4161967114ab5ecff778a81f4d449..fe1e3ceed7cb83cf50d4fb476021fd40a71d480b 100644 (file)
@@ -107,8 +107,6 @@ EXPORT_SYMBOL(__bug);
 #endif
 EXPORT_SYMBOL(__bad_xchg);
 EXPORT_SYMBOL(__readwrite_bug);
-EXPORT_SYMBOL(enable_irq);
-EXPORT_SYMBOL(disable_irq);
 EXPORT_SYMBOL(set_irq_type);
 EXPORT_SYMBOL(pm_idle);
 EXPORT_SYMBOL(pm_power_off);
index d53382c83bf9fdb05ddfb66122313bfda0e9268a..2ffe695b062e7f3b3fe7f72d64ab27fda474b6bb 100644 (file)
@@ -95,6 +95,11 @@ void disable_irq(unsigned int irq)
                desc->enabled = 0;
        spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
+EXPORT_SYMBOL(disable_irq);
+
+void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq")));
+
+EXPORT_SYMBOL(disable_irq_nosync);
 
 /**
  *     enable_irq - enable interrupt handling on an irq
@@ -131,6 +136,7 @@ void enable_irq(unsigned int irq)
        }
        spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
+EXPORT_SYMBOL(enable_irq);
 
 int show_interrupts(struct seq_file *p, void *v)
 {
index 6c4dc0a00e9f0e8ffd0ddbf27d0074d01dbffaa4..2edcecdea8bdd3402c2e323e0afceb7c7937bb83 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/linkage.h>
 #include <linux/platform_device.h>
 #include <linux/types.h>
+#include <linux/leds.h>
 #include <linux/spi/spi.h>
 
 #include <asm/io.h>
@@ -21,6 +22,7 @@
 #include <asm/arch/at32ap7000.h>
 #include <asm/arch/board.h>
 #include <asm/arch/init.h>
+#include <asm/arch/portmux.h>
 
 /* Initialized by bootloader-specific startup code. */
 struct tag *bootloader_tags __initdata;
@@ -100,8 +102,31 @@ void __init setup_board(void)
        at32_setup_serial_console(0);
 }
 
+static const struct gpio_led ngw_leds[] = {
+       { .name = "sys", .gpio = GPIO_PIN_PA(16), .active_low = 1,
+               .default_trigger = "heartbeat",
+       },
+       { .name = "a", .gpio = GPIO_PIN_PA(19), .active_low = 1, },
+       { .name = "b", .gpio = GPIO_PIN_PE(19), .active_low = 1, },
+};
+
+static const struct gpio_led_platform_data ngw_led_data = {
+       .num_leds =     ARRAY_SIZE(ngw_leds),
+       .leds =         (void *) ngw_leds,
+};
+
+static struct platform_device ngw_gpio_leds = {
+       .name =         "leds-gpio",
+       .id =           -1,
+       .dev = {
+               .platform_data = (void *) &ngw_led_data,
+       }
+};
+
 static int __init atngw100_init(void)
 {
+       unsigned        i;
+
        /*
         * ATNGW100 uses 16-bit SDRAM interface, so we don't need to
         * reserve any pins for it.
@@ -116,6 +141,12 @@ static int __init atngw100_init(void)
 
        at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
 
+       for (i = 0; i < ARRAY_SIZE(ngw_leds); i++) {
+               at32_select_gpio(ngw_leds[i].gpio,
+                               AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
+       }
+       platform_device_register(&ngw_gpio_leds);
+
        return 0;
 }
 postcore_initcall(atngw100_init);
index 49493ad3b5a976b7d24b47b11971e01f0a83075f..b799a68ffd9706d74afef2942d0ef0ea45b302ab 100644 (file)
@@ -712,7 +712,21 @@ CONFIG_SPI_ATMEL=y
 #
 # LED devices
 #
-# CONFIG_NEW_LEDS is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_GPIO=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+
 
 #
 # LED drivers
index 7a11b905ef49d0949c23d80a985fae3c400528c0..abb582bc218fdf4207d3fa3ce92d753fffa35f40 100644 (file)
@@ -18,6 +18,10 @@ config GENERIC_TIME
        bool
        default y
 
+config GENERIC_CMOS_UPDATE
+       bool
+       default y
+
 config CLOCKSOURCE_WATCHDOG
        bool
        default y
@@ -544,6 +548,7 @@ config HIGHMEM4G
 config HIGHMEM64G
        bool "64GB"
        depends on !M386 && !M486
+       select X86_PAE
        help
          Select this if you have a 32-bit processor and more than 4
          gigabytes of physical RAM.
@@ -573,12 +578,12 @@ choice
        config VMSPLIT_3G
                bool "3G/1G user/kernel split"
        config VMSPLIT_3G_OPT
-               depends on !HIGHMEM
+               depends on !X86_PAE
                bool "3G/1G user/kernel split (for full 1G low memory)"
        config VMSPLIT_2G
                bool "2G/2G user/kernel split"
        config VMSPLIT_2G_OPT
-               depends on !HIGHMEM
+               depends on !X86_PAE
                bool "2G/2G user/kernel split (for full 2G low memory)"
        config VMSPLIT_1G
                bool "1G/3G user/kernel split"
@@ -598,10 +603,15 @@ config HIGHMEM
        default y
 
 config X86_PAE
-       bool
-       depends on HIGHMEM64G
-       default y
+       bool "PAE (Physical Address Extension) Support"
+       default n
+       depends on !HIGHMEM4G
        select RESOURCES_64BIT
+       help
+         PAE is required for NX support, and furthermore enables
+         larger swapspace support for non-overcommit purposes. It
+         has the cost of more pagetable lookup overhead, and also
+         consumes more pagetable space per process.
 
 # Common NUMA Features
 config NUMA
@@ -817,6 +827,7 @@ config CRASH_DUMP
 
 config PHYSICAL_START
        hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
+       default "0x1000000" if X86_NUMAQ
        default "0x100000"
        help
          This gives the physical address where the kernel is loaded.
index 0ac62cdcd3b7843f18839cd81b7fe8852565f41c..54ee1764fdaebbb3d21aefc48083188d716ce256 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22-rc2
-# Mon May 21 13:23:44 2007
+# Linux kernel version: 2.6.22-git14
+# Fri Jul 20 09:53:15 2007
 #
 CONFIG_X86_32=y
 CONFIG_GENERIC_TIME=y
@@ -37,19 +37,18 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
+# CONFIG_USER_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=18
 # CONFIG_CPUSETS is not set
 CONFIG_SYSFS_DEPRECATED=y
-# CONFIG_RELAY is not set
+CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -73,16 +72,13 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
@@ -90,14 +86,11 @@ CONFIG_MODULE_FORCE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 # CONFIG_KMOD is not set
 CONFIG_STOP_MACHINE=y
-
-#
-# Block layer
-#
 CONFIG_BLOCK=y
 CONFIG_LBD=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
 
 #
 # IO Schedulers
@@ -201,6 +194,7 @@ CONFIG_X86_CPUID=y
 # CONFIG_EDD is not set
 # CONFIG_DELL_RBU is not set
 # CONFIG_DCDBAS is not set
+CONFIG_DMIID=y
 # CONFIG_NOHIGHMEM is not set
 CONFIG_HIGHMEM4G=y
 # CONFIG_HIGHMEM64G is not set
@@ -217,7 +211,9 @@ CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_RESOURCES_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
 CONFIG_NR_QUICK=1
+CONFIG_VIRT_TO_BUS=y
 # CONFIG_HIGHPTE is not set
 # CONFIG_MATH_EMULATION is not set
 CONFIG_MTRR=y
@@ -244,7 +240,6 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_PM=y
 CONFIG_PM_LEGACY=y
 # CONFIG_PM_DEBUG is not set
-# CONFIG_PM_SYSFS_DEPRECATED is not set
 
 #
 # ACPI (Advanced Configuration and Power Interface) Support
@@ -284,7 +279,7 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
 # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
 
 #
 # CPUFreq processor drivers
@@ -325,7 +320,7 @@ CONFIG_PCI_MMCONFIG=y
 CONFIG_ARCH_SUPPORTS_MSI=y
 CONFIG_PCI_MSI=y
 # CONFIG_PCI_DEBUG is not set
-CONFIG_HT_IRQ=y
+# CONFIG_HT_IRQ is not set
 CONFIG_ISA_DMA_API=y
 # CONFIG_ISA is not set
 # CONFIG_MCA is not set
@@ -381,7 +376,7 @@ CONFIG_IP_PNP_DHCP=y
 CONFIG_INET_TUNNEL=y
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_XFRM_MODE_BEET is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -400,27 +395,15 @@ CONFIG_IPV6=y
 # CONFIG_INET6_TUNNEL is not set
 CONFIG_INET6_XFRM_MODE_TRANSPORT=y
 CONFIG_INET6_XFRM_MODE_TUNNEL=y
-CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_BEET is not set
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 CONFIG_IPV6_SIT=y
 # CONFIG_IPV6_TUNNEL is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -457,6 +440,7 @@ CONFIG_IPV6_SIT=y
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
 # CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -471,21 +455,9 @@ CONFIG_FW_LOADER=y
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
 CONFIG_PNP=y
 # CONFIG_PNP_DEBUG is not set
 
@@ -493,10 +465,7 @@ CONFIG_PNP=y
 # Protocols
 #
 CONFIG_PNPACPI=y
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
 CONFIG_BLK_DEV_FD=y
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
@@ -514,17 +483,14 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# Misc devices
-#
+CONFIG_MISC_DEVICES=y
 # CONFIG_IBM_ASM is not set
 # CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_SONY_LAPTOP is not set
 # CONFIG_THINKPAD_ACPI is not set
-# CONFIG_BLINK is not set
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDE=y
 
@@ -596,6 +562,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
 # CONFIG_SCSI_TGT is not set
 CONFIG_SCSI_NETLINK=y
 # CONFIG_SCSI_PROC_FS is not set
@@ -606,8 +573,9 @@ CONFIG_SCSI_NETLINK=y
 CONFIG_BLK_DEV_SD=y
 # CONFIG_CHR_DEV_ST is not set
 # CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=y
 # CONFIG_CHR_DEV_SCH is not set
 
 #
@@ -667,6 +635,7 @@ CONFIG_AIC79XX_DEBUG_MASK=0
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_QLA_ISCSI is not set
@@ -675,14 +644,73 @@ CONFIG_AIC79XX_DEBUG_MASK=0
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_ESP_CORE is not set
 # CONFIG_SCSI_SRP is not set
-# CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_ACPI=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_SVW=y
+CONFIG_ATA_PIIX=y
+# CONFIG_SATA_MV is not set
+CONFIG_SATA_NV=y
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_SATA_SIL=y
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+CONFIG_SATA_VIA=y
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CS5535 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+CONFIG_MD=y
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
+# CONFIG_DM_CRYPT is not set
+# CONFIG_DM_SNAPSHOT is not set
+# CONFIG_DM_MIRROR is not set
+# CONFIG_DM_ZERO is not set
+# CONFIG_DM_MULTIPATH is not set
+# CONFIG_DM_DELAY is not set
 
 #
 # Fusion MPT device support
@@ -723,42 +751,27 @@ CONFIG_IEEE1394_OHCI1394=y
 # CONFIG_IEEE1394_ETH1394 is not set
 # CONFIG_IEEE1394_DV1394 is not set
 CONFIG_IEEE1394_RAWIO=y
-
-#
-# I2O device support
-#
 # CONFIG_I2O is not set
-# CONFIG_MACINTOSH_DRIVERS is not set
-
-#
-# Network device support
-#
+CONFIG_MACINTOSH_DRIVERS=y
+# CONFIG_MAC_EMUMOUSEBTN is not set
 CONFIG_NETDEVICES=y
+CONFIG_NETDEVICES_MULTIQUEUE=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_NET_SB1000 is not set
-
-#
-# ARCnet devices
-#
 # CONFIG_ARCNET is not set
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM is not set
-
-#
-# Tulip family network device support
-#
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=y
+# CONFIG_TYPHOON is not set
 CONFIG_NET_TULIP=y
 # CONFIG_DE2104X is not set
 CONFIG_TULIP=y
@@ -809,7 +822,6 @@ CONFIG_R8169=y
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 CONFIG_SKY2=y
-# CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
 CONFIG_BNX2=y
@@ -823,10 +835,6 @@ CONFIG_NETDEV_10000=y
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_MLX4_CORE is not set
-
-#
-# Token Ring devices
-#
 # CONFIG_TR is not set
 
 #
@@ -855,15 +863,7 @@ CONFIG_NETCONSOLE=y
 CONFIG_NETPOLL=y
 # CONFIG_NETPOLL_TRAP is not set
 CONFIG_NET_POLL_CONTROLLER=y
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -871,6 +871,7 @@ CONFIG_NET_POLL_CONTROLLER=y
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -936,6 +937,7 @@ CONFIG_HW_CONSOLE=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_FIX_EARLYCON_MEM=y
 CONFIG_SERIAL_8250_PCI=y
 CONFIG_SERIAL_8250_PNP=y
 CONFIG_SERIAL_8250_NR_UARTS=4
@@ -951,10 +953,6 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_HW_RANDOM=y
@@ -988,11 +986,7 @@ CONFIG_MAX_RAW_DEVS=256
 CONFIG_HPET=y
 # CONFIG_HPET_RTC_IRQ is not set
 CONFIG_HPET_MMAP=y
-CONFIG_HANGCHECK_TIMER=y
-
-#
-# TPM devices
-#
+# CONFIG_HANGCHECK_TIMER is not set
 # CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 CONFIG_DEVPORT=y
@@ -1003,11 +997,8 @@ CONFIG_DEVPORT=y
 #
 # CONFIG_SPI is not set
 # CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
 # CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 
 #
@@ -1041,7 +1032,7 @@ CONFIG_DAB=y
 CONFIG_VGA_CONSOLE=y
 CONFIG_VGACON_SOFT_SCROLLBACK=y
 CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=128
-# CONFIG_VIDEO_SELECT is not set
+CONFIG_VIDEO_SELECT=y
 CONFIG_DUMMY_CONSOLE=y
 
 #
@@ -1058,15 +1049,11 @@ CONFIG_SOUND=y
 # Open Sound System
 #
 CONFIG_SOUND_PRIME=y
-# CONFIG_OSS_OBSOLETE is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
 # CONFIG_SOUND_OSS is not set
-
-#
-# HID Devices
-#
+CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
 
@@ -1077,10 +1064,7 @@ CONFIG_USB_HID=y
 # CONFIG_USB_HIDINPUT_POWERBOOK is not set
 # CONFIG_HID_FF is not set
 # CONFIG_USB_HIDDEV is not set
-
-#
-# USB support
-#
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
@@ -1094,6 +1078,7 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_PERSIST is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -1103,7 +1088,6 @@ CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
-# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
@@ -1111,6 +1095,7 @@ CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=y
 # CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
 
 #
 # USB Device Class drivers
@@ -1201,15 +1186,7 @@ CONFIG_USB_MON=y
 #
 # LED Triggers
 #
-
-#
-# InfiniBand support
-#
 # CONFIG_INFINIBAND is not set
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
 # CONFIG_EDAC is not set
 
 #
@@ -1229,11 +1206,13 @@ CONFIG_USB_MON=y
 #
 # DMA Devices
 #
+CONFIG_VIRTUALIZATION=y
+# CONFIG_KVM is not set
 
 #
-# Virtualization
+# Userspace I/O
 #
-# CONFIG_KVM is not set
+# CONFIG_UIO is not set
 
 #
 # File systems
@@ -1271,6 +1250,7 @@ CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 CONFIG_AUTOFS4_FS=y
 # CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
 
 #
 # CD-ROM/DVD Filesystems
@@ -1298,7 +1278,7 @@ CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
+CONFIG_TMPFS_POSIX_ACL=y
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
@@ -1348,7 +1328,6 @@ CONFIG_SUNRPC=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -1404,10 +1383,7 @@ CONFIG_NLS_UTF8=y
 # Distributed Lock Manager
 #
 # CONFIG_DLM is not set
-
-#
-# Instrumentation Support
-#
+CONFIG_INSTRUMENTATION=y
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
 CONFIG_KPROBES=y
@@ -1417,7 +1393,7 @@ CONFIG_KPROBES=y
 #
 CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_UNUSED_SYMBOLS=y
 # CONFIG_DEBUG_FS is not set
@@ -1425,15 +1401,17 @@ CONFIG_UNUSED_SYMBOLS=y
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHED_DEBUG is not set
 # CONFIG_SCHEDSTATS is not set
-# CONFIG_TIMER_STATS is not set
-# CONFIG_DEBUG_SLAB is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
 # CONFIG_DEBUG_LOCK_ALLOC is not set
 # CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -1443,7 +1421,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_FRAME_POINTER is not set
-# CONFIG_UNWIND_INFO is not set
 # CONFIG_FORCED_INLINING is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
@@ -1462,10 +1439,6 @@ CONFIG_DOUBLEFAULT=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
 # CONFIG_CRYPTO is not set
 
 #
@@ -1476,6 +1449,7 @@ CONFIG_BITREVERSE=y
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_PLIST=y
index 06da59f6f837097d0826687295e25aeb34935458..dbe5e87e0d66fd02064843aee01a04a0fe3eb09e 100644 (file)
@@ -40,6 +40,7 @@ obj-$(CONFIG_VM86)            += vm86.o
 obj-$(CONFIG_EARLY_PRINTK)     += early_printk.o
 obj-$(CONFIG_HPET_TIMER)       += hpet.o
 obj-$(CONFIG_K8_NB)            += k8.o
+obj-$(CONFIG_MGEODE_LX)                += geode.o
 
 obj-$(CONFIG_VMI)              += vmi.o vmiclock.o
 obj-$(CONFIG_PARAVIRT)         += paravirt.o
index a574cd2c8b61c5ac1ec273b1a7741f1868611abc..cacdd883bf2b8d545b7045daf79f2ad8325dd69a 100644 (file)
@@ -618,6 +618,8 @@ static int __init acpi_parse_sbf(struct acpi_table_header *table)
 #ifdef CONFIG_HPET_TIMER
 #include <asm/hpet.h>
 
+static struct __initdata resource *hpet_res;
+
 static int __init acpi_parse_hpet(struct acpi_table_header *table)
 {
        struct acpi_table_hpet *hpet_tbl;
@@ -638,8 +640,42 @@ static int __init acpi_parse_hpet(struct acpi_table_header *table)
        printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n",
               hpet_tbl->id, hpet_address);
 
+       /*
+        * Allocate and initialize the HPET firmware resource for adding into
+        * the resource tree during the lateinit timeframe.
+        */
+#define HPET_RESOURCE_NAME_SIZE 9
+       hpet_res = alloc_bootmem(sizeof(*hpet_res) + HPET_RESOURCE_NAME_SIZE);
+
+       if (!hpet_res)
+               return 0;
+
+       memset(hpet_res, 0, sizeof(*hpet_res));
+       hpet_res->name = (void *)&hpet_res[1];
+       hpet_res->flags = IORESOURCE_MEM;
+       snprintf((char *)hpet_res->name, HPET_RESOURCE_NAME_SIZE, "HPET %u",
+                hpet_tbl->sequence);
+
+       hpet_res->start = hpet_address;
+       hpet_res->end = hpet_address + (1 * 1024) - 1;
+
        return 0;
 }
+
+/*
+ * hpet_insert_resource inserts the HPET resources used into the resource
+ * tree.
+ */
+static __init int hpet_insert_resource(void)
+{
+       if (!hpet_res)
+               return 1;
+
+       return insert_resource(&iomem_resource, hpet_res);
+}
+
+late_initcall(hpet_insert_resource);
+
 #else
 #define        acpi_parse_hpet NULL
 #endif
@@ -948,14 +984,6 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = {
                     DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
                     },
         },
-       {
-        .callback = force_acpi_ht,
-        .ident = "DELL GX240",
-        .matches = {
-                    DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
-                    DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
-                    },
-        },
        {
         .callback = force_acpi_ht,
         .ident = "HP VISUALIZE NT Workstation",
index d8cda14fff8bc4713f41a15a0193cb935550c602..c3750c2c41137a694be9570443f59b379cc4cc4d 100644 (file)
@@ -2,12 +2,17 @@
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/list.h>
+#include <linux/kprobes.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
 #include <asm/alternative.h>
 #include <asm/sections.h>
+#include <asm/pgtable.h>
+#include <asm/mce.h>
+#include <asm/nmi.h>
 
-static int noreplace_smp     = 0;
-static int smp_alt_once      = 0;
-static int debug_alternative = 0;
+#ifdef CONFIG_HOTPLUG_CPU
+static int smp_alt_once;
 
 static int __init bootonly(char *str)
 {
@@ -15,6 +20,11 @@ static int __init bootonly(char *str)
        return 1;
 }
 __setup("smp-alt-boot", bootonly);
+#else
+#define smp_alt_once 1
+#endif
+
+static int debug_alternative;
 
 static int __init debug_alt(char *str)
 {
@@ -23,6 +33,8 @@ static int __init debug_alt(char *str)
 }
 __setup("debug-alternative", debug_alt);
 
+static int noreplace_smp;
+
 static int __init setup_noreplace_smp(char *str)
 {
        noreplace_smp = 1;
@@ -144,7 +156,7 @@ static void nop_out(void *insns, unsigned int len)
                unsigned int noplen = len;
                if (noplen > ASM_NOP_MAX)
                        noplen = ASM_NOP_MAX;
-               memcpy(insns, noptable[noplen], noplen);
+               text_poke(insns, noptable[noplen], noplen);
                insns += noplen;
                len -= noplen;
        }
@@ -196,7 +208,7 @@ static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
                        continue;
                if (*ptr > text_end)
                        continue;
-               **ptr = 0xf0; /* lock prefix */
+               text_poke(*ptr, ((unsigned char []){0xf0}), 1); /* add lock prefix */
        };
 }
 
@@ -354,10 +366,6 @@ void apply_paravirt(struct paravirt_patch_site *start,
                /* Pad the rest with nops */
                nop_out(p->instr + used, p->len - used);
        }
-
-       /* Sync to be conservative, in case we patched following
-        * instructions */
-       sync_core();
 }
 extern struct paravirt_patch_site __start_parainstructions[],
        __stop_parainstructions[];
@@ -367,6 +375,14 @@ void __init alternative_instructions(void)
 {
        unsigned long flags;
 
+       /* The patching is not fully atomic, so try to avoid local interruptions
+          that might execute the to be patched code.
+          Other CPUs are not running. */
+       stop_nmi();
+#ifdef CONFIG_MCE
+       stop_mce();
+#endif
+
        local_irq_save(flags);
        apply_alternatives(__alt_instructions, __alt_instructions_end);
 
@@ -376,8 +392,6 @@ void __init alternative_instructions(void)
 #ifdef CONFIG_HOTPLUG_CPU
        if (num_possible_cpus() < 2)
                smp_alt_once = 1;
-#else
-       smp_alt_once = 1;
 #endif
 
 #ifdef CONFIG_SMP
@@ -401,4 +415,37 @@ void __init alternative_instructions(void)
 #endif
        apply_paravirt(__parainstructions, __parainstructions_end);
        local_irq_restore(flags);
+
+       restart_nmi();
+#ifdef CONFIG_MCE
+       restart_mce();
+#endif
+}
+
+/*
+ * Warning:
+ * When you use this code to patch more than one byte of an instruction
+ * you need to make sure that other CPUs cannot execute this code in parallel.
+ * Also no thread must be currently preempted in the middle of these instructions.
+ * And on the local CPU you need to be protected again NMI or MCE handlers
+ * seeing an inconsistent instruction while you patch.
+ */
+void __kprobes text_poke(void *oaddr, unsigned char *opcode, int len)
+{
+        u8 *addr = oaddr;
+       if (!pte_write(*lookup_address((unsigned long)addr))) {
+               struct page *p[2] = { virt_to_page(addr), virt_to_page(addr+PAGE_SIZE) };
+               addr = vmap(p, 2, VM_MAP, PAGE_KERNEL);
+               if (!addr)
+                       return;
+               addr += ((unsigned long)oaddr) % PAGE_SIZE;
+       }
+       memcpy(addr, opcode, len);
+       sync_core();
+       /* Not strictly needed, but can speed CPU recovery up. Ignore cross cacheline
+          case. */
+       if (cpu_has_clflush)
+               asm("clflush (%0) " :: "r" (oaddr) : "memory");
+       if (addr != oaddr)
+               vunmap(addr);
 }
index 67824f3bb974113aab84b73c79239b1ba0283f30..bfc6cb7df7e7ff0a3d00f48bc8221e37e3e54e0d 100644 (file)
@@ -263,6 +263,9 @@ static void lapic_timer_setup(enum clock_event_mode mode,
                v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
                apic_write_around(APIC_LVTT, v);
                break;
+       case CLOCK_EVT_MODE_RESUME:
+               /* Nothing to do here */
+               break;
        }
 
        local_irq_restore(flags);
@@ -315,7 +318,7 @@ static void __devinit setup_APIC_timer(void)
 
 #define LAPIC_CAL_LOOPS                (HZ/10)
 
-static __initdata volatile int lapic_cal_loops = -1;
+static __initdata int lapic_cal_loops = -1;
 static __initdata long lapic_cal_t1, lapic_cal_t2;
 static __initdata unsigned long long lapic_cal_tsc1, lapic_cal_tsc2;
 static __initdata unsigned long lapic_cal_pm1, lapic_cal_pm2;
@@ -485,7 +488,7 @@ void __init setup_boot_APIC_clock(void)
                /* Let the interrupts run */
                local_irq_enable();
 
-               while(lapic_cal_loops <= LAPIC_CAL_LOOPS)
+               while (lapic_cal_loops <= LAPIC_CAL_LOOPS)
                        cpu_relax();
 
                local_irq_disable();
@@ -521,6 +524,9 @@ void __init setup_boot_APIC_clock(void)
                 */
                if (nmi_watchdog != NMI_IO_APIC)
                        lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
+               else
+                       printk(KERN_WARNING "APIC timer registered as dummy,"
+                              " due to nmi_watchdog=1!\n");
        }
 
        /* Setup the lapic or request the broadcast */
index 0b6a8551e9e222167c44fbb8e6bd63bd0d10141c..778396c78d65c5f4d4c779314223fe2874e6b429 100644 (file)
@@ -9,7 +9,6 @@ obj-y   +=      cyrix.o
 obj-y  +=      centaur.o
 obj-y  +=      transmeta.o
 obj-y  +=      intel.o intel_cacheinfo.o addon_cpuid_features.o
-obj-y  +=      rise.o
 obj-y  +=      nexgen.o
 obj-y  +=      umc.o
 
index 6f47eeeb93ea65d3c513c9e81458551a9a58c52f..c7ba455d5ac77d97747f1c13a4f5ac6737bfb48d 100644 (file)
@@ -231,6 +231,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
 
        switch (c->x86) {
        case 15:
+       /* Use K8 tuning for Fam10h and Fam11h */
+       case 0x10:
+       case 0x11:
                set_bit(X86_FEATURE_K8, c->x86_capability);
                break;
        case 6:
@@ -272,8 +275,12 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
        }
 #endif
 
-       if (cpuid_eax(0x80000000) >= 0x80000006)
-               num_cache_leaves = 3;
+       if (cpuid_eax(0x80000000) >= 0x80000006) {
+               if ((c->x86 == 0x10) && (cpuid_edx(0x80000006) & 0xf000))
+                       num_cache_leaves = 4;
+               else
+                       num_cache_leaves = 3;
+       }
 
        if (amd_apic_timer_broken())
                set_bit(X86_FEATURE_LAPIC_TIMER_BROKEN, c->x86_capability);
index e5419a9dec885e1d1135f1f46279e3388039a71f..d506201d397c5fb2e13b364189a37d058876dd46 100644 (file)
@@ -606,7 +606,6 @@ extern int nsc_init_cpu(void);
 extern int amd_init_cpu(void);
 extern int centaur_init_cpu(void);
 extern int transmeta_init_cpu(void);
-extern int rise_init_cpu(void);
 extern int nexgen_init_cpu(void);
 extern int umc_init_cpu(void);
 
@@ -618,7 +617,6 @@ void __init early_cpu_init(void)
        amd_init_cpu();
        centaur_init_cpu();
        transmeta_init_cpu();
-       rise_init_cpu();
        nexgen_init_cpu();
        umc_init_cpu();
        early_cpu_detect();
index 18c8b67ea3a75ce4b5d740e1eb8a68b3cda46915..6f846bee2103d4b17eec817d4a6e4501b675194c 100644 (file)
@@ -665,8 +665,8 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
        data->max_freq = perf->states[0].core_frequency * 1000;
        /* table init */
        for (i=0; i<perf->state_count; i++) {
-               if (i>0 && perf->states[i].core_frequency ==
-                   perf->states[i-1].core_frequency)
+               if (i>0 && perf->states[i].core_frequency >=
+                   data->freq_table[valid_states-1].frequency / 1000)
                        continue;
 
                data->freq_table[valid_states].index = i;
index 194144539a6f34ccddd67e4e7f3393b68e5fecba..461dabc4e4959d23a7b5411d109b1a239a8c3872 100644 (file)
@@ -79,7 +79,7 @@
 #include <linux/smp.h>
 #include <linux/cpufreq.h>
 #include <linux/pci.h>
-#include <asm/processor.h>
+#include <asm/processor-cyrix.h>
 #include <asm/errno.h>
 
 /* PCI config registers, all at F0 */
index e88d2fba156b89d49ea24b9abba1d3b0cd41e5b4..122d2d75aa9f9bbce77211038240686ebf2dc7e8 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/pci.h>
 #include <asm/dma.h>
 #include <asm/io.h>
-#include <asm/processor.h>
+#include <asm/processor-cyrix.h>
 #include <asm/timer.h>
 #include <asm/pci-direct.h>
 #include <asm/tsc.h>
index e5be819492ef1daf5bed9ff653dfeaee6f117e24..d5a456d27d82420c3d690f51af5a80a8e940c937 100644 (file)
@@ -4,7 +4,7 @@
  *      Changes:
  *      Venkatesh Pallipadi    : Adding cache identification through cpuid(4)
  *             Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure.
- *     Andi Kleen              : CPUID4 emulation on AMD.
+ *     Andi Kleen / Andreas Herrmann   : CPUID4 emulation on AMD.
  */
 
 #include <linux/init.h>
@@ -135,7 +135,7 @@ unsigned short                      num_cache_leaves;
 
 /* AMD doesn't have CPUID4. Emulate it here to report the same
    information to the user.  This makes some assumptions about the machine:
-   No L3, L2 not shared, no SMT etc. that is currently true on AMD CPUs.
+   L2 not shared, no SMT etc. that is currently true on AMD CPUs.
 
    In theory the TLBs could be reported as fake type (they are in "dummy").
    Maybe later */
@@ -159,13 +159,26 @@ union l2_cache {
        unsigned val;
 };
 
+union l3_cache {
+       struct {
+               unsigned line_size : 8;
+               unsigned lines_per_tag : 4;
+               unsigned assoc : 4;
+               unsigned res : 2;
+               unsigned size_encoded : 14;
+       };
+       unsigned val;
+};
+
 static const unsigned short assocs[] = {
        [1] = 1, [2] = 2, [4] = 4, [6] = 8,
-       [8] = 16,
+       [8] = 16, [0xa] = 32, [0xb] = 48,
+       [0xc] = 64,
        [0xf] = 0xffff // ??
-       };
-static const unsigned char levels[] = { 1, 1, 2 };
-static const unsigned char types[] = { 1, 2, 3 };
+};
+
+static const unsigned char levels[] = { 1, 1, 2, 3 };
+static const unsigned char types[] = { 1, 2, 3, 3 };
 
 static void __cpuinit amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
                       union _cpuid4_leaf_ebx *ebx,
@@ -175,37 +188,58 @@ static void __cpuinit amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
        unsigned line_size, lines_per_tag, assoc, size_in_kb;
        union l1_cache l1i, l1d;
        union l2_cache l2;
+       union l3_cache l3;
+       union l1_cache *l1 = &l1d;
 
        eax->full = 0;
        ebx->full = 0;
        ecx->full = 0;
 
        cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val);
-       cpuid(0x80000006, &dummy, &dummy, &l2.val, &dummy);
-
-       if (leaf > 2 || !l1d.val || !l1i.val || !l2.val)
-               return;
-
-       eax->split.is_self_initializing = 1;
-       eax->split.type = types[leaf];
-       eax->split.level = levels[leaf];
-       eax->split.num_threads_sharing = 0;
-       eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
-
-       if (leaf <= 1) {
-               union l1_cache *l1 = leaf == 0 ? &l1d : &l1i;
+       cpuid(0x80000006, &dummy, &dummy, &l2.val, &l3.val);
+
+       switch (leaf) {
+       case 1:
+               l1 = &l1i;
+       case 0:
+               if (!l1->val)
+                       return;
                assoc = l1->assoc;
                line_size = l1->line_size;
                lines_per_tag = l1->lines_per_tag;
                size_in_kb = l1->size_in_kb;
-       } else {
+               break;
+       case 2:
+               if (!l2.val)
+                       return;
                assoc = l2.assoc;
                line_size = l2.line_size;
                lines_per_tag = l2.lines_per_tag;
                /* cpu_data has errata corrections for K7 applied */
                size_in_kb = current_cpu_data.x86_cache_size;
+               break;
+       case 3:
+               if (!l3.val)
+                       return;
+               assoc = l3.assoc;
+               line_size = l3.line_size;
+               lines_per_tag = l3.lines_per_tag;
+               size_in_kb = l3.size_encoded * 512;
+               break;
+       default:
+               return;
        }
 
+       eax->split.is_self_initializing = 1;
+       eax->split.type = types[leaf];
+       eax->split.level = levels[leaf];
+       if (leaf == 3)
+               eax->split.num_threads_sharing = current_cpu_data.x86_max_cores - 1;
+       else
+               eax->split.num_threads_sharing = 0;
+       eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
+
+
        if (assoc == 0xf)
                eax->split.is_fully_associative = 1;
        ebx->split.coherency_line_size = line_size - 1;
@@ -239,8 +273,7 @@ static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_le
        return 0;
 }
 
-/* will only be called once; __init is safe here */
-static int __init find_num_cache_leaves(void)
+static int __cpuinit find_num_cache_leaves(void)
 {
        unsigned int            eax, ebx, ecx, edx;
        union _cpuid4_leaf_eax  cache_eax;
@@ -710,7 +743,7 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
        return retval;
 }
 
-static void __cpuexit cache_remove_dev(struct sys_device * sys_dev)
+static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
 {
        unsigned int cpu = sys_dev->id;
        unsigned long i;
index 56cd485b127ce59b2da500e9f176b83bb755b7b7..34c781eddee4cdc6fce3419366b63329965655a5 100644 (file)
@@ -60,6 +60,20 @@ void mcheck_init(struct cpuinfo_x86 *c)
        }
 }
 
+static unsigned long old_cr4 __initdata;
+
+void __init stop_mce(void)
+{
+       old_cr4 = read_cr4();
+       clear_in_cr4(X86_CR4_MCE);
+}
+
+void __init restart_mce(void)
+{
+       if (old_cr4 & X86_CR4_MCE)
+               set_in_cr4(X86_CR4_MCE);
+}
+
 static int __init mcheck_disable(char *str)
 {
        mce_disabled = 1;
index 6b5d3518a1c09b3532871fc337419b9477dcbc0c..bf39409b383808897bb3d2495fa2b06988172264 100644 (file)
@@ -57,7 +57,7 @@ static DECLARE_DELAYED_WORK(mce_work, mce_work_fn);
 static void mce_work_fn(struct work_struct *work)
 { 
        on_each_cpu(mce_checkregs, NULL, 1, 1);
-       schedule_delayed_work(&mce_work, MCE_RATE);
+       schedule_delayed_work(&mce_work, round_jiffies_relative(MCE_RATE));
 } 
 
 static int __init init_nonfatal_mce_checker(void)
@@ -82,7 +82,7 @@ static int __init init_nonfatal_mce_checker(void)
        /*
         * Check for non-fatal errors every MCE_RATE s
         */
-       schedule_delayed_work(&mce_work, MCE_RATE);
+       schedule_delayed_work(&mce_work, round_jiffies_relative(MCE_RATE));
        printk(KERN_INFO "Machine check exception polling timer started.\n");
        return 0;
 }
index 1001f1e0fe6d7dee0ae39147e054881fe5373736..2287d4863a8a01f7b060c39ffcebfe05dc33a94e 100644 (file)
@@ -3,6 +3,7 @@
 #include <asm/mtrr.h>
 #include <asm/msr.h>
 #include <asm/io.h>
+#include <asm/processor-cyrix.h>
 #include "mtrr.h"
 
 int arr3_protected;
index f6e46943e6efbf6a63ca2265ab6177d304338717..56f64e34829f937e878b0855187689e1abb35bab 100644 (file)
@@ -79,7 +79,7 @@ static void print_fixed(unsigned base, unsigned step, const mtrr_type*types)
 }
 
 /*  Grab all of the MTRR state for this CPU into *state  */
-void get_mtrr_state(void)
+void __init get_mtrr_state(void)
 {
        unsigned int i;
        struct mtrr_var_range *vrs;
index 75dc6d5214bc5271b07b1d389d96670fed758d64..c48b6fea5ab4edd5fb53133fc03de2309f2e80af 100644 (file)
@@ -643,7 +643,7 @@ static struct sysdev_driver mtrr_sysdev_driver = {
  * initialized (i.e. before smp_init()).
  * 
  */
-__init void mtrr_bp_init(void)
+void __init mtrr_bp_init(void)
 {
        init_ifs();
 
index 7b39a2f954d9026c422862d522b5114ead35c242..c9014ca4a575d3bbd1766bf6a0873bd7e2953e1f 100644 (file)
@@ -3,6 +3,7 @@
 #include <asm/io.h>
 #include <asm/mtrr.h>
 #include <asm/msr.h>
+#include <asm-i386/processor-cyrix.h>
 #include "mtrr.h"
 
 
index 4d26d514c56f97aa37d8977b280565682fd4a2aa..4be488e73bee11760f9de2b9c8b8acd65e556a38 100644 (file)
@@ -325,7 +325,7 @@ static struct wd_ops k7_wd_ops = {
        .stop = single_msr_stop_watchdog,
        .perfctr = MSR_K7_PERFCTR0,
        .evntsel = MSR_K7_EVNTSEL0,
-       .checkbit = 1ULL<<63,
+       .checkbit = 1ULL<<47,
 };
 
 /* Intel Model 6 (PPro+,P2,P3,P-M,Core1) */
@@ -346,7 +346,9 @@ static int setup_p6_watchdog(unsigned nmi_hz)
        perfctr_msr = MSR_P6_PERFCTR0;
        evntsel_msr = MSR_P6_EVNTSEL0;
 
-       wrmsrl(perfctr_msr, 0UL);
+       /* KVM doesn't implement this MSR */
+       if (wrmsr_safe(perfctr_msr, 0, 0) < 0)
+               return 0;
 
        evntsel = P6_EVNTSEL_INT
                | P6_EVNTSEL_OS
@@ -599,8 +601,8 @@ static struct wd_ops intel_arch_wd_ops = {
        .setup = setup_intel_arch_watchdog,
        .rearm = p6_rearm,
        .stop = single_msr_stop_watchdog,
-       .perfctr = MSR_ARCH_PERFMON_PERFCTR0,
-       .evntsel = MSR_ARCH_PERFMON_EVENTSEL0,
+       .perfctr = MSR_ARCH_PERFMON_PERFCTR1,
+       .evntsel = MSR_ARCH_PERFMON_EVENTSEL1,
 };
 
 static void probe_nmi_watchdog(void)
diff --git a/arch/i386/kernel/cpu/rise.c b/arch/i386/kernel/cpu/rise.c
deleted file mode 100644 (file)
index 50076f2..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-#include <asm/processor.h>
-
-#include "cpu.h"
-
-static void __cpuinit init_rise(struct cpuinfo_x86 *c)
-{
-       printk("CPU: Rise iDragon");
-       if (c->x86_model > 2)
-               printk(" II");
-       printk("\n");
-
-       /* Unhide possibly hidden capability flags
-          The mp6 iDragon family don't have MSRs.
-          We switch on extra features with this cpuid weirdness: */
-       __asm__ (
-               "movl $0x6363452a, %%eax\n\t"
-               "movl $0x3231206c, %%ecx\n\t"
-               "movl $0x2a32313a, %%edx\n\t"
-               "cpuid\n\t"
-               "movl $0x63634523, %%eax\n\t"
-               "movl $0x32315f6c, %%ecx\n\t"
-               "movl $0x2333313a, %%edx\n\t"
-               "cpuid\n\t" : : : "eax", "ebx", "ecx", "edx"
-       );
-       set_bit(X86_FEATURE_CX8, c->x86_capability);
-}
-
-static struct cpu_dev rise_cpu_dev __cpuinitdata = {
-       .c_vendor       = "Rise",
-       .c_ident        = { "RiseRiseRise" },
-       .c_models = {
-               { .vendor = X86_VENDOR_RISE, .family = 5, .model_names = 
-                 { 
-                         [0] = "iDragon", 
-                         [2] = "iDragon", 
-                         [8] = "iDragon II", 
-                         [9] = "iDragon II"
-                 }
-               },
-       },
-       .c_init         = init_rise,
-};
-
-int __init rise_init_cpu(void)
-{
-       cpu_devs[X86_VENDOR_RISE] = &rise_cpu_dev;
-       return 0;
-}
-
index fc822a46897a720de02dd29d9a286c92c8e9e605..e60cddbc4cfbc39380c751f0d5793851ff25c96b 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/efi.h>
 #include <linux/pfn.h>
 #include <linux/uaccess.h>
+#include <linux/suspend.h>
 
 #include <asm/pgtable.h>
 #include <asm/page.h>
@@ -320,6 +321,37 @@ static int __init request_standard_resources(void)
 
 subsys_initcall(request_standard_resources);
 
+#if defined(CONFIG_PM) && defined(CONFIG_SOFTWARE_SUSPEND)
+/**
+ * e820_mark_nosave_regions - Find the ranges of physical addresses that do not
+ * correspond to e820 RAM areas and mark the corresponding pages as nosave for
+ * hibernation.
+ *
+ * This function requires the e820 map to be sorted and without any
+ * overlapping entries and assumes the first e820 area to be RAM.
+ */
+void __init e820_mark_nosave_regions(void)
+{
+       int i;
+       unsigned long pfn;
+
+       pfn = PFN_DOWN(e820.map[0].addr + e820.map[0].size);
+       for (i = 1; i < e820.nr_map; i++) {
+               struct e820entry *ei = &e820.map[i];
+
+               if (pfn < PFN_UP(ei->addr))
+                       register_nosave_region(pfn, PFN_UP(ei->addr));
+
+               pfn = PFN_DOWN(ei->addr + ei->size);
+               if (ei->type != E820_RAM)
+                       register_nosave_region(PFN_UP(ei->addr), pfn);
+
+               if (pfn >= max_low_pfn)
+                       break;
+       }
+}
+#endif
+
 void __init add_memory_region(unsigned long long start,
                              unsigned long long size, int type)
 {
diff --git a/arch/i386/kernel/geode.c b/arch/i386/kernel/geode.c
new file mode 100644 (file)
index 0000000..41e8aec
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * AMD Geode southbridge support code
+ * Copyright (C) 2006, Advanced Micro Devices, 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 published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <asm/msr.h>
+#include <asm/geode.h>
+
+static struct {
+       char *name;
+       u32 msr;
+       int size;
+       u32 base;
+} lbars[] = {
+       { "geode-pms",   MSR_LBAR_PMS, LBAR_PMS_SIZE, 0 },
+       { "geode-acpi",  MSR_LBAR_ACPI, LBAR_ACPI_SIZE, 0 },
+       { "geode-gpio",  MSR_LBAR_GPIO, LBAR_GPIO_SIZE, 0 },
+       { "geode-mfgpt", MSR_LBAR_MFGPT, LBAR_MFGPT_SIZE, 0 }
+};
+
+static void __init init_lbars(void)
+{
+       u32 lo, hi;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(lbars); i++) {
+               rdmsr(lbars[i].msr, lo, hi);
+               if (hi & 0x01)
+                       lbars[i].base = lo & 0x0000ffff;
+
+               if (lbars[i].base == 0)
+                       printk(KERN_ERR "geode:  Couldn't initialize '%s'\n",
+                                       lbars[i].name);
+       }
+}
+
+int geode_get_dev_base(unsigned int dev)
+{
+       BUG_ON(dev >= ARRAY_SIZE(lbars));
+       return lbars[dev].base;
+}
+EXPORT_SYMBOL_GPL(geode_get_dev_base);
+
+/* === GPIO API === */
+
+void geode_gpio_set(unsigned int gpio, unsigned int reg)
+{
+       u32 base = geode_get_dev_base(GEODE_DEV_GPIO);
+
+       if (!base)
+               return;
+
+       if (gpio < 16)
+               outl(1 << gpio, base + reg);
+       else
+               outl(1 << (gpio - 16), base + 0x80 + reg);
+}
+EXPORT_SYMBOL_GPL(geode_gpio_set);
+
+void geode_gpio_clear(unsigned int gpio, unsigned int reg)
+{
+       u32 base = geode_get_dev_base(GEODE_DEV_GPIO);
+
+       if (!base)
+               return;
+
+       if (gpio < 16)
+               outl(1 << (gpio + 16), base + reg);
+       else
+               outl(1 << gpio, base + 0x80 + reg);
+}
+EXPORT_SYMBOL_GPL(geode_gpio_clear);
+
+int geode_gpio_isset(unsigned int gpio, unsigned int reg)
+{
+       u32 base = geode_get_dev_base(GEODE_DEV_GPIO);
+
+       if (!base)
+               return 0;
+
+       if (gpio < 16)
+               return (inl(base + reg) & (1 << gpio)) ? 1 : 0;
+       else
+               return (inl(base + 0x80 + reg) & (1 << (gpio - 16))) ? 1 : 0;
+}
+EXPORT_SYMBOL_GPL(geode_gpio_isset);
+
+void geode_gpio_set_irq(unsigned int group, unsigned int irq)
+{
+       u32 lo, hi;
+
+       if (group > 7 || irq > 15)
+               return;
+
+       rdmsr(MSR_PIC_ZSEL_HIGH, lo, hi);
+
+       lo &= ~(0xF << (group * 4));
+       lo |= (irq & 0xF) << (group * 4);
+
+       wrmsr(MSR_PIC_ZSEL_HIGH, lo, hi);
+}
+EXPORT_SYMBOL_GPL(geode_gpio_set_irq);
+
+void geode_gpio_setup_event(unsigned int gpio, int pair, int pme)
+{
+       u32 base = geode_get_dev_base(GEODE_DEV_GPIO);
+       u32 offset, shift, val;
+
+       if (gpio >= 24)
+               offset = GPIO_MAP_W;
+       else if (gpio >= 16)
+               offset = GPIO_MAP_Z;
+       else if (gpio >= 8)
+               offset = GPIO_MAP_Y;
+       else
+               offset = GPIO_MAP_X;
+
+       shift = (gpio % 8) * 4;
+
+       val = inl(base + offset);
+
+       /* Clear whatever was there before */
+       val &= ~(0xF << shift);
+
+       /* And set the new value */
+
+       val |= ((pair & 7) << shift);
+
+       /* Set the PME bit if this is a PME event */
+
+       if (pme)
+               val |= (1 << (shift + 3));
+
+       outl(val, base + offset);
+}
+EXPORT_SYMBOL_GPL(geode_gpio_setup_event);
+
+static int __init geode_southbridge_init(void)
+{
+       if (!is_geode())
+               return -ENODEV;
+
+       init_lbars();
+       return 0;
+}
+
+postcore_initcall(geode_southbridge_init);
index 17d73459fc5f3310b58109656ff27db1174843c3..533d4932bc79384805da8d6acee0bd84094e941e 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/init.h>
 #include <linux/sysdev.h>
 #include <linux/pm.h>
+#include <linux/delay.h>
 
 #include <asm/hpet.h>
 #include <asm/io.h>
@@ -187,6 +188,10 @@ static void hpet_set_mode(enum clock_event_mode mode,
                cfg &= ~HPET_TN_ENABLE;
                hpet_writel(cfg, HPET_T0_CFG);
                break;
+
+       case CLOCK_EVT_MODE_RESUME:
+               hpet_enable_int();
+               break;
        }
 }
 
@@ -217,6 +222,7 @@ static struct clocksource clocksource_hpet = {
        .mask           = HPET_MASK,
        .shift          = HPET_SHIFT,
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+       .resume         = hpet_start_counter,
 };
 
 /*
@@ -226,7 +232,8 @@ int __init hpet_enable(void)
 {
        unsigned long id;
        uint64_t hpet_freq;
-       u64 tmp;
+       u64 tmp, start, now;
+       cycle_t t1;
 
        if (!is_hpet_capable())
                return 0;
@@ -273,6 +280,27 @@ int __init hpet_enable(void)
        /* Start the counter */
        hpet_start_counter();
 
+       /* Verify whether hpet counter works */
+       t1 = read_hpet();
+       rdtscll(start);
+
+       /*
+        * We don't know the TSC frequency yet, but waiting for
+        * 200000 TSC cycles is safe:
+        * 4 GHz == 50us
+        * 1 GHz == 200us
+        */
+       do {
+               rep_nop();
+               rdtscll(now);
+       } while ((now - start) < 200000UL);
+
+       if (t1 == read_hpet()) {
+               printk(KERN_WARNING
+                      "HPET counter not counting. HPET disabled\n");
+               goto out_nohpet;
+       }
+
        /* Initialize and register HPET clocksource
         *
         * hpet period is in femto seconds per cycle
@@ -291,7 +319,6 @@ int __init hpet_enable(void)
 
        clocksource_register(&clocksource_hpet);
 
-
        if (id & HPET_ID_LEGSUP) {
                hpet_enable_int();
                hpet_reserve_platform_timers(id);
@@ -299,7 +326,7 @@ int __init hpet_enable(void)
                 * Start hpet with the boot cpu mask and make it
                 * global after the IO_APIC has been initialized.
                 */
-               hpet_clockevent.cpumask =cpumask_of_cpu(0);
+               hpet_clockevent.cpumask = cpumask_of_cpu(smp_processor_id());
                clockevents_register_device(&hpet_clockevent);
                global_clock_event = &hpet_clockevent;
                return 1;
@@ -524,68 +551,3 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 #endif
-
-
-/*
- * Suspend/resume part
- */
-
-#ifdef CONFIG_PM
-
-static int hpet_suspend(struct sys_device *sys_device, pm_message_t state)
-{
-       unsigned long cfg = hpet_readl(HPET_CFG);
-
-       cfg &= ~(HPET_CFG_ENABLE|HPET_CFG_LEGACY);
-       hpet_writel(cfg, HPET_CFG);
-
-       return 0;
-}
-
-static int hpet_resume(struct sys_device *sys_device)
-{
-       unsigned int id;
-
-       hpet_start_counter();
-
-       id = hpet_readl(HPET_ID);
-
-       if (id & HPET_ID_LEGSUP)
-               hpet_enable_int();
-
-       return 0;
-}
-
-static struct sysdev_class hpet_class = {
-       set_kset_name("hpet"),
-       .suspend        = hpet_suspend,
-       .resume         = hpet_resume,
-};
-
-static struct sys_device hpet_device = {
-       .id             = 0,
-       .cls            = &hpet_class,
-};
-
-
-static __init int hpet_register_sysfs(void)
-{
-       int err;
-
-       if (!is_hpet_capable())
-               return 0;
-
-       err = sysdev_class_register(&hpet_class);
-
-       if (!err) {
-               err = sysdev_register(&hpet_device);
-               if (err)
-                       sysdev_class_unregister(&hpet_class);
-       }
-
-       return err;
-}
-
-device_initcall(hpet_register_sysfs);
-
-#endif
index f8a3c4054c702d592f4049d98f9791d4d938af0c..6d839f2f1b1a6e1abca311760ac89f6a6deec6af 100644 (file)
@@ -3,18 +3,17 @@
  *
  */
 #include <linux/clockchips.h>
-#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/jiffies.h>
-#include <linux/sysdev.h>
 #include <linux/module.h>
-#include <linux/init.h>
+#include <linux/spinlock.h>
 
 #include <asm/smp.h>
 #include <asm/delay.h>
 #include <asm/i8253.h>
 #include <asm/io.h>
-
-#include "io_ports.h"
+#include <asm/timer.h>
 
 DEFINE_SPINLOCK(i8253_lock);
 EXPORT_SYMBOL(i8253_lock);
@@ -41,26 +40,27 @@ static void init_pit_timer(enum clock_event_mode mode,
        case CLOCK_EVT_MODE_PERIODIC:
                /* binary, mode 2, LSB/MSB, ch 0 */
                outb_p(0x34, PIT_MODE);
-               udelay(10);
                outb_p(LATCH & 0xff , PIT_CH0); /* LSB */
-               udelay(10);
                outb(LATCH >> 8 , PIT_CH0);     /* MSB */
                break;
 
-       /*
-        * Avoid unnecessary state transitions, as it confuses
-        * Geode / Cyrix based boxen.
-        */
        case CLOCK_EVT_MODE_SHUTDOWN:
-               if (evt->mode == CLOCK_EVT_MODE_UNUSED)
-                       break;
        case CLOCK_EVT_MODE_UNUSED:
-               if (evt->mode == CLOCK_EVT_MODE_SHUTDOWN)
-                       break;
+               if (evt->mode == CLOCK_EVT_MODE_PERIODIC ||
+                   evt->mode == CLOCK_EVT_MODE_ONESHOT) {
+                       outb_p(0x30, PIT_MODE);
+                       outb_p(0, PIT_CH0);
+                       outb_p(0, PIT_CH0);
+               }
+               break;
+
        case CLOCK_EVT_MODE_ONESHOT:
                /* One shot setup */
                outb_p(0x38, PIT_MODE);
-               udelay(10);
+               break;
+
+       case CLOCK_EVT_MODE_RESUME:
+               /* Nothing to do here */
                break;
        }
        spin_unlock_irqrestore(&i8253_lock, flags);
index 21db8f56c9a149df9a4d0954df3f28aa64900827..893df8280756194b68bb844852f1b69955985c5c 100644 (file)
@@ -353,14 +353,6 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask)
 # include <linux/slab.h>               /* kmalloc() */
 # include <linux/timer.h>      /* time_after() */
  
-#ifdef CONFIG_BALANCED_IRQ_DEBUG
-#  define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0)
-#  define Dprintk(x...) do { TDprintk(x); } while (0)
-# else
-#  define TDprintk(x...) 
-#  define Dprintk(x...) 
-# endif
-
 #define IRQBALANCE_CHECK_ARCH -999
 #define MAX_BALANCED_IRQ_INTERVAL      (5*HZ)
 #define MIN_BALANCED_IRQ_INTERVAL      (HZ/2)
@@ -443,7 +435,7 @@ static inline void balance_irq(int cpu, int irq)
 static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold)
 {
        int i, j;
-       Dprintk("Rotating IRQs among CPUs.\n");
+
        for_each_online_cpu(i) {
                for (j = 0; j < NR_IRQS; j++) {
                        if (!irq_desc[j].action)
@@ -560,19 +552,11 @@ tryanothercpu:
        max_loaded = tmp_loaded;        /* processor */
        imbalance = (max_cpu_irq - min_cpu_irq) / 2;
        
-       Dprintk("max_loaded cpu = %d\n", max_loaded);
-       Dprintk("min_loaded cpu = %d\n", min_loaded);
-       Dprintk("max_cpu_irq load = %ld\n", max_cpu_irq);
-       Dprintk("min_cpu_irq load = %ld\n", min_cpu_irq);
-       Dprintk("load imbalance = %lu\n", imbalance);
-
        /* if imbalance is less than approx 10% of max load, then
         * observe diminishing returns action. - quit
         */
-       if (imbalance < (max_cpu_irq >> 3)) {
-               Dprintk("Imbalance too trivial\n");
+       if (imbalance < (max_cpu_irq >> 3))
                goto not_worth_the_effort;
-       }
 
 tryanotherirq:
        /* if we select an IRQ to move that can't go where we want, then
@@ -629,9 +613,6 @@ tryanotherirq:
        cpus_and(tmp, target_cpu_mask, allowed_mask);
 
        if (!cpus_empty(tmp)) {
-
-               Dprintk("irq = %d moved to cpu = %d\n",
-                               selected_irq, min_loaded);
                /* mark for change destination */
                set_pending_irq(selected_irq, cpumask_of_cpu(min_loaded));
 
@@ -651,7 +632,6 @@ not_worth_the_effort:
         */
        balanced_irq_interval = min((long)MAX_BALANCED_IRQ_INTERVAL,
                balanced_irq_interval + BALANCED_IRQ_MORE_DELTA);       
-       Dprintk("IRQ worth rotating not found\n");
        return;
 }
 
@@ -1902,7 +1882,7 @@ __setup("no_timer_check", notimercheck);
  *     - if this function detects that timer IRQs are defunct, then we fall
  *       back to ISA timer IRQs
  */
-int __init timer_irq_works(void)
+static int __init timer_irq_works(void)
 {
        unsigned long t1 = jiffies;
 
index ba44d40b066d0588f07f9dca68b84f4d197615c3..dd2b97fc00b2ad8c76fe2f7bce0a2164e4866ae6 100644 (file)
@@ -149,15 +149,11 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
 
 #ifdef CONFIG_4KSTACKS
 
-/*
- * These should really be __section__(".bss.page_aligned") as well, but
- * gcc's 3.0 and earlier don't handle that correctly.
- */
 static char softirq_stack[NR_CPUS * THREAD_SIZE]
-               __attribute__((__aligned__(THREAD_SIZE)));
+               __attribute__((__section__(".bss.page_aligned")));
 
 static char hardirq_stack[NR_CPUS * THREAD_SIZE]
-               __attribute__((__aligned__(THREAD_SIZE)));
+               __attribute__((__section__(".bss.page_aligned")));
 
 /*
  * allocate per-cpu stacks for hardirq and for softirq processing
index dde828a333c3e8355e49d0a3ed8d562b3071d4f9..448a50b1324c94636d1a2b71f672f901991eedc6 100644 (file)
@@ -35,6 +35,7 @@
 #include <asm/cacheflush.h>
 #include <asm/desc.h>
 #include <asm/uaccess.h>
+#include <asm/alternative.h>
 
 void jprobe_return_end(void);
 
@@ -169,16 +170,12 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
 
 void __kprobes arch_arm_kprobe(struct kprobe *p)
 {
-       *p->addr = BREAKPOINT_INSTRUCTION;
-       flush_icache_range((unsigned long) p->addr,
-                          (unsigned long) p->addr + sizeof(kprobe_opcode_t));
+       text_poke(p->addr, ((unsigned char []){BREAKPOINT_INSTRUCTION}), 1);
 }
 
 void __kprobes arch_disarm_kprobe(struct kprobe *p)
 {
-       *p->addr = p->opcode;
-       flush_icache_range((unsigned long) p->addr,
-                          (unsigned long) p->addr + sizeof(kprobe_opcode_t));
+       text_poke(p->addr, &p->opcode, 1);
 }
 
 void __kprobes arch_remove_kprobe(struct kprobe *p)
index 03b7f5584d713b60216c25d5ad73df7dbf363e39..99beac7f96ceb4df737c9c02c304ba9d9999710f 100644 (file)
@@ -353,7 +353,7 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
         * Take the local apic timer and PIT/HPET into account. We don't
         * know which one is active, when we have highres/dyntick on
         */
-       sum = per_cpu(irq_stat, cpu).apic_timer_irqs + kstat_irqs(0);
+       sum = per_cpu(irq_stat, cpu).apic_timer_irqs + kstat_cpu(cpu).irqs[0];
 
        /* if the none of the timers isn't firing, this cpu isn't doing much */
        if (!touched && last_irq_sums[cpu] == sum) {
index 53f07a8275e3a9b39ba4581e8f8a03bb75e336ce..ea962c0667d50edb07df04e43a3ab1884dd7df1d 100644 (file)
@@ -124,20 +124,28 @@ unsigned paravirt_patch_ignore(unsigned len)
        return len;
 }
 
+struct branch {
+       unsigned char opcode;
+       u32 delta;
+} __attribute__((packed));
+
 unsigned paravirt_patch_call(void *target, u16 tgt_clobbers,
                             void *site, u16 site_clobbers,
                             unsigned len)
 {
        unsigned char *call = site;
        unsigned long delta = (unsigned long)target - (unsigned long)(call+5);
+       struct branch b;
 
        if (tgt_clobbers & ~site_clobbers)
                return len;     /* target would clobber too much for this site */
        if (len < 5)
                return len;     /* call too long for patch site */
 
-       *call++ = 0xe8;         /* call */
-       *(unsigned long *)call = delta;
+       b.opcode = 0xe8; /* call */
+       b.delta = delta;
+       BUILD_BUG_ON(sizeof(b) != 5);
+       text_poke(call, (unsigned char *)&b, 5);
 
        return 5;
 }
@@ -146,12 +154,14 @@ unsigned paravirt_patch_jmp(void *target, void *site, unsigned len)
 {
        unsigned char *jmp = site;
        unsigned long delta = (unsigned long)target - (unsigned long)(jmp+5);
+       struct branch b;
 
        if (len < 5)
                return len;     /* call too long for patch site */
 
-       *jmp++ = 0xe9;          /* jmp */
-       *(unsigned long *)jmp = delta;
+       b.opcode = 0xe9;        /* jmp */
+       b.delta = delta;
+       text_poke(jmp, (unsigned char *)&b, 5);
 
        return 5;
 }
index 6c49acb9698210849ed6e74090717c7499a21562..84664710b78442d1bad1dd220c6de6f9d0033a63 100644 (file)
@@ -300,6 +300,7 @@ early_param("idle", idle_setup);
 void show_regs(struct pt_regs * regs)
 {
        unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
+       unsigned long d0, d1, d2, d3, d6, d7;
 
        printk("\n");
        printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
@@ -324,6 +325,17 @@ void show_regs(struct pt_regs * regs)
        cr3 = read_cr3();
        cr4 = read_cr4_safe();
        printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
+
+       get_debugreg(d0, 0);
+       get_debugreg(d1, 1);
+       get_debugreg(d2, 2);
+       get_debugreg(d3, 3);
+       printk("DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
+                       d0, d1, d2, d3);
+       get_debugreg(d6, 6);
+       get_debugreg(d7, 7);
+       printk("DR6: %08lx DR7: %08lx\n", d6, d7);
+
        show_trace(NULL, regs, &regs->esp);
 }
 
index 5513f8d5b5becff34c9e77cceb77835aeb90b0ec..0d796248866cfcf892f53b5d79717aa9ecf9e10f 100644 (file)
@@ -113,6 +113,15 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"),
                },
        },
+       {       /* Handle problems with rebooting on Dell Optiplex 745's SFF*/
+               .callback = set_bios_reboot,
+               .ident = "Dell OptiPlex 745",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 745"),
+                       DMI_MATCH(DMI_BOARD_NAME, "0WF810"),
+               },
+       },
        {       /* Handle problems with rebooting on Dell 2400's */
                .callback = set_bios_reboot,
                .ident = "Dell PowerEdge 2400",
index 74871d066c2b0ce85351d36748865f293f620759..d474cd639bcb8ece22f706d285950926a50541ac 100644 (file)
@@ -273,18 +273,18 @@ unsigned long __init find_max_low_pfn(void)
                printk(KERN_WARNING "Warning only %ldMB will be used.\n",
                                        MAXMEM>>20);
                if (max_pfn > MAX_NONPAE_PFN)
-                       printk(KERN_WARNING "Use a PAE enabled kernel.\n");
+                       printk(KERN_WARNING "Use a HIGHMEM64G enabled kernel.\n");
                else
                        printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
                max_pfn = MAXMEM_PFN;
 #else /* !CONFIG_HIGHMEM */
-#ifndef CONFIG_X86_PAE
+#ifndef CONFIG_HIGHMEM64G
                if (max_pfn > MAX_NONPAE_PFN) {
                        max_pfn = MAX_NONPAE_PFN;
                        printk(KERN_WARNING "Warning only 4GB will be used.\n");
-                       printk(KERN_WARNING "Use a PAE enabled kernel.\n");
+                       printk(KERN_WARNING "Use a HIGHMEM64G enabled kernel.\n");
                }
-#endif /* !CONFIG_X86_PAE */
+#endif /* !CONFIG_HIGHMEM64G */
 #endif /* !CONFIG_HIGHMEM */
        } else {
                if (highmem_pages == -1)
@@ -466,7 +466,7 @@ void __init setup_bootmem_allocator(void)
  *
  * This should all compile down to nothing when NUMA is off.
  */
-void __init remapped_pgdat_init(void)
+static void __init remapped_pgdat_init(void)
 {
        int nid;
 
@@ -640,6 +640,7 @@ void __init setup_arch(char **cmdline_p)
 #endif
 
        e820_register_memory();
+       e820_mark_nosave_regions();
 
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
index d574e38f0f774e67896ad8cfbd8420faca9f9ec9..f5dd85656c1890eb93f8d25fc68fb2d97132e917 100644 (file)
@@ -199,6 +199,13 @@ asmlinkage int sys_sigreturn(unsigned long __unused)
        return eax;
 
 badframe:
+       if (show_unhandled_signals && printk_ratelimit())
+               printk("%s%s[%d] bad frame in sigreturn frame:%p eip:%lx"
+                      " esp:%lx oeax:%lx\n",
+                   current->pid > 1 ? KERN_INFO : KERN_EMERG,
+                   current->comm, current->pid, frame, regs->eip,
+                   regs->esp, regs->orig_eax);
+
        force_sig(SIGSEGV, current);
        return 0;
 }      
index 5910d3fac561d5f33d26df53f63fad2ac0c8d2fe..e4f61d1c6248d8116810e122651f3fb109b5b78e 100644 (file)
@@ -308,7 +308,7 @@ cpumask_t cpu_coregroup_map(int cpu)
 /* representing cpus for which sibling maps can be computed */
 static cpumask_t cpu_sibling_setup_map;
 
-void set_cpu_sibling_map(int cpu)
+void __cpuinit set_cpu_sibling_map(int cpu)
 {
        int i;
        struct cpuinfo_x86 *c = cpu_data;
index ff4ee6f3326b300a5504370b8720b4263d311f6e..6deb159d08e0cf761fe402ed5ab355bcfc9e3d4b 100644 (file)
@@ -336,7 +336,9 @@ struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
 
 int in_gate_area(struct task_struct *task, unsigned long addr)
 {
-       return 0;
+       const struct vm_area_struct *vma = get_gate_vma(task);
+
+       return vma && addr >= vma->vm_start && addr < vma->vm_end;
 }
 
 int in_gate_area_no_task(unsigned long addr)
index a665df61f08c0695e2c94b53fa9429c27e043f1e..19a6c678d02ecc1448cff0bf0b6f03b997d478c0 100644 (file)
@@ -207,55 +207,9 @@ unsigned long read_persistent_clock(void)
        return retval;
 }
 
-static void sync_cmos_clock(unsigned long dummy);
-
-static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0);
-int no_sync_cmos_clock;
-
-static void sync_cmos_clock(unsigned long dummy)
-{
-       struct timeval now, next;
-       int fail = 1;
-
-       /*
-        * If we have an externally synchronized Linux clock, then update
-        * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
-        * called as close as possible to 500 ms before the new second starts.
-        * This code is run on a timer.  If the clock is set, that timer
-        * may not expire at the correct time.  Thus, we adjust...
-        */
-       if (!ntp_synced())
-               /*
-                * Not synced, exit, do not restart a timer (if one is
-                * running, let it run out).
-                */
-               return;
-
-       do_gettimeofday(&now);
-       if (now.tv_usec >= USEC_AFTER - ((unsigned) TICK_SIZE) / 2 &&
-           now.tv_usec <= USEC_BEFORE + ((unsigned) TICK_SIZE) / 2)
-               fail = set_rtc_mmss(now.tv_sec);
-
-       next.tv_usec = USEC_AFTER - now.tv_usec;
-       if (next.tv_usec <= 0)
-               next.tv_usec += USEC_PER_SEC;
-
-       if (!fail)
-               next.tv_sec = 659;
-       else
-               next.tv_sec = 0;
-
-       if (next.tv_usec >= USEC_PER_SEC) {
-               next.tv_sec++;
-               next.tv_usec -= USEC_PER_SEC;
-       }
-       mod_timer(&sync_cmos_timer, jiffies + timeval_to_jiffies(&next));
-}
-
-void notify_arch_cmos_timer(void)
+int update_persistent_clock(struct timespec now)
 {
-       if (!no_sync_cmos_clock)
-               mod_timer(&sync_cmos_timer, jiffies + 1);
+       return set_rtc_mmss(now.tv_sec);
 }
 
 extern void (*late_time_init)(void);
index 3e7753c78b9b536fc27ee660ced4c5acdee819d7..cfffe3dd9e838315089c9461a49b0fa2b6aef12b 100644 (file)
@@ -152,7 +152,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
        if (!stack) {
                unsigned long dummy;
                stack = &dummy;
-               if (task && task != current)
+               if (task != current)
                        stack = (unsigned long *)task->thread.esp;
        }
 
@@ -211,6 +211,7 @@ static void print_trace_address(void *data, unsigned long addr)
 {
        printk("%s [<%08lx>] ", (char *)data, addr);
        print_symbol("%s\n", addr);
+       touch_nmi_watchdog();
 }
 
 static struct stacktrace_ops print_trace_ops = {
@@ -617,6 +618,13 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs,
 
        current->thread.error_code = error_code;
        current->thread.trap_no = 13;
+       if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
+           printk_ratelimit())
+               printk(KERN_INFO
+                   "%s[%d] general protection eip:%lx esp:%lx error:%lx\n",
+                   current->comm, current->pid,
+                   regs->eip, regs->esp, error_code);
+
        force_sig(SIGSEGV, current);
        return;
 
@@ -767,6 +775,8 @@ static __kprobes void default_do_nmi(struct pt_regs * regs)
        reassert_nmi();
 }
 
+static int ignore_nmis;
+
 fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code)
 {
        int cpu;
@@ -777,11 +787,24 @@ fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code)
 
        ++nmi_count(cpu);
 
-       default_do_nmi(regs);
+       if (!ignore_nmis)
+               default_do_nmi(regs);
 
        nmi_exit();
 }
 
+void stop_nmi(void)
+{
+       acpi_nmi_disable();
+       ignore_nmis++;
+}
+
+void restart_nmi(void)
+{
+       ignore_nmis--;
+       acpi_nmi_enable();
+}
+
 #ifdef CONFIG_KPROBES
 fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code)
 {
index f9b845f4e6923818817dfc87f32c626a0ff6bbe4..b1b5ab08b26eaaa26a955eb93f9502f7ed8e89ce 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/apicdef.h>
 #include <asm/apic.h>
 #include <asm/timer.h>
+#include <asm/i8253.h>
 
 #include <irq_vectors.h>
 #include "io_ports.h"
@@ -142,6 +143,7 @@ static void vmi_timer_set_mode(enum clock_event_mode mode,
 
        switch (mode) {
        case CLOCK_EVT_MODE_ONESHOT:
+       case CLOCK_EVT_MODE_RESUME:
                break;
        case CLOCK_EVT_MODE_PERIODIC:
                cycles_per_hz = vmi_timer_ops.get_cycle_frequency();
index 22d8ac5815f03475c6abb7376d7994e92fa57a51..4d105fdfe817f2c30ba5e588ff847867149f3a35 100644 (file)
@@ -4,7 +4,7 @@
 
 
 lib-y = checksum.o delay.o usercopy.o getuser.o putuser.o memcpy.o strstr.o \
-       bitops.o semaphore.o
+       bitops.o semaphore.o string.o
 
 lib-$(CONFIG_X86_USE_3DNOW) += mmx.o
 
diff --git a/arch/i386/lib/string.c b/arch/i386/lib/string.c
new file mode 100644 (file)
index 0000000..2c773fe
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * Most of the string-functions are rather heavily hand-optimized,
+ * see especially strsep,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ * AK: On P4 and K7 using non string instruction implementations might be faster
+ * for large memory blocks. But most of them are unlikely to be used on large
+ * strings.
+ */
+
+#include <linux/string.h>
+#include <linux/module.h>
+
+#ifdef __HAVE_ARCH_STRCPY
+char *strcpy(char * dest,const char *src)
+{
+       int d0, d1, d2;
+       asm volatile( "1:\tlodsb\n\t"
+               "stosb\n\t"
+               "testb %%al,%%al\n\t"
+               "jne 1b"
+               : "=&S" (d0), "=&D" (d1), "=&a" (d2)
+               :"0" (src),"1" (dest) : "memory");
+       return dest;
+}
+EXPORT_SYMBOL(strcpy);
+#endif
+
+#ifdef __HAVE_ARCH_STRNCPY
+char *strncpy(char * dest,const char *src,size_t count)
+{
+       int d0, d1, d2, d3;
+       asm volatile( "1:\tdecl %2\n\t"
+               "js 2f\n\t"
+               "lodsb\n\t"
+               "stosb\n\t"
+               "testb %%al,%%al\n\t"
+               "jne 1b\n\t"
+               "rep\n\t"
+               "stosb\n"
+               "2:"
+               : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
+               :"0" (src),"1" (dest),"2" (count) : "memory");
+       return dest;
+}
+EXPORT_SYMBOL(strncpy);
+#endif
+
+#ifdef __HAVE_ARCH_STRCAT
+char *strcat(char * dest,const char * src)
+{
+       int d0, d1, d2, d3;
+       asm volatile( "repne\n\t"
+               "scasb\n\t"
+               "decl %1\n"
+               "1:\tlodsb\n\t"
+               "stosb\n\t"
+               "testb %%al,%%al\n\t"
+               "jne 1b"
+               : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
+               : "0" (src), "1" (dest), "2" (0), "3" (0xffffffffu): "memory");
+       return dest;
+}
+EXPORT_SYMBOL(strcat);
+#endif
+
+#ifdef __HAVE_ARCH_STRNCAT
+char *strncat(char * dest,const char * src,size_t count)
+{
+       int d0, d1, d2, d3;
+       asm volatile( "repne\n\t"
+               "scasb\n\t"
+               "decl %1\n\t"
+               "movl %8,%3\n"
+               "1:\tdecl %3\n\t"
+               "js 2f\n\t"
+               "lodsb\n\t"
+               "stosb\n\t"
+               "testb %%al,%%al\n\t"
+               "jne 1b\n"
+               "2:\txorl %2,%2\n\t"
+               "stosb"
+               : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
+               : "0" (src),"1" (dest),"2" (0),"3" (0xffffffffu), "g" (count)
+               : "memory");
+       return dest;
+}
+EXPORT_SYMBOL(strncat);
+#endif
+
+#ifdef __HAVE_ARCH_STRCMP
+int strcmp(const char * cs,const char * ct)
+{
+       int d0, d1;
+       int res;
+       asm volatile( "1:\tlodsb\n\t"
+               "scasb\n\t"
+               "jne 2f\n\t"
+               "testb %%al,%%al\n\t"
+               "jne 1b\n\t"
+               "xorl %%eax,%%eax\n\t"
+               "jmp 3f\n"
+               "2:\tsbbl %%eax,%%eax\n\t"
+               "orb $1,%%al\n"
+               "3:"
+               :"=a" (res), "=&S" (d0), "=&D" (d1)
+               :"1" (cs),"2" (ct)
+               :"memory");
+       return res;
+}
+EXPORT_SYMBOL(strcmp);
+#endif
+
+#ifdef __HAVE_ARCH_STRNCMP
+int strncmp(const char * cs,const char * ct,size_t count)
+{
+       int res;
+       int d0, d1, d2;
+       asm volatile( "1:\tdecl %3\n\t"
+               "js 2f\n\t"
+               "lodsb\n\t"
+               "scasb\n\t"
+               "jne 3f\n\t"
+               "testb %%al,%%al\n\t"
+               "jne 1b\n"
+               "2:\txorl %%eax,%%eax\n\t"
+               "jmp 4f\n"
+               "3:\tsbbl %%eax,%%eax\n\t"
+               "orb $1,%%al\n"
+               "4:"
+               :"=a" (res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
+               :"1" (cs),"2" (ct),"3" (count)
+               :"memory");
+       return res;
+}
+EXPORT_SYMBOL(strncmp);
+#endif
+
+#ifdef __HAVE_ARCH_STRCHR
+char *strchr(const char * s, int c)
+{
+       int d0;
+       char * res;
+       asm volatile( "movb %%al,%%ah\n"
+               "1:\tlodsb\n\t"
+               "cmpb %%ah,%%al\n\t"
+               "je 2f\n\t"
+               "testb %%al,%%al\n\t"
+               "jne 1b\n\t"
+               "movl $1,%1\n"
+               "2:\tmovl %1,%0\n\t"
+               "decl %0"
+               :"=a" (res), "=&S" (d0)
+               :"1" (s),"0" (c)
+               :"memory");
+       return res;
+}
+EXPORT_SYMBOL(strchr);
+#endif
+
+#ifdef __HAVE_ARCH_STRRCHR
+char *strrchr(const char * s, int c)
+{
+       int d0, d1;
+       char * res;
+       asm volatile( "movb %%al,%%ah\n"
+               "1:\tlodsb\n\t"
+               "cmpb %%ah,%%al\n\t"
+               "jne 2f\n\t"
+               "leal -1(%%esi),%0\n"
+               "2:\ttestb %%al,%%al\n\t"
+               "jne 1b"
+               :"=g" (res), "=&S" (d0), "=&a" (d1)
+               :"0" (0),"1" (s),"2" (c)
+               :"memory");
+       return res;
+}
+EXPORT_SYMBOL(strrchr);
+#endif
+
+#ifdef __HAVE_ARCH_STRLEN
+size_t strlen(const char * s)
+{
+       int d0;
+       int res;
+       asm volatile( "repne\n\t"
+               "scasb\n\t"
+               "notl %0\n\t"
+               "decl %0"
+               :"=c" (res), "=&D" (d0)
+               :"1" (s),"a" (0), "0" (0xffffffffu)
+               :"memory");
+       return res;
+}
+EXPORT_SYMBOL(strlen);
+#endif
+
+#ifdef __HAVE_ARCH_MEMCHR
+void *memchr(const void *cs,int c,size_t count)
+{
+       int d0;
+       void *res;
+       if (!count)
+               return NULL;
+       asm volatile( "repne\n\t"
+               "scasb\n\t"
+               "je 1f\n\t"
+               "movl $1,%0\n"
+               "1:\tdecl %0"
+               :"=D" (res), "=&c" (d0)
+               :"a" (c),"0" (cs),"1" (count)
+               :"memory");
+       return res;
+}
+EXPORT_SYMBOL(memchr);
+#endif
+
+#ifdef __HAVE_ARCH_MEMSCAN
+void *memscan(void * addr, int c, size_t size)
+{
+       if (!size)
+               return addr;
+       asm volatile("repnz; scasb\n\t"
+           "jnz 1f\n\t"
+           "dec %%edi\n"
+           "1:"
+           : "=D" (addr), "=c" (size)
+           : "0" (addr), "1" (size), "a" (c)
+           : "memory");
+       return addr;
+}
+EXPORT_SYMBOL(memscan);
+#endif
+
+#ifdef __HAVE_ARCH_STRNLEN
+size_t strnlen(const char *s, size_t count)
+{
+       int d0;
+       int res;
+       asm volatile( "movl %2,%0\n\t"
+               "jmp 2f\n"
+               "1:\tcmpb $0,(%0)\n\t"
+               "je 3f\n\t"
+               "incl %0\n"
+               "2:\tdecl %1\n\t"
+               "cmpl $-1,%1\n\t"
+               "jne 1b\n"
+               "3:\tsubl %2,%0"
+               :"=a" (res), "=&d" (d0)
+               :"c" (s),"1" (count)
+               :"memory");
+       return res;
+}
+EXPORT_SYMBOL(strnlen);
+#endif
index e92a10124935c006a22a55775b0aee755b2b08c3..01ffdd4964f08e9bec86c5ae759da9f5cbe8270a 100644 (file)
@@ -283,6 +283,8 @@ static inline int vmalloc_fault(unsigned long address)
        return 0;
 }
 
+int show_unhandled_signals = 1;
+
 /*
  * This routine handles page faults.  It determines the address,
  * and the problem, and then passes it off to one of the appropriate
@@ -469,6 +471,14 @@ bad_area_nosemaphore:
                if (is_prefetch(regs, address, error_code))
                        return;
 
+               if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
+                   printk_ratelimit()) {
+                       printk("%s%s[%d]: segfault at %08lx eip %08lx "
+                           "esp %08lx error %lx\n",
+                           tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
+                           tsk->comm, tsk->pid, address, regs->eip,
+                           regs->esp, error_code);
+               }
                tsk->thread.cr2 = address;
                /* Kernel addresses are always protection faults */
                tsk->thread.error_code = error_code | (address >= TASK_SIZE);
index 6e72f22e6bbd840adf0311d55d2551afca690f0f..c3b9905af2d5024b71451e796c052a2ad1813718 100644 (file)
@@ -471,6 +471,10 @@ void zap_low_mappings (void)
        flush_tlb_all();
 }
 
+int nx_enabled = 0;
+
+#ifdef CONFIG_X86_PAE
+
 static int disable_nx __initdata = 0;
 u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
 EXPORT_SYMBOL_GPL(__supported_pte_mask);
@@ -500,9 +504,6 @@ static int __init noexec_setup(char *str)
 }
 early_param("noexec", noexec_setup);
 
-int nx_enabled = 0;
-#ifdef CONFIG_X86_PAE
-
 static void __init set_nx(void)
 {
        unsigned int v[4], l, h;
@@ -799,17 +800,9 @@ void mark_rodata_ro(void)
        unsigned long start = PFN_ALIGN(_text);
        unsigned long size = PFN_ALIGN(_etext) - start;
 
-#ifndef CONFIG_KPROBES
-#ifdef CONFIG_HOTPLUG_CPU
-       /* It must still be possible to apply SMP alternatives. */
-       if (num_possible_cpus() <= 1)
-#endif
-       {
-               change_page_attr(virt_to_page(start),
-                                size >> PAGE_SHIFT, PAGE_KERNEL_RX);
-               printk("Write protecting the kernel text: %luk\n", size >> 10);
-       }
-#endif
+       change_page_attr(virt_to_page(start),
+                        size >> PAGE_SHIFT, PAGE_KERNEL_RX);
+       printk("Write protecting the kernel text: %luk\n", size >> 10);
        start += size;
        size = (unsigned long)__end_rodata - start;
        change_page_attr(virt_to_page(start),
index fff08ae7b5ed57c61767615decca493e3e9c7686..0b278315d73796e1707b94fdaa1bbba35a088881 100644 (file)
@@ -196,7 +196,7 @@ void iounmap(volatile void __iomem *addr)
        /* Reset the direct mapping. Can block */
        if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) {
                change_page_attr(virt_to_page(__va(p->phys_addr)),
-                                p->size >> PAGE_SHIFT,
+                                get_vm_area_size(p) >> PAGE_SHIFT,
                                 PAGE_KERNEL);
                global_flush_tlb();
        } 
index 37992ffb163318f78a64fb4899d3d26ea3142a7a..8927222b3ab2595202afcbb5f88810a8f8716a02 100644 (file)
@@ -82,7 +82,7 @@ static void flush_kernel_map(void *arg)
        struct page *p;
 
        /* High level code is not ready for clflush yet */
-       if (0 && cpu_has_clflush) {
+       if (cpu_has_clflush) {
                list_for_each_entry (p, lh, lru)
                        cache_flush_page(p);
        } else if (boot_cpu_data.x86_model >= 4)
@@ -136,6 +136,12 @@ static inline void revert_page(struct page *kpte_page, unsigned long address)
                            ref_prot));
 }
 
+static inline void save_page(struct page *kpte_page)
+{
+       if (!test_and_set_bit(PG_arch_1, &kpte_page->flags))
+               list_add(&kpte_page->lru, &df_list);
+}
+
 static int
 __change_page_attr(struct page *page, pgprot_t prot)
 { 
@@ -150,6 +156,9 @@ __change_page_attr(struct page *page, pgprot_t prot)
        if (!kpte)
                return -EINVAL;
        kpte_page = virt_to_page(kpte);
+       BUG_ON(PageLRU(kpte_page));
+       BUG_ON(PageCompound(kpte_page));
+
        if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) { 
                if (!pte_huge(*kpte)) {
                        set_pte_atomic(kpte, mk_pte(page, prot)); 
@@ -179,11 +188,11 @@ __change_page_attr(struct page *page, pgprot_t prot)
         * time (not via split_large_page) and in turn we must not
         * replace it with a largepage.
         */
+
+       save_page(kpte_page);
        if (!PageReserved(kpte_page)) {
                if (cpu_has_pse && (page_private(kpte_page) == 0)) {
-                       ClearPagePrivate(kpte_page);
                        paravirt_release_pt(page_to_pfn(kpte_page));
-                       list_add(&kpte_page->lru, &df_list);
                        revert_page(kpte_page, address);
                }
        }
@@ -236,6 +245,11 @@ void global_flush_tlb(void)
        spin_unlock_irq(&cpa_lock);
        flush_map(&l);
        list_for_each_entry_safe(pg, next, &l, lru) {
+               list_del(&pg->lru);
+               clear_bit(PG_arch_1, &pg->flags);
+               if (PageReserved(pg) || !cpu_has_pse || page_private(pg) != 0)
+                       continue;
+               ClearPagePrivate(pg);
                __free_page(pg);
        }
 }
index 8d7c0864cc04e664ce65a7c3f7e7fd6c2e6b8b63..01437c46baae9302e9770f4925d47cd14d8f0f78 100644 (file)
@@ -235,7 +235,7 @@ static inline void pgd_list_del(pgd_t *pgd)
 
 #if (PTRS_PER_PMD == 1)
 /* Non-PAE pgd constructor */
-void pgd_ctor(void *pgd)
+static void pgd_ctor(void *pgd)
 {
        unsigned long flags;
 
@@ -257,7 +257,7 @@ void pgd_ctor(void *pgd)
 }
 #else  /* PTRS_PER_PMD > 1 */
 /* PAE pgd constructor */
-void pgd_ctor(void *pgd)
+static void pgd_ctor(void *pgd)
 {
        /* PAE, kernel PMD may be shared */
 
@@ -276,7 +276,7 @@ void pgd_ctor(void *pgd)
 }
 #endif /* PTRS_PER_PMD */
 
-void pgd_dtor(void *pgd)
+static void pgd_dtor(void *pgd)
 {
        unsigned long flags; /* can be called from interrupt context */
 
index b33aea845f5847ffcdf6fafe10f6c0659e9b7959..bc8a44bddaa7b7f8ab83638fbfa38231d631349b 100644 (file)
@@ -8,20 +8,42 @@
 struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum)
 {
        struct pci_bus *bus;
+       struct pci_sysdata *sd;
+       int pxm;
+
+       /* Allocate per-root-bus (not per bus) arch-specific data.
+        * TODO: leak; this memory is never freed.
+        * It's arguable whether it's worth the trouble to care.
+        */
+       sd = kzalloc(sizeof(*sd), GFP_KERNEL);
+       if (!sd) {
+               printk(KERN_ERR "PCI: OOM, not probing PCI bus %02x\n", busnum);
+               return NULL;
+       }
 
        if (domain != 0) {
                printk(KERN_WARNING "PCI: Multiple domains not supported\n");
+               kfree(sd);
                return NULL;
        }
 
-       bus = pcibios_scan_root(busnum);
+       sd->node = -1;
+
+       pxm = acpi_get_pxm(device->handle);
+#ifdef CONFIG_ACPI_NUMA
+       if (pxm >= 0)
+               sd->node = pxm_to_node(pxm);
+#endif
+
+       bus = pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd);
+       if (!bus)
+               kfree(sd);
+
 #ifdef CONFIG_ACPI_NUMA
        if (bus != NULL) {
-               int pxm = acpi_get_pxm(device->handle);
                if (pxm >= 0) {
-                       bus->sysdata = (void *)(unsigned long)pxm_to_node(pxm);
-                       printk("bus %d -> pxm %d -> node %ld\n",
-                               busnum, pxm, (long)(bus->sysdata));
+                       printk("bus %d -> pxm %d -> node %d\n",
+                               busnum, pxm, sd->node);
                }
        }
 #endif
index 3f78d4d8ecf31a00798e00790e52a81404a4cee0..85503deeda46cbd336c5cf3e15bcb6a4998b8d10 100644 (file)
@@ -293,6 +293,7 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
 struct pci_bus * __devinit pcibios_scan_root(int busnum)
 {
        struct pci_bus *bus = NULL;
+       struct pci_sysdata *sd;
 
        dmi_check_system(pciprobe_dmi_table);
 
@@ -303,9 +304,19 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum)
                }
        }
 
+       /* Allocate per-root-bus (not per bus) arch-specific data.
+        * TODO: leak; this memory is never freed.
+        * It's arguable whether it's worth the trouble to care.
+        */
+       sd = kzalloc(sizeof(*sd), GFP_KERNEL);
+       if (!sd) {
+               printk(KERN_ERR "PCI: OOM, not probing PCI bus %02x\n", busnum);
+               return NULL;
+       }
+
        printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum);
 
-       return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL);
+       return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd);
 }
 
 extern u8 pci_cache_line_size;
index c7cabeed4d7b589cc9637ab326d71ae68efba1da..4df637e34f813da1e47839c75d9cd3fc502bc560 100644 (file)
@@ -24,6 +24,9 @@
 
 DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
 
+/* Indicate if the mmcfg resources have been placed into the resource table. */
+static int __initdata pci_mmcfg_resources_inserted;
+
 /* K8 systems have some devices (typically in the builtin northbridge)
    that are only accessible using type1
    Normally this can be expressed in the MCFG by not listing them
@@ -170,7 +173,7 @@ static int __init pci_mmcfg_check_hostbridge(void)
        return name != NULL;
 }
 
-static void __init pci_mmcfg_insert_resources(void)
+static void __init pci_mmcfg_insert_resources(unsigned long resource_flags)
 {
 #define PCI_MMCFG_RESOURCE_NAME_LEN 19
        int i;
@@ -194,10 +197,13 @@ static void __init pci_mmcfg_insert_resources(void)
                         cfg->pci_segment);
                res->start = cfg->address;
                res->end = res->start + (num_buses << 20) - 1;
-               res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+               res->flags = IORESOURCE_MEM | resource_flags;
                insert_resource(&iomem_resource, res);
                names += PCI_MMCFG_RESOURCE_NAME_LEN;
        }
+
+       /* Mark that the resources have been inserted. */
+       pci_mmcfg_resources_inserted = 1;
 }
 
 static void __init pci_mmcfg_reject_broken(int type)
@@ -267,7 +273,43 @@ void __init pci_mmcfg_init(int type)
                if (type == 1)
                        unreachable_devices();
                if (known_bridge)
-                       pci_mmcfg_insert_resources();
+                       pci_mmcfg_insert_resources(IORESOURCE_BUSY);
                pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
+       } else {
+               /*
+                * Signal not to attempt to insert mmcfg resources because
+                * the architecture mmcfg setup could not initialize.
+                */
+               pci_mmcfg_resources_inserted = 1;
        }
 }
+
+static int __init pci_mmcfg_late_insert_resources(void)
+{
+       /*
+        * If resources are already inserted or we are not using MMCONFIG,
+        * don't insert the resources.
+        */
+       if ((pci_mmcfg_resources_inserted == 1) ||
+           (pci_probe & PCI_PROBE_MMCONF) == 0 ||
+           (pci_mmcfg_config_num == 0) ||
+           (pci_mmcfg_config == NULL) ||
+           (pci_mmcfg_config[0].address == 0))
+               return 1;
+
+       /*
+        * Attempt to insert the mmcfg resources but not with the busy flag
+        * marked so it won't cause request errors when __request_region is
+        * called.
+        */
+       pci_mmcfg_insert_resources(0);
+
+       return 0;
+}
+
+/*
+ * Perform MMCONFIG resource insertion after PCI initialization to allow for
+ * misprogrammed MCFG tables that state larger sizes but actually conflict
+ * with other system resources.
+ */
+late_initcall(pci_mmcfg_late_insert_resources);
index 51fdabf1fd4dd813645737cbab05c6894227d0ae..dfd6db69ead5072dd5a7430ad4750285d44d7031 100644 (file)
@@ -412,6 +412,7 @@ static void xen_timerop_set_mode(enum clock_event_mode mode,
                break;
 
        case CLOCK_EVT_MODE_ONESHOT:
+       case CLOCK_EVT_MODE_RESUME:
                break;
 
        case CLOCK_EVT_MODE_UNUSED:
@@ -474,6 +475,8 @@ static void xen_vcpuop_set_mode(enum clock_event_mode mode,
                    HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, cpu, NULL))
                        BUG();
                break;
+       case CLOCK_EVT_MODE_RESUME:
+               break;
        }
 }
 
index 2998d55a001790b96196b04dabd3718067bc9629..bc71f3bc40141019214201586ed292b743f81dc3 100644 (file)
@@ -7,6 +7,7 @@
 #include <asm/boot.h>
 #include <xen/interface/elfnote.h>
 
+       .section .init.text
 ENTRY(startup_xen)
        movl %esi,xen_start_info
        cld
@@ -19,6 +20,7 @@ ENTRY(hypercall_page)
        .skip 0x1000
 .popsection
 
+       .section .text
        ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz "linux")
        ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz "2.6")
        ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz "xen-3.0")
index e1189ba1ca5e279a450533cc519bdde97809fb53..1cfab326fb7e33260c88c3a533bc01a61d267540 100644 (file)
@@ -226,7 +226,7 @@ elf32_set_personality (void)
 }
 
 static unsigned long
-elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type, unsigned long unused)
+elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
 {
        unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK;
 
index 60d4d75f5798692b7a4ce4c9c019df6cf323650e..2b412454cb419fb91d898df93fcd0ffe507b6c32 100644 (file)
@@ -326,6 +326,10 @@ void disable_irq(unsigned int irq)
 
 EXPORT_SYMBOL(disable_irq);
 
+void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq")));
+
+EXPORT_SYMBOL(disable_irq_nosync);
+
 int m68k_irq_startup(unsigned int irq)
 {
        if (irq <= IRQ_AUTO_7)
index 1a6d64a68df560ab54ec62e0b0ffb0743beeea1e..a55c2735f759040dd713f9fe56d33d280554c892 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "ppc_asm.h"
 
+       .machine "ppc64"
+
        .text
 
 /*
index c8b7df3210d1dcd8abac2916bd63f0fc220fe7b3..585965f7e6a89edc988e02f38e802e5de0e23627 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "ppc_asm.h"
 
+       .machine "ppc64"
+
 /*
  * The PS3 hypervisor uses a 64 bit "C" language calling convention.
  * The routines here marshal arguments between the 32 bit wrapper
index fb504a714625faeb08d07d7f308ab651e8e935fc..858f865f2d59da7deb96c53d6cb16483330443e8 100644 (file)
@@ -48,7 +48,7 @@ CONFIG_PPC_STD_MMU_32=y
 # CONFIG_PPC_MM_SLICES is not set
 # CONFIG_SMP is not set
 CONFIG_NOT_COHERENT_CACHE=y
-CONFIG_CONFIG_CHECK_CACHE_COHERENCY=y
+CONFIG_CHECK_CACHE_COHERENCY=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
index 94b4a028232a957b5e65321204de4cdf327f5c18..fe7d1255e11ea903dbd01f41e56c839ccb04f703 100644 (file)
@@ -166,7 +166,7 @@ int pcibios_add_platform_entries(struct pci_dev *pdev)
 
 }
 
-char __init *pcibios_setup(char *str)
+char __devinit *pcibios_setup(char *str)
 {
        return str;
 }
index bdcd23d8d8b99f8648b61a63aa4ece60f66c375a..a38197b12d3e991a22dd06850911cecdd1869cce 100644 (file)
@@ -1218,7 +1218,7 @@ void of_attach_node(struct device_node *np)
  * a reference to the node.  The memory associated with the node
  * is not freed until its refcount goes to zero.
  */
-void of_detach_node(const struct device_node *np)
+void of_detach_node(struct device_node *np)
 {
        struct device_node *parent;
 
index d577b71db37549433ca2f36aa6ad0bcea8cd3a5a..087c92f2a3ebd75bac059df639c9bd1d75d92081 100644 (file)
@@ -284,7 +284,7 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int
                        int wait)
 {
        cpumask_t map = CPU_MASK_NONE;
-       int ret = -EBUSY;
+       int ret = 0;
 
        if (!cpu_online(cpu))
                return -EINVAL;
@@ -292,6 +292,11 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int
        cpu_set(cpu, map);
        if (cpu != get_cpu())
                ret = smp_call_function_map(func,info,nonatomic,wait,map);
+       else {
+               local_irq_disable();
+               func(info);
+               local_irq_enable();
+       }
        put_cpu();
        return ret;
 }
index 3767211b3d0f665e0666dcfcea246009c1d159ed..ab3546c5ac3a2a8f4b022ba8150c13a9c7686728 100644 (file)
@@ -283,7 +283,13 @@ good_area:
                /* protection fault */
                if (error_code & DSISR_PROTFAULT)
                        goto bad_area;
-               if (!(vma->vm_flags & VM_EXEC))
+               /*
+                * Allow execution from readable areas if the MMU does not
+                * provide separate controls over reading and executing.
+                */
+               if (!(vma->vm_flags & VM_EXEC) &&
+                   (cpu_has_feature(CPU_FTR_NOEXECUTE) ||
+                    !(vma->vm_flags & (VM_READ | VM_WRITE))))
                        goto bad_area;
 #else
                pte_t *ptep;
index 2ce9491b48d409d4763d4822426415c4f5a8c088..bc7b0cedae5e555ab711d2d5099059070766de17 100644 (file)
@@ -609,7 +609,7 @@ static void demote_segment_4k(struct mm_struct *mm, unsigned long addr)
        mm->context.sllp = SLB_VSID_USER | mmu_psize_defs[MMU_PAGE_4K].sllp;
 #endif /* CONFIG_PPC_MM_SLICES */
 
-#ifdef CONFIG_SPE_BASE
+#ifdef CONFIG_SPU_BASE
        spu_flush_all_slbs(mm);
 #endif
 }
@@ -744,7 +744,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
                               "to 4kB pages because of "
                               "non-cacheable mapping\n");
                        psize = mmu_vmalloc_psize = MMU_PAGE_4K;
-#ifdef CONFIG_SPE_BASE
+#ifdef CONFIG_SPU_BASE
                        spu_flush_all_slbs(mm);
 #endif
                }
index 06c7e77e097ab2ba56a824a9fa930fa55c8c3498..eb4b512d65fabc4a2b6b291d04d8dacac08e9813 100644 (file)
@@ -26,6 +26,8 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/highmem.h>
+#include <linux/pagemap.h>
+
 #include <asm/tlbflush.h>
 #include <asm/tlb.h>
 
index b8b5fde9466863cc634b32b5d0430391da0874a9..e4b2aee53a73f2ce9815b5d63e19b318c44de006 100644 (file)
@@ -215,7 +215,7 @@ config NOT_COHERENT_CACHE
        depends on 4xx || 8xx || E200
        default y
 
-config CONFIG_CHECK_CACHE_COHERENCY
+config CHECK_CACHE_COHERENCY
        bool
 
 endmenu
index 7de4e919687b48b717bdb6001f30c088cfe49997..4100ddc52f0227fb0fcb300fb50da78bffa9b9d3 100644 (file)
@@ -2177,8 +2177,8 @@ struct tree_descr spufs_dir_contents[] = {
        { "mbox_stat", &spufs_mbox_stat_fops, 0444, },
        { "ibox_stat", &spufs_ibox_stat_fops, 0444, },
        { "wbox_stat", &spufs_wbox_stat_fops, 0444, },
-       { "signal1", &spufs_signal1_fops, 0666, },
-       { "signal2", &spufs_signal2_fops, 0666, },
+       { "signal1", &spufs_signal1_nosched_fops, 0222, },
+       { "signal2", &spufs_signal2_nosched_fops, 0222, },
        { "signal1_type", &spufs_signal1_type, 0666, },
        { "signal2_type", &spufs_signal2_type, 0666, },
        { "cntl", &spufs_cntl_fops,  0666, },
index bec772674e4066db350f22b77d77bf74c5b32134..2d12f77e46bcbee9987213561cfe7c2c5a022db6 100644 (file)
@@ -59,7 +59,7 @@ config MPC10X_BRIDGE
 config MV64X60
        bool
        select PPC_INDIRECT_PCI
-       select CONFIG_CHECK_CACHE_COHERENCY
+       select CHECK_CACHE_COHERENCY
 
 config MPC10X_OPENPIC
        bool
index a05079b07696b3bdd43be061df046a4b0e943d8f..d4fc74f7bb15a09eb6d2f4b357ac574c9def5e7b 100644 (file)
@@ -102,4 +102,40 @@ config PS3_STORAGE
        depends on PPC_PS3
        tristate
 
+config PS3_DISK
+       tristate "PS3 Disk Storage Driver"
+       depends on PPC_PS3 && BLOCK
+       select PS3_STORAGE
+       help
+         Include support for the PS3 Disk Storage.
+
+         This support is required to access the PS3 hard disk.
+         In general, all users will say Y or M.
+
+config PS3_ROM
+       tristate "PS3 BD/DVD/CD-ROM Storage Driver"
+       depends on PPC_PS3 && SCSI
+       select PS3_STORAGE
+       help
+         Include support for the PS3 ROM Storage.
+
+         This support is required to access the PS3 BD/DVD/CD-ROM drive.
+         In general, all users will say Y or M.
+         Also make sure to say Y or M to "SCSI CDROM support" later.
+
+config PS3_FLASH
+       tristate "PS3 FLASH ROM Storage Driver"
+       depends on PPC_PS3
+       select PS3_STORAGE
+       help
+         Include support for the PS3 FLASH ROM Storage.
+
+         This support is required to access the PS3 FLASH ROM, which
+         contains the boot loader and some boot options.
+         In general, all users will say Y or M.
+
+         As this driver needs a fixed buffer of 256 KiB of memory, it can
+         be disabled on the kernel command line using "ps3flash=off", to
+         not allocate this fixed buffer.
+
 endmenu
index 29bf83bfb1f086b98f6657357606229b0332c266..8b18a1c40092c5e7c68402c8ce78a1232a67ef41 100644 (file)
@@ -66,24 +66,13 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = {
  * device-tree/ibm,hypertas-functions.  Ultimately this functionality may
  * be moved into prom.c prom_init().
  */
-void __init fw_feature_init(void)
+void __init fw_feature_init(const char *hypertas, unsigned long len)
 {
-       struct device_node *dn;
-       const char *hypertas, *s;
-       int len, i;
+       const char *s;
+       int i;
 
        DBG(" -> fw_feature_init()\n");
 
-       dn = of_find_node_by_path("/rtas");
-       if (dn == NULL) {
-               printk(KERN_ERR "WARNING! Cannot find RTAS in device-tree!\n");
-               goto out;
-       }
-
-       hypertas = of_get_property(dn, "ibm,hypertas-functions", &len);
-       if (hypertas == NULL)
-               goto out;
-
        for (s = hypertas; s < hypertas + len; s += strlen(s) + 1) {
                for (i = 0; i < FIRMWARE_MAX_FEATURES; i++) {
                        /* check value against table of strings */
@@ -98,7 +87,5 @@ void __init fw_feature_init(void)
                }
        }
 
-out:
-       of_node_put(dn);
        DBG(" <- fw_feature_init()\n");
 }
index 61e19f78b923099c3691de50ece491adbf158d31..61136d019554944e1c681da0b191504a6a7b94ca 100644 (file)
@@ -10,7 +10,7 @@
 #ifndef _PSERIES_PSERIES_H
 #define _PSERIES_PSERIES_H
 
-extern void __init fw_feature_init(void);
+extern void __init fw_feature_init(const char *hypertas, unsigned long len);
 
 struct pt_regs;
 
index 59e69f085cb419e2ca037fb1273ccbcf1b8824d9..f0b7146a110f7238abcd39d633db63dd44711481 100644 (file)
@@ -320,8 +320,6 @@ static void __init pSeries_init_early(void)
 {
        DBG(" -> pSeries_init_early()\n");
 
-       fw_feature_init();
-
        if (firmware_has_feature(FW_FEATURE_LPAR))
                find_udbg_vterm();
 
@@ -343,14 +341,21 @@ static int __init pSeries_probe_hypertas(unsigned long node,
                                         const char *uname, int depth,
                                         void *data)
 {
+       const char *hypertas;
+       unsigned long len;
+
        if (depth != 1 ||
            (strcmp(uname, "rtas") != 0 && strcmp(uname, "rtas@0") != 0))
-               return 0;
+               return 0;
+
+       hypertas = of_get_flat_dt_prop(node, "ibm,hypertas-functions", &len);
+       if (!hypertas)
+               return 1;
 
-       if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL)
-               powerpc_firmware_features |= FW_FEATURE_LPAR;
+       powerpc_firmware_features |= FW_FEATURE_LPAR;
+       fw_feature_init(hypertas, len);
 
-       return 1;
+       return 1;
 }
 
 static int __init pSeries_probe(void)
index 75aad38179f0131e733690bde4a51461fb67b8d6..74c64c0d3b71d91841703f1c4b069508dca71769 100644 (file)
@@ -877,6 +877,8 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
 
        if (hw == mpic->spurious_vec)
                return -EINVAL;
+       if (mpic->protected && test_bit(hw, mpic->protected))
+               return -EINVAL;
 
 #ifdef CONFIG_SMP
        else if (hw >= mpic->ipi_vecs[0]) {
@@ -1034,6 +1036,25 @@ struct mpic * __init mpic_alloc(struct device_node *node,
        if (node && of_get_property(node, "big-endian", NULL) != NULL)
                mpic->flags |= MPIC_BIG_ENDIAN;
 
+       /* Look for protected sources */
+       if (node) {
+               unsigned int psize, bits, mapsize;
+               const u32 *psrc =
+                       of_get_property(node, "protected-sources", &psize);
+               if (psrc) {
+                       psize /= 4;
+                       bits = intvec_top + 1;
+                       mapsize = BITS_TO_LONGS(bits) * sizeof(unsigned long);
+                       mpic->protected = alloc_bootmem(mapsize);
+                       BUG_ON(mpic->protected == NULL);
+                       memset(mpic->protected, 0, mapsize);
+                       for (i = 0; i < psize; i++) {
+                               if (psrc[i] > intvec_top)
+                                       continue;
+                               __set_bit(psrc[i], mpic->protected);
+                       }
+               }
+       }
 
 #ifdef CONFIG_MPIC_WEIRD
        mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)];
@@ -1213,6 +1234,9 @@ void __init mpic_init(struct mpic *mpic)
                u32 vecpri = MPIC_VECPRI_MASK | i |
                        (8 << MPIC_VECPRI_PRIORITY_SHIFT);
                
+               /* check if protected */
+               if (mpic->protected && test_bit(i, mpic->protected))
+                       continue;
                /* init hw */
                mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
                mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
@@ -1407,6 +1431,14 @@ unsigned int mpic_get_one_irq(struct mpic *mpic)
                        mpic_eoi(mpic);
                return NO_IRQ;
        }
+       if (unlikely(mpic->protected && test_bit(src, mpic->protected))) {
+               if (printk_ratelimit())
+                       printk(KERN_WARNING "%s: Got protected source %d !\n",
+                              mpic->name, (int)src);
+               mpic_eoi(mpic);
+               return NO_IRQ;
+       }
+
        return irq_linear_revmap(mpic->irqhost, src);
 }
 
index 78765833f4c0459fa66022596824b2df951a607d..bfac84fbe7806693797decdd8db0deaea98bf097 100644 (file)
@@ -132,3 +132,8 @@ void xmon_printf(const char *format, ...)
        va_end(args);
        xmon_write(xmon_outbuf, n);
 }
+
+void xmon_puts(const char *str)
+{
+       xmon_write(str, strlen(str));
+}
index 47cebbd2b1b1b06e3d53d99c9dc3a41eb42b6db2..23dd95f4599c3fd049eb17be31990ca6b00d3732 100644 (file)
@@ -5,10 +5,11 @@
 
 extern int xmon_putchar(int c);
 extern int xmon_getchar(void);
+extern void xmon_puts(const char *);
 extern char *xmon_gets(char *, int);
 extern void xmon_printf(const char *, ...);
 extern void xmon_map_scc(void);
 extern int xmon_expect(const char *str, unsigned long timeout);
-extern int xmon_write(void *ptr, int nb);
+extern int xmon_write(const void *ptr, int nb);
 extern int xmon_readchar(void);
 extern int xmon_read_poll(void);
index 712552c4f24215f263d495c75bbbc2cc1cf72481..8864de2af382f767540ad4aeac24a7606750e72e 100644 (file)
@@ -14,7 +14,7 @@ void xmon_map_scc(void)
 {
 }
 
-int xmon_write(void *ptr, int nb)
+int xmon_write(const void *ptr, int nb)
 {
        return udbg_write(ptr, nb);
 }
index 669e6566ad70983fc2fa1d3a246460521d3cf059..121b04d165d1937b2805a5a1dabaaa30c0467f6f 100644 (file)
@@ -833,7 +833,7 @@ cmds(struct pt_regs *excp)
                        mdelay(2000);
                        return cmd;
                case '?':
-                       printf(help_string);
+                       xmon_puts(help_string);
                        break;
                case 'b':
                        bpt_cmds();
index 032f4b7f42257c7566fee56e084bd88ed6f5bc23..d212b1c418a99cef263e33d6125d5b150a33c0fd 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/string.h>
 #include <linux/spinlock.h>
 #include <linux/mv643xx.h>
@@ -2359,7 +2360,7 @@ mv64460_chip_specific_init(struct mv64x60_handle *bh,
 /* Export the hotswap register via sysfs for enum event monitoring */
 #define        VAL_LEN_MAX     11 /* 32-bit hex or dec stringified number + '\n' */
 
-DECLARE_MUTEX(mv64xxx_hs_lock);
+static DEFINE_MUTEX(mv64xxx_hs_lock);
 
 static ssize_t
 mv64xxx_hs_reg_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
@@ -2372,14 +2373,14 @@ mv64xxx_hs_reg_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
        if (count < VAL_LEN_MAX)
                return -EINVAL;
 
-       if (down_interruptible(&mv64xxx_hs_lock))
+       if (mutex_lock_interruptible(&mv64xxx_hs_lock))
                return -ERESTARTSYS;
        save_exclude = mv64x60_pci_exclude_bridge;
        mv64x60_pci_exclude_bridge = 0;
        early_read_config_dword(&sysfs_hose_a, 0, PCI_DEVFN(0, 0),
                        MV64360_PCICFG_CPCI_HOTSWAP, &v);
        mv64x60_pci_exclude_bridge = save_exclude;
-       up(&mv64xxx_hs_lock);
+       mutex_unlock(&mv64xxx_hs_lock);
 
        return sprintf(buf, "0x%08x\n", v);
 }
@@ -2396,14 +2397,14 @@ mv64xxx_hs_reg_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
                return -EINVAL;
 
        if (sscanf(buf, "%i", &v) == 1) {
-               if (down_interruptible(&mv64xxx_hs_lock))
+               if (mutex_lock_interruptible(&mv64xxx_hs_lock))
                        return -ERESTARTSYS;
                save_exclude = mv64x60_pci_exclude_bridge;
                mv64x60_pci_exclude_bridge = 0;
                early_write_config_dword(&sysfs_hose_a, 0, PCI_DEVFN(0, 0),
                                MV64360_PCICFG_CPCI_HOTSWAP, v);
                mv64x60_pci_exclude_bridge = save_exclude;
-               up(&mv64xxx_hs_lock);
+               mutex_unlock(&mv64xxx_hs_lock);
        }
        else
                count = -EINVAL;
@@ -2433,10 +2434,10 @@ mv64xxx_hs_reg_valid_show(struct device *dev, struct device_attribute *attr,
        pdev = container_of(dev, struct platform_device, dev);
        pdp = (struct mv64xxx_pdata *)pdev->dev.platform_data;
 
-       if (down_interruptible(&mv64xxx_hs_lock))
+       if (mutex_lock_interruptible(&mv64xxx_hs_lock))
                return -ERESTARTSYS;
        v = pdp->hs_reg_valid;
-       up(&mv64xxx_hs_lock);
+       mutex_unlock(&mv64xxx_hs_lock);
 
        return sprintf(buf, "%i\n", v);
 }
index 097ebd49f1bf0ef0964d847c14df3de3e92ae6bf..7aca37d79766f5c19dae8cc0af9cd43269eeed3d 100644 (file)
@@ -80,6 +80,7 @@ static void tmu_set_mode(enum clock_event_mode mode,
                break;
        case CLOCK_EVT_MODE_UNUSED:
        case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_RESUME:
                break;
        }
 }
index 831f540251f887a55ec40b061905f0f8d07cf944..eac38388f5fd354bf35681e97534ba14368a27e5 100644 (file)
@@ -1749,8 +1749,8 @@ fpload:
 __ndelay:
        save    %sp, -STACKFRAME_SZ, %sp
        mov     %i0, %o0
-       call    .umul
-        mov    0x1ad, %o1              ! 2**32 / (1 000 000 000 / HZ)
+       call    .umul                   ! round multiplier up so large ns ok
+        mov    0x1ae, %o1              ! 2**32 / (1 000 000 000 / HZ)
        call    .umul
         mov    %i1, %o1                ! udelay_val
        ba      delay_continue
@@ -1760,11 +1760,17 @@ __ndelay:
 __udelay:
        save    %sp, -STACKFRAME_SZ, %sp
        mov     %i0, %o0
-       sethi   %hi(0x10c6), %o1
+       sethi   %hi(0x10c7), %o1        ! round multiplier up so large us ok
        call    .umul
-        or     %o1, %lo(0x10c6), %o1   ! 2**32 / 1 000 000
+        or     %o1, %lo(0x10c7), %o1   ! 2**32 / 1 000 000
        call    .umul
         mov    %i1, %o1                ! udelay_val
+       sethi   %hi(0x028f4b62), %l0    ! Add in rounding constant * 2**32,
+       or      %g0, %lo(0x028f4b62), %l0
+       addcc   %o0, %l0, %o0           ! 2**32 * 0.009 999
+       bcs,a   3f
+        add    %o1, 0x01, %o1
+3:
        call    .umul
         mov    HZ, %o0                 ! >>32 earlier for wider range
 
index f257a67bcf933dc3b7d3902b29a9d995f252c2ed..75b2240ad0f9efe1bd73290a3ed076a700de0186 100644 (file)
@@ -47,6 +47,8 @@
 #include <asm/cacheflush.h>
 #include <asm/irq_regs.h>
 
+#include "irq.h"
+
 #ifdef CONFIG_SMP
 #define SMP_NOP2 "nop; nop;\n\t"
 #define SMP_NOP3 "nop; nop; nop;\n\t"
@@ -268,7 +270,7 @@ void free_irq(unsigned int irq, void *dev_id)
        kfree(action);
 
        if (!sparc_irq[cpu_irq].action)
-               disable_irq(irq);
+               __disable_irq(irq);
 
 out_unlock:
        spin_unlock_irqrestore(&irq_action_lock, flags);
@@ -464,7 +466,7 @@ int request_fast_irq(unsigned int irq,
 
        sparc_irq[cpu_irq].action = action;
 
-       enable_irq(irq);
+       __enable_irq(irq);
 
        ret = 0;
 out_unlock:
@@ -544,7 +546,7 @@ int request_irq(unsigned int irq,
 
        *actionp = action;
 
-       enable_irq(irq);
+       __enable_irq(irq);
 
        ret = 0;
 out_unlock:
@@ -555,6 +557,25 @@ out:
 
 EXPORT_SYMBOL(request_irq);
 
+void disable_irq_nosync(unsigned int irq)
+{
+       return __disable_irq(irq);
+}
+EXPORT_SYMBOL(disable_irq_nosync);
+
+void disable_irq(unsigned int irq)
+{
+       return __disable_irq(irq);
+}
+EXPORT_SYMBOL(disable_irq);
+
+void enable_irq(unsigned int irq)
+{
+       return __enable_irq(irq);
+}
+
+EXPORT_SYMBOL(enable_irq);
+
 /* We really don't need these at all on the Sparc.  We only have
  * stubs here because they are exported to modules.
  */
diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h
new file mode 100644 (file)
index 0000000..32ef3eb
--- /dev/null
@@ -0,0 +1,68 @@
+#include <asm/btfixup.h>
+
+/* Dave Redman (djhr@tadpole.co.uk)
+ * changed these to function pointers.. it saves cycles and will allow
+ * the irq dependencies to be split into different files at a later date
+ * sun4c_irq.c, sun4m_irq.c etc so we could reduce the kernel size.
+ * Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Changed these to btfixup entities... It saves cycles :)
+ */
+
+BTFIXUPDEF_CALL(void, disable_irq, unsigned int)
+BTFIXUPDEF_CALL(void, enable_irq, unsigned int)
+BTFIXUPDEF_CALL(void, disable_pil_irq, unsigned int)
+BTFIXUPDEF_CALL(void, enable_pil_irq, unsigned int)
+BTFIXUPDEF_CALL(void, clear_clock_irq, void)
+BTFIXUPDEF_CALL(void, clear_profile_irq, int)
+BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int)
+
+static inline void __disable_irq(unsigned int irq)
+{
+       BTFIXUP_CALL(disable_irq)(irq);
+}
+
+static inline void __enable_irq(unsigned int irq)
+{
+       BTFIXUP_CALL(enable_irq)(irq);
+}
+
+static inline void disable_pil_irq(unsigned int irq)
+{
+       BTFIXUP_CALL(disable_pil_irq)(irq);
+}
+
+static inline void enable_pil_irq(unsigned int irq)
+{
+       BTFIXUP_CALL(enable_pil_irq)(irq);
+}
+
+static inline void clear_clock_irq(void)
+{
+       BTFIXUP_CALL(clear_clock_irq)();
+}
+
+static inline void clear_profile_irq(int irq)
+{
+       BTFIXUP_CALL(clear_profile_irq)(irq);
+}
+
+static inline void load_profile_irq(int cpu, int limit)
+{
+       BTFIXUP_CALL(load_profile_irq)(cpu, limit);
+}
+
+extern void (*sparc_init_timers)(irq_handler_t lvl10_irq);
+
+extern void claim_ticker14(irq_handler_t irq_handler,
+                          int irq,
+                          unsigned int timeout);
+
+#ifdef CONFIG_SMP
+BTFIXUPDEF_CALL(void, set_cpu_int, int, int)
+BTFIXUPDEF_CALL(void, clear_cpu_int, int, int)
+BTFIXUPDEF_CALL(void, set_irq_udt, int)
+
+#define set_cpu_int(cpu,level) BTFIXUP_CALL(set_cpu_int)(cpu,level)
+#define clear_cpu_int(cpu,level) BTFIXUP_CALL(clear_cpu_int)(cpu,level)
+#define set_irq_udt(cpu) BTFIXUP_CALL(set_irq_udt)(cpu)
+#endif
index 79177119690546cc0e26c579b6e94e6295d4484f..f2eae457fc9a24cc4c9c44a401c19a9270a3084c 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/uaccess.h>
 #include <asm/irq_regs.h>
 
+#include "irq.h"
 
 /*
  * I studied different documents and many live PROMs both from 2.30
index 4fea3ac7bff08d1b13cd4e54f2d2be6b08198d1a..6724ab90f82bc6868f2c47eb81540d7909a2ade9 100644 (file)
@@ -33,6 +33,8 @@
 #include <asm/tlbflush.h>
 #include <asm/cpudata.h>
 
+#include "irq.h"
+
 int smp_num_cpus = 1;
 volatile unsigned long cpu_callin_map[NR_CPUS] __initdata = {0,};
 unsigned char boot_cpu_id = 0;
index d8e008a04e2b4702b34ed19ff0b2302f034346e8..55bac516dfe2952b8a8de6971f567f539c003614 100644 (file)
@@ -154,8 +154,6 @@ EXPORT_SYMBOL(BTFIXUP_CALL(___xchg32));
 #else
 EXPORT_SYMBOL(BTFIXUP_CALL(__hard_smp_processor_id));
 #endif
-EXPORT_SYMBOL(BTFIXUP_CALL(enable_irq));
-EXPORT_SYMBOL(BTFIXUP_CALL(disable_irq));
 EXPORT_SYMBOL(BTFIXUP_CALL(mmu_unlockarea));
 EXPORT_SYMBOL(BTFIXUP_CALL(mmu_lockarea));
 EXPORT_SYMBOL(BTFIXUP_CALL(mmu_get_scsi_sgl));
index 009e891a4329cd6e727dca78c3a00b3dc3862a35..c6ac9fc525632d96548e84cb4750874c57f015dc 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/init.h>
+#include "irq.h"
 
 #include <asm/ptrace.h>
 #include <asm/processor.h>
@@ -40,6 +41,20 @@ static struct resource sun4c_timer_eb = { "sun4c_timer" };
 static struct resource sun4c_intr_eb = { "sun4c_intr" };
 #endif
 
+/*
+ * Bit field defines for the interrupt registers on various
+ * Sparc machines.
+ */
+
+/* The sun4c interrupt register. */
+#define SUN4C_INT_ENABLE  0x01     /* Allow interrupts. */
+#define SUN4C_INT_E14     0x80     /* Enable level 14 IRQ. */
+#define SUN4C_INT_E10     0x20     /* Enable level 10 IRQ. */
+#define SUN4C_INT_E8      0x10     /* Enable level 8 IRQ. */
+#define SUN4C_INT_E6      0x08     /* Enable level 6 IRQ. */
+#define SUN4C_INT_E4      0x04     /* Enable level 4 IRQ. */
+#define SUN4C_INT_E1      0x02     /* Enable level 1 IRQ. */
+
 /* Pointer to the interrupt enable byte
  *
  * Dave Redman (djhr@tadpole.co.uk)
index 396797e20c392b143ca4821e4975fd9bb5d0eb8d..e0efab2a6befa16823c326e3ab4bbda0d14800db 100644 (file)
@@ -39,6 +39,8 @@
 #include <asm/cacheflush.h>
 #include <asm/irq_regs.h>
 
+#include "irq.h"
+
 /* If you trust current SCSI layer to handle different SCSI IRQs, enable this. I don't trust it... -jj */
 /* #define DISTRIBUTE_IRQS */
 
@@ -188,7 +190,7 @@ void sun4d_free_irq(unsigned int irq, void *dev_id)
        kfree(action);
 
        if (!(*actionp))
-               disable_irq(irq);
+               __disable_irq(irq);
 
 out_unlock:
        spin_unlock_irqrestore(&irq_action_lock, flags);
@@ -346,7 +348,7 @@ int sun4d_request_irq(unsigned int irq,
        else
                *actionp = action;
                
-       enable_irq(irq);
+       __enable_irq(irq);
 
        ret = 0;
 out_unlock:
index 098c94f1a322bffccbaa4c36e5e06b91208a9998..89a6de95070c761d0fe3237bc89a49f2063fc1fb 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/cacheflush.h>
 #include <asm/cpudata.h>
 
+#include "irq.h"
 #define IRQ_CROSS_CALL         15
 
 extern ctxd_t *srmmu_ctx_table_phys;
index 91a803ea88bec1d1a59f5dc4dc245d785522387c..b92d6d2d5b04c8f0ea98a7b07baa0c7f27c02667 100644 (file)
 #include <asm/sbus.h>
 #include <asm/cacheflush.h>
 
+#include "irq.h"
+
+/* On the sun4m, just like the timers, we have both per-cpu and master
+ * interrupt registers.
+ */
+
+/* These registers are used for sending/receiving irqs from/to
+ * different cpu's.
+ */
+struct sun4m_intreg_percpu {
+       unsigned int tbt;        /* Interrupts still pending for this cpu. */
+
+       /* These next two registers are WRITE-ONLY and are only
+        * "on bit" sensitive, "off bits" written have NO affect.
+        */
+       unsigned int clear;  /* Clear this cpus irqs here. */
+       unsigned int set;    /* Set this cpus irqs here. */
+       unsigned char space[PAGE_SIZE - 12];
+};
+
+/*
+ * djhr
+ * Actually the clear and set fields in this struct are misleading..
+ * according to the SLAVIO manual (and the same applies for the SEC)
+ * the clear field clears bits in the mask which will ENABLE that IRQ
+ * the set field sets bits in the mask to DISABLE the IRQ.
+ *
+ * Also the undirected_xx address in the SLAVIO is defined as
+ * RESERVED and write only..
+ *
+ * DAVEM_NOTE: The SLAVIO only specifies behavior on uniprocessor
+ *             sun4m machines, for MP the layout makes more sense.
+ */
+struct sun4m_intregs {
+       struct sun4m_intreg_percpu cpu_intregs[SUN4M_NCPUS];
+       unsigned int tbt;                /* IRQ's that are still pending. */
+       unsigned int irqs;               /* Master IRQ bits. */
+
+       /* Again, like the above, two these registers are WRITE-ONLY. */
+       unsigned int clear;              /* Clear master IRQ's by setting bits here. */
+       unsigned int set;                /* Set master IRQ's by setting bits here. */
+
+       /* This register is both READ and WRITE. */
+       unsigned int undirected_target;  /* Which cpu gets undirected irqs. */
+};
+
 static unsigned long dummy;
 
 struct sun4m_intregs *sun4m_interrupts;
 unsigned long *irq_rcvreg = &dummy;
 
+/* Dave Redman (djhr@tadpole.co.uk)
+ * The sun4m interrupt registers.
+ */
+#define SUN4M_INT_ENABLE       0x80000000
+#define SUN4M_INT_E14          0x00000080
+#define SUN4M_INT_E10          0x00080000
+
+#define SUN4M_HARD_INT(x)      (0x000000001 << (x))
+#define SUN4M_SOFT_INT(x)      (0x000010000 << (x))
+
+#define        SUN4M_INT_MASKALL       0x80000000        /* mask all interrupts */
+#define        SUN4M_INT_MODULE_ERR    0x40000000        /* module error */
+#define        SUN4M_INT_M2S_WRITE     0x20000000        /* write buffer error */
+#define        SUN4M_INT_ECC           0x10000000        /* ecc memory error */
+#define        SUN4M_INT_FLOPPY        0x00400000        /* floppy disk */
+#define        SUN4M_INT_MODULE        0x00200000        /* module interrupt */
+#define        SUN4M_INT_VIDEO         0x00100000        /* onboard video */
+#define        SUN4M_INT_REALTIME      0x00080000        /* system timer */
+#define        SUN4M_INT_SCSI          0x00040000        /* onboard scsi */
+#define        SUN4M_INT_AUDIO         0x00020000        /* audio/isdn */
+#define        SUN4M_INT_ETHERNET      0x00010000        /* onboard ethernet */
+#define        SUN4M_INT_SERIAL        0x00008000        /* serial ports */
+#define        SUN4M_INT_KBDMS         0x00004000        /* keyboard/mouse */
+#define        SUN4M_INT_SBUSBITS      0x00003F80        /* sbus int bits */
+
+#define SUN4M_INT_SBUS(x)      (1 << (x+7))
+#define SUN4M_INT_VME(x)       (1 << (x))
+
 /* These tables only apply for interrupts greater than 15..
  * 
  * any intr value below 0x10 is considered to be a soft-int
index 63ed19bfd028f9b85ab5e631a9effd2021bdff61..730eb5796f8edb98b83332e4a9099996ca1e3083 100644 (file)
@@ -31,6 +31,8 @@
 #include <asm/oplib.h>
 #include <asm/cpudata.h>
 
+#include "irq.h"
+
 #define IRQ_RESCHEDULE         13
 #define IRQ_STOP_CPU           14
 #define IRQ_CROSS_CALL         15
index f1a7bd19e04fd1acaec49d879676313756a7cfe9..707bfda86570d2acb9d139404b08dd15849b679e 100644 (file)
@@ -25,6 +25,8 @@
 #include <asm/irq.h>
 #include <asm/io.h>
 
+#include "irq.h"
+
 extern unsigned long lvl14_save[5];
 static unsigned long *linux_lvl14 = NULL;
 static unsigned long obp_lvl14[4];
@@ -62,7 +64,7 @@ void claim_ticker14(irq_handler_t handler,
 
        /* first we copy the obp handler instructions
         */
-       disable_irq(irq_nr);
+       __disable_irq(irq_nr);
        if (!handler)
                return;
     
@@ -79,6 +81,6 @@ void claim_ticker14(irq_handler_t handler,
                         NULL)) {
                install_linux_ticker();
                load_profile_irq(cpu, timeout);
-               enable_irq(irq_nr);
+               __enable_irq(irq_nr);
        }
 }
index f2fdbb3664d37e34d3aaf8a6c19f6733e3c47e1a..6a25133216207df68d62f3cded23eddd12070079 100644 (file)
@@ -44,6 +44,8 @@
 #include <asm/of_device.h>
 #include <asm/irq_regs.h>
 
+#include "irq.h"
+
 DEFINE_SPINLOCK(rtc_lock);
 enum sparc_clock_type sp_clock_typ;
 DEFINE_SPINLOCK(mostek_lock);
index a532922e2e3540ad6316414657cf7c6ee50c4aaa..a1bef07755a920076d186880269af56f5f9348db 100644 (file)
@@ -308,6 +308,9 @@ extern void sun4c_paging_init(void);
 extern void srmmu_paging_init(void);
 extern void device_scan(void);
 
+pgprot_t PAGE_SHARED __read_mostly;
+EXPORT_SYMBOL(PAGE_SHARED);
+
 void __init paging_init(void)
 {
        switch(sparc_cpu_model) {
index ca26232da7abc96de39cf3b5c437ab7614d7e54d..17b485f2825c94345432e4fecb88b9903d4e94e7 100644 (file)
@@ -2154,7 +2154,7 @@ void __init ld_mmu_srmmu(void)
        BTFIXUPSET_SIMM13(ptrs_per_pgd, SRMMU_PTRS_PER_PGD);
 
        BTFIXUPSET_INT(page_none, pgprot_val(SRMMU_PAGE_NONE));
-       BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
+       PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
        BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
        BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
        BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
index bdd835fba02e8c3f02b58acfbf6f98c7c98aa57a..a57a366e339ac6cb3796357087ca20c088f90558 100644 (file)
@@ -2155,7 +2155,7 @@ void __init ld_mmu_sun4c(void)
        BTFIXUPSET_SIMM13(user_ptrs_per_pgd, KERNBASE / SUN4C_PGDIR_SIZE);
 
        BTFIXUPSET_INT(page_none, pgprot_val(SUN4C_PAGE_NONE));
-       BTFIXUPSET_INT(page_shared, pgprot_val(SUN4C_PAGE_SHARED));
+       PAGE_SHARED = pgprot_val(SUN4C_PAGE_SHARED);
        BTFIXUPSET_INT(page_copy, pgprot_val(SUN4C_PAGE_COPY));
        BTFIXUPSET_INT(page_readonly, pgprot_val(SUN4C_PAGE_READONLY));
        BTFIXUPSET_INT(page_kernel, pgprot_val(SUN4C_PAGE_KERNEL));
index f1cc55677ff24b874db671be74d8ba736c727dbf..33dabf588bdd5a41276ac2675ffd583a4a9a71ae 100644 (file)
@@ -23,6 +23,10 @@ config GENERIC_TIME
        bool
        default y
 
+config GENERIC_CMOS_UPDATE
+       bool
+       default y
+
 config GENERIC_CLOCKEVENTS
        bool
        default y
index 7d36531aa5b98d3e243a1917ceb595a5f870cf7a..d270c2f0be0fdf0c8e31fe6100df7305e120ebca 100644 (file)
@@ -280,6 +280,7 @@ EXPORT_SYMBOL(sys_getgid);
 EXPORT_SYMBOL(svr4_getcontext);
 EXPORT_SYMBOL(svr4_setcontext);
 EXPORT_SYMBOL(compat_sys_ioctl);
+EXPORT_SYMBOL(sys_ioctl);
 EXPORT_SYMBOL(sparc32_open);
 #endif
 
index e340eb401fb956642028b4eb8f912989487e2378..49063ca2efcdf53bfa6932185cc870a40948b02c 100644 (file)
@@ -403,58 +403,9 @@ static struct sparc64_tick_ops hbtick_operations __read_mostly = {
 
 static unsigned long timer_ticks_per_nsec_quotient __read_mostly;
 
-#define TICK_SIZE (tick_nsec / 1000)
-
-#define USEC_AFTER     500000
-#define USEC_BEFORE    500000
-
-static void sync_cmos_clock(unsigned long dummy);
-
-static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0);
-
-static void sync_cmos_clock(unsigned long dummy)
-{
-       struct timeval now, next;
-       int fail = 1;
-
-       /*
-        * If we have an externally synchronized Linux clock, then update
-        * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
-        * called as close as possible to 500 ms before the new second starts.
-        * This code is run on a timer.  If the clock is set, that timer
-        * may not expire at the correct time.  Thus, we adjust...
-        */
-       if (!ntp_synced())
-               /*
-                * Not synced, exit, do not restart a timer (if one is
-                * running, let it run out).
-                */
-               return;
-
-       do_gettimeofday(&now);
-       if (now.tv_usec >= USEC_AFTER - ((unsigned) TICK_SIZE) / 2 &&
-           now.tv_usec <= USEC_BEFORE + ((unsigned) TICK_SIZE) / 2)
-               fail = set_rtc_mmss(now.tv_sec);
-
-       next.tv_usec = USEC_AFTER - now.tv_usec;
-       if (next.tv_usec <= 0)
-               next.tv_usec += USEC_PER_SEC;
-
-       if (!fail)
-               next.tv_sec = 659;
-       else
-               next.tv_sec = 0;
-
-       if (next.tv_usec >= USEC_PER_SEC) {
-               next.tv_sec++;
-               next.tv_usec -= USEC_PER_SEC;
-       }
-       mod_timer(&sync_cmos_timer, jiffies + timeval_to_jiffies(&next));
-}
-
-void notify_arch_cmos_timer(void)
+int update_persistent_clock(struct timespec now)
 {
-       mod_timer(&sync_cmos_timer, jiffies + 1);
+       return set_rtc_mmss(now.tv_sec);
 }
 
 /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */
@@ -931,6 +882,7 @@ static void sparc64_timer_setup(enum clock_event_mode mode,
 {
        switch (mode) {
        case CLOCK_EVT_MODE_ONESHOT:
+       case CLOCK_EVT_MODE_RESUME:
                break;
 
        case CLOCK_EVT_MODE_SHUTDOWN:
index 14bf8ce3ea23f70ad78a30caa8d6b93a119715c8..45f82ae6d38978ae02d049e7bf18b0624a9b98b2 100644 (file)
@@ -32,6 +32,10 @@ config GENERIC_TIME_VSYSCALL
        bool
        default y
 
+config GENERIC_CMOS_UPDATE
+       bool
+       default y
+
 config ZONE_DMA32
        bool
        default y
@@ -56,6 +60,14 @@ config ZONE_DMA
        bool
        default y
 
+config QUICKLIST
+       bool
+       default y
+
+config NR_QUICK
+       int
+       default 2
+
 config ISA
        bool
 
index 29617ae3926d133128caddbc7dfba748069352df..128561d3e876f13b4d84b70dbdc0d5a8b6039d15 100644 (file)
@@ -76,7 +76,8 @@ head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kern
 libs-y                                         += arch/x86_64/lib/
 core-y                                 += arch/x86_64/kernel/ \
                                           arch/x86_64/mm/ \
-                                          arch/x86_64/crypto/
+                                          arch/x86_64/crypto/ \
+                                          arch/x86_64/vdso/
 core-$(CONFIG_IA32_EMULATION)          += arch/x86_64/ia32/
 drivers-$(CONFIG_PCI)                  += arch/x86_64/pci/
 drivers-$(CONFIG_OPROFILE)             += arch/x86_64/oprofile/
index c9f2da7496c14d738b0c8453dd835dd70db9cf96..877c0bdbbc67006473a1ca9754721f186910bf61 100644 (file)
@@ -3,8 +3,6 @@
 #
 # create a compressed vmlinux image from the original vmlinux
 #
-# Note all the files here are compiled/linked as 32bit executables.
-#
 
 targets                := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
 
index 40178e5c310406578a9e9888051538985dd1e314..b7c4cd04bfc3c08d5711e3215d476ad3e629e272 100644 (file)
@@ -1,19 +1,22 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22-rc2
-# Mon May 21 13:23:40 2007
+# Linux kernel version: 2.6.22-git14
+# Fri Jul 20 09:53:15 2007
 #
 CONFIG_X86_64=y
 CONFIG_64BIT=y
 CONFIG_X86=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_ZONE_DMA32=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_SEMAPHORE_SLEEPERS=y
 CONFIG_MMU=y
 CONFIG_ZONE_DMA=y
+CONFIG_QUICKLIST=y
+CONFIG_NR_QUICK=2
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
@@ -44,19 +47,18 @@ CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
+# CONFIG_USER_NS is not set
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=18
 # CONFIG_CPUSETS is not set
 CONFIG_SYSFS_DEPRECATED=y
-# CONFIG_RELAY is not set
+CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -86,10 +88,6 @@ CONFIG_SLAB=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
@@ -97,12 +95,9 @@ CONFIG_MODULE_FORCE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 # CONFIG_KMOD is not set
 CONFIG_STOP_MACHINE=y
-
-#
-# Block layer
-#
 CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
 
 #
 # IO Schedulers
@@ -165,9 +160,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 CONFIG_RESOURCES_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
 CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
 CONFIG_OUT_OF_LINE_PFN_TO_PAGE=y
 CONFIG_NR_CPUS=32
+CONFIG_PHYSICAL_ALIGN=0x200000
 CONFIG_HOTPLUG_CPU=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_HPET_TIMER=y
@@ -180,7 +178,7 @@ CONFIG_X86_MCE_INTEL=y
 CONFIG_X86_MCE_AMD=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
-CONFIG_RELOCATABLE=y
+# CONFIG_RELOCATABLE is not set
 CONFIG_PHYSICAL_START=0x200000
 CONFIG_SECCOMP=y
 # CONFIG_CC_STACKPROTECTOR is not set
@@ -201,7 +199,6 @@ CONFIG_GENERIC_PENDING_IRQ=y
 CONFIG_PM=y
 # CONFIG_PM_LEGACY is not set
 # CONFIG_PM_DEBUG is not set
-# CONFIG_PM_SYSFS_DEPRECATED is not set
 CONFIG_SOFTWARE_SUSPEND=y
 CONFIG_PM_STD_PARTITION=""
 CONFIG_SUSPEND_SMP=y
@@ -248,7 +245,7 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
 # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_ONDEMAND=y
-# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
 
 #
 # CPUFreq processor drivers
@@ -351,20 +348,8 @@ CONFIG_IPV6_SIT=y
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
 # CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -401,6 +386,7 @@ CONFIG_IPV6_SIT=y
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
 # CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
 
 #
 # Device Drivers
@@ -415,21 +401,9 @@ CONFIG_FW_LOADER=y
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
 # CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
 CONFIG_PNP=y
 # CONFIG_PNP_DEBUG is not set
 
@@ -437,10 +411,7 @@ CONFIG_PNP=y
 # Protocols
 #
 CONFIG_PNPACPI=y
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
 CONFIG_BLK_DEV_FD=y
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
@@ -458,17 +429,14 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-
-#
-# Misc devices
-#
+CONFIG_MISC_DEVICES=y
 # CONFIG_IBM_ASM is not set
 # CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_SONY_LAPTOP is not set
 # CONFIG_THINKPAD_ACPI is not set
-# CONFIG_BLINK is not set
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDE=y
 
@@ -539,6 +507,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
 # CONFIG_SCSI_TGT is not set
 CONFIG_SCSI_NETLINK=y
 # CONFIG_SCSI_PROC_FS is not set
@@ -590,11 +559,9 @@ CONFIG_AIC79XX_DEBUG_MASK=0
 # CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
 # CONFIG_SCSI_AIC94XX is not set
 # CONFIG_SCSI_ARCMSR is not set
-CONFIG_MEGARAID_NEWGEN=y
-CONFIG_MEGARAID_MM=y
-CONFIG_MEGARAID_MAILBOX=y
+# CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
-CONFIG_MEGARAID_SAS=y
+# CONFIG_MEGARAID_SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -614,7 +581,6 @@ CONFIG_MEGARAID_SAS=y
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_ESP_CORE is not set
 # CONFIG_SCSI_SRP is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
@@ -671,10 +637,6 @@ CONFIG_SATA_VIA=y
 # CONFIG_PATA_SIS is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
 CONFIG_MD=y
 # CONFIG_BLK_DEV_MD is not set
 CONFIG_BLK_DEV_DM=y
@@ -692,7 +654,7 @@ CONFIG_BLK_DEV_DM=y
 CONFIG_FUSION=y
 CONFIG_FUSION_SPI=y
 # CONFIG_FUSION_FC is not set
-CONFIG_FUSION_SAS=y
+# CONFIG_FUSION_SAS is not set
 CONFIG_FUSION_MAX_SGE=128
 # CONFIG_FUSION_CTL is not set
 
@@ -710,7 +672,10 @@ CONFIG_IEEE1394=y
 #
 # Controllers
 #
-# CONFIG_IEEE1394_PCILYNX is not set
+
+#
+# Texas Instruments PCILynx requires I2C
+#
 CONFIG_IEEE1394_OHCI1394=y
 
 #
@@ -722,32 +687,19 @@ CONFIG_IEEE1394_OHCI1394=y
 # CONFIG_IEEE1394_ETH1394 is not set
 # CONFIG_IEEE1394_DV1394 is not set
 CONFIG_IEEE1394_RAWIO=y
-
-#
-# I2O device support
-#
 # CONFIG_I2O is not set
-# CONFIG_MACINTOSH_DRIVERS is not set
-
-#
-# Network device support
-#
+CONFIG_MACINTOSH_DRIVERS=y
+# CONFIG_MAC_EMUMOUSEBTN is not set
 CONFIG_NETDEVICES=y
+CONFIG_NETDEVICES_MULTIQUEUE=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 CONFIG_TUN=y
 # CONFIG_NET_SB1000 is not set
-
-#
-# ARCnet devices
-#
 # CONFIG_ARCNET is not set
 # CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_HAPPYMEAL is not set
@@ -756,10 +708,6 @@ CONFIG_MII=y
 CONFIG_NET_VENDOR_3COM=y
 CONFIG_VORTEX=y
 # CONFIG_TYPHOON is not set
-
-#
-# Tulip family network device support
-#
 CONFIG_NET_TULIP=y
 # CONFIG_DE2104X is not set
 CONFIG_TULIP=y
@@ -773,7 +721,8 @@ CONFIG_TULIP=y
 # CONFIG_HP100 is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
+CONFIG_AMD8111_ETH=y
+# CONFIG_AMD8111E_NAPI is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
 CONFIG_B44=y
 CONFIG_FORCEDETH=y
@@ -808,7 +757,6 @@ CONFIG_E1000=y
 # CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 # CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
 CONFIG_BNX2=y
@@ -823,10 +771,6 @@ CONFIG_S2IO=m
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_MLX4_CORE is not set
-
-#
-# Token Ring devices
-#
 # CONFIG_TR is not set
 
 #
@@ -855,15 +799,7 @@ CONFIG_NETCONSOLE=y
 CONFIG_NETPOLL=y
 # CONFIG_NETPOLL_TRAP is not set
 CONFIG_NET_POLL_CONTROLLER=y
-
-#
-# ISDN subsystem
-#
 # CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
 # CONFIG_PHONE is not set
 
 #
@@ -871,6 +807,7 @@ CONFIG_NET_POLL_CONTROLLER=y
 #
 CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
 
 #
 # Userland interfaces
@@ -936,6 +873,7 @@ CONFIG_HW_CONSOLE=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_FIX_EARLYCON_MEM=y
 CONFIG_SERIAL_8250_PCI=y
 CONFIG_SERIAL_8250_PNP=y
 CONFIG_SERIAL_8250_NR_UARTS=4
@@ -951,16 +889,11 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_HW_RANDOM=y
 CONFIG_HW_RANDOM_INTEL=y
 CONFIG_HW_RANDOM_AMD=y
-# CONFIG_HW_RANDOM_GEODE is not set
 # CONFIG_NVRAM is not set
 CONFIG_RTC=y
 # CONFIG_R3964 is not set
@@ -979,127 +912,19 @@ CONFIG_HPET=y
 # CONFIG_HPET_RTC_IRQ is not set
 CONFIG_HPET_MMAP=y
 # CONFIG_HANGCHECK_TIMER is not set
-
-#
-# TPM devices
-#
 # CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 CONFIG_DEVPORT=y
-CONFIG_I2C=m
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=m
-
-#
-# I2C Algorithms
-#
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_I2C_SIMTEC is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_TINY_USB is not set
-# CONFIG_I2C_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VOODOO3 is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_I2C is not set
 
 #
 # SPI support
 #
 # CONFIG_SPI is not set
 # CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
 # CONFIG_W1 is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_AD7418 is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1029 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_K8TEMP is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-CONFIG_SENSORS_CORETEMP=y
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_MAX6650 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_SIS5595 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47M192 is not set
-CONFIG_SENSORS_SMSC47B397=m
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_VT8231 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83791D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83793 is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_SENSORS_HDAPS is not set
-# CONFIG_SENSORS_APPLESMC is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
 
 #
 # Multifunction device drivers
@@ -1149,15 +974,11 @@ CONFIG_SOUND=y
 # Open Sound System
 #
 CONFIG_SOUND_PRIME=y
-# CONFIG_OSS_OBSOLETE is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
 # CONFIG_SOUND_OSS is not set
-
-#
-# HID Devices
-#
+CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
 
@@ -1168,10 +989,7 @@ CONFIG_USB_HID=y
 # CONFIG_USB_HIDINPUT_POWERBOOK is not set
 # CONFIG_HID_FF is not set
 # CONFIG_USB_HIDDEV is not set
-
-#
-# USB support
-#
+CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
@@ -1185,6 +1003,7 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_PERSIST is not set
 # CONFIG_USB_OTG is not set
 
 #
@@ -1194,7 +1013,6 @@ CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
-# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
@@ -1202,6 +1020,7 @@ CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=y
 # CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
 
 #
 # USB Device Class drivers
@@ -1292,15 +1111,7 @@ CONFIG_USB_MON=y
 #
 # LED Triggers
 #
-
-#
-# InfiniBand support
-#
 # CONFIG_INFINIBAND is not set
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
 # CONFIG_EDAC is not set
 
 #
@@ -1320,11 +1131,13 @@ CONFIG_USB_MON=y
 #
 # DMA Devices
 #
+CONFIG_VIRTUALIZATION=y
+# CONFIG_KVM is not set
 
 #
-# Virtualization
+# Userspace I/O
 #
-# CONFIG_KVM is not set
+# CONFIG_UIO is not set
 
 #
 # Firmware Drivers
@@ -1332,6 +1145,7 @@ CONFIG_USB_MON=y
 # CONFIG_EDD is not set
 # CONFIG_DELL_RBU is not set
 # CONFIG_DCDBAS is not set
+CONFIG_DMIID=y
 
 #
 # File systems
@@ -1447,7 +1261,6 @@ CONFIG_SUNRPC=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -1524,8 +1337,9 @@ CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHED_DEBUG is not set
 # CONFIG_SCHEDSTATS is not set
-# CONFIG_TIMER_STATS is not set
+CONFIG_TIMER_STATS=y
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
@@ -1533,6 +1347,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_DEBUG_MUTEXES is not set
 # CONFIG_DEBUG_LOCK_ALLOC is not set
 # CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -1541,8 +1356,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_FRAME_POINTER is not set
-CONFIG_UNWIND_INFO=y
-CONFIG_STACK_UNWIND=y
 # CONFIG_FORCED_INLINING is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
@@ -1557,10 +1370,6 @@ CONFIG_DEBUG_STACKOVERFLOW=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
 # CONFIG_CRYPTO is not set
 
 #
@@ -1571,6 +1380,7 @@ CONFIG_BITREVERSE=y
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_PLIST=y
index ed56a8806eaba081efae13022bbceb32480bc2f4..b70f3e7cf06ca7a8943b4d90a7027c6c7e8a42cf 100644 (file)
@@ -38,6 +38,7 @@
 
 int sysctl_vsyscall32 = 1;
 
+#undef ARCH_DLINFO
 #define ARCH_DLINFO do {  \
        if (sysctl_vsyscall32) { \
        NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \
index 3f66e970d86fc692f4a4d1b205e87de279d76351..938278697e206bdb10027918f5aff8a587383be0 100644 (file)
@@ -104,7 +104,7 @@ ENTRY(ia32_sysenter_target)
        pushq   %rax
        CFI_ADJUST_CFA_OFFSET 8
        cld
-       SAVE_ARGS 0,0,0
+       SAVE_ARGS 0,0,1
        /* no need to do an access_ok check here because rbp has been
           32bit zero extended */ 
 1:     movl    (%rbp),%r9d
@@ -294,7 +294,7 @@ ia32_badarg:
  */                            
 
 ENTRY(ia32_syscall)
-       CFI_STARTPROC   simple
+       CFI_STARTPROC32 simple
        CFI_SIGNAL_FRAME
        CFI_DEF_CFA     rsp,SS+8-RIP
        /*CFI_REL_OFFSET        ss,SS-RIP*/
@@ -330,6 +330,7 @@ ia32_sysret:
 
 ia32_tracesys:                  
        SAVE_REST
+       CLEAR_RREGS
        movq $-ENOSYS,RAX(%rsp) /* really needed? */
        movq %rsp,%rdi        /* &pt_regs -> arg1 */
        call syscall_trace_enter
index a3d450d6c15b5219443efc735457a1c7f326ad1d..8f681cae7bf7df3c8a6749799d1d5b2f14682170 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/ioport.h>
 #include <asm/e820.h>
 #include <asm/io.h>
-#include <asm/proto.h>
+#include <asm/iommu.h>
 #include <asm/pci-direct.h>
 #include <asm/dma.h>
 #include <asm/k8.h>
@@ -214,7 +214,7 @@ void __init iommu_hole_init(void)
        if (iommu_aperture_disabled || !fix_aperture || !early_pci_allowed())
                return;
 
-       printk("Checking aperture...\n"); 
+       printk(KERN_INFO  "Checking aperture...\n");
 
        fix = 0;
        for (num = 24; num < 32; num++) {               
index 1b0e07bb87289cc5248fd9ecb7cde2338fcf6887..900ff38d68de5418d2fe6b6d34937da43035050a 100644 (file)
@@ -92,8 +92,9 @@ unsigned int safe_apic_wait_icr_idle(void)
 void enable_NMI_through_LVT0 (void * dummy)
 {
        unsigned int v;
-       
-       v = APIC_DM_NMI;                        /* unmask and set to NMI */
+
+       /* unmask and set to NMI */
+       v = APIC_DM_NMI;
        apic_write(APIC_LVT0, v);
 }
 
@@ -120,7 +121,7 @@ void ack_bad_irq(unsigned int irq)
         * holds up an irq slot - in excessive cases (when multiple
         * unexpected vectors occur) that might lock up the APIC
         * completely.
-        * But don't ack when the APIC is disabled. -AK
+        * But don't ack when the APIC is disabled. -AK
         */
        if (!disable_apic)
                ack_APIC_irq();
@@ -616,7 +617,7 @@ early_param("apic", apic_set_verbosity);
  * Detect and enable local APICs on non-SMP boards.
  * Original code written by Keir Fraser.
  * On AMD64 we trust the BIOS - if it says no APIC it is likely
- * not correctly set up (usually the APIC timer won't work etc.) 
+ * not correctly set up (usually the APIC timer won't work etc.)
  */
 
 static int __init detect_init_APIC (void)
@@ -789,13 +790,13 @@ static void setup_APIC_timer(unsigned int clocks)
        local_irq_save(flags);
 
        /* wait for irq slice */
-       if (hpet_address && hpet_use_timer) {
-               int trigger = hpet_readl(HPET_T0_CMP);
-               while (hpet_readl(HPET_COUNTER) >= trigger)
-                       /* do nothing */ ;
-               while (hpet_readl(HPET_COUNTER) <  trigger)
-                       /* do nothing */ ;
-       } else {
+       if (hpet_address && hpet_use_timer) {
+               int trigger = hpet_readl(HPET_T0_CMP);
+               while (hpet_readl(HPET_COUNTER) >= trigger)
+                       /* do nothing */ ;
+               while (hpet_readl(HPET_COUNTER) <  trigger)
+                       /* do nothing */ ;
+       } else {
                int c1, c2;
                outb_p(0x00, 0x43);
                c2 = inb_p(0x40);
@@ -881,10 +882,10 @@ static unsigned int calibration_result;
 
 void __init setup_boot_APIC_clock (void)
 {
-       if (disable_apic_timer) { 
-               printk(KERN_INFO "Disabling APIC timer\n"); 
-               return; 
-       } 
+       if (disable_apic_timer) {
+               printk(KERN_INFO "Disabling APIC timer\n");
+               return;
+       }
 
        printk(KERN_INFO "Using local APIC timer interrupts.\n");
        using_apic_timer = 1;
@@ -990,8 +991,8 @@ int setup_profiling_timer(unsigned int multiplier)
        return -EINVAL;
 }
 
-void setup_APIC_extened_lvt(unsigned char lvt_off, unsigned char vector,
-                           unsigned char msg_type, unsigned char mask)
+void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector,
+                            unsigned char msg_type, unsigned char mask)
 {
        unsigned long reg = (lvt_off << 4) + K8_APIC_EXT_LVT_BASE;
        unsigned int  v   = (mask << 16) | (msg_type << 8) | vector;
@@ -1128,20 +1129,6 @@ asmlinkage void smp_spurious_interrupt(void)
        if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
                ack_APIC_irq();
 
-#if 0
-       static unsigned long last_warning; 
-       static unsigned long skipped; 
-
-       /* see sw-dev-man vol 3, chapter 7.4.13.5 */
-       if (time_before(last_warning+30*HZ,jiffies)) { 
-               printk(KERN_INFO "spurious APIC interrupt on CPU#%d, %ld skipped.\n",
-                      smp_processor_id(), skipped);
-               last_warning = jiffies; 
-               skipped = 0;
-       } else { 
-               skipped++; 
-       } 
-#endif 
        irq_exit();
 }
 
@@ -1173,11 +1160,11 @@ asmlinkage void smp_error_interrupt(void)
           7: Illegal register address
        */
        printk (KERN_DEBUG "APIC error on CPU%d: %02x(%02x)\n",
-               smp_processor_id(), v , v1);
+               smp_processor_id(), v , v1);
        irq_exit();
 }
 
-int disable_apic; 
+int disable_apic;
 
 /*
  * This initializes the IO-APIC and APIC hardware if this is
@@ -1185,11 +1172,11 @@ int disable_apic;
  */
 int __init APIC_init_uniprocessor (void)
 {
-       if (disable_apic) { 
+       if (disable_apic) {
                printk(KERN_INFO "Apic disabled\n");
-               return -1; 
+               return -1;
        }
-       if (!cpu_has_apic) { 
+       if (!cpu_has_apic) {
                disable_apic = 1;
                printk(KERN_INFO "Apic disabled by BIOS\n");
                return -1;
@@ -1211,8 +1198,8 @@ int __init APIC_init_uniprocessor (void)
        return 0;
 }
 
-static __init int setup_disableapic(char *str) 
-{ 
+static __init int setup_disableapic(char *str)
+{
        disable_apic = 1;
        clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
        return 0;
@@ -1220,10 +1207,10 @@ static __init int setup_disableapic(char *str)
 early_param("disableapic", setup_disableapic);
 
 /* same as disableapic, for compatibility */
-static __init int setup_nolapic(char *str) 
-{ 
+static __init int setup_nolapic(char *str)
+{
        return setup_disableapic(str);
-} 
+}
 early_param("nolapic", setup_nolapic);
 
 static int __init parse_lapic_timer_c2_ok(char *arg)
@@ -1233,13 +1220,13 @@ static int __init parse_lapic_timer_c2_ok(char *arg)
 }
 early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok);
 
-static __init int setup_noapictimer(char *str) 
-{ 
+static __init int setup_noapictimer(char *str)
+{
        if (str[0] != ' ' && str[0] != 0)
                return 0;
        disable_apic_timer = 1;
        return 1;
-} 
+}
 
 static __init int setup_apicmaintimer(char *str)
 {
@@ -1264,5 +1251,5 @@ static __init int setup_apicpmtimer(char *s)
 }
 __setup("apicpmtimer", setup_apicpmtimer);
 
-__setup("noapictimer", setup_noapictimer); 
+__setup("noapictimer", setup_noapictimer);
 
index 13c6c37610e029978e13f829018600b21ed5ca42..0f4d5e209e9b7b015b1f99d55af809f4b80075bd 100644 (file)
@@ -193,37 +193,6 @@ unsigned long __init e820_end_of_ram(void)
        return end_pfn; 
 }
 
-/*
- * Find the hole size in the range.
- */
-unsigned long __init e820_hole_size(unsigned long start, unsigned long end)
-{
-       unsigned long ram = 0;
-       int i;
-
-       for (i = 0; i < e820.nr_map; i++) {
-               struct e820entry *ei = &e820.map[i];
-               unsigned long last, addr;
-
-               if (ei->type != E820_RAM ||
-                   ei->addr+ei->size <= start ||
-                   ei->addr >= end)
-                       continue;
-
-               addr = round_up(ei->addr, PAGE_SIZE);
-               if (addr < start)
-                       addr = start;
-
-               last = round_down(ei->addr + ei->size, PAGE_SIZE);
-               if (last >= end)
-                       last = end;
-
-               if (last > addr)
-                       ram += last - addr;
-       }
-       return ((end - start) - ram);
-}
-
 /*
  * Mark e820 reserved areas as busy for the resource manager.
  */
@@ -289,47 +258,61 @@ void __init e820_mark_nosave_regions(void)
        }
 }
 
-/* Walk the e820 map and register active regions within a node */
-void __init
-e820_register_active_regions(int nid, unsigned long start_pfn,
-                                                       unsigned long end_pfn)
+/*
+ * Finds an active region in the address range from start_pfn to end_pfn and
+ * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
+ */
+static int __init e820_find_active_region(const struct e820entry *ei,
+                                         unsigned long start_pfn,
+                                         unsigned long end_pfn,
+                                         unsigned long *ei_startpfn,
+                                         unsigned long *ei_endpfn)
 {
-       int i;
-       unsigned long ei_startpfn, ei_endpfn;
-       for (i = 0; i < e820.nr_map; i++) {
-               struct e820entry *ei = &e820.map[i];
-               ei_startpfn = round_up(ei->addr, PAGE_SIZE) >> PAGE_SHIFT;
-               ei_endpfn = round_down(ei->addr + ei->size, PAGE_SIZE)
-                                                               >> PAGE_SHIFT;
+       *ei_startpfn = round_up(ei->addr, PAGE_SIZE) >> PAGE_SHIFT;
+       *ei_endpfn = round_down(ei->addr + ei->size, PAGE_SIZE) >> PAGE_SHIFT;
 
-               /* Skip map entries smaller than a page */
-               if (ei_startpfn >= ei_endpfn)
-                       continue;
+       /* Skip map entries smaller than a page */
+       if (*ei_startpfn >= *ei_endpfn)
+               return 0;
 
-               /* Check if end_pfn_map should be updated */
-               if (ei->type != E820_RAM && ei_endpfn > end_pfn_map)
-                       end_pfn_map = ei_endpfn;
+       /* Check if end_pfn_map should be updated */
+       if (ei->type != E820_RAM && *ei_endpfn > end_pfn_map)
+               end_pfn_map = *ei_endpfn;
 
-               /* Skip if map is outside the node */
-               if (ei->type != E820_RAM ||
-                               ei_endpfn <= start_pfn ||
-                               ei_startpfn >= end_pfn)
-                       continue;
+       /* Skip if map is outside the node */
+       if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||
+                                   *ei_startpfn >= end_pfn)
+               return 0;
 
-               /* Check for overlaps */
-               if (ei_startpfn < start_pfn)
-                       ei_startpfn = start_pfn;
-               if (ei_endpfn > end_pfn)
-                       ei_endpfn = end_pfn;
+       /* Check for overlaps */
+       if (*ei_startpfn < start_pfn)
+               *ei_startpfn = start_pfn;
+       if (*ei_endpfn > end_pfn)
+               *ei_endpfn = end_pfn;
 
-               /* Obey end_user_pfn to save on memmap */
-               if (ei_startpfn >= end_user_pfn)
-                       continue;
-               if (ei_endpfn > end_user_pfn)
-                       ei_endpfn = end_user_pfn;
+       /* Obey end_user_pfn to save on memmap */
+       if (*ei_startpfn >= end_user_pfn)
+               return 0;
+       if (*ei_endpfn > end_user_pfn)
+               *ei_endpfn = end_user_pfn;
 
-               add_active_range(nid, ei_startpfn, ei_endpfn);
-       }
+       return 1;
+}
+
+/* Walk the e820 map and register active regions within a node */
+void __init
+e820_register_active_regions(int nid, unsigned long start_pfn,
+                                                       unsigned long end_pfn)
+{
+       unsigned long ei_startpfn;
+       unsigned long ei_endpfn;
+       int i;
+
+       for (i = 0; i < e820.nr_map; i++)
+               if (e820_find_active_region(&e820.map[i],
+                                           start_pfn, end_pfn,
+                                           &ei_startpfn, &ei_endpfn))
+                       add_active_range(nid, ei_startpfn, ei_endpfn);
 }
 
 /* 
@@ -350,12 +333,35 @@ void __init add_memory_region(unsigned long start, unsigned long size, int type)
        e820.nr_map++;
 }
 
+/*
+ * Find the hole size (in bytes) in the memory range.
+ * @start: starting address of the memory range to scan
+ * @end: ending address of the memory range to scan
+ */
+unsigned long __init e820_hole_size(unsigned long start, unsigned long end)
+{
+       unsigned long start_pfn = start >> PAGE_SHIFT;
+       unsigned long end_pfn = end >> PAGE_SHIFT;
+       unsigned long ei_startpfn;
+       unsigned long ei_endpfn;
+       unsigned long ram = 0;
+       int i;
+
+       for (i = 0; i < e820.nr_map; i++) {
+               if (e820_find_active_region(&e820.map[i],
+                                           start_pfn, end_pfn,
+                                           &ei_startpfn, &ei_endpfn))
+                       ram += ei_endpfn - ei_startpfn;
+       }
+       return end - start - (ram << PAGE_SHIFT);
+}
+
 void __init e820_print_map(char *who)
 {
        int i;
 
        for (i = 0; i < e820.nr_map; i++) {
-               printk(" %s: %016Lx - %016Lx ", who,
+               printk(KERN_INFO " %s: %016Lx - %016Lx ", who,
                        (unsigned long long) e820.map[i].addr,
                        (unsigned long long) (e820.map[i].addr + e820.map[i].size));
                switch (e820.map[i].type) {
index 990d9c218a5dd10e056833b6c2fa81e61b90919e..13aa4fd728f3dc7543ad49a37f825852a9a8ef00 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/pci_ids.h>
 #include <asm/pci-direct.h>
 #include <asm/proto.h>
+#include <asm/iommu.h>
 #include <asm/dma.h>
 
 static void __init via_bugs(void)
index a67f87bf4015a4072ae1ec9876b07f1f8555a790..830cfc6ee8cb1ac08297650f3efcf9e8a7a469a8 100644 (file)
@@ -282,7 +282,7 @@ sysret_careful:
 sysret_signal:
        TRACE_IRQS_ON
        sti
-       testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
+       testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP|_TIF_MCE_NOTIFY),%edx
        jz    1f
 
        /* Really a signal */
@@ -375,7 +375,7 @@ int_very_careful:
        jmp int_restore_rest
        
 int_signal:
-       testl $(_TIF_NOTIFY_RESUME|_TIF_SIGPENDING|_TIF_SINGLESTEP),%edx
+       testl $(_TIF_NOTIFY_RESUME|_TIF_SIGPENDING|_TIF_SINGLESTEP|_TIF_MCE_NOTIFY),%edx
        jz 1f
        movq %rsp,%rdi          # &ptregs -> arg1
        xorl %esi,%esi          # oldset -> arg2
@@ -599,7 +599,7 @@ retint_careful:
        jmp retint_check
        
 retint_signal:
-       testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx
+       testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP|_TIF_MCE_NOTIFY),%edx
        jz    retint_swapgs
        TRACE_IRQS_ON
        sti
index 941c84baecc8da3fc4496d912216760a083e034a..e89abcdbdde8172e25d6dff0ddb8323471495c66 100644 (file)
@@ -25,7 +25,7 @@
  */
 
        .text
-       .section .bootstrap.text
+       .section .text.head
        .code64
        .globl startup_64
 startup_64:
@@ -243,10 +243,16 @@ ENTRY(secondary_startup_64)
        lretq
 
        /* SMP bootup changes these two */
+#ifndef CONFIG_HOTPLUG_CPU
+       .pushsection .init.data
+#endif
        .align  8
        .globl  initial_code
 initial_code:
        .quad   x86_64_start_kernel
+#ifndef CONFIG_HOTPLUG_CPU
+       .popsection
+#endif
        .globl init_rsp
 init_rsp:
        .quad  init_thread_union+THREAD_SIZE-8
index b8286968662d0d19d21a99443f604016e0883ce2..e2d1b912e15469c1110553fa3ebc27c97fc3af9e 100644 (file)
@@ -133,7 +133,7 @@ struct clocksource clocksource_hpet = {
        .vread          = vread_hpet,
 };
 
-int hpet_arch_init(void)
+int __init hpet_arch_init(void)
 {
        unsigned int id;
        u64 tmp;
@@ -190,7 +190,7 @@ int hpet_reenable(void)
  */
 
 #define TICK_COUNT 100000000
-#define TICK_MIN   5000
+#define SMI_THRESHOLD 50000
 #define MAX_TRIES  5
 
 /*
@@ -205,7 +205,7 @@ static void __init read_hpet_tsc(int *hpet, int *tsc)
                tsc1 = get_cycles_sync();
                hpet1 = hpet_readl(HPET_COUNTER);
                tsc2 = get_cycles_sync();
-               if (tsc2 - tsc1 > TICK_MIN)
+               if ((tsc2 - tsc1) < SMI_THRESHOLD)
                        break;
        }
        *hpet = hpet1;
@@ -439,7 +439,7 @@ int hpet_rtc_dropped_irq(void)
        return 1;
 }
 
-irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id)
 {
        struct rtc_time curr_time;
        unsigned long rtc_int_flag = 0;
index 4b326655b2084a736272f1adb546ac5247d87863..948cae646099cc451a834e53c9a8b0ab5da037b7 100644 (file)
@@ -444,24 +444,6 @@ void __init init_ISA_irqs (void)
        }
 }
 
-void apic_timer_interrupt(void);
-void spurious_interrupt(void);
-void error_interrupt(void);
-void reschedule_interrupt(void);
-void call_function_interrupt(void);
-void irq_move_cleanup_interrupt(void);
-void invalidate_interrupt0(void);
-void invalidate_interrupt1(void);
-void invalidate_interrupt2(void);
-void invalidate_interrupt3(void);
-void invalidate_interrupt4(void);
-void invalidate_interrupt5(void);
-void invalidate_interrupt6(void);
-void invalidate_interrupt7(void);
-void thermal_interrupt(void);
-void threshold_interrupt(void);
-void i8254_timer_resume(void);
-
 static void setup_timer_hardware(void)
 {
        outb_p(0x34,0x43);              /* binary, mode 2, LSB/MSB, ch 0 */
index 1c6c6f7245736a77a95bc9ae3643156f5bd8d02c..050141c0602bbd10d6a429d0016ccd8e6fd3ad83 100644 (file)
@@ -152,6 +152,32 @@ static inline void io_apic_modify(unsigned int apic, unsigned int value)
        writel(value, &io_apic->data);
 }
 
+static int io_apic_level_ack_pending(unsigned int irq)
+{
+       struct irq_pin_list *entry;
+       unsigned long flags;
+       int pending = 0;
+
+       spin_lock_irqsave(&ioapic_lock, flags);
+       entry = irq_2_pin + irq;
+       for (;;) {
+               unsigned int reg;
+               int pin;
+
+               pin = entry->pin;
+               if (pin == -1)
+                       break;
+               reg = io_apic_read(entry->apic, 0x10 + pin*2);
+               /* Is the remote IRR bit set? */
+               pending |= (reg >> 14) & 1;
+               if (!entry->next)
+                       break;
+               entry = irq_2_pin + entry->next;
+       }
+       spin_unlock_irqrestore(&ioapic_lock, flags);
+       return pending;
+}
+
 /*
  * Synchronize the IO-APIC and the CPU by doing
  * a dummy read from the IO-APIC
@@ -1418,9 +1444,37 @@ static void ack_apic_level(unsigned int irq)
        ack_APIC_irq();
 
        /* Now we can move and renable the irq */
-       move_masked_irq(irq);
-       if (unlikely(do_unmask_irq))
+       if (unlikely(do_unmask_irq)) {
+               /* Only migrate the irq if the ack has been received.
+                *
+                * On rare occasions the broadcast level triggered ack gets
+                * delayed going to ioapics, and if we reprogram the
+                * vector while Remote IRR is still set the irq will never
+                * fire again.
+                *
+                * To prevent this scenario we read the Remote IRR bit
+                * of the ioapic.  This has two effects.
+                * - On any sane system the read of the ioapic will
+                *   flush writes (and acks) going to the ioapic from
+                *   this cpu.
+                * - We get to see if the ACK has actually been delivered.
+                *
+                * Based on failed experiments of reprogramming the
+                * ioapic entry from outside of irq context starting
+                * with masking the ioapic entry and then polling until
+                * Remote IRR was clear before reprogramming the
+                * ioapic I don't trust the Remote IRR bit to be
+                * completey accurate.
+                *
+                * However there appears to be no other way to plug
+                * this race, so if the Remote IRR bit is not
+                * accurate and is causing problems then it is a hardware bug
+                * and you can go talk to the chipset vendor about it.
+                */
+               if (!io_apic_level_ack_pending(irq))
+                       move_masked_irq(irq);
                unmask_IO_APIC_irq(irq);
+       }
 }
 
 static struct irq_chip ioapic_chip __read_mostly = {
index d4a0d0ac99351a8fd1b67ca9f65fa6aa01861b9b..a30e004682e2dc60fe81a7e1caf007fbbcf314a7 100644 (file)
@@ -39,9 +39,9 @@
 #include <linux/module.h>
 #include <linux/kdebug.h>
 
-#include <asm/cacheflush.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
+#include <asm/alternative.h>
 
 void jprobe_return_end(void);
 static void __kprobes arch_copy_kprobe(struct kprobe *p);
@@ -209,16 +209,12 @@ static void __kprobes arch_copy_kprobe(struct kprobe *p)
 
 void __kprobes arch_arm_kprobe(struct kprobe *p)
 {
-       *p->addr = BREAKPOINT_INSTRUCTION;
-       flush_icache_range((unsigned long) p->addr,
-                          (unsigned long) p->addr + sizeof(kprobe_opcode_t));
+       text_poke(p->addr, ((unsigned char []){BREAKPOINT_INSTRUCTION}), 1);
 }
 
 void __kprobes arch_disarm_kprobe(struct kprobe *p)
 {
-       *p->addr = p->opcode;
-       flush_icache_range((unsigned long) p->addr,
-                          (unsigned long) p->addr + sizeof(kprobe_opcode_t));
+       text_poke(p->addr, &p->opcode, 1);
 }
 
 void __kprobes arch_remove_kprobe(struct kprobe *p)
index f3fb8174559e43000a0a1defa029e5026c8469d7..a66d607f5b924e09d864120d1d656c3e1a1c2da0 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/capability.h>
 #include <linux/cpu.h>
 #include <linux/percpu.h>
+#include <linux/poll.h>
+#include <linux/thread_info.h>
 #include <linux/ctype.h>
 #include <linux/kmod.h>
 #include <linux/kdebug.h>
@@ -26,6 +28,7 @@
 #include <asm/mce.h>
 #include <asm/uaccess.h>
 #include <asm/smp.h>
+#include <asm/idle.h>
 
 #define MISC_MCELOG_MINOR 227
 #define NR_BANKS 6
@@ -34,13 +37,17 @@ atomic_t mce_entry;
 
 static int mce_dont_init;
 
-/* 0: always panic, 1: panic if deadlock possible, 2: try to avoid panic,
-   3: never panic or exit (for testing only) */
+/*
+ * Tolerant levels:
+ *   0: always panic on uncorrected errors, log corrected errors
+ *   1: panic or SIGBUS on uncorrected errors, log corrected errors
+ *   2: SIGBUS or log uncorrected errors (if possible), log corrected errors
+ *   3: never panic or SIGBUS, log all errors (for testing only)
+ */
 static int tolerant = 1;
 static int banks;
 static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL };
-static unsigned long console_logged;
-static int notify_user;
+static unsigned long notify_user;
 static int rip_msr;
 static int mce_bootlog = 1;
 static atomic_t mce_events;
@@ -48,6 +55,8 @@ static atomic_t mce_events;
 static char trigger[128];
 static char *trigger_argv[2] = { trigger, NULL };
 
+static DECLARE_WAIT_QUEUE_HEAD(mce_wait);
+
 /*
  * Lockless MCE logging infrastructure.
  * This avoids deadlocks on printk locks without having to break locks. Also
@@ -94,8 +103,7 @@ void mce_log(struct mce *mce)
        mcelog.entry[entry].finished = 1;
        wmb();
 
-       if (!test_and_set_bit(0, &console_logged))
-               notify_user = 1;
+       set_bit(0, &notify_user);
 }
 
 static void print_mce(struct mce *m)
@@ -128,6 +136,7 @@ static void print_mce(struct mce *m)
 static void mce_panic(char *msg, struct mce *backup, unsigned long start)
 { 
        int i;
+
        oops_begin();
        for (i = 0; i < MCE_LOG_LEN; i++) {
                unsigned long tsc = mcelog.entry[i].tsc;
@@ -139,10 +148,7 @@ static void mce_panic(char *msg, struct mce *backup, unsigned long start)
        }
        if (backup)
                print_mce(backup);
-       if (tolerant >= 3)
-               printk("Fake panic: %s\n", msg);
-       else
-               panic(msg);
+       panic(msg);
 } 
 
 static int mce_available(struct cpuinfo_x86 *c)
@@ -167,17 +173,6 @@ static inline void mce_get_rip(struct mce *m, struct pt_regs *regs)
        }
 }
 
-static void do_mce_trigger(void)
-{
-       static atomic_t mce_logged;
-       int events = atomic_read(&mce_events);
-       if (events != atomic_read(&mce_logged) && trigger[0]) {
-               /* Small race window, but should be harmless.  */
-               atomic_set(&mce_logged, events);
-               call_usermodehelper(trigger, trigger_argv, NULL, UMH_NO_WAIT);
-       }
-}
-
 /* 
  * The actual machine check handler
  */
@@ -185,11 +180,19 @@ static void do_mce_trigger(void)
 void do_machine_check(struct pt_regs * regs, long error_code)
 {
        struct mce m, panicm;
-       int nowayout = (tolerant < 1); 
-       int kill_it = 0;
        u64 mcestart = 0;
        int i;
        int panicm_found = 0;
+       /*
+        * If no_way_out gets set, there is no safe way to recover from this
+        * MCE.  If tolerant is cranked up, we'll try anyway.
+        */
+       int no_way_out = 0;
+       /*
+        * If kill_it gets set, there might be a way to recover from this
+        * error.
+        */
+       int kill_it = 0;
 
        atomic_inc(&mce_entry);
 
@@ -201,8 +204,9 @@ void do_machine_check(struct pt_regs * regs, long error_code)
        memset(&m, 0, sizeof(struct mce));
        m.cpu = smp_processor_id();
        rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus);
+       /* if the restart IP is not valid, we're done for */
        if (!(m.mcgstatus & MCG_STATUS_RIPV))
-               kill_it = 1;
+               no_way_out = 1;
        
        rdtscll(mcestart);
        barrier();
@@ -221,10 +225,18 @@ void do_machine_check(struct pt_regs * regs, long error_code)
                        continue;
 
                if (m.status & MCI_STATUS_EN) {
-                       /* In theory _OVER could be a nowayout too, but
-                          assume any overflowed errors were no fatal. */
-                       nowayout |= !!(m.status & MCI_STATUS_PCC);
-                       kill_it |= !!(m.status & MCI_STATUS_UC);
+                       /* if PCC was set, there's no way out */
+                       no_way_out |= !!(m.status & MCI_STATUS_PCC);
+                       /*
+                        * If this error was uncorrectable and there was
+                        * an overflow, we're in trouble.  If no overflow,
+                        * we might get away with just killing a task.
+                        */
+                       if (m.status & MCI_STATUS_UC) {
+                               if (tolerant < 1 || m.status & MCI_STATUS_OVER)
+                                       no_way_out = 1;
+                               kill_it = 1;
+                       }
                }
 
                if (m.status & MCI_STATUS_MISCV)
@@ -235,7 +247,6 @@ void do_machine_check(struct pt_regs * regs, long error_code)
                mce_get_rip(&m, regs);
                if (error_code >= 0)
                        rdtscll(m.tsc);
-               wrmsrl(MSR_IA32_MC0_STATUS + i*4, 0);
                if (error_code != -2)
                        mce_log(&m);
 
@@ -251,45 +262,59 @@ void do_machine_check(struct pt_regs * regs, long error_code)
        }
 
        /* Never do anything final in the polling timer */
-       if (!regs) {
-               /* Normal interrupt context here. Call trigger for any new
-                  events. */
-               do_mce_trigger();
+       if (!regs)
                goto out;
-       }
 
        /* If we didn't find an uncorrectable error, pick
           the last one (shouldn't happen, just being safe). */
        if (!panicm_found)
                panicm = m;
-       if (nowayout)
+
+       /*
+        * If we have decided that we just CAN'T continue, and the user
+        *  has not set tolerant to an insane level, give up and die.
+        */
+       if (no_way_out && tolerant < 3)
                mce_panic("Machine check", &panicm, mcestart);
-       if (kill_it) {
+
+       /*
+        * If the error seems to be unrecoverable, something should be
+        * done.  Try to kill as little as possible.  If we can kill just
+        * one task, do that.  If the user has set the tolerance very
+        * high, don't try to do anything at all.
+        */
+       if (kill_it && tolerant < 3) {
                int user_space = 0;
 
-               if (m.mcgstatus & MCG_STATUS_RIPV)
+               /*
+                * If the EIPV bit is set, it means the saved IP is the
+                * instruction which caused the MCE.
+                */
+               if (m.mcgstatus & MCG_STATUS_EIPV)
                        user_space = panicm.rip && (panicm.cs & 3);
-               
-               /* When the machine was in user space and the CPU didn't get
-                  confused it's normally not necessary to panic, unless you 
-                  are paranoid (tolerant == 0)
-
-                  RED-PEN could be more tolerant for MCEs in idle,
-                  but most likely they occur at boot anyways, where
-                  it is best to just halt the machine. */
-               if ((!user_space && (panic_on_oops || tolerant < 2)) ||
-                   (unsigned)current->pid <= 1)
-                       mce_panic("Uncorrected machine check", &panicm, mcestart);
-
-               /* do_exit takes an awful lot of locks and has as
-                  slight risk of deadlocking. If you don't want that
-                  don't set tolerant >= 2 */
-               if (tolerant < 3)
+
+               /*
+                * If we know that the error was in user space, send a
+                * SIGBUS.  Otherwise, panic if tolerance is low.
+                *
+                * do_exit() takes an awful lot of locks and has a slight
+                * risk of deadlocking.
+                */
+               if (user_space) {
                        do_exit(SIGBUS);
+               } else if (panic_on_oops || tolerant < 2) {
+                       mce_panic("Uncorrected machine check",
+                               &panicm, mcestart);
+               }
        }
 
+       /* notify userspace ASAP */
+       set_thread_flag(TIF_MCE_NOTIFY);
+
  out:
-       /* Last thing done in the machine check exception to clear state. */
+       /* the last thing we do is clear state */
+       for (i = 0; i < banks; i++)
+               wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0);
        wrmsrl(MSR_IA32_MCG_STATUS, 0);
  out2:
        atomic_dec(&mce_entry);
@@ -344,37 +369,69 @@ static void mcheck_timer(struct work_struct *work)
        on_each_cpu(mcheck_check_cpu, NULL, 1, 1);
 
        /*
-        * It's ok to read stale data here for notify_user and
-        * console_logged as we'll simply get the updated versions
-        * on the next mcheck_timer execution and atomic operations
-        * on console_logged act as synchronization for notify_user
-        * writes.
+        * Alert userspace if needed.  If we logged an MCE, reduce the
+        * polling interval, otherwise increase the polling interval.
         */
-       if (notify_user && console_logged) {
+       if (mce_notify_user()) {
+               next_interval = max(next_interval/2, HZ/100);
+       } else {
+               next_interval = min(next_interval*2,
+                               (int)round_jiffies_relative(check_interval*HZ));
+       }
+
+       schedule_delayed_work(&mcheck_work, next_interval);
+}
+
+/*
+ * This is only called from process context.  This is where we do
+ * anything we need to alert userspace about new MCEs.  This is called
+ * directly from the poller and also from entry.S and idle, thanks to
+ * TIF_MCE_NOTIFY.
+ */
+int mce_notify_user(void)
+{
+       clear_thread_flag(TIF_MCE_NOTIFY);
+       if (test_and_clear_bit(0, &notify_user)) {
                static unsigned long last_print;
                unsigned long now = jiffies;
 
-               /* if we logged an MCE, reduce the polling interval */
-               next_interval = max(next_interval/2, HZ/100);
-               notify_user = 0;
-               clear_bit(0, &console_logged);
+               wake_up_interruptible(&mce_wait);
+               if (trigger[0])
+                       call_usermodehelper(trigger, trigger_argv, NULL,
+                                               UMH_NO_WAIT);
+
                if (time_after_eq(now, last_print + (check_interval*HZ))) {
                        last_print = now;
                        printk(KERN_INFO "Machine check events logged\n");
                }
-       } else {
-               next_interval = min(next_interval*2, check_interval*HZ);
+
+               return 1;
        }
+       return 0;
+}
 
-       schedule_delayed_work(&mcheck_work, next_interval);
+/* see if the idle task needs to notify userspace */
+static int
+mce_idle_callback(struct notifier_block *nfb, unsigned long action, void *junk)
+{
+       /* IDLE_END should be safe - interrupts are back on */
+       if (action == IDLE_END && test_thread_flag(TIF_MCE_NOTIFY))
+               mce_notify_user();
+
+       return NOTIFY_OK;
 }
 
+static struct notifier_block mce_idle_notifier = {
+       .notifier_call = mce_idle_callback,
+};
 
 static __init int periodic_mcheck_init(void)
 { 
        next_interval = check_interval * HZ;
        if (next_interval)
-               schedule_delayed_work(&mcheck_work, next_interval);
+               schedule_delayed_work(&mcheck_work,
+                                     round_jiffies_relative(next_interval));
+       idle_notifier_register(&mce_idle_notifier);
        return 0;
 } 
 __initcall(periodic_mcheck_init);
@@ -465,6 +522,40 @@ void __cpuinit mcheck_init(struct cpuinfo_x86 *c)
  * Character device to read and clear the MCE log.
  */
 
+static DEFINE_SPINLOCK(mce_state_lock);
+static int open_count; /* #times opened */
+static int open_exclu; /* already open exclusive? */
+
+static int mce_open(struct inode *inode, struct file *file)
+{
+       spin_lock(&mce_state_lock);
+
+       if (open_exclu || (open_count && (file->f_flags & O_EXCL))) {
+               spin_unlock(&mce_state_lock);
+               return -EBUSY;
+       }
+
+       if (file->f_flags & O_EXCL)
+               open_exclu = 1;
+       open_count++;
+
+       spin_unlock(&mce_state_lock);
+
+       return nonseekable_open(inode, file);
+}
+
+static int mce_release(struct inode *inode, struct file *file)
+{
+       spin_lock(&mce_state_lock);
+
+       open_count--;
+       open_exclu = 0;
+
+       spin_unlock(&mce_state_lock);
+
+       return 0;
+}
+
 static void collect_tscs(void *data) 
 { 
        unsigned long *cpu_tsc = (unsigned long *)data;
@@ -532,6 +623,14 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff
        return err ? -EFAULT : buf - ubuf; 
 }
 
+static unsigned int mce_poll(struct file *file, poll_table *wait)
+{
+       poll_wait(file, &mce_wait, wait);
+       if (rcu_dereference(mcelog.next))
+               return POLLIN | POLLRDNORM;
+       return 0;
+}
+
 static int mce_ioctl(struct inode *i, struct file *f,unsigned int cmd, unsigned long arg)
 {
        int __user *p = (int __user *)arg;
@@ -555,7 +654,10 @@ static int mce_ioctl(struct inode *i, struct file *f,unsigned int cmd, unsigned
 }
 
 static const struct file_operations mce_chrdev_ops = {
+       .open = mce_open,
+       .release = mce_release,
        .read = mce_read,
+       .poll = mce_poll,
        .ioctl = mce_ioctl,
 };
 
@@ -565,6 +667,20 @@ static struct miscdevice mce_log_device = {
        &mce_chrdev_ops,
 };
 
+static unsigned long old_cr4 __initdata;
+
+void __init stop_mce(void)
+{
+       old_cr4 = read_cr4();
+       clear_in_cr4(X86_CR4_MCE);
+}
+
+void __init restart_mce(void)
+{
+       if (old_cr4 & X86_CR4_MCE)
+               set_in_cr4(X86_CR4_MCE);
+}
+
 /* 
  * Old style boot options parsing. Only for compatibility. 
  */
@@ -620,7 +736,8 @@ static void mce_restart(void)
        on_each_cpu(mce_init, NULL, 1, 1);       
        next_interval = check_interval * HZ;
        if (next_interval)
-               schedule_delayed_work(&mcheck_work, next_interval);
+               schedule_delayed_work(&mcheck_work,
+                                     round_jiffies_relative(next_interval));
 }
 
 static struct sysdev_class mce_sysclass = {
index 03356e64f9c8cde580f27075e00451440d2751e3..2f8a7f18b0fea31d9e9c90b829de6f1548b6b584 100644 (file)
@@ -157,9 +157,9 @@ void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c)
                        high |= K8_APIC_EXT_LVT_ENTRY_THRESHOLD << 20;
                        wrmsr(address, low, high);
 
-                       setup_APIC_extened_lvt(K8_APIC_EXT_LVT_ENTRY_THRESHOLD,
-                                              THRESHOLD_APIC_VECTOR,
-                                              K8_APIC_EXT_INT_MSG_FIX, 0);
+                       setup_APIC_extended_lvt(K8_APIC_EXT_LVT_ENTRY_THRESHOLD,
+                                               THRESHOLD_APIC_VECTOR,
+                                               K8_APIC_EXT_INT_MSG_FIX, 0);
 
                        threshold_defaults.address = address;
                        threshold_restart_bank(&threshold_defaults, 0, 0);
index 61ae57eb9e4ca4a526bcb8e82db6cfa373b75022..8bf0ca03ac8e8a78f13ca5ea86842e02cfca9be0 100644 (file)
@@ -32,7 +32,6 @@
 
 /* Have we found an MP table */
 int smp_found_config;
-unsigned int __initdata maxcpus = NR_CPUS;
 
 /*
  * Various Linux-internal data structures created from the
@@ -649,6 +648,20 @@ static int mp_find_ioapic(int gsi)
        return -1;
 }
 
+static u8 uniq_ioapic_id(u8 id)
+{
+       int i;
+       DECLARE_BITMAP(used, 256);
+       bitmap_zero(used, 256);
+       for (i = 0; i < nr_ioapics; i++) {
+               struct mpc_config_ioapic *ia = &mp_ioapics[i];
+               __set_bit(ia->mpc_apicid, used);
+       }
+       if (!test_bit(id, used))
+               return id;
+       return find_first_zero_bit(used, 256);
+}
+
 void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base)
 {
        int idx = 0;
@@ -656,14 +669,14 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base)
        if (bad_ioapic(address))
                return;
 
-       idx = nr_ioapics++;
+       idx = nr_ioapics;
 
        mp_ioapics[idx].mpc_type = MP_IOAPIC;
        mp_ioapics[idx].mpc_flags = MPC_APIC_USABLE;
        mp_ioapics[idx].mpc_apicaddr = address;
 
        set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
-       mp_ioapics[idx].mpc_apicid = id;
+       mp_ioapics[idx].mpc_apicid = uniq_ioapic_id(id);
        mp_ioapics[idx].mpc_apicver = 0;
        
        /* 
@@ -680,6 +693,8 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base)
                mp_ioapics[idx].mpc_apicaddr,
                mp_ioapic_routing[idx].gsi_start,
                mp_ioapic_routing[idx].gsi_end);
+
+       nr_ioapics++;
 }
 
 void __init
index edbbc59b752334d570cb939c70ece3f43ca8ae42..cb8ee9d02f8682d4e52374aae1847a4daf03292a 100644 (file)
@@ -384,11 +384,14 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
        return rc;
 }
 
+static unsigned ignore_nmis;
+
 asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code)
 {
        nmi_enter();
        add_pda(__nmi_count,1);
-       default_do_nmi(regs);
+       if (!ignore_nmis)
+               default_do_nmi(regs);
        nmi_exit();
 }
 
@@ -401,6 +404,18 @@ int do_nmi_callback(struct pt_regs * regs, int cpu)
        return 0;
 }
 
+void stop_nmi(void)
+{
+       acpi_nmi_disable();
+       ignore_nmis++;
+}
+
+void restart_nmi(void)
+{
+       ignore_nmis--;
+       acpi_nmi_enable();
+}
+
 #ifdef CONFIG_SYSCTL
 
 static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
index 5bd20b542c1efc47a0d93da505135bb08a35f346..ba16c968ca3f8a8a4f37c1862b1a9caa35261204 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Derived from arch/powerpc/kernel/iommu.c
  *
- * Copyright (C) IBM Corporation, 2006
+ * Copyright IBM Corporation, 2006-2007
  * Copyright (C) 2006  Jon Mason <jdmason@kudzu.us>
  *
  * Author: Jon Mason <jdmason@kudzu.us>
@@ -35,7 +35,7 @@
 #include <linux/pci_ids.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
-#include <asm/proto.h>
+#include <asm/iommu.h>
 #include <asm/calgary.h>
 #include <asm/tce.h>
 #include <asm/pci-direct.h>
@@ -50,13 +50,7 @@ int use_calgary __read_mostly = 0;
 #endif /* CONFIG_CALGARY_DEFAULT_ENABLED */
 
 #define PCI_DEVICE_ID_IBM_CALGARY 0x02a1
-#define PCI_VENDOR_DEVICE_ID_CALGARY \
-       (PCI_VENDOR_ID_IBM | PCI_DEVICE_ID_IBM_CALGARY << 16)
-
-/* we need these for register space address calculation */
-#define START_ADDRESS           0xfe000000
-#define CHASSIS_BASE            0
-#define ONE_BASED_CHASSIS_NUM   1
+#define PCI_DEVICE_ID_IBM_CALIOC2 0x0308
 
 /* register offsets inside the host bridge space */
 #define CALGARY_CONFIG_REG     0x0108
@@ -80,6 +74,12 @@ int use_calgary __read_mostly = 0;
 #define PHB_MEM_2_SIZE_LOW     0x02E0
 #define PHB_DOSHOLE_OFFSET     0x08E0
 
+/* CalIOC2 specific */
+#define PHB_SAVIOR_L2          0x0DB0
+#define PHB_PAGE_MIG_CTRL      0x0DA8
+#define PHB_PAGE_MIG_DEBUG     0x0DA0
+#define PHB_ROOT_COMPLEX_STATUS 0x0CB0
+
 /* PHB_CONFIG_RW */
 #define PHB_TCE_ENABLE         0x20000000
 #define PHB_SLOT_DISABLE       0x1C000000
@@ -92,7 +92,11 @@ int use_calgary __read_mostly = 0;
 /* CSR (Channel/DMA Status Register) */
 #define CSR_AGENT_MASK         0xffe0ffff
 /* CCR (Calgary Configuration Register) */
-#define CCR_2SEC_TIMEOUT        0x000000000000000EUL
+#define CCR_2SEC_TIMEOUT       0x000000000000000EUL
+/* PMCR/PMDR (Page Migration Control/Debug Registers */
+#define PMR_SOFTSTOP           0x80000000
+#define PMR_SOFTSTOPFAULT      0x40000000
+#define PMR_HARDSTOP           0x20000000
 
 #define MAX_NUM_OF_PHBS                8 /* how many PHBs in total? */
 #define MAX_NUM_CHASSIS                8 /* max number of chassis */
@@ -155,9 +159,26 @@ struct calgary_bus_info {
        void __iomem *bbar;
 };
 
-static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, };
+static void calgary_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev);
+static void calgary_tce_cache_blast(struct iommu_table *tbl);
+static void calgary_dump_error_regs(struct iommu_table *tbl);
+static void calioc2_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev);
+static void calioc2_tce_cache_blast(struct iommu_table *tbl);
+static void calioc2_dump_error_regs(struct iommu_table *tbl);
+
+static struct cal_chipset_ops calgary_chip_ops = {
+       .handle_quirks = calgary_handle_quirks,
+       .tce_cache_blast = calgary_tce_cache_blast,
+       .dump_error_regs = calgary_dump_error_regs
+};
 
-static void tce_cache_blast(struct iommu_table *tbl);
+static struct cal_chipset_ops calioc2_chip_ops = {
+       .handle_quirks = calioc2_handle_quirks,
+       .tce_cache_blast = calioc2_tce_cache_blast,
+       .dump_error_regs = calioc2_dump_error_regs
+};
+
+static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, };
 
 /* enable this to stress test the chip's TCE cache */
 #ifdef CONFIG_IOMMU_DEBUG
@@ -187,6 +208,7 @@ static inline unsigned long verify_bit_range(unsigned long* bitmap,
 {
        return ~0UL;
 }
+
 #endif /* CONFIG_IOMMU_DEBUG */
 
 static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen)
@@ -206,11 +228,12 @@ static inline int translate_phb(struct pci_dev* dev)
 }
 
 static void iommu_range_reserve(struct iommu_table *tbl,
-        unsigned long start_addr, unsigned int npages)
+       unsigned long start_addr, unsigned int npages)
 {
        unsigned long index;
        unsigned long end;
        unsigned long badbit;
+       unsigned long flags;
 
        index = start_addr >> PAGE_SHIFT;
 
@@ -222,6 +245,8 @@ static void iommu_range_reserve(struct iommu_table *tbl,
        if (end > tbl->it_size) /* don't go off the table */
                end = tbl->it_size;
 
+       spin_lock_irqsave(&tbl->it_lock, flags);
+
        badbit = verify_bit_range(tbl->it_map, 0, index, end);
        if (badbit != ~0UL) {
                if (printk_ratelimit())
@@ -231,23 +256,29 @@ static void iommu_range_reserve(struct iommu_table *tbl,
        }
 
        set_bit_string(tbl->it_map, index, npages);
+
+       spin_unlock_irqrestore(&tbl->it_lock, flags);
 }
 
 static unsigned long iommu_range_alloc(struct iommu_table *tbl,
        unsigned int npages)
 {
+       unsigned long flags;
        unsigned long offset;
 
        BUG_ON(npages == 0);
 
+       spin_lock_irqsave(&tbl->it_lock, flags);
+
        offset = find_next_zero_string(tbl->it_map, tbl->it_hint,
                                       tbl->it_size, npages);
        if (offset == ~0UL) {
-               tce_cache_blast(tbl);
+               tbl->chip_ops->tce_cache_blast(tbl);
                offset = find_next_zero_string(tbl->it_map, 0,
                                               tbl->it_size, npages);
                if (offset == ~0UL) {
                        printk(KERN_WARNING "Calgary: IOMMU full.\n");
+                       spin_unlock_irqrestore(&tbl->it_lock, flags);
                        if (panic_on_overflow)
                                panic("Calgary: fix the allocator.\n");
                        else
@@ -259,17 +290,17 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl,
        tbl->it_hint = offset + npages;
        BUG_ON(tbl->it_hint > tbl->it_size);
 
+       spin_unlock_irqrestore(&tbl->it_lock, flags);
+
        return offset;
 }
 
 static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *vaddr,
        unsigned int npages, int direction)
 {
-       unsigned long entry, flags;
+       unsigned long entry;
        dma_addr_t ret = bad_dma_address;
 
-       spin_lock_irqsave(&tbl->it_lock, flags);
-
        entry = iommu_range_alloc(tbl, npages);
 
        if (unlikely(entry == bad_dma_address))
@@ -282,23 +313,21 @@ static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *vaddr,
        tce_build(tbl, entry, npages, (unsigned long)vaddr & PAGE_MASK,
                  direction);
 
-       spin_unlock_irqrestore(&tbl->it_lock, flags);
-
        return ret;
 
 error:
-       spin_unlock_irqrestore(&tbl->it_lock, flags);
        printk(KERN_WARNING "Calgary: failed to allocate %u pages in "
               "iommu %p\n", npages, tbl);
        return bad_dma_address;
 }
 
-static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
+static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
        unsigned int npages)
 {
        unsigned long entry;
        unsigned long badbit;
        unsigned long badend;
+       unsigned long flags;
 
        /* were we called with bad_dma_address? */
        badend = bad_dma_address + (EMERGENCY_PAGES * PAGE_SIZE);
@@ -315,6 +344,8 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
 
        tce_free(tbl, entry, npages);
 
+       spin_lock_irqsave(&tbl->it_lock, flags);
+
        badbit = verify_bit_range(tbl->it_map, 1, entry, entry + npages);
        if (badbit != ~0UL) {
                if (printk_ratelimit())
@@ -324,23 +355,40 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
        }
 
        __clear_bit_string(tbl->it_map, entry, npages);
+
+       spin_unlock_irqrestore(&tbl->it_lock, flags);
 }
 
-static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
-       unsigned int npages)
+static inline struct iommu_table *find_iommu_table(struct device *dev)
 {
-       unsigned long flags;
+       struct pci_dev *pdev;
+       struct pci_bus *pbus;
+       struct iommu_table *tbl;
 
-       spin_lock_irqsave(&tbl->it_lock, flags);
+       pdev = to_pci_dev(dev);
 
-       __iommu_free(tbl, dma_addr, npages);
+       /* is the device behind a bridge? */
+       if (unlikely(pdev->bus->parent))
+               pbus = pdev->bus->parent;
+       else
+               pbus = pdev->bus;
 
-       spin_unlock_irqrestore(&tbl->it_lock, flags);
+       tbl = pci_iommu(pbus);
+
+       BUG_ON(pdev->bus->parent &&
+              (tbl->it_busno != pdev->bus->parent->number));
+
+       return tbl;
 }
 
-static void __calgary_unmap_sg(struct iommu_table *tbl,
+static void calgary_unmap_sg(struct device *dev,
        struct scatterlist *sglist, int nelems, int direction)
 {
+       struct iommu_table *tbl = find_iommu_table(dev);
+
+       if (!translate_phb(to_pci_dev(dev)))
+               return;
+
        while (nelems--) {
                unsigned int npages;
                dma_addr_t dma = sglist->dma_address;
@@ -350,33 +398,17 @@ static void __calgary_unmap_sg(struct iommu_table *tbl,
                        break;
 
                npages = num_dma_pages(dma, dmalen);
-               __iommu_free(tbl, dma, npages);
+               iommu_free(tbl, dma, npages);
                sglist++;
        }
 }
 
-void calgary_unmap_sg(struct device *dev, struct scatterlist *sglist,
-                     int nelems, int direction)
-{
-       unsigned long flags;
-       struct iommu_table *tbl = to_pci_dev(dev)->bus->self->sysdata;
-
-       if (!translate_phb(to_pci_dev(dev)))
-               return;
-
-       spin_lock_irqsave(&tbl->it_lock, flags);
-
-       __calgary_unmap_sg(tbl, sglist, nelems, direction);
-
-       spin_unlock_irqrestore(&tbl->it_lock, flags);
-}
-
 static int calgary_nontranslate_map_sg(struct device* dev,
        struct scatterlist *sg, int nelems, int direction)
 {
        int i;
 
-       for (i = 0; i < nelems; i++ ) {
+       for (i = 0; i < nelems; i++ ) {
                struct scatterlist *s = &sg[i];
                BUG_ON(!s->page);
                s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
@@ -385,11 +417,10 @@ static int calgary_nontranslate_map_sg(struct device* dev,
        return nelems;
 }
 
-int calgary_map_sg(struct device *dev, struct scatterlist *sg,
+static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
        int nelems, int direction)
 {
-       struct iommu_table *tbl = to_pci_dev(dev)->bus->self->sysdata;
-       unsigned long flags;
+       struct iommu_table *tbl = find_iommu_table(dev);
        unsigned long vaddr;
        unsigned int npages;
        unsigned long entry;
@@ -398,8 +429,6 @@ int calgary_map_sg(struct device *dev, struct scatterlist *sg,
        if (!translate_phb(to_pci_dev(dev)))
                return calgary_nontranslate_map_sg(dev, sg, nelems, direction);
 
-       spin_lock_irqsave(&tbl->it_lock, flags);
-
        for (i = 0; i < nelems; i++ ) {
                struct scatterlist *s = &sg[i];
                BUG_ON(!s->page);
@@ -423,26 +452,23 @@ int calgary_map_sg(struct device *dev, struct scatterlist *sg,
                s->dma_length = s->length;
        }
 
-       spin_unlock_irqrestore(&tbl->it_lock, flags);
-
        return nelems;
 error:
-       __calgary_unmap_sg(tbl, sg, nelems, direction);
+       calgary_unmap_sg(dev, sg, nelems, direction);
        for (i = 0; i < nelems; i++) {
                sg[i].dma_address = bad_dma_address;
                sg[i].dma_length = 0;
        }
-       spin_unlock_irqrestore(&tbl->it_lock, flags);
        return 0;
 }
 
-dma_addr_t calgary_map_single(struct device *dev, void *vaddr,
+static dma_addr_t calgary_map_single(struct device *dev, void *vaddr,
        size_t size, int direction)
 {
        dma_addr_t dma_handle = bad_dma_address;
        unsigned long uaddr;
        unsigned int npages;
-       struct iommu_table *tbl = to_pci_dev(dev)->bus->self->sysdata;
+       struct iommu_table *tbl = find_iommu_table(dev);
 
        uaddr = (unsigned long)vaddr;
        npages = num_dma_pages(uaddr, size);
@@ -455,10 +481,10 @@ dma_addr_t calgary_map_single(struct device *dev, void *vaddr,
        return dma_handle;
 }
 
-void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle,
+static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle,
        size_t size, int direction)
 {
-       struct iommu_table *tbl = to_pci_dev(dev)->bus->self->sysdata;
+       struct iommu_table *tbl = find_iommu_table(dev);
        unsigned int npages;
 
        if (!translate_phb(to_pci_dev(dev)))
@@ -468,15 +494,13 @@ void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle,
        iommu_free(tbl, dma_handle, npages);
 }
 
-void* calgary_alloc_coherent(struct device *dev, size_t size,
+static void* calgary_alloc_coherent(struct device *dev, size_t size,
        dma_addr_t *dma_handle, gfp_t flag)
 {
        void *ret = NULL;
        dma_addr_t mapping;
        unsigned int npages, order;
-       struct iommu_table *tbl;
-
-       tbl = to_pci_dev(dev)->bus->self->sysdata;
+       struct iommu_table *tbl = find_iommu_table(dev);
 
        size = PAGE_ALIGN(size); /* size rounded up to full pages */
        npages = size >> PAGE_SHIFT;
@@ -552,7 +576,22 @@ static inline void __iomem* calgary_reg(void __iomem *bar, unsigned long offset)
        return (void __iomem*)target;
 }
 
-static void tce_cache_blast(struct iommu_table *tbl)
+static inline int is_calioc2(unsigned short device)
+{
+       return (device == PCI_DEVICE_ID_IBM_CALIOC2);
+}
+
+static inline int is_calgary(unsigned short device)
+{
+       return (device == PCI_DEVICE_ID_IBM_CALGARY);
+}
+
+static inline int is_cal_pci_dev(unsigned short device)
+{
+       return (is_calgary(device) || is_calioc2(device));
+}
+
+static void calgary_tce_cache_blast(struct iommu_table *tbl)
 {
        u64 val;
        u32 aer;
@@ -589,6 +628,85 @@ static void tce_cache_blast(struct iommu_table *tbl)
        (void)readl(target); /* flush */
 }
 
+static void calioc2_tce_cache_blast(struct iommu_table *tbl)
+{
+       void __iomem *bbar = tbl->bbar;
+       void __iomem *target;
+       u64 val64;
+       u32 val;
+       int i = 0;
+       int count = 1;
+       unsigned char bus = tbl->it_busno;
+
+begin:
+       printk(KERN_DEBUG "Calgary: CalIOC2 bus 0x%x entering tce cache blast "
+              "sequence - count %d\n", bus, count);
+
+       /* 1. using the Page Migration Control reg set SoftStop */
+       target = calgary_reg(bbar, phb_offset(bus) | PHB_PAGE_MIG_CTRL);
+       val = be32_to_cpu(readl(target));
+       printk(KERN_DEBUG "1a. read 0x%x [LE] from %p\n", val, target);
+       val |= PMR_SOFTSTOP;
+       printk(KERN_DEBUG "1b. writing 0x%x [LE] to %p\n", val, target);
+       writel(cpu_to_be32(val), target);
+
+       /* 2. poll split queues until all DMA activity is done */
+       printk(KERN_DEBUG "2a. starting to poll split queues\n");
+       target = calgary_reg(bbar, split_queue_offset(bus));
+       do {
+               val64 = readq(target);
+               i++;
+       } while ((val64 & 0xff) != 0xff && i < 100);
+       if (i == 100)
+               printk(KERN_WARNING "CalIOC2: PCI bus not quiesced, "
+                      "continuing anyway\n");
+
+       /* 3. poll Page Migration DEBUG for SoftStopFault */
+       target = calgary_reg(bbar, phb_offset(bus) | PHB_PAGE_MIG_DEBUG);
+       val = be32_to_cpu(readl(target));
+       printk(KERN_DEBUG "3. read 0x%x [LE] from %p\n", val, target);
+
+       /* 4. if SoftStopFault - goto (1) */
+       if (val & PMR_SOFTSTOPFAULT) {
+               if (++count < 100)
+                       goto begin;
+               else {
+                       printk(KERN_WARNING "CalIOC2: too many SoftStopFaults, "
+                              "aborting TCE cache flush sequence!\n");
+                       return; /* pray for the best */
+               }
+       }
+
+       /* 5. Slam into HardStop by reading PHB_PAGE_MIG_CTRL */
+       target = calgary_reg(bbar, phb_offset(bus) | PHB_PAGE_MIG_CTRL);
+       printk(KERN_DEBUG "5a. slamming into HardStop by reading %p\n", target);
+       val = be32_to_cpu(readl(target));
+       printk(KERN_DEBUG "5b. read 0x%x [LE] from %p\n", val, target);
+       target = calgary_reg(bbar, phb_offset(bus) | PHB_PAGE_MIG_DEBUG);
+       val = be32_to_cpu(readl(target));
+       printk(KERN_DEBUG "5c. read 0x%x [LE] from %p (debug)\n", val, target);
+
+       /* 6. invalidate TCE cache */
+       printk(KERN_DEBUG "6. invalidating TCE cache\n");
+       target = calgary_reg(bbar, tar_offset(bus));
+       writeq(tbl->tar_val, target);
+
+       /* 7. Re-read PMCR */
+       printk(KERN_DEBUG "7a. Re-reading PMCR\n");
+       target = calgary_reg(bbar, phb_offset(bus) | PHB_PAGE_MIG_CTRL);
+       val = be32_to_cpu(readl(target));
+       printk(KERN_DEBUG "7b. read 0x%x [LE] from %p\n", val, target);
+
+       /* 8. Remove HardStop */
+       printk(KERN_DEBUG "8a. removing HardStop from PMCR\n");
+       target = calgary_reg(bbar, phb_offset(bus) | PHB_PAGE_MIG_CTRL);
+       val = 0;
+       printk(KERN_DEBUG "8b. writing 0x%x [LE] to %p\n", val, target);
+       writel(cpu_to_be32(val), target);
+       val = be32_to_cpu(readl(target));
+       printk(KERN_DEBUG "8c. read 0x%x [LE] from %p\n", val, target);
+}
+
 static void __init calgary_reserve_mem_region(struct pci_dev *dev, u64 start,
        u64 limit)
 {
@@ -598,7 +716,7 @@ static void __init calgary_reserve_mem_region(struct pci_dev *dev, u64 start,
        limit++;
 
        numpages = ((limit - start) >> PAGE_SHIFT);
-       iommu_range_reserve(dev->sysdata, start, numpages);
+       iommu_range_reserve(pci_iommu(dev->bus), start, numpages);
 }
 
 static void __init calgary_reserve_peripheral_mem_1(struct pci_dev *dev)
@@ -606,7 +724,7 @@ static void __init calgary_reserve_peripheral_mem_1(struct pci_dev *dev)
        void __iomem *target;
        u64 low, high, sizelow;
        u64 start, limit;
-       struct iommu_table *tbl = dev->sysdata;
+       struct iommu_table *tbl = pci_iommu(dev->bus);
        unsigned char busnum = dev->bus->number;
        void __iomem *bbar = tbl->bbar;
 
@@ -630,7 +748,7 @@ static void __init calgary_reserve_peripheral_mem_2(struct pci_dev *dev)
        u32 val32;
        u64 low, high, sizelow, sizehigh;
        u64 start, limit;
-       struct iommu_table *tbl = dev->sysdata;
+       struct iommu_table *tbl = pci_iommu(dev->bus);
        unsigned char busnum = dev->bus->number;
        void __iomem *bbar = tbl->bbar;
 
@@ -666,14 +784,20 @@ static void __init calgary_reserve_regions(struct pci_dev *dev)
 {
        unsigned int npages;
        u64 start;
-       struct iommu_table *tbl = dev->sysdata;
+       struct iommu_table *tbl = pci_iommu(dev->bus);
 
        /* reserve EMERGENCY_PAGES from bad_dma_address and up */
        iommu_range_reserve(tbl, bad_dma_address, EMERGENCY_PAGES);
 
        /* avoid the BIOS/VGA first 640KB-1MB region */
-       start = (640 * 1024);
-       npages = ((1024 - 640) * 1024) >> PAGE_SHIFT;
+       /* for CalIOC2 - avoid the entire first MB */
+       if (is_calgary(dev->device)) {
+               start = (640 * 1024);
+               npages = ((1024 - 640) * 1024) >> PAGE_SHIFT;
+       } else { /* calioc2 */
+               start = 0;
+               npages = (1 * 1024 * 1024) >> PAGE_SHIFT;
+       }
        iommu_range_reserve(tbl, start, npages);
 
        /* reserve the two PCI peripheral memory regions in IO space */
@@ -694,10 +818,17 @@ static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar)
        if (ret)
                return ret;
 
-       tbl = dev->sysdata;
+       tbl = pci_iommu(dev->bus);
        tbl->it_base = (unsigned long)bus_info[dev->bus->number].tce_space;
        tce_free(tbl, 0, tbl->it_size);
 
+       if (is_calgary(dev->device))
+               tbl->chip_ops = &calgary_chip_ops;
+       else if (is_calioc2(dev->device))
+               tbl->chip_ops = &calioc2_chip_ops;
+       else
+               BUG();
+
        calgary_reserve_regions(dev);
 
        /* set TARs for each PHB */
@@ -706,15 +837,15 @@ static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar)
 
        /* zero out all TAR bits under sw control */
        val64 &= ~TAR_SW_BITS;
-
-       tbl = dev->sysdata;
        table_phys = (u64)__pa(tbl->it_base);
+
        val64 |= table_phys;
 
        BUG_ON(specified_table_size > TCE_TABLE_SIZE_8M);
        val64 |= (u64) specified_table_size;
 
        tbl->tar_val = cpu_to_be64(val64);
+
        writeq(tbl->tar_val, target);
        readq(target); /* flush */
 
@@ -724,7 +855,7 @@ static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar)
 static void __init calgary_free_bus(struct pci_dev *dev)
 {
        u64 val64;
-       struct iommu_table *tbl = dev->sysdata;
+       struct iommu_table *tbl = pci_iommu(dev->bus);
        void __iomem *target;
        unsigned int bitmapsz;
 
@@ -739,16 +870,81 @@ static void __init calgary_free_bus(struct pci_dev *dev)
        tbl->it_map = NULL;
 
        kfree(tbl);
-       dev->sysdata = NULL;
+       
+       set_pci_iommu(dev->bus, NULL);
 
        /* Can't free bootmem allocated memory after system is up :-( */
        bus_info[dev->bus->number].tce_space = NULL;
 }
 
+static void calgary_dump_error_regs(struct iommu_table *tbl)
+{
+       void __iomem *bbar = tbl->bbar;
+       void __iomem *target;
+       u32 csr, plssr;
+
+       target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_CSR_OFFSET);
+       csr = be32_to_cpu(readl(target));
+
+       target = calgary_reg(bbar, phb_offset(tbl->it_busno) | PHB_PLSSR_OFFSET);
+       plssr = be32_to_cpu(readl(target));
+
+       /* If no error, the agent ID in the CSR is not valid */
+       printk(KERN_EMERG "Calgary: DMA error on Calgary PHB 0x%x, "
+              "0x%08x@CSR 0x%08x@PLSSR\n", tbl->it_busno, csr, plssr);
+}
+
+static void calioc2_dump_error_regs(struct iommu_table *tbl)
+{
+       void __iomem *bbar = tbl->bbar;
+       u32 csr, csmr, plssr, mck, rcstat;
+       void __iomem *target;
+       unsigned long phboff = phb_offset(tbl->it_busno);
+       unsigned long erroff;
+       u32 errregs[7];
+       int i;
+
+       /* dump CSR */
+       target = calgary_reg(bbar, phboff | PHB_CSR_OFFSET);
+       csr = be32_to_cpu(readl(target));
+       /* dump PLSSR */
+       target = calgary_reg(bbar, phboff | PHB_PLSSR_OFFSET);
+       plssr = be32_to_cpu(readl(target));
+       /* dump CSMR */
+       target = calgary_reg(bbar, phboff | 0x290);
+       csmr = be32_to_cpu(readl(target));
+       /* dump mck */
+       target = calgary_reg(bbar, phboff | 0x800);
+       mck = be32_to_cpu(readl(target));
+
+       printk(KERN_EMERG "Calgary: DMA error on CalIOC2 PHB 0x%x\n",
+              tbl->it_busno);
+
+       printk(KERN_EMERG "Calgary: 0x%08x@CSR 0x%08x@PLSSR 0x%08x@CSMR 0x%08x@MCK\n",
+              csr, plssr, csmr, mck);
+
+       /* dump rest of error regs */
+       printk(KERN_EMERG "Calgary: ");
+       for (i = 0; i < ARRAY_SIZE(errregs); i++) {
+               /* err regs are at 0x810 - 0x870 */
+               erroff = (0x810 + (i * 0x10));
+               target = calgary_reg(bbar, phboff | erroff);
+               errregs[i] = be32_to_cpu(readl(target));
+               printk("0x%08x@0x%lx ", errregs[i], erroff);
+       }
+       printk("\n");
+
+       /* root complex status */
+       target = calgary_reg(bbar, phboff | PHB_ROOT_COMPLEX_STATUS);
+       rcstat = be32_to_cpu(readl(target));
+       printk(KERN_EMERG "Calgary: 0x%08x@0x%x\n", rcstat,
+              PHB_ROOT_COMPLEX_STATUS);
+}
+
 static void calgary_watchdog(unsigned long data)
 {
        struct pci_dev *dev = (struct pci_dev *)data;
-       struct iommu_table *tbl = dev->sysdata;
+       struct iommu_table *tbl = pci_iommu(dev->bus);
        void __iomem *bbar = tbl->bbar;
        u32 val32;
        void __iomem *target;
@@ -758,13 +954,14 @@ static void calgary_watchdog(unsigned long data)
 
        /* If no error, the agent ID in the CSR is not valid */
        if (val32 & CSR_AGENT_MASK) {
-               printk(KERN_EMERG "calgary_watchdog: DMA error on PHB %#x, "
-                                 "CSR = %#x\n", dev->bus->number, val32);
+               tbl->chip_ops->dump_error_regs(tbl);
+
+               /* reset error */
                writel(0, target);
 
                /* Disable bus that caused the error */
                target = calgary_reg(bbar, phb_offset(tbl->it_busno) |
-                                          PHB_CONFIG_RW_OFFSET);
+                                    PHB_CONFIG_RW_OFFSET);
                val32 = be32_to_cpu(readl(target));
                val32 |= PHB_SLOT_DISABLE;
                writel(cpu_to_be32(val32), target);
@@ -775,8 +972,8 @@ static void calgary_watchdog(unsigned long data)
        }
 }
 
-static void __init calgary_increase_split_completion_timeout(void __iomem *bbar,
-       unsigned char busnum)
+static void __init calgary_set_split_completion_timeout(void __iomem *bbar,
+       unsigned char busnum, unsigned long timeout)
 {
        u64 val64;
        void __iomem *target;
@@ -802,11 +999,40 @@ static void __init calgary_increase_split_completion_timeout(void __iomem *bbar,
        /* zero out this PHB's timer bits */
        mask = ~(0xFUL << phb_shift);
        val64 &= mask;
-       val64 |= (CCR_2SEC_TIMEOUT << phb_shift);
+       val64 |= (timeout << phb_shift);
        writeq(cpu_to_be64(val64), target);
        readq(target); /* flush */
 }
 
+static void calioc2_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev)
+{
+       unsigned char busnum = dev->bus->number;
+       void __iomem *bbar = tbl->bbar;
+       void __iomem *target;
+       u32 val;
+
+       /*
+        * CalIOC2 designers recommend setting bit 8 in 0xnDB0 to 1
+        */
+       target = calgary_reg(bbar, phb_offset(busnum) | PHB_SAVIOR_L2);
+       val = cpu_to_be32(readl(target));
+       val |= 0x00800000;
+       writel(cpu_to_be32(val), target);
+}
+
+static void calgary_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev)
+{
+       unsigned char busnum = dev->bus->number;
+
+       /*
+        * Give split completion a longer timeout on bus 1 for aic94xx
+        * http://bugzilla.kernel.org/show_bug.cgi?id=7180
+        */
+       if (is_calgary(dev->device) && (busnum == 1))
+               calgary_set_split_completion_timeout(tbl->bbar, busnum,
+                                                    CCR_2SEC_TIMEOUT);
+}
+
 static void __init calgary_enable_translation(struct pci_dev *dev)
 {
        u32 val32;
@@ -816,7 +1042,7 @@ static void __init calgary_enable_translation(struct pci_dev *dev)
        struct iommu_table *tbl;
 
        busnum = dev->bus->number;
-       tbl = dev->sysdata;
+       tbl = pci_iommu(dev->bus);
        bbar = tbl->bbar;
 
        /* enable TCE in PHB Config Register */
@@ -824,20 +1050,15 @@ static void __init calgary_enable_translation(struct pci_dev *dev)
        val32 = be32_to_cpu(readl(target));
        val32 |= PHB_TCE_ENABLE | PHB_DAC_DISABLE | PHB_MCSR_ENABLE;
 
-       printk(KERN_INFO "Calgary: enabling translation on PHB %#x\n", busnum);
+       printk(KERN_INFO "Calgary: enabling translation on %s PHB %#x\n",
+              (dev->device == PCI_DEVICE_ID_IBM_CALGARY) ?
+              "Calgary" : "CalIOC2", busnum);
        printk(KERN_INFO "Calgary: errant DMAs will now be prevented on this "
               "bus.\n");
 
        writel(cpu_to_be32(val32), target);
        readl(target); /* flush */
 
-       /*
-        * Give split completion a longer timeout on bus 1 for aic94xx
-        * http://bugzilla.kernel.org/show_bug.cgi?id=7180
-        */
-       if (busnum == 1)
-               calgary_increase_split_completion_timeout(bbar, busnum);
-
        init_timer(&tbl->watchdog_timer);
        tbl->watchdog_timer.function = &calgary_watchdog;
        tbl->watchdog_timer.data = (unsigned long)dev;
@@ -853,7 +1074,7 @@ static void __init calgary_disable_translation(struct pci_dev *dev)
        struct iommu_table *tbl;
 
        busnum = dev->bus->number;
-       tbl = dev->sysdata;
+       tbl = pci_iommu(dev->bus);
        bbar = tbl->bbar;
 
        /* disable TCE in PHB Config Register */
@@ -871,13 +1092,19 @@ static void __init calgary_disable_translation(struct pci_dev *dev)
 static void __init calgary_init_one_nontraslated(struct pci_dev *dev)
 {
        pci_dev_get(dev);
-       dev->sysdata = NULL;
-       dev->bus->self = dev;
+       set_pci_iommu(dev->bus, NULL);
+
+       /* is the device behind a bridge? */
+       if (dev->bus->parent)
+               dev->bus->parent->self = dev;
+       else
+               dev->bus->self = dev;
 }
 
 static int __init calgary_init_one(struct pci_dev *dev)
 {
        void __iomem *bbar;
+       struct iommu_table *tbl;
        int ret;
 
        BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM);
@@ -888,7 +1115,18 @@ static int __init calgary_init_one(struct pci_dev *dev)
                goto done;
 
        pci_dev_get(dev);
-       dev->bus->self = dev;
+
+       if (dev->bus->parent) {
+               if (dev->bus->parent->self)
+                       printk(KERN_WARNING "Calgary: IEEEE, dev %p has "
+                              "bus->parent->self!\n", dev);
+               dev->bus->parent->self = dev;
+       } else
+               dev->bus->self = dev;
+
+       tbl = pci_iommu(dev->bus);
+       tbl->chip_ops->handle_quirks(tbl, dev);
+
        calgary_enable_translation(dev);
 
        return 0;
@@ -924,11 +1162,18 @@ static int __init calgary_locate_bbars(void)
                        target = calgary_reg(bbar, offset);
 
                        val = be32_to_cpu(readl(target));
+
                        start_bus = (u8)((val & 0x00FF0000) >> 16);
                        end_bus = (u8)((val & 0x0000FF00) >> 8);
-                       for (bus = start_bus; bus <= end_bus; bus++) {
-                               bus_info[bus].bbar = bbar;
-                               bus_info[bus].phbid = phb;
+
+                       if (end_bus) {
+                               for (bus = start_bus; bus <= end_bus; bus++) {
+                                       bus_info[bus].bbar = bbar;
+                                       bus_info[bus].phbid = phb;
+                               }
+                       } else {
+                               bus_info[start_bus].bbar = bbar;
+                               bus_info[start_bus].phbid = phb;
                        }
                }
        }
@@ -948,22 +1193,24 @@ static int __init calgary_init(void)
 {
        int ret;
        struct pci_dev *dev = NULL;
+       void *tce_space;
 
        ret = calgary_locate_bbars();
        if (ret)
                return ret;
 
        do {
-               dev = pci_get_device(PCI_VENDOR_ID_IBM,
-                                    PCI_DEVICE_ID_IBM_CALGARY,
-                                    dev);
+               dev = pci_get_device(PCI_VENDOR_ID_IBM, PCI_ANY_ID, dev);
                if (!dev)
                        break;
+               if (!is_cal_pci_dev(dev->device))
+                       continue;
                if (!translate_phb(dev)) {
                        calgary_init_one_nontraslated(dev);
                        continue;
                }
-               if (!bus_info[dev->bus->number].tce_space && !translate_empty_slots)
+               tce_space = bus_info[dev->bus->number].tce_space;
+               if (!tce_space && !translate_empty_slots)
                        continue;
 
                ret = calgary_init_one(dev);
@@ -976,10 +1223,11 @@ static int __init calgary_init(void)
 error:
        do {
                dev = pci_get_device_reverse(PCI_VENDOR_ID_IBM,
-                                             PCI_DEVICE_ID_IBM_CALGARY,
-                                             dev);
+                                            PCI_ANY_ID, dev);
                if (!dev)
                        break;
+               if (!is_cal_pci_dev(dev->device))
+                       continue;
                if (!translate_phb(dev)) {
                        pci_dev_put(dev);
                        continue;
@@ -1057,9 +1305,29 @@ static int __init build_detail_arrays(void)
        return 0;
 }
 
-void __init detect_calgary(void)
+static int __init calgary_bus_has_devices(int bus, unsigned short pci_dev)
 {
+       int dev;
        u32 val;
+
+       if (pci_dev == PCI_DEVICE_ID_IBM_CALIOC2) {
+               /*
+                * FIXME: properly scan for devices accross the
+                * PCI-to-PCI bridge on every CalIOC2 port.
+                */
+               return 1;
+       }
+
+       for (dev = 1; dev < 8; dev++) {
+               val = read_pci_config(bus, dev, 0, 0);
+               if (val != 0xffffffff)
+                       break;
+       }
+       return (val != 0xffffffff);
+}
+
+void __init detect_calgary(void)
+{
        int bus;
        void *tbl;
        int calgary_found = 0;
@@ -1116,29 +1384,26 @@ void __init detect_calgary(void)
        specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE);
 
        for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) {
-               int dev;
                struct calgary_bus_info *info = &bus_info[bus];
+               unsigned short pci_device;
+               u32 val;
+
+               val = read_pci_config(bus, 0, 0, 0);
+               pci_device = (val & 0xFFFF0000) >> 16;
 
-               if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY)
+               if (!is_cal_pci_dev(pci_device))
                        continue;
 
                if (info->translation_disabled)
                        continue;
 
-               /*
-                * Scan the slots of the PCI bus to see if there is a device present.
-                * The parent bus will be the zero-ith device, so start at 1.
-                */
-               for (dev = 1; dev < 8; dev++) {
-                       val = read_pci_config(bus, dev, 0, 0);
-                       if (val != 0xffffffff || translate_empty_slots) {
-                               tbl = alloc_tce_table();
-                               if (!tbl)
-                                       goto cleanup;
-                               info->tce_space = tbl;
-                               calgary_found = 1;
-                               break;
-                       }
+               if (calgary_bus_has_devices(bus, pci_device) ||
+                   translate_empty_slots) {
+                       tbl = alloc_tce_table();
+                       if (!tbl)
+                               goto cleanup;
+                       info->tce_space = tbl;
+                       calgary_found = 1;
                }
        }
 
@@ -1249,3 +1514,66 @@ static int __init calgary_parse_options(char *p)
        return 1;
 }
 __setup("calgary=", calgary_parse_options);
+
+static void __init calgary_fixup_one_tce_space(struct pci_dev *dev)
+{
+       struct iommu_table *tbl;
+       unsigned int npages;
+       int i;
+
+       tbl = pci_iommu(dev->bus);
+
+       for (i = 0; i < 4; i++) {
+               struct resource *r = &dev->resource[PCI_BRIDGE_RESOURCES + i];
+
+               /* Don't give out TCEs that map MEM resources */
+               if (!(r->flags & IORESOURCE_MEM))
+                       continue;
+
+               /* 0-based? we reserve the whole 1st MB anyway */
+               if (!r->start)
+                       continue;
+
+               /* cover the whole region */
+               npages = (r->end - r->start) >> PAGE_SHIFT;
+               npages++;
+
+               iommu_range_reserve(tbl, r->start, npages);
+       }
+}
+
+static int __init calgary_fixup_tce_spaces(void)
+{
+       struct pci_dev *dev = NULL;
+       void *tce_space;
+
+       if (no_iommu || swiotlb || !calgary_detected)
+               return -ENODEV;
+
+       printk(KERN_DEBUG "Calgary: fixing up tce spaces\n");
+
+       do {
+               dev = pci_get_device(PCI_VENDOR_ID_IBM, PCI_ANY_ID, dev);
+               if (!dev)
+                       break;
+               if (!is_cal_pci_dev(dev->device))
+                       continue;
+               if (!translate_phb(dev))
+                       continue;
+
+               tce_space = bus_info[dev->bus->number].tce_space;
+               if (!tce_space)
+                       continue;
+
+               calgary_fixup_one_tce_space(dev);
+
+       } while (1);
+
+       return 0;
+}
+
+/*
+ * We need to be call after pcibios_assign_resources (fs_initcall level)
+ * and before device_initcall.
+ */
+rootfs_initcall(calgary_fixup_tce_spaces);
index 90f6315d02d42c062a57d0453b3ab58326a1e6a7..05d745ede561320a6c50d0a47c5a3cbb26cdf1f1 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <asm/io.h>
-#include <asm/proto.h>
+#include <asm/iommu.h>
 #include <asm/calgary.h>
 
 int iommu_merge __read_mostly = 0;
@@ -321,6 +321,11 @@ static int __init pci_iommu_init(void)
        return 0;
 }
 
+void pci_iommu_shutdown(void)
+{
+       gart_iommu_shutdown();
+}
+
 #ifdef CONFIG_PCI
 /* Many VIA bridges seem to corrupt data for DAC. Disable it here */
 
index ae091cdc1a4de3764389c5a18e36adb42b9ddfcc..4918c575d582cfd901ca23f47e8327a16045998f 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/mtrr.h>
 #include <asm/pgtable.h>
 #include <asm/proto.h>
+#include <asm/iommu.h>
 #include <asm/cacheflush.h>
 #include <asm/swiotlb.h>
 #include <asm/dma.h>
@@ -235,7 +236,7 @@ static dma_addr_t gart_map_simple(struct device *dev, char *buf,
 }
 
 /* Map a single area into the IOMMU */
-dma_addr_t gart_map_single(struct device *dev, void *addr, size_t size, int dir)
+static dma_addr_t gart_map_single(struct device *dev, void *addr, size_t size, int dir)
 {
        unsigned long phys_mem, bus;
 
@@ -253,7 +254,7 @@ dma_addr_t gart_map_single(struct device *dev, void *addr, size_t size, int dir)
 /*
  * Free a DMA mapping.
  */
-void gart_unmap_single(struct device *dev, dma_addr_t dma_addr,
+static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr,
                      size_t size, int direction)
 {
        unsigned long iommu_page;
@@ -275,7 +276,7 @@ void gart_unmap_single(struct device *dev, dma_addr_t dma_addr,
 /*
  * Wrapper for pci_unmap_single working with scatterlists.
  */
-void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
+static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
 {
        int i;
 
@@ -571,6 +572,26 @@ static const struct dma_mapping_ops gart_dma_ops = {
        .unmap_sg = gart_unmap_sg,
 };
 
+void gart_iommu_shutdown(void)
+{
+       struct pci_dev *dev;
+       int i;
+
+       if (no_agp && (dma_ops != &gart_dma_ops))
+               return;
+
+        for (i = 0; i < num_k8_northbridges; i++) {
+                u32 ctl;
+
+                dev = k8_northbridges[i];
+                pci_read_config_dword(dev, 0x90, &ctl);
+
+                ctl &= ~1;
+
+                pci_write_config_dword(dev, 0x90, ctl);
+        }
+}
+
 void __init gart_iommu_init(void)
 { 
        struct agp_kern_info info;
index 6dade0c867cc68bd2319eadcf42e4820d42474f2..2a34c6c025a920832455dc0c32c4978ee5881ee0 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/string.h>
 #include <linux/dma-mapping.h>
 
-#include <asm/proto.h>
+#include <asm/iommu.h>
 #include <asm/processor.h>
 #include <asm/dma.h>
 
@@ -34,7 +34,7 @@ nommu_map_single(struct device *hwdev, void *ptr, size_t size,
        return bus;
 }
 
-void nommu_unmap_single(struct device *dev, dma_addr_t addr,size_t size,
+static void nommu_unmap_single(struct device *dev, dma_addr_t addr,size_t size,
                        int direction)
 {
 }
@@ -54,7 +54,7 @@ void nommu_unmap_single(struct device *dev, dma_addr_t addr,size_t size,
  * Device ownership issues as mentioned above for pci_map_single are
  * the same here.
  */
-int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
+static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
               int nents, int direction)
 {
        int i;
@@ -74,7 +74,7 @@ int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
  * Again, cpu read rules concerning calls here are the same as for
  * pci_unmap_single() above.
  */
-void nommu_unmap_sg(struct device *dev, struct scatterlist *sg,
+static void nommu_unmap_sg(struct device *dev, struct scatterlist *sg,
                  int nents, int dir)
 {
 }
index 4b4569abc60c8d3f3b993d2f1e0f9ee320ea0d82..b2f405ea7c85002b779b3c928a26ce424c9a0a0e 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/module.h>
 #include <linux/dma-mapping.h>
 
-#include <asm/proto.h>
+#include <asm/iommu.h>
 #include <asm/swiotlb.h>
 #include <asm/dma.h>
 
index 5909039f37aa01132d9f752168be82078a540daf..e7ac629d4c4654ec97ddc387fc5ba71c0892e92a 100644 (file)
@@ -207,6 +207,7 @@ void cpu_idle (void)
                        if (__get_cpu_var(cpu_idle_state))
                                __get_cpu_var(cpu_idle_state) = 0;
 
+                       check_pgt_cache();
                        rmb();
                        idle = pm_idle;
                        if (!idle)
@@ -278,7 +279,7 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
                 */
                if (!pm_idle) {
                        if (!printed) {
-                               printk("using mwait in idle threads.\n");
+                               printk(KERN_INFO "using mwait in idle threads.\n");
                                printed = 1;
                        }
                        pm_idle = mwait_idle;
@@ -305,6 +306,7 @@ early_param("idle", idle_setup);
 void __show_regs(struct pt_regs * regs)
 {
        unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs;
+       unsigned long d0, d1, d2, d3, d6, d7;
        unsigned int fsindex,gsindex;
        unsigned int ds,cs,es; 
 
@@ -340,15 +342,24 @@ void __show_regs(struct pt_regs * regs)
        rdmsrl(MSR_GS_BASE, gs); 
        rdmsrl(MSR_KERNEL_GS_BASE, shadowgs); 
 
-       asm("movq %%cr0, %0": "=r" (cr0));
-       asm("movq %%cr2, %0": "=r" (cr2));
-       asm("movq %%cr3, %0": "=r" (cr3));
-       asm("movq %%cr4, %0": "=r" (cr4));
+       cr0 = read_cr0();
+       cr2 = read_cr2();
+       cr3 = read_cr3();
+       cr4 = read_cr4();
 
        printk("FS:  %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n", 
               fs,fsindex,gs,gsindex,shadowgs); 
        printk("CS:  %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds, es, cr0); 
        printk("CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4);
+
+       get_debugreg(d0, 0);
+       get_debugreg(d1, 1);
+       get_debugreg(d2, 2);
+       printk("DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2);
+       get_debugreg(d3, 3);
+       get_debugreg(d6, 6);
+       get_debugreg(d7, 7);
+       printk("DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7);
 }
 
 void show_regs(struct pt_regs *regs)
index 7503068e788d903565c97841482125bb9993fd3b..368db2b9c5ac3977b0ec32edabe2aec9359df6de 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 #include <asm/apic.h>
+#include <asm/iommu.h>
 
 /*
  * Power off function, if any
@@ -81,6 +82,7 @@ static inline void kb_wait(void)
 void machine_shutdown(void)
 {
        unsigned long flags;
+
        /* Stop the cpus and apics */
 #ifdef CONFIG_SMP
        int reboot_cpu_id;
@@ -111,6 +113,8 @@ void machine_shutdown(void)
        disable_IO_APIC();
 
        local_irq_restore(flags);
+
+       pci_iommu_shutdown();
 }
 
 void machine_emergency_restart(void)
index 33ef718f8cb5ee1e5cbf08c5644a25b592f685ea..af838f6b0b7fc9b7e3ed4de0ab12992e48cf9f18 100644 (file)
@@ -575,6 +575,8 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
        level = cpuid_eax(1);
        if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58))
                set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
+       if (c->x86 == 0x10)
+               set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
 
        /* Enable workaround for FXSAVE leak */
        if (c->x86 >= 6)
@@ -600,8 +602,14 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
        if (c->extended_cpuid_level >= 0x80000008)
                amd_detect_cmp(c);
 
-       /* Fix cpuid4 emulation for more */
-       num_cache_leaves = 3;
+       if (c->extended_cpuid_level >= 0x80000006 &&
+               (cpuid_edx(0x80000006) & 0xf000))
+               num_cache_leaves = 4;
+       else
+               num_cache_leaves = 3;
+
+       if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x11)
+               set_bit(X86_FEATURE_K8, &c->x86_capability);
 
        /* RDTSC can be speculated around */
        clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
index 290f5d8037cd804e6fedbc9e1b7b602e5db10b58..739175b01e06ee9553760729c5b8e6dbd6bf89cb 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/i387.h>
 #include <asm/proto.h>
 #include <asm/ia32_unistd.h>
+#include <asm/mce.h>
 
 /* #define DEBUG_SIG 1 */
 
@@ -472,6 +473,12 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
                clear_thread_flag(TIF_SINGLESTEP);
        }
 
+#ifdef CONFIG_X86_MCE
+       /* notify userspace of pending MCEs */
+       if (thread_info_flags & _TIF_MCE_NOTIFY)
+               mce_notify_user();
+#endif /* CONFIG_X86_MCE */
+
        /* deal with pending signal delivery */
        if (thread_info_flags & (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK))
                do_signal(regs);
@@ -480,7 +487,7 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
 void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
 { 
        struct task_struct *me = current; 
-       if (exception_trace)
+       if (show_unhandled_signals && printk_ratelimit())
                printk("%s[%d] bad frame in %s frame:%p rip:%lx rsp:%lx orax:%lx\n",
               me->comm,me->pid,where,frame,regs->rip,regs->rsp,regs->orig_rax); 
 
index 0694940b2e730b3160ade5d6046ec349ad3c351a..673a300b59442df7dcc193f6fb78e7aaa30eceda 100644 (file)
@@ -241,7 +241,7 @@ void flush_tlb_mm (struct mm_struct * mm)
        }
        if (!cpus_empty(cpu_mask))
                flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
-
+       check_pgt_cache();
        preempt_enable();
 }
 EXPORT_SYMBOL(flush_tlb_mm);
@@ -386,9 +386,9 @@ int smp_call_function_single (int cpu, void (*func) (void *info), void *info,
                return 0;
        }
 
-       spin_lock_bh(&call_lock);
+       spin_lock(&call_lock);
        __smp_call_function_single(cpu, func, info, nonatomic, wait);
-       spin_unlock_bh(&call_lock);
+       spin_unlock(&call_lock);
        put_cpu();
        return 0;
 }
index 6a5a98f2a75c5aac97d543f116db736182b6e73c..ea83a9f91965d3217d1f9346fefa45679f69d62a 100644 (file)
@@ -55,11 +55,11 @@ void __save_processor_state(struct saved_context *ctxt)
         * control registers 
         */
        rdmsrl(MSR_EFER, ctxt->efer);
-       asm volatile ("movq %%cr0, %0" : "=r" (ctxt->cr0));
-       asm volatile ("movq %%cr2, %0" : "=r" (ctxt->cr2));
-       asm volatile ("movq %%cr3, %0" : "=r" (ctxt->cr3));
-       asm volatile ("movq %%cr4, %0" : "=r" (ctxt->cr4));
-       asm volatile ("movq %%cr8, %0" : "=r" (ctxt->cr8));
+       ctxt->cr0 = read_cr0();
+       ctxt->cr2 = read_cr2();
+       ctxt->cr3 = read_cr3();
+       ctxt->cr4 = read_cr4();
+       ctxt->cr8 = read_cr8();
 }
 
 void save_processor_state(void)
@@ -81,11 +81,11 @@ void __restore_processor_state(struct saved_context *ctxt)
         * control registers
         */
        wrmsrl(MSR_EFER, ctxt->efer);
-       asm volatile ("movq %0, %%cr8" :: "r" (ctxt->cr8));
-       asm volatile ("movq %0, %%cr4" :: "r" (ctxt->cr4));
-       asm volatile ("movq %0, %%cr3" :: "r" (ctxt->cr3));
-       asm volatile ("movq %0, %%cr2" :: "r" (ctxt->cr2));
-       asm volatile ("movq %0, %%cr0" :: "r" (ctxt->cr0));
+       write_cr8(ctxt->cr8);
+       write_cr4(ctxt->cr4);
+       write_cr3(ctxt->cr3);
+       write_cr2(ctxt->cr2);
+       write_cr0(ctxt->cr0);
 
        /*
         * now restore the descriptor tables to their proper values
index f61fb8e4f12954b5f8f2f61dad0cf7218d9818cc..3aeae2fa2e240048a8b793db8f9f12c5659c3ca7 100644 (file)
@@ -136,9 +136,9 @@ int build_tce_table(struct pci_dev *dev, void __iomem *bbar)
        struct iommu_table *tbl;
        int ret;
 
-       if (dev->sysdata) {
-               printk(KERN_ERR "Calgary: dev %p has sysdata %p\n",
-                      dev, dev->sysdata);
+       if (pci_iommu(dev->bus)) {
+               printk(KERN_ERR "Calgary: dev %p has sysdata->iommu %p\n",
+                      dev, pci_iommu(dev->bus));
                BUG();
        }
 
@@ -155,11 +155,7 @@ int build_tce_table(struct pci_dev *dev, void __iomem *bbar)
 
        tbl->bbar = bbar;
 
-       /*
-        * NUMA is already using the bus's sysdata pointer, so we use
-        * the bus's pci_dev's sysdata instead.
-        */
-       dev->sysdata = tbl;
+       set_pci_iommu(dev->bus, tbl);
 
        return 0;
 
index 4a0895bacf5166197b0054706c7830bfe2bdf522..6d48a4e826d9d1f27dc0cf6a76b0d98b8ba3ffbb 100644 (file)
@@ -33,6 +33,7 @@
 #include <acpi/acpi_bus.h>
 #endif
 #include <asm/8253pit.h>
+#include <asm/i8253.h>
 #include <asm/pgtable.h>
 #include <asm/vsyscall.h>
 #include <asm/timex.h>
 #include <asm/hpet.h>
 #include <asm/mpspec.h>
 #include <asm/nmi.h>
+#include <asm/vgtod.h>
 
 static char *timename = NULL;
 
 DEFINE_SPINLOCK(rtc_lock);
 EXPORT_SYMBOL(rtc_lock);
 DEFINE_SPINLOCK(i8253_lock);
+EXPORT_SYMBOL(i8253_lock);
 
 volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
 
@@ -79,8 +82,9 @@ EXPORT_SYMBOL(profile_pc);
  * sheet for details.
  */
 
-static void set_rtc_mmss(unsigned long nowtime)
+static int set_rtc_mmss(unsigned long nowtime)
 {
+       int retval = 0;
        int real_seconds, real_minutes, cmos_minutes;
        unsigned char control, freq_select;
 
@@ -120,6 +124,7 @@ static void set_rtc_mmss(unsigned long nowtime)
        if (abs(real_minutes - cmos_minutes) >= 30) {
                printk(KERN_WARNING "time.c: can't update CMOS clock "
                       "from %d to %d\n", cmos_minutes, real_minutes);
+               retval = -1;
        } else {
                BIN_TO_BCD(real_seconds);
                BIN_TO_BCD(real_minutes);
@@ -139,12 +144,17 @@ static void set_rtc_mmss(unsigned long nowtime)
        CMOS_WRITE(freq_select, RTC_FREQ_SELECT);
 
        spin_unlock(&rtc_lock);
+
+       return retval;
 }
 
+int update_persistent_clock(struct timespec now)
+{
+       return set_rtc_mmss(now.tv_sec);
+}
 
 void main_timer_handler(void)
 {
-       static unsigned long rtc_update = 0;
 /*
  * Here we are in the timer irq handler. We have irqs locally disabled (so we
  * don't need spin_lock_irqsave()) but we don't know if the timer_bh is running
@@ -172,20 +182,6 @@ void main_timer_handler(void)
        if (!using_apic_timer)
                smp_local_timer_interrupt();
 
-/*
- * If we have an externally synchronized Linux clock, then update CMOS clock
- * accordingly every ~11 minutes. set_rtc_mmss() will be called in the jiffy
- * closest to exactly 500 ms before the next second. If the update fails, we
- * don't care, as it'll be updated on the next turn, and the problem (time way
- * off) isn't likely to go away much sooner anyway.
- */
-
-       if (ntp_synced() && xtime.tv_sec > rtc_update &&
-               abs(xtime.tv_nsec - 500000000) <= tick_nsec / 2) {
-               set_rtc_mmss(xtime.tv_sec);
-               rtc_update = xtime.tv_sec + 660;
-       }
        write_sequnlock(&xtime_lock);
 }
 
@@ -199,7 +195,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static unsigned long get_cmos_time(void)
+unsigned long read_persistent_clock(void)
 {
        unsigned int year, mon, day, hour, min, sec;
        unsigned long flags;
@@ -226,7 +222,7 @@ static unsigned long get_cmos_time(void)
        /*
         * We know that x86-64 always uses BCD format, no need to check the
         * config register.
-        */
+        */
 
        BCD_TO_BIN(sec);
        BCD_TO_BIN(min);
@@ -239,11 +235,11 @@ static unsigned long get_cmos_time(void)
                BCD_TO_BIN(century);
                year += century * 100;
                printk(KERN_INFO "Extended CMOS year: %d\n", century * 100);
-       } else { 
+       } else {
                /*
                 * x86-64 systems only exists since 2002.
                 * This will work up to Dec 31, 2100
-                */
+                */
                year += 2000;
        }
 
@@ -255,45 +251,45 @@ static unsigned long get_cmos_time(void)
 #define TICK_COUNT 100000000
 static unsigned int __init tsc_calibrate_cpu_khz(void)
 {
-       int tsc_start, tsc_now;
-       int i, no_ctr_free;
-       unsigned long evntsel3 = 0, pmc3 = 0, pmc_now = 0;
-       unsigned long flags;
-
-       for (i = 0; i < 4; i++)
-               if (avail_to_resrv_perfctr_nmi_bit(i))
-                       break;
-       no_ctr_free = (i == 4);
-       if (no_ctr_free) {
-               i = 3;
-               rdmsrl(MSR_K7_EVNTSEL3, evntsel3);
-               wrmsrl(MSR_K7_EVNTSEL3, 0);
-               rdmsrl(MSR_K7_PERFCTR3, pmc3);
-       } else {
-               reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i);
-               reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
-       }
-       local_irq_save(flags);
-       /* start meauring cycles, incrementing from 0 */
-       wrmsrl(MSR_K7_PERFCTR0 + i, 0);
-       wrmsrl(MSR_K7_EVNTSEL0 + i, 1 << 22 | 3 << 16 | 0x76);
-       rdtscl(tsc_start);
-       do {
-               rdmsrl(MSR_K7_PERFCTR0 + i, pmc_now);
-               tsc_now = get_cycles_sync();
-       } while ((tsc_now - tsc_start) < TICK_COUNT);
-
-       local_irq_restore(flags);
-       if (no_ctr_free) {
-               wrmsrl(MSR_K7_EVNTSEL3, 0);
-               wrmsrl(MSR_K7_PERFCTR3, pmc3);
-               wrmsrl(MSR_K7_EVNTSEL3, evntsel3);
-       } else {
-               release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
-               release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
-       }
-
-       return pmc_now * tsc_khz / (tsc_now - tsc_start);
+       int tsc_start, tsc_now;
+       int i, no_ctr_free;
+       unsigned long evntsel3 = 0, pmc3 = 0, pmc_now = 0;
+       unsigned long flags;
+
+       for (i = 0; i < 4; i++)
+               if (avail_to_resrv_perfctr_nmi_bit(i))
+                       break;
+       no_ctr_free = (i == 4);
+       if (no_ctr_free) {
+               i = 3;
+               rdmsrl(MSR_K7_EVNTSEL3, evntsel3);
+               wrmsrl(MSR_K7_EVNTSEL3, 0);
+               rdmsrl(MSR_K7_PERFCTR3, pmc3);
+       } else {
+               reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i);
+               reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
+       }
+       local_irq_save(flags);
+       /* start meauring cycles, incrementing from 0 */
+       wrmsrl(MSR_K7_PERFCTR0 + i, 0);
+       wrmsrl(MSR_K7_EVNTSEL0 + i, 1 << 22 | 3 << 16 | 0x76);
+       rdtscl(tsc_start);
+       do {
+               rdmsrl(MSR_K7_PERFCTR0 + i, pmc_now);
+               tsc_now = get_cycles_sync();
+       } while ((tsc_now - tsc_start) < TICK_COUNT);
+
+       local_irq_restore(flags);
+       if (no_ctr_free) {
+               wrmsrl(MSR_K7_EVNTSEL3, 0);
+               wrmsrl(MSR_K7_PERFCTR3, pmc3);
+               wrmsrl(MSR_K7_EVNTSEL3, evntsel3);
+       } else {
+               release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
+               release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
+       }
+
+       return pmc_now * tsc_khz / (tsc_now - tsc_start);
 }
 
 /*
@@ -321,7 +317,7 @@ static unsigned int __init pit_calibrate_tsc(void)
        end = get_cycles_sync();
 
        spin_unlock_irqrestore(&i8253_lock, flags);
-       
+
        return (end - start) / 50;
 }
 
@@ -366,25 +362,20 @@ static struct irqaction irq0 = {
        .handler        = timer_interrupt,
        .flags          = IRQF_DISABLED | IRQF_IRQPOLL,
        .mask           = CPU_MASK_NONE,
-       .name           = "timer"
+       .name           = "timer"
 };
 
 void __init time_init(void)
 {
        if (nohpet)
                hpet_address = 0;
-       xtime.tv_sec = get_cmos_time();
-       xtime.tv_nsec = 0;
-
-       set_normalized_timespec(&wall_to_monotonic,
-                               -xtime.tv_sec, -xtime.tv_nsec);
 
        if (hpet_arch_init())
                hpet_address = 0;
 
        if (hpet_use_timer) {
                /* set tick_nsec to use the proper rate for HPET */
-               tick_nsec = TICK_NSEC_HPET;
+               tick_nsec = TICK_NSEC_HPET;
                tsc_khz = hpet_calibrate_tsc();
                timename = "HPET";
        } else {
@@ -415,54 +406,21 @@ void __init time_init(void)
        setup_irq(0, &irq0);
 }
 
-
-static long clock_cmos_diff;
-static unsigned long sleep_start;
-
 /*
  * sysfs support for the timer.
  */
 
 static int timer_suspend(struct sys_device *dev, pm_message_t state)
 {
-       /*
-        * Estimate time zone so that set_time can update the clock
-        */
-       long cmos_time =  get_cmos_time();
-
-       clock_cmos_diff = -cmos_time;
-       clock_cmos_diff += get_seconds();
-       sleep_start = cmos_time;
        return 0;
 }
 
 static int timer_resume(struct sys_device *dev)
 {
-       unsigned long flags;
-       unsigned long sec;
-       unsigned long ctime = get_cmos_time();
-       long sleep_length = (ctime - sleep_start) * HZ;
-
-       if (sleep_length < 0) {
-               printk(KERN_WARNING "Time skew detected in timer resume!\n");
-               /* The time after the resume must not be earlier than the time
-                * before the suspend or some nasty things will happen
-                */
-               sleep_length = 0;
-               ctime = sleep_start;
-       }
        if (hpet_address)
                hpet_reenable();
        else
                i8254_timer_resume();
-
-       sec = ctime + clock_cmos_diff;
-       write_seqlock_irqsave(&xtime_lock,flags);
-       xtime.tv_sec = sec;
-       xtime.tv_nsec = 0;
-       jiffies += sleep_length;
-       write_sequnlock_irqrestore(&xtime_lock,flags);
-       touch_softlockup_watchdog();
        return 0;
 }
 
index 8713ad4a4db14ca350a00a5eee55a9cc365a7373..03888420775d03320f0cea3c40989e100fea3e7c 100644 (file)
@@ -584,7 +584,8 @@ static void __kprobes do_trap(int trapnr, int signr, char *str,
                tsk->thread.error_code = error_code;
                tsk->thread.trap_no = trapnr;
 
-               if (exception_trace && unhandled_signal(tsk, signr))
+               if (show_unhandled_signals && unhandled_signal(tsk, signr) &&
+                   printk_ratelimit())
                        printk(KERN_INFO
                               "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n",
                               tsk->comm, tsk->pid, str,
@@ -688,7 +689,8 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs,
                tsk->thread.error_code = error_code;
                tsk->thread.trap_no = 13;
 
-               if (exception_trace && unhandled_signal(tsk, SIGSEGV))
+               if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
+                   printk_ratelimit())
                        printk(KERN_INFO
                       "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n",
                               tsk->comm, tsk->pid,
index e850aa01e1b36bde40a413bd5ec6765862d134e2..9b76b03d06001209437382b15c6f072c70f7e0dd 100644 (file)
@@ -61,25 +61,9 @@ inline int check_tsc_unstable(void)
  * first tick after the change will be slightly wrong.
  */
 
-#include <linux/workqueue.h>
-
-static unsigned int cpufreq_delayed_issched = 0;
-static unsigned int cpufreq_init = 0;
-static struct work_struct cpufreq_delayed_get_work;
-
-static void handle_cpufreq_delayed_get(struct work_struct *v)
-{
-       unsigned int cpu;
-       for_each_online_cpu(cpu) {
-               cpufreq_get(cpu);
-       }
-       cpufreq_delayed_issched = 0;
-}
-
-static unsigned int  ref_freq = 0;
-static unsigned long loops_per_jiffy_ref = 0;
-
-static unsigned long tsc_khz_ref = 0;
+static unsigned int  ref_freq;
+static unsigned long loops_per_jiffy_ref;
+static unsigned long tsc_khz_ref;
 
 static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
                                 void *data)
@@ -125,10 +109,8 @@ static struct notifier_block time_cpufreq_notifier_block = {
 
 static int __init cpufreq_tsc(void)
 {
-       INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get);
-       if (!cpufreq_register_notifier(&time_cpufreq_notifier_block,
-                                      CPUFREQ_TRANSITION_NOTIFIER))
-               cpufreq_init = 1;
+       cpufreq_register_notifier(&time_cpufreq_notifier_block,
+                                 CPUFREQ_TRANSITION_NOTIFIER);
        return 0;
 }
 
@@ -153,17 +135,18 @@ __cpuinit int unsynchronized_tsc(void)
 #endif
        /* Most intel systems have synchronized TSCs except for
           multi node systems */
-       if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
+       if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
 #ifdef CONFIG_ACPI
                /* But TSC doesn't tick in C3 so don't use it there */
-               if (acpi_gbl_FADT.header.length > 0 && acpi_gbl_FADT.C3latency < 1000)
+               if (acpi_gbl_FADT.header.length > 0 &&
+                   acpi_gbl_FADT.C3latency < 1000)
                        return 1;
 #endif
-               return 0;
+               return 0;
        }
 
-       /* Assume multi socket systems are not synchronized */
-       return num_present_cpus() > 1;
+       /* Assume multi socket systems are not synchronized */
+       return num_present_cpus() > 1;
 }
 
 int __init notsc_setup(char *s)
index 5c57ea4591c195621545454bd947095f62f12f46..ba8ea97abd219359d6e7c68541e375dbe97f5c7a 100644 (file)
@@ -28,7 +28,7 @@ SECTIONS
   _text = .;                   /* Text and read-only data */
   .text :  AT(ADDR(.text) - LOAD_OFFSET) {
        /* First the code that has to be first for bootstrapping */
-       *(.bootstrap.text)
+       *(.text.head)
        _stext = .;
        /* Then the rest */
        TEXT_TEXT
@@ -54,6 +54,13 @@ SECTIONS
 
   RODATA
 
+  . = ALIGN(4);
+  .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
+       __tracedata_start = .;
+       *(.tracedata)
+       __tracedata_end = .;
+  }
+
   . = ALIGN(PAGE_SIZE);        /* Align data segment to page size boundary */
                                /* Data */
   .data : AT(ADDR(.data) - LOAD_OFFSET) {
@@ -93,6 +100,9 @@ SECTIONS
   .vsyscall_gtod_data : AT(VLOAD(.vsyscall_gtod_data))
                { *(.vsyscall_gtod_data) }
   vsyscall_gtod_data = VVIRT(.vsyscall_gtod_data);
+  .vsyscall_clock : AT(VLOAD(.vsyscall_clock))
+               { *(.vsyscall_clock) }
+  vsyscall_clock = VVIRT(.vsyscall_clock);
 
 
   .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1))
@@ -133,20 +143,11 @@ SECTIONS
   /* might get freed after init */
   . = ALIGN(4096);
   __smp_alt_begin = .;
-  __smp_alt_instructions = .;
-  .smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) {
-       *(.smp_altinstructions)
-  }
-  __smp_alt_instructions_end = .;
-  . = ALIGN(8);
   __smp_locks = .;
   .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
        *(.smp_locks)
   }
   __smp_locks_end = .;
-  .smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) {
-       *(.smp_altinstr_replacement)
-  }
   . = ALIGN(4096);
   __smp_alt_end = .;
 
@@ -189,6 +190,12 @@ SECTIONS
   .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
   .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
 
+/* vdso blob that is mapped into user space */
+  vdso_start = . ;
+  .vdso  : AT(ADDR(.vdso) - LOAD_OFFSET) { *(.vdso) }
+  . = ALIGN(4096);
+  vdso_end = .;
+
 #ifdef CONFIG_BLK_DEV_INITRD
   . = ALIGN(4096);
   __initramfs_start = .;
index 57660d58d5003209381c8e9c58b25f75b7ee3339..06c34949bfdc9d09e90a219765aeb711c67e85a4 100644 (file)
@@ -42,6 +42,7 @@
 #include <asm/segment.h>
 #include <asm/desc.h>
 #include <asm/topology.h>
+#include <asm/vgtod.h>
 
 #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr)))
 #define __syscall_clobber "r11","rcx","memory"
  * - writen by timer interrupt or systcl (/proc/sys/kernel/vsyscall64)
  * Try to keep this structure as small as possible to avoid cache line ping pongs
  */
-struct vsyscall_gtod_data_t {
-       seqlock_t       lock;
-
-       /* open coded 'struct timespec' */
-       time_t          wall_time_sec;
-       u32             wall_time_nsec;
-
-       int             sysctl_enabled;
-       struct timezone sys_tz;
-       struct { /* extract of a clocksource struct */
-               cycle_t (*vread)(void);
-               cycle_t cycle_last;
-               cycle_t mask;
-               u32     mult;
-               u32     shift;
-       } clock;
-};
 int __vgetcpu_mode __section_vgetcpu_mode;
 
-struct vsyscall_gtod_data_t __vsyscall_gtod_data __section_vsyscall_gtod_data =
+struct vsyscall_gtod_data __vsyscall_gtod_data __section_vsyscall_gtod_data =
 {
        .lock = SEQLOCK_UNLOCKED,
        .sysctl_enabled = 1,
@@ -96,6 +80,8 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
        vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec;
        vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
        vsyscall_gtod_data.sys_tz = sys_tz;
+       vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
+       vsyscall_gtod_data.wall_to_monotonic = wall_to_monotonic;
        write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
 }
 
index 84f11728fc76e8438907be59f187ffb7fef96d72..327c9f2fa6269f3020f94f856cd8e0b8b36ab494 100644 (file)
@@ -159,7 +159,7 @@ void dump_pagetable(unsigned long address)
        pmd_t *pmd;
        pte_t *pte;
 
-       asm("movq %%cr3,%0" : "=r" (pgd));
+       pgd = (pgd_t *)read_cr3();
 
        pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK); 
        pgd += pgd_index(address);
@@ -221,16 +221,6 @@ static int is_errata93(struct pt_regs *regs, unsigned long address)
        return 0;
 } 
 
-int unhandled_signal(struct task_struct *tsk, int sig)
-{
-       if (is_init(tsk))
-               return 1;
-       if (tsk->ptrace & PT_PTRACED)
-               return 0;
-       return (tsk->sighand->action[sig-1].sa.sa_handler == SIG_IGN) ||
-               (tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL);
-}
-
 static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs,
                                 unsigned long error_code)
 {
@@ -301,8 +291,8 @@ static int vmalloc_fault(unsigned long address)
        return 0;
 }
 
-int page_fault_trace = 0;
-int exception_trace = 1;
+static int page_fault_trace;
+int show_unhandled_signals = 1;
 
 /*
  * This routine handles page faults.  It determines the address,
@@ -326,7 +316,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
        prefetchw(&mm->mmap_sem);
 
        /* get the address */
-       __asm__("movq %%cr2,%0":"=r" (address));
+       address = read_cr2();
 
        info.si_code = SEGV_MAPERR;
 
@@ -494,7 +484,8 @@ bad_area_nosemaphore:
                    (address >> 32))
                        return;
 
-               if (exception_trace && unhandled_signal(tsk, SIGSEGV)) {
+               if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
+                   printk_ratelimit()) {
                        printk(
                       "%s%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
                                        tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
@@ -568,7 +559,7 @@ out_of_memory:
        }
        printk("VM: killing process %s\n", tsk->comm);
        if (error_code & 4)
-               do_exit(SIGKILL);
+               do_group_exit(SIGKILL);
        goto no_context;
 
 do_sigbus:
index 9a0e98accf04aae3e11282e3079fd747afa646a3..38f5d63680060769a58b7ac607f9085b6acf19d3 100644 (file)
@@ -383,7 +383,7 @@ void __meminit init_memory_mapping(unsigned long start, unsigned long end)
        } 
 
        if (!after_bootmem)
-               asm volatile("movq %%cr4,%0" : "=r" (mmu_cr4_features));
+               mmu_cr4_features = read_cr4();
        __flush_tlb_all();
 }
 
@@ -600,16 +600,6 @@ void mark_rodata_ro(void)
 {
        unsigned long start = (unsigned long)_stext, end;
 
-#ifdef CONFIG_HOTPLUG_CPU
-       /* It must still be possible to apply SMP alternatives. */
-       if (num_possible_cpus() > 1)
-               start = (unsigned long)_etext;
-#endif
-
-#ifdef CONFIG_KPROBES
-       start = (unsigned long)__start_rodata;
-#endif
-       
        end = (unsigned long)__end_rodata;
        start = (start + PAGE_SIZE - 1) & PAGE_MASK;
        end &= PAGE_MASK;
@@ -697,41 +687,6 @@ int kern_addr_valid(unsigned long addr)
        return pfn_valid(pte_pfn(*pte));
 }
 
-#ifdef CONFIG_SYSCTL
-#include <linux/sysctl.h>
-
-extern int exception_trace, page_fault_trace;
-
-static ctl_table debug_table2[] = {
-       {
-               .ctl_name       = 99,
-               .procname       = "exception-trace",
-               .data           = &exception_trace,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = proc_dointvec
-       },
-       {}
-}; 
-
-static ctl_table debug_root_table2[] = { 
-       {
-               .ctl_name = CTL_DEBUG,
-               .procname = "debug",
-               .mode = 0555,
-               .child = debug_table2
-       },
-       {}
-}; 
-
-static __init int x8664_sysctl_init(void)
-{ 
-       register_sysctl_table(debug_root_table2);
-       return 0;
-}
-__initcall(x8664_sysctl_init);
-#endif
-
 /* A pseudo VMA to allow ptrace access for the vsyscall page.  This only
    covers the 64bit vsyscall page now. 32bit has a real VMA now and does
    not need special handling anymore. */
@@ -769,8 +724,17 @@ int in_gate_area_no_task(unsigned long addr)
        return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END);
 }
 
-void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size)
+void * __init alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size)
 {
        return __alloc_bootmem_core(pgdat->bdata, size,
                        SMP_CACHE_BYTES, (4UL*1024*1024*1024), 0);
 }
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+       if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
+               return "[vdso]";
+       if (vma == &gate_vma)
+               return "[vsyscall]";
+       return NULL;
+}
index f983c75825d09f67a3cbb833d25165d80a5cd183..a96006f7ae0c84a1878e5315522d89a56ff8242f 100644 (file)
@@ -44,12 +44,12 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
 { 
        unsigned long prevbase;
        struct bootnode nodes[8];
-       int nodeid, i, nb; 
+       int nodeid, i, j, nb;
        unsigned char nodeids[8];
        int found = 0;
        u32 reg;
        unsigned numnodes;
-       unsigned dualcore = 0;
+       unsigned num_cores;
 
        if (!early_pci_allowed())
                return -1;
@@ -60,6 +60,9 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
 
        printk(KERN_INFO "Scanning NUMA topology in Northbridge %d\n", nb); 
 
+       num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
+       printk(KERN_INFO "CPU has %d num_cores\n", num_cores);
+
        reg = read_pci_config(0, nb, 0, 0x60); 
        numnodes = ((reg >> 4) & 0xF) + 1;
        if (numnodes <= 1)
@@ -73,8 +76,6 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
                unsigned long base,limit; 
                u32 nodeid;
                
-               /* Undefined before E stepping, but hopefully 0 */
-               dualcore |= ((read_pci_config(0, nb, 3, 0xe8) >> 12) & 3) == 1;
                base = read_pci_config(0, nb, 1, 0x40 + i*8);
                limit = read_pci_config(0, nb, 1, 0x44 + i*8);
 
@@ -170,8 +171,8 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
        for (i = 0; i < 8; i++) {
                if (nodes[i].start != nodes[i].end) { 
                        nodeid = nodeids[i];
-                       apicid_to_node[nodeid << dualcore] = i;
-                       apicid_to_node[(nodeid << dualcore) + dualcore] = i;
+                       for (j = 0; j < num_cores; j++)
+                               apicid_to_node[(nodeid * num_cores) + j] = i;
                        setup_node_bootmem(i, nodes[i].start, nodes[i].end); 
                } 
        }
index 51548947ad3b7f1c32080e8304e37316fcc4b948..6da235522269e856fc000807888db8e345891a90 100644 (file)
@@ -273,9 +273,6 @@ void __init numa_init_array(void)
 
 #ifdef CONFIG_NUMA_EMU
 /* Numa emulation */
-#define E820_ADDR_HOLE_SIZE(start, end)                                        \
-       (e820_hole_size((start) >> PAGE_SHIFT, (end) >> PAGE_SHIFT) <<  \
-       PAGE_SHIFT)
 char *cmdline __initdata;
 
 /*
@@ -319,7 +316,7 @@ static int __init split_nodes_equally(struct bootnode *nodes, u64 *addr,
                return -1;
        if (num_nodes > MAX_NUMNODES)
                num_nodes = MAX_NUMNODES;
-       size = (max_addr - *addr - E820_ADDR_HOLE_SIZE(*addr, max_addr)) /
+       size = (max_addr - *addr - e820_hole_size(*addr, max_addr)) /
               num_nodes;
        /*
         * Calculate the number of big nodes that can be allocated as a result
@@ -347,7 +344,7 @@ static int __init split_nodes_equally(struct bootnode *nodes, u64 *addr,
                if (i == num_nodes + node_start - 1)
                        end = max_addr;
                else
-                       while (end - *addr - E820_ADDR_HOLE_SIZE(*addr, end) <
+                       while (end - *addr - e820_hole_size(*addr, end) <
                               size) {
                                end += FAKE_NODE_MIN_SIZE;
                                if (end > max_addr) {
@@ -476,18 +473,22 @@ out:
 
        /*
         * We need to vacate all active ranges that may have been registered by
-        * SRAT.
+        * SRAT and set acpi_numa to -1 so that srat_disabled() always returns
+        * true.  NUMA emulation has succeeded so we will not scan ACPI nodes.
         */
        remove_all_active_ranges();
+#ifdef CONFIG_ACPI_NUMA
+       acpi_numa = -1;
+#endif
        for_each_node_mask(i, node_possible_map) {
                e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT,
                                                nodes[i].end >> PAGE_SHIFT);
                setup_node_bootmem(i, nodes[i].start, nodes[i].end);
        }
+       acpi_fake_nodes(nodes, num_nodes);
        numa_init_array();
        return 0;
 }
-#undef E820_ADDR_HOLE_SIZE
 #endif /* CONFIG_NUMA_EMU */
 
 void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
index 9148f4a4cec6493097e12bb8de1cff616f12e9bf..7e161c698af47cb98a766c8253c8596cfeeb4b74 100644 (file)
@@ -13,7 +13,7 @@
 #include <asm/tlbflush.h>
 #include <asm/io.h>
 
-static inline pte_t *lookup_address(unsigned long address) 
+pte_t *lookup_address(unsigned long address)
 { 
        pgd_t *pgd = pgd_offset_k(address);
        pud_t *pud;
@@ -74,14 +74,12 @@ static void flush_kernel_map(void *arg)
        struct page *pg;
 
        /* When clflush is available always use it because it is
-          much cheaper than WBINVD. Disable clflush for now because
-          the high level code is not ready yet */
-       if (1 || !cpu_has_clflush)
+          much cheaper than WBINVD. */
+       if (!cpu_has_clflush)
                asm volatile("wbinvd" ::: "memory");
        else list_for_each_entry(pg, l, lru) {
                void *adr = page_address(pg);
-               if (cpu_has_clflush)
-                       cache_flush_page(adr);
+               cache_flush_page(adr);
        }
        __flush_tlb_all();
 }
@@ -95,7 +93,8 @@ static LIST_HEAD(deferred_pages); /* protected by init_mm.mmap_sem */
 
 static inline void save_page(struct page *fpage)
 {
-       list_add(&fpage->lru, &deferred_pages);
+       if (!test_and_set_bit(PG_arch_1, &fpage->flags))
+               list_add(&fpage->lru, &deferred_pages);
 }
 
 /* 
@@ -129,9 +128,12 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
        pte_t *kpte; 
        struct page *kpte_page;
        pgprot_t ref_prot2;
+
        kpte = lookup_address(address);
        if (!kpte) return 0;
        kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
+       BUG_ON(PageLRU(kpte_page));
+       BUG_ON(PageCompound(kpte_page));
        if (pgprot_val(prot) != pgprot_val(ref_prot)) { 
                if (!pte_huge(*kpte)) {
                        set_pte(kpte, pfn_pte(pfn, prot));
@@ -159,10 +161,9 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
        /* on x86-64 the direct mapping set at boot is not using 4k pages */
        BUG_ON(PageReserved(kpte_page));
 
-       if (page_private(kpte_page) == 0) {
-               save_page(kpte_page);
+       save_page(kpte_page);
+       if (page_private(kpte_page) == 0)
                revert_page(address, ref_prot);
-       }
        return 0;
 } 
 
@@ -234,6 +235,10 @@ void global_flush_tlb(void)
        flush_map(&l);
 
        list_for_each_entry_safe(pg, next, &l, lru) {
+               list_del(&pg->lru);
+               clear_bit(PG_arch_1, &pg->flags);
+               if (page_private(pg) != 0)
+                       continue;
                ClearPagePrivate(pg);
                __free_page(pg);
        } 
index 1e76bb0a727726134317e9b085dba3d229a43e30..acdf03e191468b32ad84d16cd66ee47c106f0191 100644 (file)
@@ -106,9 +106,9 @@ static __init int slit_valid(struct acpi_table_slit *slit)
                for (j = 0; j < d; j++)  {
                        u8 val = slit->entry[d*i + j];
                        if (i == j) {
-                               if (val != 10)
+                               if (val != LOCAL_DISTANCE)
                                        return 0;
-                       } else if (val <= 10)
+                       } else if (val <= LOCAL_DISTANCE)
                                return 0;
                }
        }
@@ -350,7 +350,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
 
 /* Sanity check to catch more bad SRATs (they are amazingly common).
    Make sure the PXMs cover all memory. */
-static int nodes_cover_memory(void)
+static int __init nodes_cover_memory(const struct bootnode *nodes)
 {
        int i;
        unsigned long pxmram, e820ram;
@@ -394,6 +394,9 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
 {
        int i;
 
+       if (acpi_numa <= 0)
+               return -1;
+
        /* First clean up the node list */
        for (i = 0; i < MAX_NUMNODES; i++) {
                cutoff_node(i, start, end);
@@ -403,10 +406,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
                }
        }
 
-       if (acpi_numa <= 0)
-               return -1;
-
-       if (!nodes_cover_memory()) {
+       if (!nodes_cover_memory(nodes)) {
                bad_srat();
                return -1;
        }
@@ -440,6 +440,86 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
        return 0;
 }
 
+#ifdef CONFIG_NUMA_EMU
+static int __init find_node_by_addr(unsigned long addr)
+{
+       int ret = NUMA_NO_NODE;
+       int i;
+
+       for_each_node_mask(i, nodes_parsed) {
+               /*
+                * Find the real node that this emulated node appears on.  For
+                * the sake of simplicity, we only use a real node's starting
+                * address to determine which emulated node it appears on.
+                */
+               if (addr >= nodes[i].start && addr < nodes[i].end) {
+                       ret = i;
+                       break;
+               }
+       }
+       return i;
+}
+
+/*
+ * In NUMA emulation, we need to setup proximity domain (_PXM) to node ID
+ * mappings that respect the real ACPI topology but reflect our emulated
+ * environment.  For each emulated node, we find which real node it appears on
+ * and create PXM to NID mappings for those fake nodes which mirror that
+ * locality.  SLIT will now represent the correct distances between emulated
+ * nodes as a result of the real topology.
+ */
+void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes)
+{
+       int i, j;
+       int fake_node_to_pxm_map[MAX_NUMNODES] = {
+               [0 ... MAX_NUMNODES-1] = PXM_INVAL
+       };
+       unsigned char fake_apicid_to_node[MAX_LOCAL_APIC] = {
+               [0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE
+       };
+
+       printk(KERN_INFO "Faking PXM affinity for fake nodes on real "
+                        "topology.\n");
+       for (i = 0; i < num_nodes; i++) {
+               int nid, pxm;
+
+               nid = find_node_by_addr(fake_nodes[i].start);
+               if (nid == NUMA_NO_NODE)
+                       continue;
+               pxm = node_to_pxm(nid);
+               if (pxm == PXM_INVAL)
+                       continue;
+               fake_node_to_pxm_map[i] = pxm;
+               /*
+                * For each apicid_to_node mapping that exists for this real
+                * node, it must now point to the fake node ID.
+                */
+               for (j = 0; j < MAX_LOCAL_APIC; j++)
+                       if (apicid_to_node[j] == nid)
+                               fake_apicid_to_node[j] = i;
+       }
+       for (i = 0; i < num_nodes; i++)
+               __acpi_map_pxm_to_node(fake_node_to_pxm_map[i], i);
+       memcpy(apicid_to_node, fake_apicid_to_node, sizeof(apicid_to_node));
+
+       nodes_clear(nodes_parsed);
+       for (i = 0; i < num_nodes; i++)
+               if (fake_nodes[i].start != fake_nodes[i].end)
+                       node_set(i, nodes_parsed);
+       WARN_ON(!nodes_cover_memory(fake_nodes));
+}
+
+static int null_slit_node_compare(int a, int b)
+{
+       return node_to_pxm(a) == node_to_pxm(b);
+}
+#else
+static int null_slit_node_compare(int a, int b)
+{
+       return a == b;
+}
+#endif /* CONFIG_NUMA_EMU */
+
 void __init srat_reserve_add_area(int nodeid)
 {
        if (found_add_area && nodes_add[nodeid].end) {
@@ -464,7 +544,8 @@ int __node_distance(int a, int b)
        int index;
 
        if (!acpi_slit)
-               return a == b ? 10 : 20;
+               return null_slit_node_compare(a, b) ? LOCAL_DISTANCE :
+                                                     REMOTE_DISTANCE;
        index = acpi_slit->locality_count * node_to_pxm(a);
        return acpi_slit->entry[index + node_to_pxm(b)];
 }
index 3acf60ded2a0b54144a72b5b0faf5f8bc2c00933..9cc813e29706d3febdd70aacf5b4aa2d6e4940af 100644 (file)
@@ -59,6 +59,8 @@ fill_mp_bus_to_cpumask(void)
                                     j <= SUBORDINATE_LDT_BUS_NUMBER(ldtbus);
                                     j++) { 
                                        struct pci_bus *bus;
+                                       struct pci_sysdata *sd;
+
                                        long node = NODE_ID(nid);
                                        /* Algorithm a bit dumb, but
                                           it shouldn't matter here */
@@ -67,7 +69,9 @@ fill_mp_bus_to_cpumask(void)
                                                continue;
                                        if (!node_online(node))
                                                node = 0;
-                                       bus->sysdata = (void *)node;
+
+                                       sd = bus->sysdata;
+                                       sd->node = node;
                                }               
                        }
                }
diff --git a/arch/x86_64/vdso/Makefile b/arch/x86_64/vdso/Makefile
new file mode 100644 (file)
index 0000000..faaa72f
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# x86-64 vDSO.
+#
+
+# files to link into the vdso
+# vdso-start.o has to be first
+vobjs-y := vdso-start.o vdso-note.o vclock_gettime.o vgetcpu.o vvar.o
+
+# files to link into kernel
+obj-y := vma.o vdso.o vdso-syms.o
+
+vobjs := $(foreach F,$(vobjs-y),$(obj)/$F)
+
+$(obj)/vdso.o: $(obj)/vdso.so
+
+targets += vdso.so vdso.lds $(vobjs-y) vdso-syms.o
+
+# The DSO images are built using a special linker script.
+quiet_cmd_syscall = SYSCALL $@
+      cmd_syscall = $(CC) -m elf_x86_64 -nostdlib $(SYSCFLAGS_$(@F)) \
+                         -Wl,-T,$(filter-out FORCE,$^) -o $@
+
+export CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
+
+vdso-flags = -fPIC -shared -Wl,-soname=linux-vdso.so.1 \
+                $(call ld-option, -Wl$(comma)--hash-style=sysv) \
+               -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096
+SYSCFLAGS_vdso.so = $(vdso-flags)
+
+$(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so
+
+$(obj)/vdso.so: $(src)/vdso.lds $(vobjs) FORCE
+       $(call if_changed,syscall)
+
+CF := $(PROFILING) -mcmodel=small -fPIC -g0 -O2 -fasynchronous-unwind-tables -m64
+
+$(obj)/vclock_gettime.o: CFLAGS = $(CF)
+$(obj)/vgetcpu.o: CFLAGS = $(CF)
+
+# We also create a special relocatable object that should mirror the symbol
+# table and layout of the linked DSO.  With ld -R we can then refer to
+# these symbols in the kernel code rather than hand-coded addresses.
+extra-y += vdso-syms.o
+$(obj)/built-in.o: $(obj)/vdso-syms.o
+$(obj)/built-in.o: ld_flags += -R $(obj)/vdso-syms.o
+
+SYSCFLAGS_vdso-syms.o = -r -d
+$(obj)/vdso-syms.o: $(src)/vdso.lds $(vobjs) FORCE
+       $(call if_changed,syscall)
diff --git a/arch/x86_64/vdso/vclock_gettime.c b/arch/x86_64/vdso/vclock_gettime.c
new file mode 100644 (file)
index 0000000..17f6a00
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2006 Andi Kleen, SUSE Labs.
+ * Subject to the GNU Public License, v.2
+ *
+ * Fast user context implementation of clock_gettime and gettimeofday.
+ *
+ * The code should have no internal unresolved relocations.
+ * Check with readelf after changing.
+ * Also alternative() doesn't work.
+ */
+
+#include <linux/kernel.h>
+#include <linux/posix-timers.h>
+#include <linux/time.h>
+#include <linux/string.h>
+#include <asm/vsyscall.h>
+#include <asm/vgtod.h>
+#include <asm/timex.h>
+#include <asm/hpet.h>
+#include <asm/unistd.h>
+#include <asm/io.h>
+#include <asm/vgtod.h>
+#include "vextern.h"
+
+#define gtod vdso_vsyscall_gtod_data
+
+static long vdso_fallback_gettime(long clock, struct timespec *ts)
+{
+       long ret;
+       asm("syscall" : "=a" (ret) :
+           "0" (__NR_clock_gettime),"D" (clock), "S" (ts) : "memory");
+       return ret;
+}
+
+static inline long vgetns(void)
+{
+       cycles_t (*vread)(void);
+       vread = gtod->clock.vread;
+       return ((vread() - gtod->clock.cycle_last) * gtod->clock.mult) >>
+               gtod->clock.shift;
+}
+
+static noinline int do_realtime(struct timespec *ts)
+{
+       unsigned long seq, ns;
+       do {
+               seq = read_seqbegin(&gtod->lock);
+               ts->tv_sec = gtod->wall_time_sec;
+               ts->tv_nsec = gtod->wall_time_nsec;
+               ns = vgetns();
+       } while (unlikely(read_seqretry(&gtod->lock, seq)));
+       timespec_add_ns(ts, ns);
+       return 0;
+}
+
+/* Copy of the version in kernel/time.c which we cannot directly access */
+static void vset_normalized_timespec(struct timespec *ts, long sec, long nsec)
+{
+       while (nsec >= NSEC_PER_SEC) {
+               nsec -= NSEC_PER_SEC;
+               ++sec;
+       }
+       while (nsec < 0) {
+               nsec += NSEC_PER_SEC;
+               --sec;
+       }
+       ts->tv_sec = sec;
+       ts->tv_nsec = nsec;
+}
+
+static noinline int do_monotonic(struct timespec *ts)
+{
+       unsigned long seq, ns, secs;
+       do {
+               seq = read_seqbegin(&gtod->lock);
+               secs = gtod->wall_time_sec;
+               ns = gtod->wall_time_nsec + vgetns();
+               secs += gtod->wall_to_monotonic.tv_sec;
+               ns += gtod->wall_to_monotonic.tv_nsec;
+       } while (unlikely(read_seqretry(&gtod->lock, seq)));
+       vset_normalized_timespec(ts, secs, ns);
+       return 0;
+}
+
+int __vdso_clock_gettime(clockid_t clock, struct timespec *ts)
+{
+       if (likely(gtod->sysctl_enabled && gtod->clock.vread))
+               switch (clock) {
+               case CLOCK_REALTIME:
+                       return do_realtime(ts);
+               case CLOCK_MONOTONIC:
+                       return do_monotonic(ts);
+               }
+       return vdso_fallback_gettime(clock, ts);
+}
+int clock_gettime(clockid_t, struct timespec *)
+       __attribute__((weak, alias("__vdso_clock_gettime")));
+
+int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+       long ret;
+       if (likely(gtod->sysctl_enabled && gtod->clock.vread)) {
+               BUILD_BUG_ON(offsetof(struct timeval, tv_usec) !=
+                            offsetof(struct timespec, tv_nsec) ||
+                            sizeof(*tv) != sizeof(struct timespec));
+               do_realtime((struct timespec *)tv);
+               tv->tv_usec /= 1000;
+               if (unlikely(tz != NULL)) {
+                       /* This relies on gcc inlining the memcpy. We'll notice
+                          if it ever fails to do so. */
+                       memcpy(tz, &gtod->sys_tz, sizeof(struct timezone));
+               }
+               return 0;
+       }
+       asm("syscall" : "=a" (ret) :
+           "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory");
+       return ret;
+}
+int gettimeofday(struct timeval *, struct timezone *)
+       __attribute__((weak, alias("__vdso_gettimeofday")));
diff --git a/arch/x86_64/vdso/vdso-note.S b/arch/x86_64/vdso/vdso-note.S
new file mode 100644 (file)
index 0000000..79a071e
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
+ * Here we can supply some information useful to userland.
+ */
+
+#include <linux/uts.h>
+#include <linux/version.h>
+#include <linux/elfnote.h>
+
+ELFNOTE_START(Linux, 0, "a")
+       .long LINUX_VERSION_CODE
+ELFNOTE_END
diff --git a/arch/x86_64/vdso/vdso-start.S b/arch/x86_64/vdso/vdso-start.S
new file mode 100644 (file)
index 0000000..2dc2cdb
--- /dev/null
@@ -0,0 +1,2 @@
+       .globl vdso_kernel_start
+vdso_kernel_start:
diff --git a/arch/x86_64/vdso/vdso.S b/arch/x86_64/vdso/vdso.S
new file mode 100644 (file)
index 0000000..92e80c1
--- /dev/null
@@ -0,0 +1,2 @@
+       .section ".vdso","a"
+       .incbin "arch/x86_64/vdso/vdso.so"
diff --git a/arch/x86_64/vdso/vdso.lds.S b/arch/x86_64/vdso/vdso.lds.S
new file mode 100644 (file)
index 0000000..b9a60e6
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Linker script for vsyscall DSO.  The vsyscall page is an ELF shared
+ * object prelinked to its virtual address, and with only one read-only
+ * segment (that fits in one page).  This script controls its layout.
+ */
+#include <asm/asm-offsets.h>
+#include "voffset.h"
+
+#define VDSO_PRELINK 0xffffffffff700000
+
+SECTIONS
+{
+  . = VDSO_PRELINK + SIZEOF_HEADERS;
+
+  .hash           : { *(.hash) }               :text
+  .gnu.hash       : { *(.gnu.hash) }
+  .dynsym         : { *(.dynsym) }
+  .dynstr         : { *(.dynstr) }
+  .gnu.version    : { *(.gnu.version) }
+  .gnu.version_d  : { *(.gnu.version_d) }
+  .gnu.version_r  : { *(.gnu.version_r) }
+
+  /* This linker script is used both with -r and with -shared.
+     For the layouts to match, we need to skip more than enough
+     space for the dynamic symbol table et al.  If this amount
+     is insufficient, ld -shared will barf.  Just increase it here.  */
+  . = VDSO_PRELINK + VDSO_TEXT_OFFSET;
+
+  .text           : { *(.text) }               :text
+  .text.ptr       : { *(.text.ptr) }           :text
+  . = VDSO_PRELINK + 0x900;
+  .data           : { *(.data) }               :text
+  .bss            : { *(.bss) }                        :text
+
+  .altinstructions : { *(.altinstructions) }                   :text
+  .altinstr_replacement  : { *(.altinstr_replacement) }        :text
+
+  .note                  : { *(.note.*) }              :text :note
+  .eh_frame_hdr   : { *(.eh_frame_hdr) }       :text :eh_frame_hdr
+  .eh_frame       : { KEEP (*(.eh_frame)) }    :text
+  .dynamic        : { *(.dynamic) }            :text :dynamic
+  .useless        : {
+       *(.got.plt) *(.got)
+       *(.gnu.linkonce.d.*)
+       *(.dynbss)
+       *(.gnu.linkonce.b.*)
+  }                                            :text
+}
+
+/*
+ * We must supply the ELF program headers explicitly to get just one
+ * PT_LOAD segment, and set the flags explicitly to make segments read-only.
+ */
+PHDRS
+{
+  text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
+  dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+  note PT_NOTE FLAGS(4); /* PF_R */
+  eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */
+}
+
+/*
+ * This controls what symbols we export from the DSO.
+ */
+VERSION
+{
+  LINUX_2.6 {
+    global:
+       clock_gettime;
+       __vdso_clock_gettime;
+       gettimeofday;
+       __vdso_gettimeofday;
+       getcpu;
+       __vdso_getcpu;
+    local: *;
+  };
+}
diff --git a/arch/x86_64/vdso/vextern.h b/arch/x86_64/vdso/vextern.h
new file mode 100644 (file)
index 0000000..1683ba2
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef VEXTERN
+#include <asm/vsyscall.h>
+#define VEXTERN(x) \
+       extern typeof(x) *vdso_ ## x __attribute__((visibility("hidden")));
+#endif
+
+#define VMAGIC 0xfeedbabeabcdefabUL
+
+/* Any kernel variables used in the vDSO must be exported in the main
+   kernel's vmlinux.lds.S/vsyscall.h/proper __section and
+   put into vextern.h and be referenced as a pointer with vdso prefix.
+   The main kernel later fills in the values.   */
+
+VEXTERN(jiffies)
+VEXTERN(vgetcpu_mode)
+VEXTERN(vsyscall_gtod_data)
diff --git a/arch/x86_64/vdso/vgetcpu.c b/arch/x86_64/vdso/vgetcpu.c
new file mode 100644 (file)
index 0000000..91f6e85
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2006 Andi Kleen, SUSE Labs.
+ * Subject to the GNU Public License, v.2
+ *
+ * Fast user context implementation of getcpu()
+ */
+
+#include <linux/kernel.h>
+#include <linux/getcpu.h>
+#include <linux/jiffies.h>
+#include <linux/time.h>
+#include <asm/vsyscall.h>
+#include <asm/vgtod.h>
+#include "vextern.h"
+
+long __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache)
+{
+       unsigned int dummy, p;
+       unsigned long j = 0;
+
+       /* Fast cache - only recompute value once per jiffies and avoid
+          relatively costly rdtscp/cpuid otherwise.
+          This works because the scheduler usually keeps the process
+          on the same CPU and this syscall doesn't guarantee its
+          results anyways.
+          We do this here because otherwise user space would do it on
+          its own in a likely inferior way (no access to jiffies).
+          If you don't like it pass NULL. */
+       if (tcache && tcache->blob[0] == (j = *vdso_jiffies)) {
+               p = tcache->blob[1];
+       } else if (*vdso_vgetcpu_mode == VGETCPU_RDTSCP) {
+               /* Load per CPU data from RDTSCP */
+               rdtscp(dummy, dummy, p);
+       } else {
+               /* Load per CPU data from GDT */
+               asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG));
+       }
+       if (tcache) {
+               tcache->blob[0] = j;
+               tcache->blob[1] = p;
+       }
+       if (cpu)
+               *cpu = p & 0xfff;
+       if (node)
+               *node = p >> 12;
+       return 0;
+}
+
+long getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache)
+       __attribute__((weak, alias("__vdso_getcpu")));
diff --git a/arch/x86_64/vdso/vma.c b/arch/x86_64/vdso/vma.c
new file mode 100644 (file)
index 0000000..d4cb83a
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Set up the VMAs to tell the VM about the vDSO.
+ * Copyright 2007 Andi Kleen, SUSE Labs.
+ * Subject to the GPL, v.2
+ */
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/random.h>
+#include <asm/vsyscall.h>
+#include <asm/vgtod.h>
+#include <asm/proto.h>
+#include "voffset.h"
+
+int vdso_enabled = 1;
+
+#define VEXTERN(x) extern typeof(__ ## x) *vdso_ ## x;
+#include "vextern.h"
+#undef VEXTERN
+
+extern char vdso_kernel_start[], vdso_start[], vdso_end[];
+extern unsigned short vdso_sync_cpuid;
+
+struct page **vdso_pages;
+
+static inline void *var_ref(void *vbase, char *var, char *name)
+{
+       unsigned offset = var - &vdso_kernel_start[0] + VDSO_TEXT_OFFSET;
+       void *p = vbase + offset;
+       if (*(void **)p != (void *)VMAGIC) {
+               printk("VDSO: variable %s broken\n", name);
+               vdso_enabled = 0;
+       }
+       return p;
+}
+
+static int __init init_vdso_vars(void)
+{
+       int npages = (vdso_end - vdso_start + PAGE_SIZE - 1) / PAGE_SIZE;
+       int i;
+       char *vbase;
+
+       vdso_pages = kmalloc(sizeof(struct page *) * npages, GFP_KERNEL);
+       if (!vdso_pages)
+               goto oom;
+       for (i = 0; i < npages; i++) {
+               struct page *p;
+               p = alloc_page(GFP_KERNEL);
+               if (!p)
+                       goto oom;
+               vdso_pages[i] = p;
+               copy_page(page_address(p), vdso_start + i*PAGE_SIZE);
+       }
+
+       vbase = vmap(vdso_pages, npages, 0, PAGE_KERNEL);
+       if (!vbase)
+               goto oom;
+
+       if (memcmp(vbase, "\177ELF", 4)) {
+               printk("VDSO: I'm broken; not ELF\n");
+               vdso_enabled = 0;
+       }
+
+#define V(x) *(typeof(x) *) var_ref(vbase, (char *)RELOC_HIDE(&x, 0), #x)
+#define VEXTERN(x) \
+       V(vdso_ ## x) = &__ ## x;
+#include "vextern.h"
+#undef VEXTERN
+       return 0;
+
+ oom:
+       printk("Cannot allocate vdso\n");
+       vdso_enabled = 0;
+       return -ENOMEM;
+}
+__initcall(init_vdso_vars);
+
+struct linux_binprm;
+
+/* Put the vdso above the (randomized) stack with another randomized offset.
+   This way there is no hole in the middle of address space.
+   To save memory make sure it is still in the same PTE as the stack top.
+   This doesn't give that many random bits */
+static unsigned long vdso_addr(unsigned long start, unsigned len)
+{
+       unsigned long addr, end;
+       unsigned offset;
+       end = (start + PMD_SIZE - 1) & PMD_MASK;
+       if (end >= TASK_SIZE64)
+               end = TASK_SIZE64;
+       end -= len;
+       /* This loses some more bits than a modulo, but is cheaper */
+       offset = get_random_int() & (PTRS_PER_PTE - 1);
+       addr = start + (offset << PAGE_SHIFT);
+       if (addr >= end)
+               addr = end;
+       return addr;
+}
+
+/* Setup a VMA at program startup for the vsyscall page.
+   Not called for compat tasks */
+int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack)
+{
+       struct mm_struct *mm = current->mm;
+       unsigned long addr;
+       int ret;
+       unsigned len = round_up(vdso_end - vdso_start, PAGE_SIZE);
+
+       if (!vdso_enabled)
+               return 0;
+
+       down_write(&mm->mmap_sem);
+       addr = vdso_addr(mm->start_stack, len);
+       addr = get_unmapped_area(NULL, addr, len, 0, 0);
+       if (IS_ERR_VALUE(addr)) {
+               ret = addr;
+               goto up_fail;
+       }
+
+       ret = install_special_mapping(mm, addr, len,
+                                     VM_READ|VM_EXEC|
+                                     VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
+                                     VM_ALWAYSDUMP,
+                                     vdso_pages);
+       if (ret)
+               goto up_fail;
+
+       current->mm->context.vdso = (void *)addr;
+up_fail:
+       up_write(&mm->mmap_sem);
+       return ret;
+}
+
+static __init int vdso_setup(char *s)
+{
+       vdso_enabled = simple_strtoul(s, NULL, 0);
+       return 0;
+}
+__setup("vdso=", vdso_setup);
diff --git a/arch/x86_64/vdso/voffset.h b/arch/x86_64/vdso/voffset.h
new file mode 100644 (file)
index 0000000..5304204
--- /dev/null
@@ -0,0 +1 @@
+#define VDSO_TEXT_OFFSET 0x500
diff --git a/arch/x86_64/vdso/vvar.c b/arch/x86_64/vdso/vvar.c
new file mode 100644 (file)
index 0000000..6fc2221
--- /dev/null
@@ -0,0 +1,12 @@
+/* Define pointer to external vDSO variables.
+   These are part of the vDSO. The kernel fills in the real addresses
+   at boot time. This is done because when the vdso is linked the
+   kernel isn't yet and we don't know the final addresses. */
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <asm/vsyscall.h>
+#include <asm/timex.h>
+#include <asm/vgtod.h>
+
+#define VEXTERN(x) typeof (__ ## x) *vdso_ ## x = (void *)VMAGIC;
+#include "vextern.h"
index 0768741d681364d1ee71bbd82ace768b31271d9d..ca2ef4e08497f21a8f5f542031839f3e63e18b48 100644 (file)
@@ -53,7 +53,7 @@ endif # BLOCK
 
 config BLK_DEV_BSG
        bool "Block layer SG support v4 (EXPERIMENTAL)"
-       depends on (SCSI=y) && EXPERIMENTAL
+       depends on EXPERIMENTAL
        ---help---
        Saying Y here will enable generic SG (SCSI generic) v4 support
        for any block device.
index f2992e72b841e232d5d8b0296b6af9ddb90ac31b..b571869928a83c16dbcf6fb0c94aa5dc0c90e2da 100644 (file)
@@ -932,24 +932,34 @@ void bsg_unregister_queue(struct request_queue *q)
 {
        struct bsg_class_device *bcd = &q->bsg_dev;
 
-       WARN_ON(!bcd->class_dev);
+       if (!bcd->class_dev)
+               return;
 
        mutex_lock(&bsg_mutex);
        sysfs_remove_link(&q->kobj, "bsg");
-       class_device_destroy(bsg_class, MKDEV(bsg_major, bcd->minor));
+       class_device_unregister(bcd->class_dev);
+       put_device(bcd->dev);
        bcd->class_dev = NULL;
+       bcd->dev = NULL;
        list_del_init(&bcd->list);
        bsg_device_nr--;
        mutex_unlock(&bsg_mutex);
 }
 EXPORT_SYMBOL_GPL(bsg_unregister_queue);
 
-int bsg_register_queue(struct request_queue *q, const char *name)
+int bsg_register_queue(struct request_queue *q, struct device *gdev,
+                      const char *name)
 {
        struct bsg_class_device *bcd, *__bcd;
        dev_t dev;
        int ret = -EMFILE;
        struct class_device *class_dev = NULL;
+       const char *devname;
+
+       if (name)
+               devname = name;
+       else
+               devname = gdev->bus_id;
 
        /*
         * we need a proper transport to send commands, not a stacked device
@@ -982,18 +992,20 @@ retry:
                bsg_minor_idx = 0;
 
        bcd->queue = q;
+       bcd->dev = get_device(gdev);
        dev = MKDEV(bsg_major, bcd->minor);
-       class_dev = class_device_create(bsg_class, NULL, dev, bcd->dev, "%s", name);
+       class_dev = class_device_create(bsg_class, NULL, dev, gdev, "%s",
+                                       devname);
        if (IS_ERR(class_dev)) {
                ret = PTR_ERR(class_dev);
-               goto err;
+               goto err_put;
        }
        bcd->class_dev = class_dev;
 
        if (q->kobj.sd) {
                ret = sysfs_create_link(&q->kobj, &bcd->class_dev->kobj, "bsg");
                if (ret)
-                       goto err;
+                       goto err_unregister;
        }
 
        list_add_tail(&bcd->list, &bsg_class_list);
@@ -1001,37 +1013,17 @@ retry:
 
        mutex_unlock(&bsg_mutex);
        return 0;
+
+err_unregister:
+       class_device_unregister(class_dev);
+err_put:
+       put_device(gdev);
 err:
-       if (class_dev)
-               class_device_destroy(bsg_class, MKDEV(bsg_major, bcd->minor));
        mutex_unlock(&bsg_mutex);
        return ret;
 }
 EXPORT_SYMBOL_GPL(bsg_register_queue);
 
-static int bsg_add(struct class_device *cl_dev, struct class_interface *cl_intf)
-{
-       int ret;
-       struct scsi_device *sdp = to_scsi_device(cl_dev->dev);
-       struct request_queue *rq = sdp->request_queue;
-
-       if (rq->kobj.parent)
-               ret = bsg_register_queue(rq, kobject_name(rq->kobj.parent));
-       else
-               ret = bsg_register_queue(rq, kobject_name(&sdp->sdev_gendev.kobj));
-       return ret;
-}
-
-static void bsg_remove(struct class_device *cl_dev, struct class_interface *cl_intf)
-{
-       bsg_unregister_queue(to_scsi_device(cl_dev->dev)->request_queue);
-}
-
-static struct class_interface bsg_intf = {
-       .add    = bsg_add,
-       .remove = bsg_remove,
-};
-
 static struct cdev bsg_cdev = {
        .kobj   = {.name = "bsg", },
        .owner  = THIS_MODULE,
@@ -1069,16 +1061,9 @@ static int __init bsg_init(void)
        if (ret)
                goto unregister_chrdev;
 
-       ret = scsi_register_interface(&bsg_intf);
-       if (ret)
-               goto remove_cdev;
-
        printk(KERN_INFO BSG_DESCRIPTION " version " BSG_VERSION
               " loaded (major %d)\n", bsg_major);
        return 0;
-remove_cdev:
-       printk(KERN_ERR "bsg: failed register scsi interface %d\n", ret);
-       cdev_del(&bsg_cdev);
 unregister_chrdev:
        unregister_chrdev_region(MKDEV(bsg_major, 0), BSG_MAX_DEVS);
 destroy_bsg_class:
index 71bdf88884b2c6545176f4d964656d6ab62181ff..d359a715bbc88d2f71c499f7510a46b43f8bd6c3 100644 (file)
@@ -214,8 +214,8 @@ int blk_verify_command(unsigned char *cmd, int has_write_perm)
 }
 EXPORT_SYMBOL_GPL(blk_verify_command);
 
-int blk_fill_sghdr_rq(request_queue_t *q, struct request *rq,
-                     struct sg_io_hdr *hdr, int has_write_perm)
+static int blk_fill_sghdr_rq(request_queue_t *q, struct request *rq,
+                            struct sg_io_hdr *hdr, int has_write_perm)
 {
        memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
 
@@ -238,22 +238,20 @@ int blk_fill_sghdr_rq(request_queue_t *q, struct request *rq,
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(blk_fill_sghdr_rq);
 
 /*
  * unmap a request that was previously mapped to this sg_io_hdr. handles
  * both sg and non-sg sg_io_hdr.
  */
-int blk_unmap_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr)
+static int blk_unmap_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr)
 {
        blk_rq_unmap_user(rq->bio);
        blk_put_request(rq);
        return 0;
 }
-EXPORT_SYMBOL_GPL(blk_unmap_sghdr_rq);
 
-int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
-                         struct bio *bio)
+static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
+                                struct bio *bio)
 {
        int r, ret = 0;
 
@@ -287,7 +285,6 @@ int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
 
        return r;
 }
-EXPORT_SYMBOL_GPL(blk_complete_sghdr_rq);
 
 static int sg_io(struct file *file, request_queue_t *q,
                struct gendisk *bd_disk, struct sg_io_hdr *hdr)
index 139f41f033d8bae09144493eb77c1ac2b09d3d41..408b45168aba324a8e12e26a140dc244011c2837 100644 (file)
@@ -2,16 +2,12 @@
 # ACPI Configuration
 #
 
-menu "ACPI (Advanced Configuration and Power Interface) Support"
+menuconfig ACPI
+       bool "ACPI Support (Advanced Configuration and Power Interface) Support"
        depends on !X86_NUMAQ
        depends on !X86_VISWS
        depends on !IA64_HP_SIM
        depends on IA64 || X86
-       depends on PM
-
-config ACPI
-       bool "ACPI Support"
-       depends on IA64 || X86
        depends on PCI
        depends on PM
        select PNP
@@ -49,7 +45,6 @@ if ACPI
 config ACPI_SLEEP
        bool "Sleep States"
        depends on X86 && (!SMP || SUSPEND_SMP)
-       depends on PM
        default y
        ---help---
          This option adds support for ACPI suspend states. 
@@ -82,7 +77,6 @@ config ACPI_SLEEP_PROC_SLEEP
 
 config ACPI_PROCFS
        bool "Procfs interface (deprecated)"
-       depends on ACPI
        default y
        ---help---
          The Procfs interface for ACPI is made optional for backward compatibility.
@@ -124,7 +118,7 @@ config ACPI_BUTTON
 
 config ACPI_VIDEO
        tristate "Video"
-       depends on X86 && BACKLIGHT_CLASS_DEVICE
+       depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL
        help
          This driver implement the ACPI Extensions For Display Adapters
          for integrated graphics devices on motherboard, as specified in
@@ -280,6 +274,14 @@ config ACPI_DEBUG
          of verbosity. Saying Y enables these statements. This will increase
          your kernel size by around 50K.
 
+config ACPI_DEBUG_FUNC_TRACE
+       bool "Additionally enable ACPI function tracing"
+       default n
+       depends on ACPI_DEBUG
+       help
+         ACPI Debug Statements slow down ACPI processing. Function trace
+         is about half of the penalty and is rarely useful.
+
 config ACPI_EC
        bool
        default y
@@ -330,7 +332,6 @@ config ACPI_CONTAINER
 
 config ACPI_HOTPLUG_MEMORY
        tristate "Memory Hotplug"
-       depends on ACPI
        depends on MEMORY_HOTPLUG
        default n
        help
@@ -359,5 +360,3 @@ config ACPI_SBS
          to today's ACPI "Control Method" battery.
 
 endif  # ACPI
-
-endmenu
index e64c76c8b7268a56562969d48b6c940bbda09bfc..cad932de383d02c3f3426f3784a9ff2190a1e4b2 100644 (file)
 #define ACPI_BATTERY_CLASS             "battery"
 #define ACPI_BATTERY_HID               "PNP0C0A"
 #define ACPI_BATTERY_DEVICE_NAME       "Battery"
-#define ACPI_BATTERY_FILE_INFO         "info"
-#define ACPI_BATTERY_FILE_STATUS       "state"
-#define ACPI_BATTERY_FILE_ALARM                "alarm"
 #define ACPI_BATTERY_NOTIFY_STATUS     0x80
 #define ACPI_BATTERY_NOTIFY_INFO       0x81
 #define ACPI_BATTERY_UNITS_WATTS       "mW"
 #define ACPI_BATTERY_UNITS_AMPS                "mA"
 
 #define _COMPONENT             ACPI_BATTERY_COMPONENT
+
+#define ACPI_BATTERY_UPDATE_TIME       0
+
+#define ACPI_BATTERY_NONE_UPDATE       0
+#define ACPI_BATTERY_EASY_UPDATE       1
+#define ACPI_BATTERY_INIT_UPDATE       2
+
 ACPI_MODULE_NAME("battery");
 
 MODULE_AUTHOR("Paul Diefenbaugh");
 MODULE_DESCRIPTION("ACPI Battery Driver");
 MODULE_LICENSE("GPL");
 
+static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME;
+
+/* 0 - every time, > 0 - by update_time */
+module_param(update_time, uint, 0644);
+
 extern struct proc_dir_entry *acpi_lock_battery_dir(void);
 extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
 
@@ -76,7 +85,7 @@ static struct acpi_driver acpi_battery_driver = {
                },
 };
 
-struct acpi_battery_status {
+struct acpi_battery_state {
        acpi_integer state;
        acpi_integer present_rate;
        acpi_integer remaining_capacity;
@@ -99,33 +108,111 @@ struct acpi_battery_info {
        acpi_string oem_info;
 };
 
-struct acpi_battery_flags {
-       u8 present:1;           /* Bay occupied? */
-       u8 power_unit:1;        /* 0=watts, 1=apms */
-       u8 alarm:1;             /* _BTP present? */
-       u8 reserved:5;
+enum acpi_battery_files{
+       ACPI_BATTERY_INFO = 0,
+       ACPI_BATTERY_STATE,
+       ACPI_BATTERY_ALARM,
+       ACPI_BATTERY_NUMFILES,
 };
 
-struct acpi_battery_trips {
-       unsigned long warning;
-       unsigned long low;
+struct acpi_battery_flags {
+       u8 battery_present_prev;
+       u8 alarm_present;
+       u8 init_update;
+       u8 update[ACPI_BATTERY_NUMFILES];
+       u8 power_unit;
 };
 
 struct acpi_battery {
-       struct acpi_device * device;
+       struct mutex mutex;
+       struct acpi_device *device;
        struct acpi_battery_flags flags;
-       struct acpi_battery_trips trips;
+       struct acpi_buffer bif_data;
+       struct acpi_buffer bst_data;
        unsigned long alarm;
-       struct acpi_battery_info *info;
+       unsigned long update_time[ACPI_BATTERY_NUMFILES];
 };
 
+inline int acpi_battery_present(struct acpi_battery *battery)
+{
+       return battery->device->status.battery_present;
+}
+inline char *acpi_battery_power_units(struct acpi_battery *battery)
+{
+       if (battery->flags.power_unit)
+               return ACPI_BATTERY_UNITS_AMPS;
+       else
+               return ACPI_BATTERY_UNITS_WATTS;
+}
+
+inline acpi_handle acpi_battery_handle(struct acpi_battery *battery)
+{
+       return battery->device->handle;
+}
+
 /* --------------------------------------------------------------------------
                                Battery Management
    -------------------------------------------------------------------------- */
 
-static int
-acpi_battery_get_info(struct acpi_battery *battery,
-                     struct acpi_battery_info **bif)
+static void acpi_battery_check_result(struct acpi_battery *battery, int result)
+{
+       if (!battery)
+               return;
+
+       if (result) {
+               battery->flags.init_update = 1;
+       }
+}
+
+static int acpi_battery_extract_package(struct acpi_battery *battery,
+                                       union acpi_object *package,
+                                       struct acpi_buffer *format,
+                                       struct acpi_buffer *data,
+                                       char *package_name)
+{
+       acpi_status status = AE_OK;
+       struct acpi_buffer data_null = { 0, NULL };
+
+       status = acpi_extract_package(package, format, &data_null);
+       if (status != AE_BUFFER_OVERFLOW) {
+               ACPI_EXCEPTION((AE_INFO, status, "Extracting size %s",
+                               package_name));
+               return -ENODEV;
+       }
+
+       if (data_null.length != data->length) {
+               kfree(data->pointer);
+               data->pointer = kzalloc(data_null.length, GFP_KERNEL);
+               if (!data->pointer) {
+                       ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "kzalloc()"));
+                       return -ENOMEM;
+               }
+               data->length = data_null.length;
+       }
+
+       status = acpi_extract_package(package, format, data);
+       if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status, "Extracting %s",
+                               package_name));
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static int acpi_battery_get_status(struct acpi_battery *battery)
+{
+       int result = 0;
+
+       result = acpi_bus_get_status(battery->device);
+       if (result) {
+               ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
+               return -ENODEV;
+       }
+       return result;
+}
+
+static int acpi_battery_get_info(struct acpi_battery *battery)
 {
        int result = 0;
        acpi_status status = 0;
@@ -133,16 +220,20 @@ acpi_battery_get_info(struct acpi_battery *battery,
        struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF),
                ACPI_BATTERY_FORMAT_BIF
        };
-       struct acpi_buffer data = { 0, NULL };
        union acpi_object *package = NULL;
+       struct acpi_buffer *data = NULL;
+       struct acpi_battery_info *bif = NULL;
 
+       battery->update_time[ACPI_BATTERY_INFO] = get_seconds();
 
-       if (!battery || !bif)
-               return -EINVAL;
+       if (!acpi_battery_present(battery))
+               return 0;
 
-       /* Evalute _BIF */
+       /* Evaluate _BIF */
 
-       status = acpi_evaluate_object(battery->device->handle, "_BIF", NULL, &buffer);
+       status =
+           acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL,
+                                &buffer);
        if (ACPI_FAILURE(status)) {
                ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
                return -ENODEV;
@@ -150,41 +241,29 @@ acpi_battery_get_info(struct acpi_battery *battery,
 
        package = buffer.pointer;
 
-       /* Extract Package Data */
-
-       status = acpi_extract_package(package, &format, &data);
-       if (status != AE_BUFFER_OVERFLOW) {
-               ACPI_EXCEPTION((AE_INFO, status, "Extracting _BIF"));
-               result = -ENODEV;
-               goto end;
-       }
+       data = &battery->bif_data;
 
-       data.pointer = kzalloc(data.length, GFP_KERNEL);
-       if (!data.pointer) {
-               result = -ENOMEM;
-               goto end;
-       }
+       /* Extract Package Data */
 
-       status = acpi_extract_package(package, &format, &data);
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status, "Extracting _BIF"));
-               kfree(data.pointer);
-               result = -ENODEV;
+       result =
+           acpi_battery_extract_package(battery, package, &format, data,
+                                        "_BIF");
+       if (result)
                goto end;
-       }
 
       end:
+
        kfree(buffer.pointer);
 
-       if (!result)
-               (*bif) = data.pointer;
+       if (!result) {
+               bif = data->pointer;
+               battery->flags.power_unit = bif->power_unit;
+       }
 
        return result;
 }
 
-static int
-acpi_battery_get_status(struct acpi_battery *battery,
-                       struct acpi_battery_status **bst)
+static int acpi_battery_get_state(struct acpi_battery *battery)
 {
        int result = 0;
        acpi_status status = 0;
@@ -192,16 +271,19 @@ acpi_battery_get_status(struct acpi_battery *battery,
        struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST),
                ACPI_BATTERY_FORMAT_BST
        };
-       struct acpi_buffer data = { 0, NULL };
        union acpi_object *package = NULL;
+       struct acpi_buffer *data = NULL;
 
+       battery->update_time[ACPI_BATTERY_STATE] = get_seconds();
 
-       if (!battery || !bst)
-               return -EINVAL;
+       if (!acpi_battery_present(battery))
+               return 0;
 
-       /* Evalute _BST */
+       /* Evaluate _BST */
 
-       status = acpi_evaluate_object(battery->device->handle, "_BST", NULL, &buffer);
+       status =
+           acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL,
+                                &buffer);
        if (ACPI_FAILURE(status)) {
                ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
                return -ENODEV;
@@ -209,55 +291,49 @@ acpi_battery_get_status(struct acpi_battery *battery,
 
        package = buffer.pointer;
 
-       /* Extract Package Data */
-
-       status = acpi_extract_package(package, &format, &data);
-       if (status != AE_BUFFER_OVERFLOW) {
-               ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST"));
-               result = -ENODEV;
-               goto end;
-       }
+       data = &battery->bst_data;
 
-       data.pointer = kzalloc(data.length, GFP_KERNEL);
-       if (!data.pointer) {
-               result = -ENOMEM;
-               goto end;
-       }
+       /* Extract Package Data */
 
-       status = acpi_extract_package(package, &format, &data);
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST"));
-               kfree(data.pointer);
-               result = -ENODEV;
+       result =
+           acpi_battery_extract_package(battery, package, &format, data,
+                                        "_BST");
+       if (result)
                goto end;
-       }
 
       end:
        kfree(buffer.pointer);
 
-       if (!result)
-               (*bst) = data.pointer;
-
        return result;
 }
 
-static int
-acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm)
+static int acpi_battery_get_alarm(struct acpi_battery *battery)
+{
+       battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
+
+       return 0;
+}
+
+static int acpi_battery_set_alarm(struct acpi_battery *battery,
+                                 unsigned long alarm)
 {
        acpi_status status = 0;
        union acpi_object arg0 = { ACPI_TYPE_INTEGER };
        struct acpi_object_list arg_list = { 1, &arg0 };
 
+       battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
 
-       if (!battery)
-               return -EINVAL;
+       if (!acpi_battery_present(battery))
+               return -ENODEV;
 
-       if (!battery->flags.alarm)
+       if (!battery->flags.alarm_present)
                return -ENODEV;
 
        arg0.integer.value = alarm;
 
-       status = acpi_evaluate_object(battery->device->handle, "_BTP", &arg_list, NULL);
+       status =
+           acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
+                                &arg_list, NULL);
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
@@ -268,65 +344,114 @@ acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm)
        return 0;
 }
 
-static int acpi_battery_check(struct acpi_battery *battery)
+static int acpi_battery_init_alarm(struct acpi_battery *battery)
 {
        int result = 0;
        acpi_status status = AE_OK;
        acpi_handle handle = NULL;
-       struct acpi_device *device = NULL;
-       struct acpi_battery_info *bif = NULL;
+       struct acpi_battery_info *bif = battery->bif_data.pointer;
+       unsigned long alarm = battery->alarm;
 
+       /* See if alarms are supported, and if so, set default */
 
-       if (!battery)
-               return -EINVAL;
-
-       device = battery->device;
+       status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle);
+       if (ACPI_SUCCESS(status)) {
+               battery->flags.alarm_present = 1;
+               if (!alarm && bif) {
+                       alarm = bif->design_capacity_warning;
+               }
+               result = acpi_battery_set_alarm(battery, alarm);
+               if (result)
+                       goto end;
+       } else {
+               battery->flags.alarm_present = 0;
+       }
 
-       result = acpi_bus_get_status(device);
-       if (result)
-               return result;
+      end:
 
-       /* Insertion? */
+       return result;
+}
 
-       if (!battery->flags.present && device->status.battery_present) {
+static int acpi_battery_init_update(struct acpi_battery *battery)
+{
+       int result = 0;
 
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery inserted\n"));
+       result = acpi_battery_get_status(battery);
+       if (result)
+               return result;
 
-               /* Evalute _BIF to get certain static information */
+       battery->flags.battery_present_prev = acpi_battery_present(battery);
 
-               result = acpi_battery_get_info(battery, &bif);
+       if (acpi_battery_present(battery)) {
+               result = acpi_battery_get_info(battery);
+               if (result)
+                       return result;
+               result = acpi_battery_get_state(battery);
                if (result)
                        return result;
 
-               battery->flags.power_unit = bif->power_unit;
-               battery->trips.warning = bif->design_capacity_warning;
-               battery->trips.low = bif->design_capacity_low;
-               kfree(bif);
+               acpi_battery_init_alarm(battery);
+       }
+
+       return result;
+}
 
-               /* See if alarms are supported, and if so, set default */
+static int acpi_battery_update(struct acpi_battery *battery,
+                              int update, int *update_result_ptr)
+{
+       int result = 0;
+       int update_result = ACPI_BATTERY_NONE_UPDATE;
+
+       if (!acpi_battery_present(battery)) {
+               update = 1;
+       }
 
-               status = acpi_get_handle(battery->device->handle, "_BTP", &handle);
-               if (ACPI_SUCCESS(status)) {
-                       battery->flags.alarm = 1;
-                       acpi_battery_set_alarm(battery, battery->trips.warning);
+       if (battery->flags.init_update) {
+               result = acpi_battery_init_update(battery);
+               if (result)
+                       goto end;
+               update_result = ACPI_BATTERY_INIT_UPDATE;
+       } else if (update) {
+               result = acpi_battery_get_status(battery);
+               if (result)
+                       goto end;
+               if ((!battery->flags.battery_present_prev & acpi_battery_present(battery))
+                   || (battery->flags.battery_present_prev & !acpi_battery_present(battery))) {
+                       result = acpi_battery_init_update(battery);
+                       if (result)
+                               goto end;
+                       update_result = ACPI_BATTERY_INIT_UPDATE;
+               } else {
+                       update_result = ACPI_BATTERY_EASY_UPDATE;
                }
        }
 
-       /* Removal? */
+      end:
 
-       else if (battery->flags.present && !device->status.battery_present) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery removed\n"));
-       }
+       battery->flags.init_update = (result != 0);
 
-       battery->flags.present = device->status.battery_present;
+       *update_result_ptr = update_result;
 
        return result;
 }
 
-static void acpi_battery_check_present(struct acpi_battery *battery)
+static void acpi_battery_notify_update(struct acpi_battery *battery)
 {
-       if (!battery->flags.present) {
-               acpi_battery_check(battery);
+       acpi_battery_get_status(battery);
+
+       if (battery->flags.init_update) {
+               return;
+       }
+
+       if ((!battery->flags.battery_present_prev &
+            acpi_battery_present(battery)) ||
+           (battery->flags.battery_present_prev &
+            !acpi_battery_present(battery))) {
+               battery->flags.init_update = 1;
+       } else {
+               battery->flags.update[ACPI_BATTERY_INFO] = 1;
+               battery->flags.update[ACPI_BATTERY_STATE] = 1;
+               battery->flags.update[ACPI_BATTERY_ALARM] = 1;
        }
 }
 
@@ -335,37 +460,33 @@ static void acpi_battery_check_present(struct acpi_battery *battery)
    -------------------------------------------------------------------------- */
 
 static struct proc_dir_entry *acpi_battery_dir;
-static int acpi_battery_read_info(struct seq_file *seq, void *offset)
+
+static int acpi_battery_print_info(struct seq_file *seq, int result)
 {
-       int result = 0;
        struct acpi_battery *battery = seq->private;
        struct acpi_battery_info *bif = NULL;
        char *units = "?";
 
-
-       if (!battery)
+       if (result)
                goto end;
 
-       acpi_battery_check_present(battery);
-
-       if (battery->flags.present)
+       if (acpi_battery_present(battery))
                seq_printf(seq, "present:                 yes\n");
        else {
                seq_printf(seq, "present:                 no\n");
                goto end;
        }
 
-       /* Battery Info (_BIF) */
-
-       result = acpi_battery_get_info(battery, &bif);
-       if (result || !bif) {
-               seq_printf(seq, "ERROR: Unable to read battery information\n");
+       bif = battery->bif_data.pointer;
+       if (!bif) {
+               ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BIF buffer is NULL"));
+               result = -ENODEV;
                goto end;
        }
 
-       units =
-           bif->
-           power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS;
+       /* Battery Units */
+
+       units = acpi_battery_power_units(battery);
 
        if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
                seq_printf(seq, "design capacity:         unknown\n");
@@ -396,7 +517,6 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
        else
                seq_printf(seq, "design voltage:          %d mV\n",
                           (u32) bif->design_voltage);
-
        seq_printf(seq, "design capacity warning: %d %sh\n",
                   (u32) bif->design_capacity_warning, units);
        seq_printf(seq, "design capacity low:     %d %sh\n",
@@ -411,50 +531,40 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
        seq_printf(seq, "OEM info:                %s\n", bif->oem_info);
 
       end:
-       kfree(bif);
 
-       return 0;
-}
+       if (result)
+               seq_printf(seq, "ERROR: Unable to read battery info\n");
 
-static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
-{
-       return single_open(file, acpi_battery_read_info, PDE(inode)->data);
+       return result;
 }
 
-static int acpi_battery_read_state(struct seq_file *seq, void *offset)
+static int acpi_battery_print_state(struct seq_file *seq, int result)
 {
-       int result = 0;
        struct acpi_battery *battery = seq->private;
-       struct acpi_battery_status *bst = NULL;
+       struct acpi_battery_state *bst = NULL;
        char *units = "?";
 
-
-       if (!battery)
+       if (result)
                goto end;
 
-       acpi_battery_check_present(battery);
-
-       if (battery->flags.present)
+       if (acpi_battery_present(battery))
                seq_printf(seq, "present:                 yes\n");
        else {
                seq_printf(seq, "present:                 no\n");
                goto end;
        }
 
-       /* Battery Units */
-
-       units =
-           battery->flags.
-           power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS;
-
-       /* Battery Status (_BST) */
-
-       result = acpi_battery_get_status(battery, &bst);
-       if (result || !bst) {
-               seq_printf(seq, "ERROR: Unable to read battery status\n");
+       bst = battery->bst_data.pointer;
+       if (!bst) {
+               ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BST buffer is NULL"));
+               result = -ENODEV;
                goto end;
        }
 
+       /* Battery Units */
+
+       units = acpi_battery_power_units(battery);
+
        if (!(bst->state & 0x04))
                seq_printf(seq, "capacity state:          ok\n");
        else
@@ -490,48 +600,43 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
                           (u32) bst->present_voltage);
 
       end:
-       kfree(bst);
 
-       return 0;
-}
+       if (result) {
+               seq_printf(seq, "ERROR: Unable to read battery state\n");
+       }
 
-static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
-{
-       return single_open(file, acpi_battery_read_state, PDE(inode)->data);
+       return result;
 }
 
-static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
+static int acpi_battery_print_alarm(struct seq_file *seq, int result)
 {
        struct acpi_battery *battery = seq->private;
        char *units = "?";
 
-
-       if (!battery)
+       if (result)
                goto end;
 
-       acpi_battery_check_present(battery);
-
-       if (!battery->flags.present) {
+       if (!acpi_battery_present(battery)) {
                seq_printf(seq, "present:                 no\n");
                goto end;
        }
 
        /* Battery Units */
 
-       units =
-           battery->flags.
-           power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS;
-
-       /* Battery Alarm */
+       units = acpi_battery_power_units(battery);
 
        seq_printf(seq, "alarm:                   ");
        if (!battery->alarm)
                seq_printf(seq, "unsupported\n");
        else
-               seq_printf(seq, "%d %sh\n", (u32) battery->alarm, units);
+               seq_printf(seq, "%lu %sh\n", battery->alarm, units);
 
       end:
-       return 0;
+
+       if (result)
+               seq_printf(seq, "ERROR: Unable to read battery alarm\n");
+
+       return result;
 }
 
 static ssize_t
@@ -543,27 +648,113 @@ acpi_battery_write_alarm(struct file *file,
        char alarm_string[12] = { '\0' };
        struct seq_file *m = file->private_data;
        struct acpi_battery *battery = m->private;
-
+       int update_result = ACPI_BATTERY_NONE_UPDATE;
 
        if (!battery || (count > sizeof(alarm_string) - 1))
                return -EINVAL;
 
-       acpi_battery_check_present(battery);
+       mutex_lock(&battery->mutex);
 
-       if (!battery->flags.present)
-               return -ENODEV;
+       result = acpi_battery_update(battery, 1, &update_result);
+       if (result) {
+               result = -ENODEV;
+               goto end;
+       }
+
+       if (!acpi_battery_present(battery)) {
+               result = -ENODEV;
+               goto end;
+       }
 
-       if (copy_from_user(alarm_string, buffer, count))
-               return -EFAULT;
+       if (copy_from_user(alarm_string, buffer, count)) {
+               result = -EFAULT;
+               goto end;
+       }
 
        alarm_string[count] = '\0';
 
        result = acpi_battery_set_alarm(battery,
                                        simple_strtoul(alarm_string, NULL, 0));
        if (result)
-               return result;
+               goto end;
+
+      end:
 
-       return count;
+       acpi_battery_check_result(battery, result);
+
+       if (!result)
+               result = count;
+
+       mutex_unlock(&battery->mutex);
+
+       return result;
+}
+
+typedef int(*print_func)(struct seq_file *seq, int result);
+typedef int(*get_func)(struct acpi_battery *battery);
+
+static struct acpi_read_mux {
+       print_func print;
+       get_func get;
+} acpi_read_funcs[ACPI_BATTERY_NUMFILES] = {
+       {.get = acpi_battery_get_info, .print = acpi_battery_print_info},
+       {.get = acpi_battery_get_state, .print = acpi_battery_print_state},
+       {.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm},
+};
+
+static int acpi_battery_read(int fid, struct seq_file *seq)
+{
+       struct acpi_battery *battery = seq->private;
+       int result = 0;
+       int update_result = ACPI_BATTERY_NONE_UPDATE;
+       int update = 0;
+
+       mutex_lock(&battery->mutex);
+
+       update = (get_seconds() - battery->update_time[fid] >= update_time);
+       update = (update | battery->flags.update[fid]);
+
+       result = acpi_battery_update(battery, update, &update_result);
+       if (result)
+               goto end;
+
+       if (update_result == ACPI_BATTERY_EASY_UPDATE) {
+               result = acpi_read_funcs[fid].get(battery);
+               if (result)
+                       goto end;
+       }
+
+      end:
+       result = acpi_read_funcs[fid].print(seq, result);
+       acpi_battery_check_result(battery, result);
+       battery->flags.update[fid] = result;
+       mutex_unlock(&battery->mutex);
+       return result;
+}
+
+static int acpi_battery_read_info(struct seq_file *seq, void *offset)
+{
+       return acpi_battery_read(ACPI_BATTERY_INFO, seq);
+}
+
+static int acpi_battery_read_state(struct seq_file *seq, void *offset)
+{
+       return acpi_battery_read(ACPI_BATTERY_STATE, seq);
+}
+
+static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
+{
+       return acpi_battery_read(ACPI_BATTERY_ALARM, seq);
+}
+
+static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
+{
+       return single_open(file, acpi_battery_read_info, PDE(inode)->data);
+}
+
+static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
+{
+       return single_open(file, acpi_battery_read_state, PDE(inode)->data);
 }
 
 static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
@@ -571,35 +762,51 @@ static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
        return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
 }
 
-static const struct file_operations acpi_battery_info_ops = {
+static struct battery_file {
+       struct file_operations ops;
+       mode_t mode;
+       char *name;
+} acpi_battery_file[] = {
+       {
+       .name = "info",
+       .mode = S_IRUGO,
+       .ops = {
        .open = acpi_battery_info_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
        .release = single_release,
        .owner = THIS_MODULE,
-};
-
-static const struct file_operations acpi_battery_state_ops = {
+       },
+       },
+       {
+       .name = "state",
+       .mode = S_IRUGO,
+       .ops = {
        .open = acpi_battery_state_open_fs,
        .read = seq_read,
        .llseek = seq_lseek,
        .release = single_release,
        .owner = THIS_MODULE,
-};
-
-static const struct file_operations acpi_battery_alarm_ops = {
+       },
+       },
+       {
+       .name = "alarm",
+       .mode = S_IFREG | S_IRUGO | S_IWUSR,
+       .ops = {
        .open = acpi_battery_alarm_open_fs,
        .read = seq_read,
        .write = acpi_battery_write_alarm,
        .llseek = seq_lseek,
        .release = single_release,
        .owner = THIS_MODULE,
+       },
+       },
 };
 
 static int acpi_battery_add_fs(struct acpi_device *device)
 {
        struct proc_dir_entry *entry = NULL;
-
+       int i;
 
        if (!acpi_device_dir(device)) {
                acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
@@ -609,38 +816,16 @@ static int acpi_battery_add_fs(struct acpi_device *device)
                acpi_device_dir(device)->owner = THIS_MODULE;
        }
 
-       /* 'info' [R] */
-       entry = create_proc_entry(ACPI_BATTERY_FILE_INFO,
-                                 S_IRUGO, acpi_device_dir(device));
-       if (!entry)
-               return -ENODEV;
-       else {
-               entry->proc_fops = &acpi_battery_info_ops;
-               entry->data = acpi_driver_data(device);
-               entry->owner = THIS_MODULE;
-       }
-
-       /* 'status' [R] */
-       entry = create_proc_entry(ACPI_BATTERY_FILE_STATUS,
-                                 S_IRUGO, acpi_device_dir(device));
-       if (!entry)
-               return -ENODEV;
-       else {
-               entry->proc_fops = &acpi_battery_state_ops;
-               entry->data = acpi_driver_data(device);
-               entry->owner = THIS_MODULE;
-       }
-
-       /* 'alarm' [R/W] */
-       entry = create_proc_entry(ACPI_BATTERY_FILE_ALARM,
-                                 S_IFREG | S_IRUGO | S_IWUSR,
-                                 acpi_device_dir(device));
-       if (!entry)
-               return -ENODEV;
-       else {
-               entry->proc_fops = &acpi_battery_alarm_ops;
-               entry->data = acpi_driver_data(device);
-               entry->owner = THIS_MODULE;
+       for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
+               entry = create_proc_entry(acpi_battery_file[i].name,
+                                 acpi_battery_file[i].mode, acpi_device_dir(device));
+               if (!entry)
+                       return -ENODEV;
+               else {
+                       entry->proc_fops = &acpi_battery_file[i].ops;
+                       entry->data = acpi_driver_data(device);
+                       entry->owner = THIS_MODULE;
+               }
        }
 
        return 0;
@@ -648,15 +833,12 @@ static int acpi_battery_add_fs(struct acpi_device *device)
 
 static int acpi_battery_remove_fs(struct acpi_device *device)
 {
-
+       int i;
        if (acpi_device_dir(device)) {
-               remove_proc_entry(ACPI_BATTERY_FILE_ALARM,
+               for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
+                       remove_proc_entry(acpi_battery_file[i].name,
                                  acpi_device_dir(device));
-               remove_proc_entry(ACPI_BATTERY_FILE_STATUS,
-                                 acpi_device_dir(device));
-               remove_proc_entry(ACPI_BATTERY_FILE_INFO,
-                                 acpi_device_dir(device));
-
+               }
                remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
                acpi_device_dir(device) = NULL;
        }
@@ -673,7 +855,6 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
        struct acpi_battery *battery = data;
        struct acpi_device *device = NULL;
 
-
        if (!battery)
                return;
 
@@ -684,8 +865,10 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
        case ACPI_BATTERY_NOTIFY_INFO:
        case ACPI_NOTIFY_BUS_CHECK:
        case ACPI_NOTIFY_DEVICE_CHECK:
-               acpi_battery_check(battery);
-               acpi_bus_generate_event(device, event, battery->flags.present);
+               device = battery->device;
+               acpi_battery_notify_update(battery);
+               acpi_bus_generate_event(device, event,
+                                       acpi_battery_present(battery));
                break;
        default:
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -702,7 +885,6 @@ static int acpi_battery_add(struct acpi_device *device)
        acpi_status status = 0;
        struct acpi_battery *battery = NULL;
 
-
        if (!device)
                return -EINVAL;
 
@@ -710,15 +892,21 @@ static int acpi_battery_add(struct acpi_device *device)
        if (!battery)
                return -ENOMEM;
 
+       mutex_init(&battery->mutex);
+
+       mutex_lock(&battery->mutex);
+
        battery->device = device;
        strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
        strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
        acpi_driver_data(device) = battery;
 
-       result = acpi_battery_check(battery);
+       result = acpi_battery_get_status(battery);
        if (result)
                goto end;
 
+       battery->flags.init_update = 1;
+
        result = acpi_battery_add_fs(device);
        if (result)
                goto end;
@@ -727,6 +915,7 @@ static int acpi_battery_add(struct acpi_device *device)
                                             ACPI_ALL_NOTIFY,
                                             acpi_battery_notify, battery);
        if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status, "Installing notify handler"));
                result = -ENODEV;
                goto end;
        }
@@ -736,11 +925,14 @@ static int acpi_battery_add(struct acpi_device *device)
               device->status.battery_present ? "present" : "absent");
 
       end:
+
        if (result) {
                acpi_battery_remove_fs(device);
                kfree(battery);
        }
 
+       mutex_unlock(&battery->mutex);
+
        return result;
 }
 
@@ -749,18 +941,27 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
        acpi_status status = 0;
        struct acpi_battery *battery = NULL;
 
-
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
 
        battery = acpi_driver_data(device);
 
+       mutex_lock(&battery->mutex);
+
        status = acpi_remove_notify_handler(device->handle,
                                            ACPI_ALL_NOTIFY,
                                            acpi_battery_notify);
 
        acpi_battery_remove_fs(device);
 
+       kfree(battery->bif_data.pointer);
+
+       kfree(battery->bst_data.pointer);
+
+       mutex_unlock(&battery->mutex);
+
+       mutex_destroy(&battery->mutex);
+
        kfree(battery);
 
        return 0;
@@ -775,7 +976,10 @@ static int acpi_battery_resume(struct acpi_device *device)
                return -EINVAL;
 
        battery = device->driver_data;
-       return acpi_battery_check(battery);
+
+       battery->flags.init_update = 1;
+
+       return 0;
 }
 
 static int __init acpi_battery_init(void)
@@ -800,7 +1004,6 @@ static int __init acpi_battery_init(void)
 
 static void __exit acpi_battery_exit(void)
 {
-
        acpi_bus_unregister_driver(&acpi_battery_driver);
 
        acpi_unlock_battery_dir(acpi_battery_dir);
index fb3f31b5e69f6587ff4c7cada15b2291c64fad40..56a5b3fffeb364a14e8fe3ff7f5b9a1ff103f51e 100644 (file)
@@ -288,6 +288,11 @@ static int bay_add(acpi_handle handle, int id)
        new_bay->pdev = pdev;
        platform_set_drvdata(pdev, new_bay);
 
+       /*
+        * we want the bay driver to be able to send uevents
+        */
+       pdev->dev.uevent_suppress = 0;
+
        if (acpi_bay_add_fs(new_bay)) {
                platform_device_unregister(new_bay->pdev);
                goto bay_add_err;
@@ -328,18 +333,12 @@ static void bay_notify(acpi_handle handle, u32 event, void *data)
 {
        struct bay *bay_dev = (struct bay *)data;
        struct device *dev = &bay_dev->pdev->dev;
+       char event_string[12];
+       char *envp[] = { event_string, NULL };
 
        bay_dprintk(handle, "Bay event");
-
-       switch(event) {
-       case ACPI_NOTIFY_BUS_CHECK:
-       case ACPI_NOTIFY_DEVICE_CHECK:
-       case ACPI_NOTIFY_EJECT_REQUEST:
-               kobject_uevent(&dev->kobj, KOBJ_CHANGE);
-               break;
-       default:
-               printk(KERN_ERR PREFIX "Bay: unknown event %d\n", event);
-       }
+       sprintf(event_string, "BAY_EVENT=%d\n", event);
+       kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
 }
 
 static acpi_status
index e5084ececb6ff7f004326a3fcdf24828c45e2f0a..6b2658c9624245c7de284623058b4312bb96ff0e 100644 (file)
@@ -292,6 +292,10 @@ int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)
        if (!device)
                return -EINVAL;
 
+       if (acpi_bus_generate_genetlink_event(device, type, data))
+               printk(KERN_WARNING PREFIX
+                       "Failed to generate an ACPI event via genetlink!\n");
+
        /* drop event on the floor if no one's listening */
        if (!event_is_open)
                return 0;
index 4546bf873aea273c2a0993fb3fbb465d801543ed..6192c8be66df62587e0ee49e3af2a31b145b38bc 100644 (file)
@@ -40,8 +40,15 @@ MODULE_AUTHOR("Kristen Carlson Accardi");
 MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION);
 MODULE_LICENSE("GPL");
 
+static int immediate_undock = 1;
+module_param(immediate_undock, bool, 0644);
+MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to "
+       "undock immediately when the undock button is pressed, 0 will cause"
+       " the driver to wait for userspace to write the undock sysfs file "
+       " before undocking");
+
 static struct atomic_notifier_head dock_notifier_list;
-static struct platform_device dock_device;
+static struct platform_device *dock_device;
 static char dock_device_name[] = "dock";
 
 struct dock_station {
@@ -63,6 +70,7 @@ struct dock_dependent_device {
 };
 
 #define DOCK_DOCKING   0x00000001
+#define DOCK_UNDOCKING  0x00000002
 #define DOCK_EVENT     3
 #define UNDOCK_EVENT   2
 
@@ -327,12 +335,20 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
 
 static void dock_event(struct dock_station *ds, u32 event, int num)
 {
-       struct device *dev = &dock_device.dev;
+       struct device *dev = &dock_device->dev;
+       char event_string[7];
+       char *envp[] = { event_string, NULL };
+
+       if (num == UNDOCK_EVENT)
+               sprintf(event_string, "UNDOCK");
+       else
+               sprintf(event_string, "DOCK");
+
        /*
         * Indicate that the status of the dock station has
         * changed.
         */
-       kobject_uevent(&dev->kobj, KOBJ_CHANGE);
+       kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
 }
 
 /**
@@ -380,12 +396,11 @@ static void handle_dock(struct dock_station *ds, int dock)
        union acpi_object arg;
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
        struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-       union acpi_object *obj;
 
        acpi_get_name(ds->handle, ACPI_FULL_PATHNAME, &name_buffer);
-       obj = name_buffer.pointer;
 
-       printk(KERN_INFO PREFIX "%s\n", dock ? "docking" : "undocking");
+       printk(KERN_INFO PREFIX "%s - %s\n",
+               (char *)name_buffer.pointer, dock ? "docking" : "undocking");
 
        /* _DCK method has one argument */
        arg_list.count = 1;
@@ -394,7 +409,8 @@ static void handle_dock(struct dock_station *ds, int dock)
        arg.integer.value = dock;
        status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer);
        if (ACPI_FAILURE(status))
-               pr_debug("%s: failed to execute _DCK\n", obj->string.pointer);
+               printk(KERN_ERR PREFIX "%s - failed to execute _DCK\n",
+                        (char *)name_buffer.pointer);
        kfree(buffer.pointer);
        kfree(name_buffer.pointer);
 }
@@ -420,6 +436,16 @@ static inline void complete_dock(struct dock_station *ds)
        ds->last_dock_time = jiffies;
 }
 
+static inline void begin_undock(struct dock_station *ds)
+{
+       ds->flags |= DOCK_UNDOCKING;
+}
+
+static inline void complete_undock(struct dock_station *ds)
+{
+       ds->flags &= ~(DOCK_UNDOCKING);
+}
+
 /**
  * dock_in_progress - see if we are in the middle of handling a dock event
  * @ds: the dock station
@@ -550,7 +576,7 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
                printk(KERN_ERR PREFIX "Unable to undock!\n");
                return -EBUSY;
        }
-
+       complete_undock(ds);
        return 0;
 }
 
@@ -594,7 +620,11 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
         * to the driver who wish to hotplug.
          */
        case ACPI_NOTIFY_EJECT_REQUEST:
-               handle_eject_request(ds, event);
+               begin_undock(ds);
+               if (immediate_undock)
+                       handle_eject_request(ds, event);
+               else
+                       dock_event(ds, event, UNDOCK_EVENT);
                break;
        default:
                printk(KERN_ERR PREFIX "Unknown dock event %d\n", event);
@@ -652,6 +682,17 @@ static ssize_t show_docked(struct device *dev,
 }
 DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
 
+/*
+ * show_flags - read method for flags file in sysfs
+ */
+static ssize_t show_flags(struct device *dev,
+                         struct device_attribute *attr, char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags);
+
+}
+DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL);
+
 /*
  * write_undock - write method for "undock" file in sysfs
  */
@@ -675,16 +716,15 @@ static ssize_t show_dock_uid(struct device *dev,
                             struct device_attribute *attr, char *buf)
 {
        unsigned long lbuf;
-       acpi_status status = acpi_evaluate_integer(dock_station->handle, "_UID", NULL, &lbuf);
-       if(ACPI_FAILURE(status)) {
+       acpi_status status = acpi_evaluate_integer(dock_station->handle,
+                                       "_UID", NULL, &lbuf);
+       if (ACPI_FAILURE(status))
            return 0;
-       }
+
        return snprintf(buf, PAGE_SIZE, "%lx\n", lbuf);
 }
 DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL);
 
-
-
 /**
  * dock_add - add a new dock station
  * @handle: the dock station handle
@@ -711,33 +751,53 @@ static int dock_add(acpi_handle handle)
        ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
 
        /* initialize platform device stuff */
-       dock_device.name = dock_device_name;
-       ret = platform_device_register(&dock_device);
+       dock_device =
+               platform_device_register_simple(dock_device_name, 0, NULL, 0);
+       if (IS_ERR(dock_device)) {
+               kfree(dock_station);
+               dock_station = NULL;
+               return PTR_ERR(dock_device);
+       }
+
+       /* we want the dock device to send uevents */
+       dock_device->dev.uevent_suppress = 0;
+
+       ret = device_create_file(&dock_device->dev, &dev_attr_docked);
        if (ret) {
-               printk(KERN_ERR PREFIX "Error %d registering dock device\n", ret);
+               printk("Error %d adding sysfs file\n", ret);
+               platform_device_unregister(dock_device);
                kfree(dock_station);
+               dock_station = NULL;
                return ret;
        }
-       ret = device_create_file(&dock_device.dev, &dev_attr_docked);
+       ret = device_create_file(&dock_device->dev, &dev_attr_undock);
        if (ret) {
                printk("Error %d adding sysfs file\n", ret);
-               platform_device_unregister(&dock_device);
+               device_remove_file(&dock_device->dev, &dev_attr_docked);
+               platform_device_unregister(dock_device);
                kfree(dock_station);
+               dock_station = NULL;
                return ret;
        }
-       ret = device_create_file(&dock_device.dev, &dev_attr_undock);
+       ret = device_create_file(&dock_device->dev, &dev_attr_uid);
        if (ret) {
                printk("Error %d adding sysfs file\n", ret);
-               device_remove_file(&dock_device.dev, &dev_attr_docked);
-               platform_device_unregister(&dock_device);
+               device_remove_file(&dock_device->dev, &dev_attr_docked);
+               device_remove_file(&dock_device->dev, &dev_attr_undock);
+               platform_device_unregister(dock_device);
                kfree(dock_station);
+               dock_station = NULL;
                return ret;
        }
-       ret = device_create_file(&dock_device.dev, &dev_attr_uid);
+       ret = device_create_file(&dock_device->dev, &dev_attr_flags);
        if (ret) {
                printk("Error %d adding sysfs file\n", ret);
-               platform_device_unregister(&dock_device);
+               device_remove_file(&dock_device->dev, &dev_attr_docked);
+               device_remove_file(&dock_device->dev, &dev_attr_undock);
+               device_remove_file(&dock_device->dev, &dev_attr_uid);
+               platform_device_unregister(dock_device);
                kfree(dock_station);
+               dock_station = NULL;
                return ret;
        }
 
@@ -750,6 +810,7 @@ static int dock_add(acpi_handle handle)
        dd = alloc_dock_dependent_device(handle);
        if (!dd) {
                kfree(dock_station);
+               dock_station = NULL;
                ret = -ENOMEM;
                goto dock_add_err_unregister;
        }
@@ -773,10 +834,13 @@ static int dock_add(acpi_handle handle)
 dock_add_err:
        kfree(dd);
 dock_add_err_unregister:
-       device_remove_file(&dock_device.dev, &dev_attr_docked);
-       device_remove_file(&dock_device.dev, &dev_attr_undock);
-       platform_device_unregister(&dock_device);
+       device_remove_file(&dock_device->dev, &dev_attr_docked);
+       device_remove_file(&dock_device->dev, &dev_attr_undock);
+       device_remove_file(&dock_device->dev, &dev_attr_uid);
+       device_remove_file(&dock_device->dev, &dev_attr_flags);
+       platform_device_unregister(dock_device);
        kfree(dock_station);
+       dock_station = NULL;
        return ret;
 }
 
@@ -804,12 +868,15 @@ static int dock_remove(void)
                printk(KERN_ERR "Error removing notify handler\n");
 
        /* cleanup sysfs */
-       device_remove_file(&dock_device.dev, &dev_attr_docked);
-       device_remove_file(&dock_device.dev, &dev_attr_undock);
-       platform_device_unregister(&dock_device);
+       device_remove_file(&dock_device->dev, &dev_attr_docked);
+       device_remove_file(&dock_device->dev, &dev_attr_undock);
+       device_remove_file(&dock_device->dev, &dev_attr_uid);
+       device_remove_file(&dock_device->dev, &dev_attr_flags);
+       platform_device_unregister(dock_device);
 
        /* free dock station memory */
        kfree(dock_station);
+       dock_station = NULL;
        return 0;
 }
 
index 82f496c07675c66e3cf76020cfbf81fc3dc4139f..10e851021ecabcc01e2c86354401eeda2b3cbd47 100644 (file)
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
+#include <linux/list.h>
 #include <asm/io.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/actypes.h>
 
-#define _COMPONENT             ACPI_EC_COMPONENT
-ACPI_MODULE_NAME("ec");
-#define ACPI_EC_COMPONENT              0x00100000
 #define ACPI_EC_CLASS                  "embedded_controller"
 #define ACPI_EC_HID                    "PNP0C09"
 #define ACPI_EC_DEVICE_NAME            "Embedded Controller"
 #define ACPI_EC_FILE_INFO              "info"
+
 #undef PREFIX
 #define PREFIX                         "ACPI: EC: "
+
 /* EC status register */
 #define ACPI_EC_FLAG_OBF       0x01    /* Output buffer full */
 #define ACPI_EC_FLAG_IBF       0x02    /* Input buffer full */
 #define ACPI_EC_FLAG_BURST     0x10    /* burst mode */
 #define ACPI_EC_FLAG_SCI       0x20    /* EC-SCI occurred */
+
 /* EC commands */
 enum ec_command {
        ACPI_EC_COMMAND_READ = 0x80,
@@ -61,6 +62,7 @@ enum ec_command {
        ACPI_EC_BURST_DISABLE = 0x83,
        ACPI_EC_COMMAND_QUERY = 0x84,
 };
+
 /* EC events */
 enum ec_event {
        ACPI_EC_EVENT_OBF_1 = 1,        /* Output buffer full */
@@ -94,6 +96,16 @@ static struct acpi_driver acpi_ec_driver = {
 
 /* If we find an EC via the ECDT, we need to keep a ptr to its context */
 /* External interfaces use first EC only, so remember */
+typedef int (*acpi_ec_query_func) (void *data);
+
+struct acpi_ec_query_handler {
+       struct list_head node;
+       acpi_ec_query_func func;
+       acpi_handle handle;
+       void *data;
+       u8 query_bit;
+};
+
 static struct acpi_ec {
        acpi_handle handle;
        unsigned long gpe;
@@ -104,6 +116,7 @@ static struct acpi_ec {
        atomic_t query_pending;
        atomic_t event_count;
        wait_queue_head_t wait;
+       struct list_head list;
 } *boot_ec, *first_ec;
 
 /* --------------------------------------------------------------------------
@@ -245,7 +258,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
 
        status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0, 0);
        if (status) {
-               printk(KERN_DEBUG PREFIX
+               printk(KERN_ERR PREFIX
                       "input buffer is not empty, aborting transaction\n");
                goto end;
        }
@@ -394,21 +407,67 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
 /* --------------------------------------------------------------------------
                                 Event Management
    -------------------------------------------------------------------------- */
+int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
+                             acpi_handle handle, acpi_ec_query_func func,
+                             void *data)
+{
+       struct acpi_ec_query_handler *handler =
+           kzalloc(sizeof(struct acpi_ec_query_handler), GFP_KERNEL);
+       if (!handler)
+               return -ENOMEM;
+
+       handler->query_bit = query_bit;
+       handler->handle = handle;
+       handler->func = func;
+       handler->data = data;
+       mutex_lock(&ec->lock);
+       list_add_tail(&handler->node, &ec->list);
+       mutex_unlock(&ec->lock);
+       return 0;
+}
+
+EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler);
+
+void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
+{
+       struct acpi_ec_query_handler *handler;
+       mutex_lock(&ec->lock);
+       list_for_each_entry(handler, &ec->list, node) {
+               if (query_bit == handler->query_bit) {
+                       list_del(&handler->node);
+                       kfree(handler);
+                       break;
+               }
+       }
+       mutex_unlock(&ec->lock);
+}
+
+EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
 
 static void acpi_ec_gpe_query(void *ec_cxt)
 {
        struct acpi_ec *ec = ec_cxt;
        u8 value = 0;
-       char object_name[8];
+       struct acpi_ec_query_handler *handler, copy;
 
        if (!ec || acpi_ec_query(ec, &value))
                return;
-
-       snprintf(object_name, 8, "_Q%2.2X", value);
-
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name));
-
-       acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
+       mutex_lock(&ec->lock);
+       list_for_each_entry(handler, &ec->list, node) {
+               if (value == handler->query_bit) {
+                       /* have custom handler for this bit */
+                       memcpy(&copy, handler, sizeof(copy));
+                       mutex_unlock(&ec->lock);
+                       if (copy.func) {
+                               copy.func(copy.data);
+                       } else if (copy.handle) {
+                               acpi_evaluate_object(copy.handle, NULL, NULL, NULL);
+                       }
+                       return;
+               }
+       }
+       mutex_unlock(&ec->lock);
+       printk(KERN_ERR PREFIX "Handler for query 0x%x is not found!\n", value);
 }
 
 static u32 acpi_ec_gpe_handler(void *data)
@@ -427,8 +486,7 @@ static u32 acpi_ec_gpe_handler(void *data)
        if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) {
                atomic_set(&ec->query_pending, 1);
                status =
-                   acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query,
-                                   ec);
+                   acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec);
        }
 
        return status == AE_OK ?
@@ -454,57 +512,35 @@ acpi_ec_space_setup(acpi_handle region_handle,
 }
 
 static acpi_status
-acpi_ec_space_handler(u32 function,
-                     acpi_physical_address address,
-                     u32 bit_width,
-                     acpi_integer * value,
+acpi_ec_space_handler(u32 function, acpi_physical_address address,
+                     u32 bits, acpi_integer *value,
                      void *handler_context, void *region_context)
 {
-       int result = 0;
        struct acpi_ec *ec = handler_context;
-       u64 temp = *value;
-       acpi_integer f_v = 0;
-       int i = 0;
+       int result = 0, i = 0;
+       u8 temp = 0;
 
        if ((address > 0xFF) || !value || !handler_context)
                return AE_BAD_PARAMETER;
 
-       if (bit_width != 8 && acpi_strict) {
+       if (function != ACPI_READ && function != ACPI_WRITE)
                return AE_BAD_PARAMETER;
-       }
-
-      next_byte:
-       switch (function) {
-       case ACPI_READ:
-               temp = 0;
-               result = acpi_ec_read(ec, (u8) address, (u8 *) & temp);
-               break;
-       case ACPI_WRITE:
-               result = acpi_ec_write(ec, (u8) address, (u8) temp);
-               break;
-       default:
-               result = -EINVAL;
-               goto out;
-               break;
-       }
 
-       bit_width -= 8;
-       if (bit_width) {
-               if (function == ACPI_READ)
-                       f_v |= temp << 8 * i;
-               if (function == ACPI_WRITE)
-                       temp >>= 8;
-               i++;
-               address++;
-               goto next_byte;
-       }
+       if (bits != 8 && acpi_strict)
+               return AE_BAD_PARAMETER;
 
-       if (function == ACPI_READ) {
-               f_v |= temp << 8 * i;
-               *value = f_v;
+       while (bits - i > 0) {
+               if (function == ACPI_READ) {
+                       result = acpi_ec_read(ec, address, &temp);
+                       (*value) |= ((acpi_integer)temp) << i;
+               } else {
+                       temp = 0xff & ((*value) >> i);
+                       result = acpi_ec_write(ec, address, temp);
+               }
+               i += 8;
+               ++address;
        }
 
-      out:
        switch (result) {
        case -EINVAL:
                return AE_BAD_PARAMETER;
@@ -597,9 +633,6 @@ static int acpi_ec_remove_fs(struct acpi_device *device)
 static acpi_status
 ec_parse_io_ports(struct acpi_resource *resource, void *context);
 
-static acpi_status
-ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval);
-
 static struct acpi_ec *make_acpi_ec(void)
 {
        struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
@@ -610,13 +643,52 @@ static struct acpi_ec *make_acpi_ec(void)
        atomic_set(&ec->event_count, 1);
        mutex_init(&ec->lock);
        init_waitqueue_head(&ec->wait);
+       INIT_LIST_HEAD(&ec->list);
 
        return ec;
 }
 
+static acpi_status
+acpi_ec_register_query_methods(acpi_handle handle, u32 level,
+                              void *context, void **return_value)
+{
+       struct acpi_namespace_node *node = handle;
+       struct acpi_ec *ec = context;
+       int value = 0;
+       if (sscanf(node->name.ascii, "_Q%x", &value) == 1) {
+               acpi_ec_add_query_handler(ec, value, handle, NULL, NULL);
+       }
+       return AE_OK;
+}
+
+static int ec_parse_device(struct acpi_ec *ec, acpi_handle handle)
+{
+       if (ACPI_FAILURE(acpi_walk_resources(handle, METHOD_NAME__CRS,
+                                    ec_parse_io_ports, ec)))
+               return -EINVAL;
+
+       /* Get GPE bit assignment (EC events). */
+       /* TODO: Add support for _GPE returning a package */
+       if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe)))
+               return -EINVAL;
+
+       /* Use the global lock for all EC transactions? */
+       acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
+
+       /* Find and register all query methods */
+       acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
+                           acpi_ec_register_query_methods, ec, NULL);
+
+       ec->handle = handle;
+
+       printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx",
+                         ec->gpe, ec->command_addr, ec->data_addr);
+
+       return 0;
+}
+
 static int acpi_ec_add(struct acpi_device *device)
 {
-       acpi_status status = AE_OK;
        struct acpi_ec *ec = NULL;
 
        if (!device)
@@ -629,8 +701,7 @@ static int acpi_ec_add(struct acpi_device *device)
        if (!ec)
                return -ENOMEM;
 
-       status = ec_parse_device(device->handle, 0, ec, NULL);
-       if (status != AE_CTRL_TERMINATE) {
+       if (ec_parse_device(ec, device->handle)) {
                kfree(ec);
                return -EINVAL;
        }
@@ -641,6 +712,8 @@ static int acpi_ec_add(struct acpi_device *device)
                        /* We might have incorrect info for GL at boot time */
                        mutex_lock(&boot_ec->lock);
                        boot_ec->global_lock = ec->global_lock;
+                       /* Copy handlers from new ec into boot ec */
+                       list_splice(&ec->list, &boot_ec->list);
                        mutex_unlock(&boot_ec->lock);
                        kfree(ec);
                        ec = boot_ec;
@@ -651,22 +724,24 @@ static int acpi_ec_add(struct acpi_device *device)
        acpi_driver_data(device) = ec;
 
        acpi_ec_add_fs(device);
-
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.",
-                         acpi_device_name(device), acpi_device_bid(device),
-                         (u32) ec->gpe));
-
        return 0;
 }
 
 static int acpi_ec_remove(struct acpi_device *device, int type)
 {
        struct acpi_ec *ec;
+       struct acpi_ec_query_handler *handler;
 
        if (!device)
                return -EINVAL;
 
        ec = acpi_driver_data(device);
+       mutex_lock(&ec->lock);
+       list_for_each_entry(handler, &ec->list, node) {
+               list_del(&handler->node);
+               kfree(handler);
+       }
+       mutex_unlock(&ec->lock);
        acpi_ec_remove_fs(device);
        acpi_driver_data(device) = NULL;
        if (ec == first_ec)
@@ -722,15 +797,13 @@ static int ec_install_handlers(struct acpi_ec *ec)
                return -ENODEV;
        }
 
-       /* EC is fully operational, allow queries */
-       atomic_set(&ec->query_pending, 0);
-
        return 0;
 }
 
 static int acpi_ec_start(struct acpi_device *device)
 {
        struct acpi_ec *ec;
+       int ret = 0;
 
        if (!device)
                return -EINVAL;
@@ -740,14 +813,14 @@ static int acpi_ec_start(struct acpi_device *device)
        if (!ec)
                return -EINVAL;
 
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx",
-                         ec->gpe, ec->command_addr, ec->data_addr));
-
        /* Boot EC is already working */
-       if (ec == boot_ec)
-               return 0;
+       if (ec != boot_ec)
+               ret = ec_install_handlers(ec);
+
+       /* EC is fully operational, allow queries */
+       atomic_set(&ec->query_pending, 0);
 
-       return ec_install_handlers(ec);
+       return ret;
 }
 
 static int acpi_ec_stop(struct acpi_device *device, int type)
@@ -779,34 +852,6 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
        return 0;
 }
 
-static acpi_status
-ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
-{
-       acpi_status status;
-
-       struct acpi_ec *ec = context;
-       status = acpi_walk_resources(handle, METHOD_NAME__CRS,
-                                    ec_parse_io_ports, ec);
-       if (ACPI_FAILURE(status))
-               return status;
-
-       /* Get GPE bit assignment (EC events). */
-       /* TODO: Add support for _GPE returning a package */
-       status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
-       if (ACPI_FAILURE(status))
-               return status;
-
-       /* Use the global lock for all EC transactions? */
-       acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
-
-       ec->handle = handle;
-
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
-                         ec->gpe, ec->command_addr, ec->data_addr));
-
-       return AE_CTRL_TERMINATE;
-}
-
 int __init acpi_ec_ecdt_probe(void)
 {
        int ret;
@@ -825,7 +870,7 @@ int __init acpi_ec_ecdt_probe(void)
        if (ACPI_FAILURE(status))
                goto error;
 
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT"));
+       printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n");
 
        boot_ec->command_addr = ecdt_ptr->control.address;
        boot_ec->data_addr = ecdt_ptr->data.address;
index 3b23562e6f92d195ea24dad4b1eb24131b6f519a..dfa5853b17f097555095c9b87668d03a39ba6bd8 100644 (file)
@@ -11,6 +11,8 @@
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <acpi/acpi_drivers.h>
+#include <net/netlink.h>
+#include <net/genetlink.h>
 
 #define _COMPONENT             ACPI_SYSTEM_COMPONENT
 ACPI_MODULE_NAME("event");
@@ -48,7 +50,6 @@ acpi_system_read_event(struct file *file, char __user * buffer, size_t count,
        static int chars_remaining = 0;
        static char *ptr;
 
-
        if (!chars_remaining) {
                memset(&event, 0, sizeof(struct acpi_bus_event));
 
@@ -106,23 +107,161 @@ static const struct file_operations acpi_system_event_ops = {
        .poll = acpi_system_poll_event,
 };
 
+#ifdef CONFIG_NET
+unsigned int acpi_event_seqnum;
+struct acpi_genl_event {
+       acpi_device_class device_class;
+       char bus_id[15];
+       u32 type;
+       u32 data;
+};
+
+/* attributes of acpi_genl_family */
+enum {
+       ACPI_GENL_ATTR_UNSPEC,
+       ACPI_GENL_ATTR_EVENT,   /* ACPI event info needed by user space */
+       __ACPI_GENL_ATTR_MAX,
+};
+#define ACPI_GENL_ATTR_MAX (__ACPI_GENL_ATTR_MAX - 1)
+
+/* commands supported by the acpi_genl_family */
+enum {
+       ACPI_GENL_CMD_UNSPEC,
+       ACPI_GENL_CMD_EVENT,    /* kernel->user notifications for ACPI events */
+       __ACPI_GENL_CMD_MAX,
+};
+#define ACPI_GENL_CMD_MAX (__ACPI_GENL_CMD_MAX - 1)
+
+#define ACPI_GENL_FAMILY_NAME          "acpi_event"
+#define ACPI_GENL_VERSION              0x01
+#define ACPI_GENL_MCAST_GROUP_NAME     "acpi_mc_group"
+
+static struct genl_family acpi_event_genl_family = {
+       .id = GENL_ID_GENERATE,
+       .name = ACPI_GENL_FAMILY_NAME,
+       .version = ACPI_GENL_VERSION,
+       .maxattr = ACPI_GENL_ATTR_MAX,
+};
+
+static struct genl_multicast_group acpi_event_mcgrp = {
+       .name = ACPI_GENL_MCAST_GROUP_NAME,
+};
+
+int acpi_bus_generate_genetlink_event(struct acpi_device *device,
+                                     u8 type, int data)
+{
+       struct sk_buff *skb;
+       struct nlattr *attr;
+       struct acpi_genl_event *event;
+       void *msg_header;
+       int size;
+       int result;
+
+       /* allocate memory */
+       size = nla_total_size(sizeof(struct acpi_genl_event)) +
+           nla_total_size(0);
+
+       skb = genlmsg_new(size, GFP_ATOMIC);
+       if (!skb)
+               return -ENOMEM;
+
+       /* add the genetlink message header */
+       msg_header = genlmsg_put(skb, 0, acpi_event_seqnum++,
+                                &acpi_event_genl_family, 0,
+                                ACPI_GENL_CMD_EVENT);
+       if (!msg_header) {
+               nlmsg_free(skb);
+               return -ENOMEM;
+       }
+
+       /* fill the data */
+       attr =
+           nla_reserve(skb, ACPI_GENL_ATTR_EVENT,
+                       sizeof(struct acpi_genl_event));
+       if (!attr) {
+               nlmsg_free(skb);
+               return -EINVAL;
+       }
+
+       event = nla_data(attr);
+       if (!event) {
+               nlmsg_free(skb);
+               return -EINVAL;
+       }
+
+       memset(event, 0, sizeof(struct acpi_genl_event));
+
+       strcpy(event->device_class, device->pnp.device_class);
+       strcpy(event->bus_id, device->dev.bus_id);
+       event->type = type;
+       event->data = data;
+
+       /* send multicast genetlink message */
+       result = genlmsg_end(skb, msg_header);
+       if (result < 0) {
+               nlmsg_free(skb);
+               return result;
+       }
+
+       result =
+           genlmsg_multicast(skb, 0, acpi_event_mcgrp.id, GFP_ATOMIC);
+       if (result)
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                                 "Failed to send a Genetlink message!\n"));
+       return 0;
+}
+
+static int acpi_event_genetlink_init(void)
+{
+       int result;
+
+       result = genl_register_family(&acpi_event_genl_family);
+       if (result)
+               return result;
+
+       result = genl_register_mc_group(&acpi_event_genl_family,
+                                       &acpi_event_mcgrp);
+       if (result)
+               genl_unregister_family(&acpi_event_genl_family);
+
+       return result;
+}
+
+#else
+int acpi_bus_generate_genetlink_event(struct acpi_device *device, u8 type,
+                                     int data)
+{
+       return 0;
+}
+
+static int acpi_event_genetlink_init(void)
+{
+       return -ENODEV;
+}
+#endif
+
 static int __init acpi_event_init(void)
 {
        struct proc_dir_entry *entry;
        int error = 0;
 
-
        if (acpi_disabled)
                return 0;
 
+       /* create genetlink for acpi event */
+       error = acpi_event_genetlink_init();
+       if (error)
+               printk(KERN_WARNING PREFIX
+                      "Failed to create genetlink family for ACPI event\n");
+
        /* 'event' [R] */
        entry = create_proc_entry("event", S_IRUSR, acpi_root_dir);
        if (entry)
                entry->proc_fops = &acpi_system_event_ops;
-       else {
-               error = -ENODEV;
-       }
-       return error;
+       else
+               return -ENODEV;
+
+       return 0;
 }
 
-subsys_initcall(acpi_event_init);
+fs_initcall(acpi_event_init);
index 902c287b3a4fd0295f2a9f38418a1ba1228904ab..361ebe6c4a6f0b40cdf9c86acb484eb235862dbd 100644 (file)
@@ -586,6 +586,10 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt)
        flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
        if (gpe_xrupt->previous) {
                gpe_xrupt->previous->next = gpe_xrupt->next;
+       } else {
+               /* No previous, update list head */
+
+               acpi_gbl_gpe_xrupt_list_head = gpe_xrupt->next;
        }
 
        if (gpe_xrupt->next) {
index 400d90fca966ca9c08aa2c68233d56f47790bc00..23ee7bc4a705459579f5122c31ea368bb43235d8 100644 (file)
@@ -284,6 +284,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
        }
 
        if (!pci_device_node) {
+               ACPI_FREE(pci_id);
                return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
        }
 
index 41427a41f6201fbcad4c8b7bcbaaa62228e21ed3..4893e256e399bea43ee35a62a0c0fa16667d3bdf 100644 (file)
@@ -16,7 +16,7 @@
 #if ACPI_GLUE_DEBUG
 #define DBG(x...) printk(PREFIX x)
 #else
-#define DBG(x...)
+#define DBG(x...) do { } while(0)
 #endif
 static LIST_HEAD(bus_type_list);
 static DECLARE_RWSEM(bus_type_sem);
index 0c9f15c54e8c6265d3eaec4ea14f0b4e7991cc52..ab04d848b19d9c2c42553e502e736119e4b6ff61 100644 (file)
 ACPI_MODULE_NAME("numa");
 
 static nodemask_t nodes_found_map = NODE_MASK_NONE;
-#define PXM_INVAL      -1
-#define NID_INVAL      -1
 
 /* maps to convert between proximity domain and logical node ID */
-static int pxm_to_node_map[MAX_PXM_DOMAINS]
+static int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS]
                                = { [0 ... MAX_PXM_DOMAINS - 1] = NID_INVAL };
-static int node_to_pxm_map[MAX_NUMNODES]
+static int __cpuinitdata node_to_pxm_map[MAX_NUMNODES]
                                = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
 
 int pxm_to_node(int pxm)
@@ -59,6 +57,12 @@ int node_to_pxm(int node)
        return node_to_pxm_map[node];
 }
 
+void __acpi_map_pxm_to_node(int pxm, int node)
+{
+       pxm_to_node_map[pxm] = node;
+       node_to_pxm_map[node] = pxm;
+}
+
 int acpi_map_pxm_to_node(int pxm)
 {
        int node = pxm_to_node_map[pxm];
@@ -67,8 +71,7 @@ int acpi_map_pxm_to_node(int pxm)
                if (nodes_weight(nodes_found_map) >= MAX_NUMNODES)
                        return NID_INVAL;
                node = first_unset_node(nodes_found_map);
-               pxm_to_node_map[pxm] = node;
-               node_to_pxm_map[node] = pxm;
+               __acpi_map_pxm_to_node(pxm, node);
                node_set(node, nodes_found_map);
        }
 
@@ -83,7 +86,8 @@ void __cpuinit acpi_unmap_pxm_to_node(int node)
        node_clear(node, nodes_found_map);
 }
 
-void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header)
+static void __init
+acpi_table_print_srat_entry(struct acpi_subtable_header *header)
 {
 
        ACPI_FUNCTION_NAME("acpi_table_print_srat_entry");
@@ -200,7 +204,7 @@ static int __init acpi_parse_srat(struct acpi_table_header *table)
        return 0;
 }
 
-int __init
+static int __init
 acpi_table_parse_srat(enum acpi_srat_type id,
                      acpi_table_entry_handler handler, unsigned int max_entries)
 {
@@ -211,14 +215,13 @@ acpi_table_parse_srat(enum acpi_srat_type id,
 
 int __init acpi_numa_init(void)
 {
-       int result;
-
        /* SRAT: Static Resource Affinity Table */
        if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
-               result = acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
-                                              acpi_parse_processor_affinity,
-                                              NR_CPUS);
-               result = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, acpi_parse_memory_affinity, NR_NODE_MEMBLKS);    // IA64 specific
+               acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
+                                     acpi_parse_processor_affinity, NR_CPUS);
+               acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
+                                     acpi_parse_memory_affinity,
+                                     NR_NODE_MEMBLKS);
        }
 
        /* SLIT: System Locality Information Table */
index 00d53c2fd1e823bbf088863d3ae6577ef1da0606..12c09fafce9a29de915966be172e96a94eef79a1 100644 (file)
@@ -77,13 +77,7 @@ static struct workqueue_struct *kacpi_notify_wq;
 #define        OSI_STRING_LENGTH_MAX 64        /* arbitrary */
 static char osi_additional_string[OSI_STRING_LENGTH_MAX];
 
-#define OSI_LINUX_ENABLED
-#ifdef OSI_LINUX_ENABLED
-int osi_linux = 1;     /* enable _OSI(Linux) by default */
-#else
-int osi_linux;         /* disable _OSI(Linux) by default */
-#endif
-
+static int osi_linux;          /* disable _OSI(Linux) by default */
 
 #ifdef CONFIG_DMI
 static struct __initdata dmi_system_id acpi_osl_dmi_table[];
@@ -1183,17 +1177,10 @@ acpi_os_validate_interface (char *interface)
        if (!strcmp("Linux", interface)) {
                printk(KERN_WARNING PREFIX
                        "System BIOS is requesting _OSI(Linux)\n");
-#ifdef OSI_LINUX_ENABLED
-               printk(KERN_WARNING PREFIX
-                       "Please test with \"acpi_osi=!Linux\"\n"
-                       "Please send dmidecode "
-                       "to linux-acpi@vger.kernel.org\n");
-#else
                printk(KERN_WARNING PREFIX
                        "If \"acpi_osi=Linux\" works better,\n"
                        "Please send dmidecode "
                        "to linux-acpi@vger.kernel.org\n");
-#endif
                if(osi_linux)
                        return AE_OK;
        }
@@ -1227,36 +1214,14 @@ acpi_os_validate_address (
 }
 
 #ifdef CONFIG_DMI
-#ifdef OSI_LINUX_ENABLED
-static int dmi_osi_not_linux(struct dmi_system_id *d)
-{
-       printk(KERN_NOTICE "%s detected: requires not _OSI(Linux)\n", d->ident);
-       enable_osi_linux(0);
-       return 0;
-}
-#else
 static int dmi_osi_linux(struct dmi_system_id *d)
 {
-       printk(KERN_NOTICE "%s detected: requires _OSI(Linux)\n", d->ident);
+       printk(KERN_NOTICE "%s detected: enabling _OSI(Linux)\n", d->ident);
        enable_osi_linux(1);
        return 0;
 }
-#endif
 
 static struct dmi_system_id acpi_osl_dmi_table[] __initdata = {
-#ifdef OSI_LINUX_ENABLED
-       /*
-        * Boxes that need NOT _OSI(Linux)
-        */
-       {
-        .callback = dmi_osi_not_linux,
-        .ident = "Toshiba Satellite P100",
-        .matches = {
-                    DMI_MATCH(DMI_BOARD_VENDOR, "TOSHIBA"),
-                    DMI_MATCH(DMI_BOARD_NAME, "Satellite P100"),
-                    },
-        },
-#else
        /*
         * Boxes that need _OSI(Linux)
         */
@@ -1268,7 +1233,6 @@ static struct dmi_system_id acpi_osl_dmi_table[] __initdata = {
                     DMI_MATCH(DMI_BOARD_NAME, "MPAD-MSAE Customer Reference Boards"),
                     },
         },
-#endif
        {}
 };
 #endif /* CONFIG_DMI */
index acc594771379af521ef06a5f7a549ca781583d8d..3448edd61dc406d977afb3b90ec28b3a5e9dfc17 100644 (file)
@@ -733,7 +733,7 @@ static int acpi_pci_link_add(struct acpi_device *device)
        /* query and set link->irq.active */
        acpi_pci_link_get_current(link);
 
-       printk(PREFIX "%s [%s] (IRQs", acpi_device_name(device),
+       printk(KERN_INFO PREFIX "%s [%s] (IRQs", acpi_device_name(device),
               acpi_device_bid(device));
        for (i = 0; i < link->irq.possible_count; i++) {
                if (link->irq.active == link->irq.possible[i]) {
index e1ca86dfdd661fa2a53fbf78d3207296795ea165..81aceb5da7c7948f905787fd040c5b9f7f810c1b 100644 (file)
@@ -66,6 +66,7 @@
 #define ACPI_PROCESSOR_FILE_LIMIT      "limit"
 #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
 #define ACPI_PROCESSOR_NOTIFY_POWER    0x81
+#define ACPI_PROCESSOR_NOTIFY_THROTTLING       0x82
 
 #define ACPI_PROCESSOR_LIMIT_USER      0
 #define ACPI_PROCESSOR_LIMIT_THERMAL   1
@@ -84,6 +85,8 @@ static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
 static void acpi_processor_notify(acpi_handle handle, u32 event, void *data);
 static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
 static int acpi_processor_handle_eject(struct acpi_processor *pr);
+extern int acpi_processor_tstate_has_changed(struct acpi_processor *pr);
+
 
 static struct acpi_driver acpi_processor_driver = {
        .name = "processor",
@@ -696,6 +699,9 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
                acpi_processor_cst_has_changed(pr);
                acpi_bus_generate_event(device, event, 0);
                break;
+       case ACPI_PROCESSOR_NOTIFY_THROTTLING:
+               acpi_processor_tstate_has_changed(pr);
+               acpi_bus_generate_event(device, event, 0);
        default:
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                  "Unsupported event [0x%x]\n", event));
index bb5d23be42607fe4ebb3c91c6dd118287242131b..a898991f77cbcfb18fc41c481afeca1fc63f0697 100644 (file)
@@ -490,7 +490,17 @@ static void acpi_processor_idle(void)
 
        case ACPI_STATE_C3:
 
-               if (pr->flags.bm_check) {
+               /*
+                * disable bus master
+                * bm_check implies we need ARB_DIS
+                * !bm_check implies we need cache flush
+                * bm_control implies whether we can do ARB_DIS
+                *
+                * That leaves a case where bm_check is set and bm_control is
+                * not set. In that case we cannot do much, we enter C3
+                * without doing anything.
+                */
+               if (pr->flags.bm_check && pr->flags.bm_control) {
                        if (atomic_inc_return(&c3_cpu_count) ==
                            num_online_cpus()) {
                                /*
@@ -499,7 +509,7 @@ static void acpi_processor_idle(void)
                                 */
                                acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
                        }
-               } else {
+               } else if (!pr->flags.bm_check) {
                        /* SMP with no shared cache... Invalidate cache  */
                        ACPI_FLUSH_CPU_CACHE();
                }
@@ -511,7 +521,7 @@ static void acpi_processor_idle(void)
                acpi_cstate_enter(cx);
                /* Get end time (ticks) */
                t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
-               if (pr->flags.bm_check) {
+               if (pr->flags.bm_check && pr->flags.bm_control) {
                        /* Enable bus master arbitration */
                        atomic_dec(&c3_cpu_count);
                        acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
@@ -961,9 +971,9 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
        if (pr->flags.bm_check) {
                /* bus mastering control is necessary */
                if (!pr->flags.bm_control) {
+                       /* In this case we enter C3 without bus mastering */
                        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                         "C3 support requires bus mastering control\n"));
-                       return;
+                               "C3 support without bus mastering control\n"));
                }
        } else {
                /*
index b33486009f41c690f1b6bed87f4818beb17a27d6..3f55d1f90c1170d0e308693076b822c514bd65f9 100644 (file)
 #define _COMPONENT              ACPI_PROCESSOR_COMPONENT
 ACPI_MODULE_NAME("processor_throttling");
 
+static int acpi_processor_get_throttling(struct acpi_processor *pr);
+int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
+
+static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
+{
+       acpi_status status = 0;
+       unsigned long tpc = 0;
+
+       if (!pr)
+               return -EINVAL;
+       status = acpi_evaluate_integer(pr->handle, "_TPC", NULL, &tpc);
+       if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+               ACPI_EXCEPTION((AE_INFO, status, "Evaluating _TPC"));
+               return -ENODEV;
+       }
+       pr->throttling_platform_limit = (int)tpc;
+       return 0;
+}
+
+int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
+{
+       return acpi_processor_get_platform_limit(pr);
+}
+
+/* --------------------------------------------------------------------------
+                             _PTC, _TSS, _TSD support 
+   -------------------------------------------------------------------------- */
+static int acpi_processor_get_throttling_control(struct acpi_processor *pr)
+{
+       int result = 0;
+       acpi_status status = 0;
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+       union acpi_object *ptc = NULL;
+       union acpi_object obj = { 0 };
+
+       status = acpi_evaluate_object(pr->handle, "_PTC", NULL, &buffer);
+       if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PTC"));
+               return -ENODEV;
+       }
+
+       ptc = (union acpi_object *)buffer.pointer;
+       if (!ptc || (ptc->type != ACPI_TYPE_PACKAGE)
+           || (ptc->package.count != 2)) {
+               printk(KERN_ERR PREFIX "Invalid _PTC data\n");
+               result = -EFAULT;
+               goto end;
+       }
+
+       /*
+        * control_register
+        */
+
+       obj = ptc->package.elements[0];
+
+       if ((obj.type != ACPI_TYPE_BUFFER)
+           || (obj.buffer.length < sizeof(struct acpi_ptc_register))
+           || (obj.buffer.pointer == NULL)) {
+               printk(KERN_ERR PREFIX
+                      "Invalid _PTC data (control_register)\n");
+               result = -EFAULT;
+               goto end;
+       }
+       memcpy(&pr->throttling.control_register, obj.buffer.pointer,
+              sizeof(struct acpi_ptc_register));
+
+       /*
+        * status_register
+        */
+
+       obj = ptc->package.elements[1];
+
+       if ((obj.type != ACPI_TYPE_BUFFER)
+           || (obj.buffer.length < sizeof(struct acpi_ptc_register))
+           || (obj.buffer.pointer == NULL)) {
+               printk(KERN_ERR PREFIX "Invalid _PTC data (status_register)\n");
+               result = -EFAULT;
+               goto end;
+       }
+
+       memcpy(&pr->throttling.status_register, obj.buffer.pointer,
+              sizeof(struct acpi_ptc_register));
+
+      end:
+       kfree(buffer.pointer);
+
+       return result;
+}
+static int acpi_processor_get_throttling_states(struct acpi_processor *pr)
+{
+       int result = 0;
+       acpi_status status = AE_OK;
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+       struct acpi_buffer format = { sizeof("NNNNN"), "NNNNN" };
+       struct acpi_buffer state = { 0, NULL };
+       union acpi_object *tss = NULL;
+       int i;
+
+       status = acpi_evaluate_object(pr->handle, "_TSS", NULL, &buffer);
+       if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status, "Evaluating _TSS"));
+               return -ENODEV;
+       }
+
+       tss = buffer.pointer;
+       if (!tss || (tss->type != ACPI_TYPE_PACKAGE)) {
+               printk(KERN_ERR PREFIX "Invalid _TSS data\n");
+               result = -EFAULT;
+               goto end;
+       }
+
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d throttling states\n",
+                         tss->package.count));
+
+       pr->throttling.state_count = tss->package.count;
+       pr->throttling.states_tss =
+           kmalloc(sizeof(struct acpi_processor_tx_tss) * tss->package.count,
+                   GFP_KERNEL);
+       if (!pr->throttling.states_tss) {
+               result = -ENOMEM;
+               goto end;
+       }
+
+       for (i = 0; i < pr->throttling.state_count; i++) {
+
+               struct acpi_processor_tx_tss *tx =
+                   (struct acpi_processor_tx_tss *)&(pr->throttling.
+                                                     states_tss[i]);
+
+               state.length = sizeof(struct acpi_processor_tx_tss);
+               state.pointer = tx;
+
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i));
+
+               status = acpi_extract_package(&(tss->package.elements[i]),
+                                             &format, &state);
+               if (ACPI_FAILURE(status)) {
+                       ACPI_EXCEPTION((AE_INFO, status, "Invalid _TSS data"));
+                       result = -EFAULT;
+                       kfree(pr->throttling.states_tss);
+                       goto end;
+               }
+
+               if (!tx->freqpercentage) {
+                       printk(KERN_ERR PREFIX
+                              "Invalid _TSS data: freq is zero\n");
+                       result = -EFAULT;
+                       kfree(pr->throttling.states_tss);
+                       goto end;
+               }
+       }
+
+      end:
+       kfree(buffer.pointer);
+
+       return result;
+}
+static int acpi_processor_get_tsd(struct acpi_processor *pr)
+{
+       int result = 0;
+       acpi_status status = AE_OK;
+       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+       struct acpi_buffer format = { sizeof("NNNNN"), "NNNNN" };
+       struct acpi_buffer state = { 0, NULL };
+       union acpi_object *tsd = NULL;
+       struct acpi_tsd_package *pdomain;
+
+       status = acpi_evaluate_object(pr->handle, "_TSD", NULL, &buffer);
+       if (ACPI_FAILURE(status)) {
+               return -ENODEV;
+       }
+
+       tsd = buffer.pointer;
+       if (!tsd || (tsd->type != ACPI_TYPE_PACKAGE)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
+               result = -EFAULT;
+               goto end;
+       }
+
+       if (tsd->package.count != 1) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
+               result = -EFAULT;
+               goto end;
+       }
+
+       pdomain = &(pr->throttling.domain_info);
+
+       state.length = sizeof(struct acpi_tsd_package);
+       state.pointer = pdomain;
+
+       status = acpi_extract_package(&(tsd->package.elements[0]),
+                                     &format, &state);
+       if (ACPI_FAILURE(status)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
+               result = -EFAULT;
+               goto end;
+       }
+
+       if (pdomain->num_entries != ACPI_TSD_REV0_ENTRIES) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:num_entries\n"));
+               result = -EFAULT;
+               goto end;
+       }
+
+       if (pdomain->revision != ACPI_TSD_REV0_REVISION) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:revision\n"));
+               result = -EFAULT;
+               goto end;
+       }
+
+      end:
+       kfree(buffer.pointer);
+       return result;
+}
+
 /* --------------------------------------------------------------------------
                               Throttling Control
    -------------------------------------------------------------------------- */
-static int acpi_processor_get_throttling(struct acpi_processor *pr)
+static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr)
 {
        int state = 0;
        u32 value = 0;
        u32 duty_mask = 0;
        u32 duty_value = 0;
 
-
        if (!pr)
                return -EINVAL;
 
@@ -94,13 +308,115 @@ static int acpi_processor_get_throttling(struct acpi_processor *pr)
        return 0;
 }
 
-int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
+static int acpi_read_throttling_status(struct acpi_processor_throttling
+                                      *throttling)
+{
+       int value = -1;
+       switch (throttling->status_register.space_id) {
+       case ACPI_ADR_SPACE_SYSTEM_IO:
+               acpi_os_read_port((acpi_io_address) throttling->status_register.
+                                 address, &value,
+                                 (u32) throttling->status_register.bit_width *
+                                 8);
+               break;
+       case ACPI_ADR_SPACE_FIXED_HARDWARE:
+               printk(KERN_ERR PREFIX
+                      "HARDWARE addr space,NOT supported yet\n");
+               break;
+       default:
+               printk(KERN_ERR PREFIX "Unknown addr space %d\n",
+                      (u32) (throttling->status_register.space_id));
+       }
+       return value;
+}
+
+static int acpi_write_throttling_state(struct acpi_processor_throttling
+                                      *throttling, int value)
+{
+       int ret = -1;
+
+       switch (throttling->control_register.space_id) {
+       case ACPI_ADR_SPACE_SYSTEM_IO:
+               acpi_os_write_port((acpi_io_address) throttling->
+                                  control_register.address, value,
+                                  (u32) throttling->control_register.
+                                  bit_width * 8);
+               ret = 0;
+               break;
+       case ACPI_ADR_SPACE_FIXED_HARDWARE:
+               printk(KERN_ERR PREFIX
+                      "HARDWARE addr space,NOT supported yet\n");
+               break;
+       default:
+               printk(KERN_ERR PREFIX "Unknown addr space %d\n",
+                      (u32) (throttling->control_register.space_id));
+       }
+       return ret;
+}
+
+static int acpi_get_throttling_state(struct acpi_processor *pr, int value)
+{
+       int i;
+
+       for (i = 0; i < pr->throttling.state_count; i++) {
+               struct acpi_processor_tx_tss *tx =
+                   (struct acpi_processor_tx_tss *)&(pr->throttling.
+                                                     states_tss[i]);
+               if (tx->control == value)
+                       break;
+       }
+       if (i > pr->throttling.state_count)
+               i = -1;
+       return i;
+}
+
+static int acpi_get_throttling_value(struct acpi_processor *pr, int state)
+{
+       int value = -1;
+       if (state >= 0 && state <= pr->throttling.state_count) {
+               struct acpi_processor_tx_tss *tx =
+                   (struct acpi_processor_tx_tss *)&(pr->throttling.
+                                                     states_tss[state]);
+               value = tx->control;
+       }
+       return value;
+}
+
+static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr)
+{
+       int state = 0;
+       u32 value = 0;
+
+       if (!pr)
+               return -EINVAL;
+
+       if (!pr->flags.throttling)
+               return -ENODEV;
+
+       pr->throttling.state = 0;
+       local_irq_disable();
+       value = acpi_read_throttling_status(&pr->throttling);
+       if (value >= 0) {
+               state = acpi_get_throttling_state(pr, value);
+               pr->throttling.state = state;
+       }
+       local_irq_enable();
+
+       return 0;
+}
+
+static int acpi_processor_get_throttling(struct acpi_processor *pr)
+{
+       return pr->throttling.acpi_processor_get_throttling(pr);
+}
+
+static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
+                                             int state)
 {
        u32 value = 0;
        u32 duty_mask = 0;
        u32 duty_value = 0;
 
-
        if (!pr)
                return -EINVAL;
 
@@ -113,6 +429,8 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
        if (state == pr->throttling.state)
                return 0;
 
+       if (state < pr->throttling_platform_limit)
+               return -EPERM;
        /*
         * Calculate the duty_value and duty_mask.
         */
@@ -165,12 +483,51 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
        return 0;
 }
 
+static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
+                                            int state)
+{
+       u32 value = 0;
+
+       if (!pr)
+               return -EINVAL;
+
+       if ((state < 0) || (state > (pr->throttling.state_count - 1)))
+               return -EINVAL;
+
+       if (!pr->flags.throttling)
+               return -ENODEV;
+
+       if (state == pr->throttling.state)
+               return 0;
+
+       if (state < pr->throttling_platform_limit)
+               return -EPERM;
+
+       local_irq_disable();
+
+       value = acpi_get_throttling_value(pr, state);
+       if (value >= 0) {
+               acpi_write_throttling_state(&pr->throttling, value);
+               pr->throttling.state = state;
+       }
+       local_irq_enable();
+
+       return 0;
+}
+
+int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
+{
+       return pr->throttling.acpi_processor_set_throttling(pr, state);
+}
+
 int acpi_processor_get_throttling_info(struct acpi_processor *pr)
 {
        int result = 0;
        int step = 0;
        int i = 0;
-
+       int no_ptc = 0;
+       int no_tss = 0;
+       int no_tsd = 0;
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                          "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
@@ -182,6 +539,21 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
                return -EINVAL;
 
        /* TBD: Support ACPI 2.0 objects */
+       no_ptc = acpi_processor_get_throttling_control(pr);
+       no_tss = acpi_processor_get_throttling_states(pr);
+       no_tsd = acpi_processor_get_tsd(pr);
+
+       if (no_ptc || no_tss) {
+               pr->throttling.acpi_processor_get_throttling =
+                   &acpi_processor_get_throttling_fadt;
+               pr->throttling.acpi_processor_set_throttling =
+                   &acpi_processor_set_throttling_fadt;
+       } else {
+               pr->throttling.acpi_processor_get_throttling =
+                   &acpi_processor_get_throttling_ptc;
+               pr->throttling.acpi_processor_set_throttling =
+                   &acpi_processor_set_throttling_ptc;
+       }
 
        if (!pr->throttling.address) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n"));
@@ -262,7 +634,6 @@ static int acpi_processor_throttling_seq_show(struct seq_file *seq,
        int i = 0;
        int result = 0;
 
-
        if (!pr)
                goto end;
 
@@ -280,15 +651,25 @@ static int acpi_processor_throttling_seq_show(struct seq_file *seq,
        }
 
        seq_printf(seq, "state count:             %d\n"
-                  "active state:            T%d\n",
-                  pr->throttling.state_count, pr->throttling.state);
+                  "active state:            T%d\n"
+                  "state available: T%d to T%d\n",
+                  pr->throttling.state_count, pr->throttling.state,
+                  pr->throttling_platform_limit,
+                  pr->throttling.state_count - 1);
 
        seq_puts(seq, "states:\n");
-       for (i = 0; i < pr->throttling.state_count; i++)
-               seq_printf(seq, "   %cT%d:                  %02d%%\n",
-                          (i == pr->throttling.state ? '*' : ' '), i,
-                          (pr->throttling.states[i].performance ? pr->
-                           throttling.states[i].performance / 10 : 0));
+       if (acpi_processor_get_throttling == acpi_processor_get_throttling_fadt)
+               for (i = 0; i < pr->throttling.state_count; i++)
+                       seq_printf(seq, "   %cT%d:                  %02d%%\n",
+                                  (i == pr->throttling.state ? '*' : ' '), i,
+                                  (pr->throttling.states[i].performance ? pr->
+                                   throttling.states[i].performance / 10 : 0));
+       else
+               for (i = 0; i < pr->throttling.state_count; i++)
+                       seq_printf(seq, "   %cT%d:                  %02d%%\n",
+                                  (i == pr->throttling.state ? '*' : ' '), i,
+                                  (int)pr->throttling.states_tss[i].
+                                  freqpercentage);
 
       end:
        return 0;
@@ -301,7 +682,7 @@ static int acpi_processor_throttling_open_fs(struct inode *inode,
                           PDE(inode)->data);
 }
 
-static ssize_t acpi_processor_write_throttling(struct file * file,
+static ssize_t acpi_processor_write_throttling(struct file *file,
                                               const char __user * buffer,
                                               size_t count, loff_t * data)
 {
@@ -310,7 +691,6 @@ static ssize_t acpi_processor_write_throttling(struct file * file,
        struct acpi_processor *pr = m->private;
        char state_string[12] = { '\0' };
 
-
        if (!pr || (count > sizeof(state_string) - 1))
                return -EINVAL;
 
index c1bae106833cef03d6f7faee83e5d42c9fda36a9..974d00ccfe845209c6ced6ec09278f5dbe8b49bf 100644 (file)
@@ -127,7 +127,7 @@ static int acpi_sbs_resume(struct acpi_device *device);
 static struct acpi_driver acpi_sbs_driver = {
        .name = "sbs",
        .class = ACPI_SBS_CLASS,
-       .ids = ACPI_SBS_HID,
+       .ids = "ACPI0001,ACPI0005",
        .ops = {
                .add = acpi_sbs_add,
                .remove = acpi_sbs_remove,
@@ -176,10 +176,8 @@ struct acpi_battery {
 };
 
 struct acpi_sbs {
-       acpi_handle handle;
        int base;
        struct acpi_device *device;
-       struct acpi_ec_smbus *smbus;
        struct mutex mutex;
        int sbsm_present;
        int sbsm_batteries_supported;
@@ -511,7 +509,7 @@ static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
                                "acpi_sbs_read_word() failed"));
                goto end;
        }
-
+       sbs->sbsm_present = 1;
        sbs->sbsm_batteries_supported = battery_system_info & 0x000f;
 
       end:
@@ -1630,13 +1628,12 @@ static int acpi_sbs_add(struct acpi_device *device)
 {
        struct acpi_sbs *sbs = NULL;
        int result = 0, remove_result = 0;
-       unsigned long sbs_obj;
        int id;
        acpi_status status = AE_OK;
        unsigned long val;
 
        status =
-           acpi_evaluate_integer(device->parent->handle, "_EC", NULL, &val);
+           acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
        if (ACPI_FAILURE(status)) {
                ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC"));
                return -EIO;
@@ -1653,7 +1650,7 @@ static int acpi_sbs_add(struct acpi_device *device)
 
        sbs_mutex_lock(sbs);
 
-       sbs->base = (val & 0xff00ull) >> 8;
+       sbs->base = 0xff & (val >> 8);
        sbs->device = device;
 
        strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
@@ -1665,24 +1662,10 @@ static int acpi_sbs_add(struct acpi_device *device)
                ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed"));
                goto end;
        }
-       status = acpi_evaluate_integer(device->handle, "_SBS", NULL, &sbs_obj);
-       if (status) {
-               ACPI_EXCEPTION((AE_INFO, status,
-                               "acpi_evaluate_integer() failed"));
-               result = -EIO;
-               goto end;
-       }
-       if (sbs_obj > 0) {
-               result = acpi_sbsm_get_info(sbs);
-               if (result) {
-                       ACPI_EXCEPTION((AE_INFO, AE_ERROR,
-                                       "acpi_sbsm_get_info() failed"));
-                       goto end;
-               }
-               sbs->sbsm_present = 1;
-       }
 
-       if (sbs->sbsm_present == 0) {
+       acpi_sbsm_get_info(sbs);
+
+       if (!sbs->sbsm_present) {
                result = acpi_battery_add(sbs, 0);
                if (result) {
                        ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1702,8 +1685,6 @@ static int acpi_sbs_add(struct acpi_device *device)
                }
        }
 
-       sbs->handle = device->handle;
-
        init_timer(&sbs->update_timer);
        result = acpi_check_update_proc(sbs);
        if (result)
index 42127c0d612c8940d1060c67a5e8b5893567ef88..3279e72a94f81c0c532f72a9bd0284861a1ba345 100644 (file)
@@ -210,11 +210,6 @@ static void acpi_hibernation_finish(void)
 
        /* reset firmware waking vector */
        acpi_set_firmware_waking_vector((acpi_physical_address) 0);
-
-       if (init_8259A_after_S1) {
-               printk("Broken toshiba laptop -> kicking interrupts\n");
-               init_8259A(0);
-       }
 }
 
 static int acpi_hibernation_pre_restore(void)
index 83a8d3097904e99dbb825736ee84294bd4739de5..edee2806e37bcec904e6640a90fb2423b981260c 100644 (file)
@@ -39,15 +39,12 @@ ACPI_MODULE_NAME("system");
 
 #define ACPI_SYSTEM_CLASS              "system"
 #define ACPI_SYSTEM_DEVICE_NAME                "System"
-#define ACPI_SYSTEM_FILE_INFO          "info"
-#define ACPI_SYSTEM_FILE_EVENT         "event"
-#define ACPI_SYSTEM_FILE_DSDT          "dsdt"
-#define ACPI_SYSTEM_FILE_FADT          "fadt"
 
 /*
  * Make ACPICA version work as module param
  */
-static int param_get_acpica_version(char *buffer, struct kernel_param *kp) {
+static int param_get_acpica_version(char *buffer, struct kernel_param *kp)
+{
        int result;
 
        result = sprintf(buffer, "%x", ACPI_CA_VERSION);
@@ -57,10 +54,127 @@ static int param_get_acpica_version(char *buffer, struct kernel_param *kp) {
 
 module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);
 
+/* --------------------------------------------------------------------------
+                              FS Interface (/sys)
+   -------------------------------------------------------------------------- */
+static LIST_HEAD(acpi_table_attr_list);
+static struct kobject tables_kobj;
+
+struct acpi_table_attr {
+       struct bin_attribute attr;
+       char name[8];
+       int instance;
+       struct list_head node;
+};
+
+static ssize_t acpi_table_show(struct kobject *kobj,
+                              struct bin_attribute *bin_attr, char *buf,
+                              loff_t offset, size_t count)
+{
+       struct acpi_table_attr *table_attr =
+           container_of(bin_attr, struct acpi_table_attr, attr);
+       struct acpi_table_header *table_header = NULL;
+       acpi_status status;
+       ssize_t ret_count = count;
+
+       status =
+           acpi_get_table(table_attr->name, table_attr->instance,
+                          &table_header);
+       if (ACPI_FAILURE(status))
+               return -ENODEV;
+
+       if (offset >= table_header->length) {
+               ret_count = 0;
+               goto end;
+       }
+
+       if (offset + ret_count > table_header->length)
+               ret_count = table_header->length - offset;
+
+       memcpy(buf, ((char *)table_header) + offset, ret_count);
+
+      end:
+       return ret_count;
+}
+
+static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
+                                struct acpi_table_header *table_header)
+{
+       struct acpi_table_header *header = NULL;
+       struct acpi_table_attr *attr = NULL;
+
+       memcpy(table_attr->name, table_header->signature, ACPI_NAME_SIZE);
+
+       list_for_each_entry(attr, &acpi_table_attr_list, node) {
+               if (!memcmp(table_header->signature, attr->name,
+                           ACPI_NAME_SIZE))
+                       if (table_attr->instance < attr->instance)
+                               table_attr->instance = attr->instance;
+       }
+       table_attr->instance++;
+
+       if (table_attr->instance > 1 || (table_attr->instance == 1 &&
+                                        !acpi_get_table(table_header->
+                                                        signature, 2,
+                                                        &header)))
+               sprintf(table_attr->name + 4, "%d", table_attr->instance);
+
+       table_attr->attr.size = 0;
+       table_attr->attr.read = acpi_table_show;
+       table_attr->attr.attr.name = table_attr->name;
+       table_attr->attr.attr.mode = 0444;
+       table_attr->attr.attr.owner = THIS_MODULE;
+
+       return;
+}
+
+static int acpi_system_sysfs_init(void)
+{
+       struct acpi_table_attr *table_attr;
+       struct acpi_table_header *table_header = NULL;
+       int table_index = 0;
+       int result;
+
+       tables_kobj.parent = &acpi_subsys.kobj;
+       kobject_set_name(&tables_kobj, "tables");
+       result = kobject_register(&tables_kobj);
+       if (result)
+               return result;
+
+       do {
+               result = acpi_get_table_by_index(table_index, &table_header);
+               if (!result) {
+                       table_index++;
+                       table_attr = NULL;
+                       table_attr =
+                           kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
+                       if (!table_attr)
+                               return -ENOMEM;
+
+                       acpi_table_attr_init(table_attr, table_header);
+                       result =
+                           sysfs_create_bin_file(&tables_kobj,
+                                                 &table_attr->attr);
+                       if (result) {
+                               kfree(table_attr);
+                               return result;
+                       } else
+                               list_add_tail(&table_attr->node,
+                                             &acpi_table_attr_list);
+               }
+       } while (!result);
+
+       return 0;
+}
+
 /* --------------------------------------------------------------------------
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
 #ifdef CONFIG_ACPI_PROCFS
+#define ACPI_SYSTEM_FILE_INFO          "info"
+#define ACPI_SYSTEM_FILE_EVENT         "event"
+#define ACPI_SYSTEM_FILE_DSDT          "dsdt"
+#define ACPI_SYSTEM_FILE_FADT          "fadt"
 
 static int acpi_system_read_info(struct seq_file *seq, void *offset)
 {
@@ -80,7 +194,6 @@ static const struct file_operations acpi_system_info_ops = {
        .llseek = seq_lseek,
        .release = single_release,
 };
-#endif
 
 static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
                                     loff_t *);
@@ -97,13 +210,11 @@ acpi_system_read_dsdt(struct file *file,
        struct acpi_table_header *dsdt = NULL;
        ssize_t res;
 
-
        status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt);
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
-       res = simple_read_from_buffer(buffer, count, ppos,
-                                     dsdt, dsdt->length);
+       res = simple_read_from_buffer(buffer, count, ppos, dsdt, dsdt->length);
 
        return res;
 }
@@ -123,28 +234,21 @@ acpi_system_read_fadt(struct file *file,
        struct acpi_table_header *fadt = NULL;
        ssize_t res;
 
-
        status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt);
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
-       res = simple_read_from_buffer(buffer, count, ppos,
-                                     fadt, fadt->length);
+       res = simple_read_from_buffer(buffer, count, ppos, fadt, fadt->length);
 
        return res;
 }
 
-static int __init acpi_system_init(void)
+static int acpi_system_procfs_init(void)
 {
        struct proc_dir_entry *entry;
        int error = 0;
        char *name;
 
-
-       if (acpi_disabled)
-               return 0;
-
-#ifdef CONFIG_ACPI_PROCFS
        /* 'info' [R] */
        name = ACPI_SYSTEM_FILE_INFO;
        entry = create_proc_entry(name, S_IRUGO, acpi_root_dir);
@@ -153,7 +257,6 @@ static int __init acpi_system_init(void)
        else {
                entry->proc_fops = &acpi_system_info_ops;
        }
-#endif
 
        /* 'dsdt' [R] */
        name = ACPI_SYSTEM_FILE_DSDT;
@@ -177,12 +280,32 @@ static int __init acpi_system_init(void)
       Error:
        remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir);
        remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir);
-#ifdef CONFIG_ACPI_PROCFS
        remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir);
-#endif
 
        error = -EFAULT;
        goto Done;
 }
+#else
+static int acpi_system_procfs_init(void)
+{
+       return 0;
+}
+#endif
+
+static int __init acpi_system_init(void)
+{
+       int result = 0;
+
+       if (acpi_disabled)
+               return 0;
+
+       result = acpi_system_procfs_init();
+       if (result)
+               return result;
+
+       result = acpi_system_sysfs_init();
+
+       return result;
+}
 
 subsys_initcall(acpi_system_init);
index 1285e91474fbff4c504d82e75ebe9b63c608eb24..002bb33003af8c8c30c1b48bfb0607c397d974cf 100644 (file)
@@ -211,14 +211,17 @@ void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags)
  * DESCRIPTION: Get a local copy of the FADT and convert it to a common format.
  *              Performs validation on some important FADT fields.
  *
+ * NOTE:        We create a local copy of the FADT regardless of the version.
+ *
  ******************************************************************************/
 
 void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
 {
 
        /*
-        * Check if the FADT is larger than what we know about (ACPI 2.0 version).
-        * Truncate the table, but make some noise.
+        * Check if the FADT is larger than the largest table that we expect
+        * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue
+        * a warning.
         */
        if (length > sizeof(struct acpi_table_fadt)) {
                ACPI_WARNING((AE_INFO,
@@ -227,10 +230,12 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
                              sizeof(struct acpi_table_fadt)));
        }
 
-       /* Copy the entire FADT locally. Zero first for tb_convert_fadt */
+       /* Clear the entire local FADT */
 
        ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt));
 
+       /* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */
+
        ACPI_MEMCPY(&acpi_gbl_FADT, table,
                    ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
 
@@ -251,7 +256,7 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
  * RETURN:      None
  *
  * DESCRIPTION: Converts all versions of the FADT to a common internal format.
- *              -> Expand all 32-bit addresses to 64-bit.
+ *              Expand all 32-bit addresses to 64-bit.
  *
  * NOTE:        acpi_gbl_FADT must be of size (struct acpi_table_fadt),
  *              and must contain a copy of the actual FADT.
@@ -292,8 +297,23 @@ static void acpi_tb_convert_fadt(void)
        }
 
        /*
-        * Expand the 32-bit V1.0 addresses to the 64-bit "X" generic address
-        * structures as necessary.
+        * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
+        * should be zero are indeed zero. This will workaround BIOSs that
+        * inadvertently place values in these fields.
+        *
+        * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at
+        * offset 45, 55, 95, and the word located at offset 109, 110.
+        */
+       if (acpi_gbl_FADT.header.revision < 3) {
+               acpi_gbl_FADT.preferred_profile = 0;
+               acpi_gbl_FADT.pstate_control = 0;
+               acpi_gbl_FADT.cst_control = 0;
+               acpi_gbl_FADT.boot_flags = 0;
+       }
+
+       /*
+        * Expand the ACPI 1.0 32-bit V1.0 addresses to the ACPI 2.0 64-bit "X"
+        * generic address structures as necessary.
         */
        for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
                target =
@@ -349,18 +369,6 @@ static void acpi_tb_convert_fadt(void)
                    acpi_gbl_FADT.xpm1a_event_block.space_id;
 
        }
-
-       /*
-        * For ACPI 1.0 FADTs, ensure that reserved fields (which should be zero)
-        * are indeed zero. This will workaround BIOSs that inadvertently placed
-        * values in these fields.
-        */
-       if (acpi_gbl_FADT.header.revision < 3) {
-               acpi_gbl_FADT.preferred_profile = 0;
-               acpi_gbl_FADT.pstate_control = 0;
-               acpi_gbl_FADT.cst_control = 0;
-               acpi_gbl_FADT.boot_flags = 0;
-       }
 }
 
 /******************************************************************************
index 8ec6f8e481385d2908f286249903d44db35cf184..f112af433e36eb01afdfce5cfdcaeacf74dde19d 100644 (file)
@@ -62,16 +62,13 @@ acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
 static char *acpi_interfaces_supported[] = {
        /* Operating System Vendor Strings */
 
-       "Windows 2000",
-       "Windows 2001",
-       "Windows 2001 SP0",
-       "Windows 2001 SP1",
-       "Windows 2001 SP2",
-       "Windows 2001 SP3",
-       "Windows 2001 SP4",
-       "Windows 2001.1",
-       "Windows 2001.1 SP1",   /* Added 03/2006 */
-       "Windows 2006",         /* Added 03/2006 */
+       "Windows 2000",         /* Windows 2000 */
+       "Windows 2001",         /* Windows XP */
+       "Windows 2001 SP1",     /* Windows XP SP1 */
+       "Windows 2001 SP2",     /* Windows XP SP2 */
+       "Windows 2001.1",       /* Windows Server 2003 */
+       "Windows 2001.1 SP1",   /* Windows Server 2003 SP1 - Added 03/2006 */
+       "Windows 2006",         /* Windows Vista - Added 03/2006 */
 
        /* Feature Group Strings */
 
index 00d25b34725549e86b739354cf5f972e6a10831f..04ea697f72bff00b94cc2d1151df53d8b5d93e1e 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/seq_file.h>
 
 #include <linux/backlight.h>
+#include <linux/video_output.h>
 #include <asm/uaccess.h>
 
 #include <acpi/acpi_bus.h>
@@ -169,6 +170,7 @@ struct acpi_video_device {
        struct acpi_device *dev;
        struct acpi_video_device_brightness *brightness;
        struct backlight_device *backlight;
+       struct output_device *output_dev;
 };
 
 /* bus */
@@ -272,13 +274,17 @@ static int acpi_video_get_next_level(struct acpi_video_device *device,
                                     u32 level_current, u32 event);
 static void acpi_video_switch_brightness(struct acpi_video_device *device,
                                         int event);
+static int acpi_video_device_get_state(struct acpi_video_device *device,
+                           unsigned long *state);
+static int acpi_video_output_get(struct output_device *od);
+static int acpi_video_device_set_state(struct acpi_video_device *device, int state);
 
 /*backlight device sysfs support*/
 static int acpi_video_get_brightness(struct backlight_device *bd)
 {
        unsigned long cur_level;
        struct acpi_video_device *vd =
-               (struct acpi_video_device *)class_get_devdata(&bd->class_dev);
+               (struct acpi_video_device *)bl_get_data(bd);
        acpi_video_device_lcd_get_level_current(vd, &cur_level);
        return (int) cur_level;
 }
@@ -287,7 +293,7 @@ static int acpi_video_set_brightness(struct backlight_device *bd)
 {
        int request_level = bd->props.brightness;
        struct acpi_video_device *vd =
-               (struct acpi_video_device *)class_get_devdata(&bd->class_dev);
+               (struct acpi_video_device *)bl_get_data(bd);
        acpi_video_device_lcd_set_level(vd, request_level);
        return 0;
 }
@@ -297,6 +303,28 @@ static struct backlight_ops acpi_backlight_ops = {
        .update_status  = acpi_video_set_brightness,
 };
 
+/*video output device sysfs support*/
+static int acpi_video_output_get(struct output_device *od)
+{
+       unsigned long state;
+       struct acpi_video_device *vd =
+               (struct acpi_video_device *)class_get_devdata(&od->class_dev);
+       acpi_video_device_get_state(vd, &state);
+       return (int)state;
+}
+
+static int acpi_video_output_set(struct output_device *od)
+{
+       unsigned long state = od->request_state;
+       struct acpi_video_device *vd=
+               (struct acpi_video_device *)class_get_devdata(&od->class_dev);
+       return acpi_video_device_set_state(vd, state);
+}
+
+static struct output_properties acpi_output_properties = {
+       .set_state = acpi_video_output_set,
+       .get_status = acpi_video_output_get,
+};
 /* --------------------------------------------------------------------------
                                Video Management
    -------------------------------------------------------------------------- */
@@ -531,7 +559,6 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
 
 static void acpi_video_device_find_cap(struct acpi_video_device *device)
 {
-       acpi_integer status;
        acpi_handle h_dummy1;
        int i;
        u32 max_level = 0;
@@ -565,50 +592,55 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
                device->cap._DSS = 1;
        }
 
-       status = acpi_video_device_lcd_query_levels(device, &obj);
-
-       if (obj && obj->type == ACPI_TYPE_PACKAGE && obj->package.count >= 2) {
-               int count = 0;
-               union acpi_object *o;
-
-               br = kzalloc(sizeof(*br), GFP_KERNEL);
-               if (!br) {
-                       printk(KERN_ERR "can't allocate memory\n");
-               } else {
-                       br->levels = kmalloc(obj->package.count *
-                                            sizeof *(br->levels), GFP_KERNEL);
-                       if (!br->levels)
-                               goto out;
-
-                       for (i = 0; i < obj->package.count; i++) {
-                               o = (union acpi_object *)&obj->package.
-                                   elements[i];
-                               if (o->type != ACPI_TYPE_INTEGER) {
-                                       printk(KERN_ERR PREFIX "Invalid data\n");
-                                       continue;
-                               }
-                               br->levels[count] = (u32) o->integer.value;
-                               if (br->levels[count] > max_level)
-                                       max_level = br->levels[count];
-                               count++;
-                       }
-                     out:
-                       if (count < 2) {
-                               kfree(br->levels);
-                               kfree(br);
+       if (ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
+
+               if (obj->package.count >= 2) {
+                       int count = 0;
+                       union acpi_object *o;
+
+                       br = kzalloc(sizeof(*br), GFP_KERNEL);
+                       if (!br) {
+                               printk(KERN_ERR "can't allocate memory\n");
                        } else {
-                               br->count = count;
-                               device->brightness = br;
-                               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                                 "found %d brightness levels\n",
-                                                 count));
+                               br->levels = kmalloc(obj->package.count *
+                                                    sizeof *(br->levels), GFP_KERNEL);
+                               if (!br->levels)
+                                       goto out;
+
+                               for (i = 0; i < obj->package.count; i++) {
+                                       o = (union acpi_object *)&obj->package.
+                                           elements[i];
+                                       if (o->type != ACPI_TYPE_INTEGER) {
+                                               printk(KERN_ERR PREFIX "Invalid data\n");
+                                               continue;
+                                       }
+                                       br->levels[count] = (u32) o->integer.value;
+
+                                       if (br->levels[count] > max_level)
+                                               max_level = br->levels[count];
+                                       count++;
+                               }
+                             out:
+                               if (count < 2) {
+                                       kfree(br->levels);
+                                       kfree(br);
+                               } else {
+                                       br->count = count;
+                                       device->brightness = br;
+                                       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                                                         "found %d brightness levels\n",
+                                                         count));
+                               }
                        }
                }
+
+       } else {
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available LCD brightness level\n"));
        }
 
        kfree(obj);
 
-       if (device->cap._BCL && device->cap._BCM && device->cap._BQC){
+       if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){
                unsigned long tmp;
                static int count = 0;
                char *name;
@@ -626,6 +658,17 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
 
                kfree(name);
        }
+       if (device->cap._DCS && device->cap._DSS){
+               static int count = 0;
+               char *name;
+               name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
+               if (!name)
+                       return;
+               sprintf(name, "acpi_video%d", count++);
+               device->output_dev = video_output_register(name,
+                               NULL, device, &acpi_output_properties);
+               kfree(name);
+       }
        return;
 }
 
@@ -1669,6 +1712,7 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
                                            ACPI_DEVICE_NOTIFY,
                                            acpi_video_device_notify);
        backlight_device_unregister(device->backlight);
+       video_output_unregister(device->output_dev);
        return 0;
 }
 
index a9ab30fefffc47f3f99c062823450485cd395eef..2b0c601e422e13640759aa73dffa882c8c62272d 100644 (file)
@@ -142,6 +142,7 @@ void set_trace_device(struct device *dev)
 {
        dev_hash_value = hash_string(DEVSEED, dev->bus_id, DEVHASH);
 }
+EXPORT_SYMBOL(set_trace_device);
 
 /*
  * We could just take the "tracedata" index into the .tracedata
@@ -162,6 +163,7 @@ void generate_resume_trace(void *tracedata, unsigned int user)
        file_hash_value = hash_string(lineno, file, FILEHASH);
        set_magic_time(user_hash_value, file_hash_value, dev_hash_value);
 }
+EXPORT_SYMBOL(generate_resume_trace);
 
 extern char __tracedata_start, __tracedata_end;
 static int show_file_hash(unsigned int value)
@@ -170,7 +172,8 @@ static int show_file_hash(unsigned int value)
        char *tracedata;
 
        match = 0;
-       for (tracedata = &__tracedata_start ; tracedata < &__tracedata_end ; tracedata += 6) {
+       for (tracedata = &__tracedata_start ; tracedata < &__tracedata_end ;
+                       tracedata += 2 + sizeof(unsigned long)) {
                unsigned short lineno = *(unsigned short *)tracedata;
                const char *file = *(const char **)(tracedata + 2);
                unsigned int hash = hash_string(lineno, file, FILEHASH);
index 819c829125fb9ee549c5cbf9e416db6383de67ae..a7a099027fcadec6ff29705ba5096b13eaedb2d7 100644 (file)
@@ -8,6 +8,7 @@
 obj-$(CONFIG_MAC_FLOPPY)       += swim3.o
 obj-$(CONFIG_BLK_DEV_FD)       += floppy.o
 obj-$(CONFIG_AMIGA_FLOPPY)     += amiflop.o
+obj-$(CONFIG_PS3_DISK)         += ps3disk.o
 obj-$(CONFIG_ATARI_FLOPPY)     += ataflop.o
 obj-$(CONFIG_AMIGA_Z2RAM)      += z2ram.o
 obj-$(CONFIG_BLK_DEV_RAM)      += rd.o
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
new file mode 100644 (file)
index 0000000..170fb33
--- /dev/null
@@ -0,0 +1,630 @@
+/*
+ * PS3 Disk Storage Driver
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2007 Sony Corp.
+ *
+ * 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 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/ata.h>
+#include <linux/blkdev.h>
+
+#include <asm/lv1call.h>
+#include <asm/ps3stor.h>
+#include <asm/firmware.h>
+
+
+#define DEVICE_NAME            "ps3disk"
+
+#define BOUNCE_SIZE            (64*1024)
+
+#define PS3DISK_MAX_DISKS      16
+#define PS3DISK_MINORS         16
+
+
+#define PS3DISK_NAME           "ps3d%c"
+
+
+struct ps3disk_private {
+       spinlock_t lock;                /* Request queue spinlock */
+       struct request_queue *queue;
+       struct gendisk *gendisk;
+       unsigned int blocking_factor;
+       struct request *req;
+       u64 raw_capacity;
+       unsigned char model[ATA_ID_PROD_LEN+1];
+};
+
+
+#define LV1_STORAGE_SEND_ATA_COMMAND   (2)
+#define LV1_STORAGE_ATA_HDDOUT         (0x23)
+
+struct lv1_ata_cmnd_block {
+       u16     features;
+       u16     sector_count;
+       u16     LBA_low;
+       u16     LBA_mid;
+       u16     LBA_high;
+       u8      device;
+       u8      command;
+       u32     is_ext;
+       u32     proto;
+       u32     in_out;
+       u32     size;
+       u64     buffer;
+       u32     arglen;
+};
+
+enum lv1_ata_proto {
+       NON_DATA_PROTO     = 0,
+       PIO_DATA_IN_PROTO  = 1,
+       PIO_DATA_OUT_PROTO = 2,
+       DMA_PROTO = 3
+};
+
+enum lv1_ata_in_out {
+       DIR_WRITE = 0,                  /* memory -> device */
+       DIR_READ = 1                    /* device -> memory */
+};
+
+static int ps3disk_major;
+
+
+static struct block_device_operations ps3disk_fops = {
+       .owner          = THIS_MODULE,
+};
+
+
+static void ps3disk_scatter_gather(struct ps3_storage_device *dev,
+                                  struct request *req, int gather)
+{
+       unsigned int offset = 0;
+       struct bio *bio;
+       sector_t sector;
+       struct bio_vec *bvec;
+       unsigned int i = 0, j;
+       size_t size;
+       void *buf;
+
+       rq_for_each_bio(bio, req) {
+               sector = bio->bi_sector;
+               dev_dbg(&dev->sbd.core,
+                       "%s:%u: bio %u: %u segs %u sectors from %lu\n",
+                       __func__, __LINE__, i, bio_segments(bio),
+                       bio_sectors(bio), sector);
+               bio_for_each_segment(bvec, bio, j) {
+                       size = bvec->bv_len;
+                       buf = __bio_kmap_atomic(bio, j, KM_IRQ0);
+                       if (gather)
+                               memcpy(dev->bounce_buf+offset, buf, size);
+                       else
+                               memcpy(buf, dev->bounce_buf+offset, size);
+                       offset += size;
+                       flush_kernel_dcache_page(bio_iovec_idx(bio, j)->bv_page);
+                       __bio_kunmap_atomic(bio, KM_IRQ0);
+               }
+               i++;
+       }
+}
+
+static int ps3disk_submit_request_sg(struct ps3_storage_device *dev,
+                                    struct request *req)
+{
+       struct ps3disk_private *priv = dev->sbd.core.driver_data;
+       int write = rq_data_dir(req), res;
+       const char *op = write ? "write" : "read";
+       u64 start_sector, sectors;
+       unsigned int region_id = dev->regions[dev->region_idx].id;
+
+#ifdef DEBUG
+       unsigned int n = 0;
+       struct bio *bio;
+
+       rq_for_each_bio(bio, req)
+               n++;
+       dev_dbg(&dev->sbd.core,
+               "%s:%u: %s req has %u bios for %lu sectors %lu hard sectors\n",
+               __func__, __LINE__, op, n, req->nr_sectors,
+               req->hard_nr_sectors);
+#endif
+
+       start_sector = req->sector * priv->blocking_factor;
+       sectors = req->nr_sectors * priv->blocking_factor;
+       dev_dbg(&dev->sbd.core, "%s:%u: %s %lu sectors starting at %lu\n",
+               __func__, __LINE__, op, sectors, start_sector);
+
+       if (write) {
+               ps3disk_scatter_gather(dev, req, 1);
+
+               res = lv1_storage_write(dev->sbd.dev_id, region_id,
+                                       start_sector, sectors, 0,
+                                       dev->bounce_lpar, &dev->tag);
+       } else {
+               res = lv1_storage_read(dev->sbd.dev_id, region_id,
+                                      start_sector, sectors, 0,
+                                      dev->bounce_lpar, &dev->tag);
+       }
+       if (res) {
+               dev_err(&dev->sbd.core, "%s:%u: %s failed %d\n", __func__,
+                       __LINE__, op, res);
+               end_request(req, 0);
+               return 0;
+       }
+
+       priv->req = req;
+       return 1;
+}
+
+static int ps3disk_submit_flush_request(struct ps3_storage_device *dev,
+                                       struct request *req)
+{
+       struct ps3disk_private *priv = dev->sbd.core.driver_data;
+       u64 res;
+
+       dev_dbg(&dev->sbd.core, "%s:%u: flush request\n", __func__, __LINE__);
+
+       res = lv1_storage_send_device_command(dev->sbd.dev_id,
+                                             LV1_STORAGE_ATA_HDDOUT, 0, 0, 0,
+                                             0, &dev->tag);
+       if (res) {
+               dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%lx\n",
+                       __func__, __LINE__, res);
+               end_request(req, 0);
+               return 0;
+       }
+
+       priv->req = req;
+       return 1;
+}
+
+static void ps3disk_do_request(struct ps3_storage_device *dev,
+                              request_queue_t *q)
+{
+       struct request *req;
+
+       dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
+
+       while ((req = elv_next_request(q))) {
+               if (blk_fs_request(req)) {
+                       if (ps3disk_submit_request_sg(dev, req))
+                               break;
+               } else if (req->cmd_type == REQ_TYPE_FLUSH) {
+                       if (ps3disk_submit_flush_request(dev, req))
+                               break;
+               } else {
+                       blk_dump_rq_flags(req, DEVICE_NAME " bad request");
+                       end_request(req, 0);
+                       continue;
+               }
+       }
+}
+
+static void ps3disk_request(request_queue_t *q)
+{
+       struct ps3_storage_device *dev = q->queuedata;
+       struct ps3disk_private *priv = dev->sbd.core.driver_data;
+
+       if (priv->req) {
+               dev_dbg(&dev->sbd.core, "%s:%u busy\n", __func__, __LINE__);
+               return;
+       }
+
+       ps3disk_do_request(dev, q);
+}
+
+static irqreturn_t ps3disk_interrupt(int irq, void *data)
+{
+       struct ps3_storage_device *dev = data;
+       struct ps3disk_private *priv;
+       struct request *req;
+       int res, read, uptodate;
+       u64 tag, status;
+       unsigned long num_sectors;
+       const char *op;
+
+       res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status);
+
+       if (tag != dev->tag)
+               dev_err(&dev->sbd.core,
+                       "%s:%u: tag mismatch, got %lx, expected %lx\n",
+                       __func__, __LINE__, tag, dev->tag);
+
+       if (res) {
+               dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%lx\n",
+                       __func__, __LINE__, res, status);
+               return IRQ_HANDLED;
+       }
+
+       priv = dev->sbd.core.driver_data;
+       req = priv->req;
+       if (!req) {
+               dev_dbg(&dev->sbd.core,
+                       "%s:%u non-block layer request completed\n", __func__,
+                       __LINE__);
+               dev->lv1_status = status;
+               complete(&dev->done);
+               return IRQ_HANDLED;
+       }
+
+       if (req->cmd_type == REQ_TYPE_FLUSH) {
+               read = 0;
+               num_sectors = req->hard_cur_sectors;
+               op = "flush";
+       } else {
+               read = !rq_data_dir(req);
+               num_sectors = req->nr_sectors;
+               op = read ? "read" : "write";
+       }
+       if (status) {
+               dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__,
+                       __LINE__, op, status);
+               uptodate = 0;
+       } else {
+               dev_dbg(&dev->sbd.core, "%s:%u: %s completed\n", __func__,
+                       __LINE__, op);
+               uptodate = 1;
+               if (read)
+                       ps3disk_scatter_gather(dev, req, 0);
+       }
+
+       spin_lock(&priv->lock);
+       if (!end_that_request_first(req, uptodate, num_sectors)) {
+               add_disk_randomness(req->rq_disk);
+               blkdev_dequeue_request(req);
+               end_that_request_last(req, uptodate);
+       }
+       priv->req = NULL;
+       ps3disk_do_request(dev, priv->queue);
+       spin_unlock(&priv->lock);
+
+       return IRQ_HANDLED;
+}
+
+static int ps3disk_sync_cache(struct ps3_storage_device *dev)
+{
+       u64 res;
+
+       dev_dbg(&dev->sbd.core, "%s:%u: sync cache\n", __func__, __LINE__);
+
+       res = ps3stor_send_command(dev, LV1_STORAGE_ATA_HDDOUT, 0, 0, 0, 0);
+       if (res) {
+               dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%lx\n",
+                       __func__, __LINE__, res);
+               return -EIO;
+       }
+       return 0;
+}
+
+
+/* ATA helpers copied from drivers/ata/libata-core.c */
+
+static void swap_buf_le16(u16 *buf, unsigned int buf_words)
+{
+#ifdef __BIG_ENDIAN
+       unsigned int i;
+
+       for (i = 0; i < buf_words; i++)
+               buf[i] = le16_to_cpu(buf[i]);
+#endif /* __BIG_ENDIAN */
+}
+
+static u64 ata_id_n_sectors(const u16 *id)
+{
+       if (ata_id_has_lba(id)) {
+               if (ata_id_has_lba48(id))
+                       return ata_id_u64(id, 100);
+               else
+                       return ata_id_u32(id, 60);
+       } else {
+               if (ata_id_current_chs_valid(id))
+                       return ata_id_u32(id, 57);
+               else
+                       return id[1] * id[3] * id[6];
+       }
+}
+
+static void ata_id_string(const u16 *id, unsigned char *s, unsigned int ofs,
+                         unsigned int len)
+{
+       unsigned int c;
+
+       while (len > 0) {
+               c = id[ofs] >> 8;
+               *s = c;
+               s++;
+
+               c = id[ofs] & 0xff;
+               *s = c;
+               s++;
+
+               ofs++;
+               len -= 2;
+       }
+}
+
+static void ata_id_c_string(const u16 *id, unsigned char *s, unsigned int ofs,
+                           unsigned int len)
+{
+       unsigned char *p;
+
+       WARN_ON(!(len & 1));
+
+       ata_id_string(id, s, ofs, len - 1);
+
+       p = s + strnlen(s, len - 1);
+       while (p > s && p[-1] == ' ')
+               p--;
+       *p = '\0';
+}
+
+static int ps3disk_identify(struct ps3_storage_device *dev)
+{
+       struct ps3disk_private *priv = dev->sbd.core.driver_data;
+       struct lv1_ata_cmnd_block ata_cmnd;
+       u16 *id = dev->bounce_buf;
+       u64 res;
+
+       dev_dbg(&dev->sbd.core, "%s:%u: identify disk\n", __func__, __LINE__);
+
+       memset(&ata_cmnd, 0, sizeof(struct lv1_ata_cmnd_block));
+       ata_cmnd.command = ATA_CMD_ID_ATA;
+       ata_cmnd.sector_count = 1;
+       ata_cmnd.size = ata_cmnd.arglen = ATA_ID_WORDS * 2;
+       ata_cmnd.buffer = dev->bounce_lpar;
+       ata_cmnd.proto = PIO_DATA_IN_PROTO;
+       ata_cmnd.in_out = DIR_READ;
+
+       res = ps3stor_send_command(dev, LV1_STORAGE_SEND_ATA_COMMAND,
+                                  ps3_mm_phys_to_lpar(__pa(&ata_cmnd)),
+                                  sizeof(ata_cmnd), ata_cmnd.buffer,
+                                  ata_cmnd.arglen);
+       if (res) {
+               dev_err(&dev->sbd.core, "%s:%u: identify disk failed 0x%lx\n",
+                       __func__, __LINE__, res);
+               return -EIO;
+       }
+
+       swap_buf_le16(id, ATA_ID_WORDS);
+
+       /* All we're interested in are raw capacity and model name */
+       priv->raw_capacity = ata_id_n_sectors(id);
+       ata_id_c_string(id, priv->model, ATA_ID_PROD, sizeof(priv->model));
+       return 0;
+}
+
+static void ps3disk_prepare_flush(request_queue_t *q, struct request *req)
+{
+       struct ps3_storage_device *dev = q->queuedata;
+
+       dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
+
+       memset(req->cmd, 0, sizeof(req->cmd));
+       req->cmd_type = REQ_TYPE_FLUSH;
+}
+
+static int ps3disk_issue_flush(request_queue_t *q, struct gendisk *gendisk,
+                              sector_t *sector)
+{
+       struct ps3_storage_device *dev = q->queuedata;
+       struct request *req;
+       int res;
+
+       dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
+
+       req = blk_get_request(q, WRITE, __GFP_WAIT);
+       ps3disk_prepare_flush(q, req);
+       res = blk_execute_rq(q, gendisk, req, 0);
+       if (res)
+               dev_err(&dev->sbd.core, "%s:%u: flush request failed %d\n",
+                       __func__, __LINE__, res);
+       blk_put_request(req);
+       return res;
+}
+
+
+static unsigned long ps3disk_mask;
+
+static DEFINE_MUTEX(ps3disk_mask_mutex);
+
+static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
+{
+       struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
+       struct ps3disk_private *priv;
+       int error;
+       unsigned int devidx;
+       struct request_queue *queue;
+       struct gendisk *gendisk;
+
+       if (dev->blk_size < 512) {
+               dev_err(&dev->sbd.core,
+                       "%s:%u: cannot handle block size %lu\n", __func__,
+                       __LINE__, dev->blk_size);
+               return -EINVAL;
+       }
+
+       BUILD_BUG_ON(PS3DISK_MAX_DISKS > BITS_PER_LONG);
+       mutex_lock(&ps3disk_mask_mutex);
+       devidx = find_first_zero_bit(&ps3disk_mask, PS3DISK_MAX_DISKS);
+       if (devidx >= PS3DISK_MAX_DISKS) {
+               dev_err(&dev->sbd.core, "%s:%u: Too many disks\n", __func__,
+                       __LINE__);
+               mutex_unlock(&ps3disk_mask_mutex);
+               return -ENOSPC;
+       }
+       __set_bit(devidx, &ps3disk_mask);
+       mutex_unlock(&ps3disk_mask_mutex);
+
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv) {
+               error = -ENOMEM;
+               goto fail;
+       }
+
+       dev->sbd.core.driver_data = priv;
+       spin_lock_init(&priv->lock);
+
+       dev->bounce_size = BOUNCE_SIZE;
+       dev->bounce_buf = kmalloc(BOUNCE_SIZE, GFP_DMA);
+       if (!dev->bounce_buf) {
+               error = -ENOMEM;
+               goto fail_free_priv;
+       }
+
+       error = ps3stor_setup(dev, ps3disk_interrupt);
+       if (error)
+               goto fail_free_bounce;
+
+       ps3disk_identify(dev);
+
+       queue = blk_init_queue(ps3disk_request, &priv->lock);
+       if (!queue) {
+               dev_err(&dev->sbd.core, "%s:%u: blk_init_queue failed\n",
+                       __func__, __LINE__);
+               error = -ENOMEM;
+               goto fail_teardown;
+       }
+
+       priv->queue = queue;
+       queue->queuedata = dev;
+
+       blk_queue_bounce_limit(queue, BLK_BOUNCE_HIGH);
+
+       blk_queue_max_sectors(queue, dev->bounce_size >> 9);
+       blk_queue_segment_boundary(queue, -1UL);
+       blk_queue_dma_alignment(queue, dev->blk_size-1);
+       blk_queue_hardsect_size(queue, dev->blk_size);
+
+       blk_queue_issue_flush_fn(queue, ps3disk_issue_flush);
+       blk_queue_ordered(queue, QUEUE_ORDERED_DRAIN_FLUSH,
+                         ps3disk_prepare_flush);
+
+       blk_queue_max_phys_segments(queue, -1);
+       blk_queue_max_hw_segments(queue, -1);
+       blk_queue_max_segment_size(queue, dev->bounce_size);
+
+       gendisk = alloc_disk(PS3DISK_MINORS);
+       if (!gendisk) {
+               dev_err(&dev->sbd.core, "%s:%u: alloc_disk failed\n", __func__,
+                       __LINE__);
+               error = -ENOMEM;
+               goto fail_cleanup_queue;
+       }
+
+       priv->gendisk = gendisk;
+       gendisk->major = ps3disk_major;
+       gendisk->first_minor = devidx * PS3DISK_MINORS;
+       gendisk->fops = &ps3disk_fops;
+       gendisk->queue = queue;
+       gendisk->private_data = dev;
+       gendisk->driverfs_dev = &dev->sbd.core;
+       snprintf(gendisk->disk_name, sizeof(gendisk->disk_name), PS3DISK_NAME,
+                devidx+'a');
+       priv->blocking_factor = dev->blk_size >> 9;
+       set_capacity(gendisk,
+                    dev->regions[dev->region_idx].size*priv->blocking_factor);
+
+       dev_info(&dev->sbd.core,
+                "%s is a %s (%lu MiB total, %lu MiB for OtherOS)\n",
+                gendisk->disk_name, priv->model, priv->raw_capacity >> 11,
+                get_capacity(gendisk) >> 11);
+
+       add_disk(gendisk);
+       return 0;
+
+fail_cleanup_queue:
+       blk_cleanup_queue(queue);
+fail_teardown:
+       ps3stor_teardown(dev);
+fail_free_bounce:
+       kfree(dev->bounce_buf);
+fail_free_priv:
+       kfree(priv);
+       dev->sbd.core.driver_data = NULL;
+fail:
+       mutex_lock(&ps3disk_mask_mutex);
+       __clear_bit(devidx, &ps3disk_mask);
+       mutex_unlock(&ps3disk_mask_mutex);
+       return error;
+}
+
+static int ps3disk_remove(struct ps3_system_bus_device *_dev)
+{
+       struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
+       struct ps3disk_private *priv = dev->sbd.core.driver_data;
+
+       mutex_lock(&ps3disk_mask_mutex);
+       __clear_bit(priv->gendisk->first_minor / PS3DISK_MINORS,
+                   &ps3disk_mask);
+       mutex_unlock(&ps3disk_mask_mutex);
+       del_gendisk(priv->gendisk);
+       blk_cleanup_queue(priv->queue);
+       put_disk(priv->gendisk);
+       dev_notice(&dev->sbd.core, "Synchronizing disk cache\n");
+       ps3disk_sync_cache(dev);
+       ps3stor_teardown(dev);
+       kfree(dev->bounce_buf);
+       kfree(priv);
+       dev->sbd.core.driver_data = NULL;
+       return 0;
+}
+
+static struct ps3_system_bus_driver ps3disk = {
+       .match_id       = PS3_MATCH_ID_STOR_DISK,
+       .core.name      = DEVICE_NAME,
+       .core.owner     = THIS_MODULE,
+       .probe          = ps3disk_probe,
+       .remove         = ps3disk_remove,
+       .shutdown       = ps3disk_remove,
+};
+
+
+static int __init ps3disk_init(void)
+{
+       int error;
+
+       if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
+               return -ENODEV;
+
+       error = register_blkdev(0, DEVICE_NAME);
+       if (error <= 0) {
+               printk(KERN_ERR "%s:%u: register_blkdev failed %d\n", __func__,
+                      __LINE__, error);
+               return error;
+       }
+       ps3disk_major = error;
+
+       pr_info("%s:%u: registered block device major %d\n", __func__,
+               __LINE__, ps3disk_major);
+
+       error = ps3_system_bus_driver_register(&ps3disk);
+       if (error)
+               unregister_blkdev(ps3disk_major, DEVICE_NAME);
+
+       return error;
+}
+
+static void __exit ps3disk_exit(void)
+{
+       ps3_system_bus_driver_unregister(&ps3disk);
+       unregister_blkdev(ps3disk_major, DEVICE_NAME);
+}
+
+module_init(ps3disk_init);
+module_exit(ps3disk_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("PS3 Disk Storage Driver");
+MODULE_AUTHOR("Sony Corporation");
+MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_DISK);
index 4e6f387fd18909d1cf0bba7f4d1ed4e22a30c7b5..8fecaf4010b1dafefd06445086d8a671373abbeb 100644 (file)
@@ -107,6 +107,8 @@ obj-$(CONFIG_IPMI_HANDLER)  += ipmi/
 obj-$(CONFIG_HANGCHECK_TIMER)  += hangcheck-timer.o
 obj-$(CONFIG_TCG_TPM)          += tpm/
 
+obj-$(CONFIG_PS3_FLASH)                += ps3flash.o
+
 # Files generated that shall be removed upon make clean
 clean-files := consolemap_deftbl.c defkeymap.c
 
index b37f1d5a5be6e19e9604e80b36988573f500d58f..a08f8f981c11c8446176e8e588c0d917562dfcfb 100644 (file)
@@ -472,7 +472,7 @@ static void hvc_handle_event(struct HvLpEvent *event)
        }
 }
 
-static int send_open(HvLpIndex remoteLp, void *sem)
+static int __init send_open(HvLpIndex remoteLp, void *sem)
 {
        return HvCallEvent_signalLpEventFast(remoteLp,
                        HvLpEvent_Type_VirtualIo,
@@ -484,7 +484,7 @@ static int send_open(HvLpIndex remoteLp, void *sem)
                        0, 0, 0, 0);
 }
 
-static int hvc_vio_init(void)
+static int __init hvc_vio_init(void)
 {
        atomic_t wait_flag;
        int rc;
@@ -552,14 +552,14 @@ static int hvc_vio_init(void)
 }
 module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */
 
-static void hvc_vio_exit(void)
+static void __exit hvc_vio_exit(void)
 {
        vio_unregister_driver(&hvc_vio_driver);
 }
 module_exit(hvc_vio_exit);
 
 /* the device tree order defines our numbering */
-static int hvc_find_vtys(void)
+static int __init hvc_find_vtys(void)
 {
        struct device_node *vty;
        int num_found = 0;
index 4b97eaf18602cbb4f139d5691c24e5a4aa5b1d71..bb09413d5a21ed5d09db2b1185c50141553ab0da 100644 (file)
@@ -115,7 +115,7 @@ static void __exit hvc_rtas_exit(void)
 module_exit(hvc_rtas_exit);
 
 /* This will happen prior to module init.  There is no tty at this time? */
-static int hvc_rtas_console_init(void)
+static int __init hvc_rtas_console_init(void)
 {
        rtascons_put_char_token = rtas_token("put-term-char");
        if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE)
index 17f96e04266fbbb5192c64ea717d50dedd8efcc1..69d8866de783f36a70ff38d63d4b47d9f0688385 100644 (file)
@@ -210,9 +210,9 @@ static struct ktermios hvcs_tty_termios = {
 static int hvcs_parm_num_devs = -1;
 module_param(hvcs_parm_num_devs, int, 0);
 
-char hvcs_driver_name[] = "hvcs";
-char hvcs_device_node[] = "hvcs";
-char hvcs_driver_string[]
+static const char hvcs_driver_name[] = "hvcs";
+static const char hvcs_device_node[] = "hvcs";
+static const char hvcs_driver_string[]
        = "IBM hvcs (Hypervisor Virtual Console Server) Driver";
 
 /* Status of partner info rescan triggered via sysfs. */
@@ -1092,7 +1092,7 @@ static int hvcs_enable_device(struct hvcs_struct *hvcsd, uint32_t unit_address,
  * NOTICE: Do NOT hold either the hvcs_struct.lock or hvcs_structs_lock when
  * calling this function or you will get deadlock.
  */
-struct hvcs_struct *hvcs_get_by_index(int index)
+static struct hvcs_struct *hvcs_get_by_index(int index)
 {
        struct hvcs_struct *hvcsd = NULL;
        unsigned long flags;
index 7cda04b335343aeb52e94b7007c38a3e3fae0c35..2d7cd486e025b45015868f2a5e51f61f36e48ed0 100644 (file)
@@ -41,7 +41,7 @@ config HW_RANDOM_AMD
 
 config HW_RANDOM_GEODE
        tristate "AMD Geode HW Random Number Generator support"
-       depends on HW_RANDOM && X86 && PCI
+       depends on HW_RANDOM && X86_32 && PCI
        default HW_RANDOM
        ---help---
          This driver provides kernel-side support for the Random Number
diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
new file mode 100644 (file)
index 0000000..79b6f46
--- /dev/null
@@ -0,0 +1,440 @@
+/*
+ * PS3 FLASH ROM Storage Driver
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2007 Sony Corp.
+ *
+ * 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 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+
+#include <asm/lv1call.h>
+#include <asm/ps3stor.h>
+
+
+#define DEVICE_NAME            "ps3flash"
+
+#define FLASH_BLOCK_SIZE       (256*1024)
+
+
+struct ps3flash_private {
+       struct mutex mutex;     /* Bounce buffer mutex */
+};
+
+static struct ps3_storage_device *ps3flash_dev;
+
+static ssize_t ps3flash_read_write_sectors(struct ps3_storage_device *dev,
+                                          u64 lpar, u64 start_sector,
+                                          u64 sectors, int write)
+{
+       u64 res = ps3stor_read_write_sectors(dev, lpar, start_sector, sectors,
+                                            write);
+       if (res) {
+               dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__,
+                       __LINE__, write ? "write" : "read", res);
+               return -EIO;
+       }
+       return sectors;
+}
+
+static ssize_t ps3flash_read_sectors(struct ps3_storage_device *dev,
+                                    u64 start_sector, u64 sectors,
+                                    unsigned int sector_offset)
+{
+       u64 max_sectors, lpar;
+
+       max_sectors = dev->bounce_size / dev->blk_size;
+       if (sectors > max_sectors) {
+               dev_dbg(&dev->sbd.core, "%s:%u Limiting sectors to %lu\n",
+                       __func__, __LINE__, max_sectors);
+               sectors = max_sectors;
+       }
+
+       lpar = dev->bounce_lpar + sector_offset * dev->blk_size;
+       return ps3flash_read_write_sectors(dev, lpar, start_sector, sectors,
+                                          0);
+}
+
+static ssize_t ps3flash_write_chunk(struct ps3_storage_device *dev,
+                                   u64 start_sector)
+{
+       u64 sectors = dev->bounce_size / dev->blk_size;
+       return ps3flash_read_write_sectors(dev, dev->bounce_lpar, start_sector,
+                                         sectors, 1);
+}
+
+static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin)
+{
+       struct ps3_storage_device *dev = ps3flash_dev;
+       loff_t res;
+
+       mutex_lock(&file->f_mapping->host->i_mutex);
+       switch (origin) {
+       case 1:
+               offset += file->f_pos;
+               break;
+       case 2:
+               offset += dev->regions[dev->region_idx].size*dev->blk_size;
+               break;
+       }
+       if (offset < 0) {
+               res = -EINVAL;
+               goto out;
+       }
+
+       file->f_pos = offset;
+       res = file->f_pos;
+
+out:
+       mutex_unlock(&file->f_mapping->host->i_mutex);
+       return res;
+}
+
+static ssize_t ps3flash_read(struct file *file, char __user *buf, size_t count,
+                            loff_t *pos)
+{
+       struct ps3_storage_device *dev = ps3flash_dev;
+       struct ps3flash_private *priv = dev->sbd.core.driver_data;
+       u64 size, start_sector, end_sector, offset;
+       ssize_t sectors_read;
+       size_t remaining, n;
+
+       dev_dbg(&dev->sbd.core,
+               "%s:%u: Reading %zu bytes at position %lld to user 0x%p\n",
+               __func__, __LINE__, count, *pos, buf);
+
+       size = dev->regions[dev->region_idx].size*dev->blk_size;
+       if (*pos >= size || !count)
+               return 0;
+
+       if (*pos + count > size) {
+               dev_dbg(&dev->sbd.core,
+                       "%s:%u Truncating count from %zu to %llu\n", __func__,
+                       __LINE__, count, size - *pos);
+               count = size - *pos;
+       }
+
+       start_sector = *pos / dev->blk_size;
+       offset = *pos % dev->blk_size;
+       end_sector = DIV_ROUND_UP(*pos + count, dev->blk_size);
+
+       remaining = count;
+       do {
+               mutex_lock(&priv->mutex);
+
+               sectors_read = ps3flash_read_sectors(dev, start_sector,
+                                                    end_sector-start_sector,
+                                                    0);
+               if (sectors_read < 0) {
+                       mutex_unlock(&priv->mutex);
+                       goto fail;
+               }
+
+               n = min(remaining, sectors_read*dev->blk_size-offset);
+               dev_dbg(&dev->sbd.core,
+                       "%s:%u: copy %lu bytes from 0x%p to user 0x%p\n",
+                       __func__, __LINE__, n, dev->bounce_buf+offset, buf);
+               if (copy_to_user(buf, dev->bounce_buf+offset, n)) {
+                       mutex_unlock(&priv->mutex);
+                       sectors_read = -EFAULT;
+                       goto fail;
+               }
+
+               mutex_unlock(&priv->mutex);
+
+               *pos += n;
+               buf += n;
+               remaining -= n;
+               start_sector += sectors_read;
+               offset = 0;
+       } while (remaining > 0);
+
+       return count;
+
+fail:
+       return sectors_read;
+}
+
+static ssize_t ps3flash_write(struct file *file, const char __user *buf,
+                             size_t count, loff_t *pos)
+{
+       struct ps3_storage_device *dev = ps3flash_dev;
+       struct ps3flash_private *priv = dev->sbd.core.driver_data;
+       u64 size, chunk_sectors, start_write_sector, end_write_sector,
+           end_read_sector, start_read_sector, head, tail, offset;
+       ssize_t res;
+       size_t remaining, n;
+       unsigned int sec_off;
+
+       dev_dbg(&dev->sbd.core,
+               "%s:%u: Writing %zu bytes at position %lld from user 0x%p\n",
+               __func__, __LINE__, count, *pos, buf);
+
+       size = dev->regions[dev->region_idx].size*dev->blk_size;
+       if (*pos >= size || !count)
+               return 0;
+
+       if (*pos + count > size) {
+               dev_dbg(&dev->sbd.core,
+                       "%s:%u Truncating count from %zu to %llu\n", __func__,
+                       __LINE__, count, size - *pos);
+               count = size - *pos;
+       }
+
+       chunk_sectors = dev->bounce_size / dev->blk_size;
+
+       start_write_sector = *pos / dev->bounce_size * chunk_sectors;
+       offset = *pos % dev->bounce_size;
+       end_write_sector = DIV_ROUND_UP(*pos + count, dev->bounce_size) *
+                          chunk_sectors;
+
+       end_read_sector = DIV_ROUND_UP(*pos, dev->blk_size);
+       start_read_sector = (*pos + count) / dev->blk_size;
+
+       /*
+        * As we have to write in 256 KiB chunks, while we can read in blk_size
+        * (usually 512 bytes) chunks, we perform the following steps:
+        *   1. Read from start_write_sector to end_read_sector ("head")
+        *   2. Read from start_read_sector to end_write_sector ("tail")
+        *   3. Copy data to buffer
+        *   4. Write from start_write_sector to end_write_sector
+        * All of this is complicated by using only one 256 KiB bounce buffer.
+        */
+
+       head = end_read_sector - start_write_sector;
+       tail = end_write_sector - start_read_sector;
+
+       remaining = count;
+       do {
+               mutex_lock(&priv->mutex);
+
+               if (end_read_sector >= start_read_sector) {
+                       /* Merge head and tail */
+                       dev_dbg(&dev->sbd.core,
+                               "Merged head and tail: %lu sectors at %lu\n",
+                               chunk_sectors, start_write_sector);
+                       res = ps3flash_read_sectors(dev, start_write_sector,
+                                                   chunk_sectors, 0);
+                       if (res < 0)
+                               goto fail;
+               } else {
+                       if (head) {
+                               /* Read head */
+                               dev_dbg(&dev->sbd.core,
+                                       "head: %lu sectors at %lu\n", head,
+                                       start_write_sector);
+                               res = ps3flash_read_sectors(dev,
+                                                           start_write_sector,
+                                                           head, 0);
+                               if (res < 0)
+                                       goto fail;
+                       }
+                       if (start_read_sector <
+                           start_write_sector+chunk_sectors) {
+                               /* Read tail */
+                               dev_dbg(&dev->sbd.core,
+                                       "tail: %lu sectors at %lu\n", tail,
+                                       start_read_sector);
+                               sec_off = start_read_sector-start_write_sector;
+                               res = ps3flash_read_sectors(dev,
+                                                           start_read_sector,
+                                                           tail, sec_off);
+                               if (res < 0)
+                                       goto fail;
+                       }
+               }
+
+               n = min(remaining, dev->bounce_size-offset);
+               dev_dbg(&dev->sbd.core,
+                       "%s:%u: copy %lu bytes from user 0x%p to 0x%p\n",
+                       __func__, __LINE__, n, buf, dev->bounce_buf+offset);
+               if (copy_from_user(dev->bounce_buf+offset, buf, n)) {
+                       res = -EFAULT;
+                       goto fail;
+               }
+
+               res = ps3flash_write_chunk(dev, start_write_sector);
+               if (res < 0)
+                       goto fail;
+
+               mutex_unlock(&priv->mutex);
+
+               *pos += n;
+               buf += n;
+               remaining -= n;
+               start_write_sector += chunk_sectors;
+               head = 0;
+               offset = 0;
+       } while (remaining > 0);
+
+       return count;
+
+fail:
+       mutex_unlock(&priv->mutex);
+       return res;
+}
+
+
+static irqreturn_t ps3flash_interrupt(int irq, void *data)
+{
+       struct ps3_storage_device *dev = data;
+       int res;
+       u64 tag, status;
+
+       res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status);
+
+       if (tag != dev->tag)
+               dev_err(&dev->sbd.core,
+                       "%s:%u: tag mismatch, got %lx, expected %lx\n",
+                       __func__, __LINE__, tag, dev->tag);
+
+       if (res) {
+               dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%lx\n",
+                       __func__, __LINE__, res, status);
+       } else {
+               dev->lv1_status = status;
+               complete(&dev->done);
+       }
+       return IRQ_HANDLED;
+}
+
+
+static const struct file_operations ps3flash_fops = {
+       .owner  = THIS_MODULE,
+       .llseek = ps3flash_llseek,
+       .read   = ps3flash_read,
+       .write  = ps3flash_write,
+};
+
+static struct miscdevice ps3flash_misc = {
+       .minor  = MISC_DYNAMIC_MINOR,
+       .name   = DEVICE_NAME,
+       .fops   = &ps3flash_fops,
+};
+
+static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev)
+{
+       struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
+       struct ps3flash_private *priv;
+       int error;
+       unsigned long tmp;
+
+       tmp = dev->regions[dev->region_idx].start*dev->blk_size;
+       if (tmp % FLASH_BLOCK_SIZE) {
+               dev_err(&dev->sbd.core,
+                       "%s:%u region start %lu is not aligned\n", __func__,
+                       __LINE__, tmp);
+               return -EINVAL;
+       }
+       tmp = dev->regions[dev->region_idx].size*dev->blk_size;
+       if (tmp % FLASH_BLOCK_SIZE) {
+               dev_err(&dev->sbd.core,
+                       "%s:%u region size %lu is not aligned\n", __func__,
+                       __LINE__, tmp);
+               return -EINVAL;
+       }
+
+       /* use static buffer, kmalloc cannot allocate 256 KiB */
+       if (!ps3flash_bounce_buffer.address)
+               return -ENODEV;
+
+       if (ps3flash_dev) {
+               dev_err(&dev->sbd.core,
+                       "Only one FLASH device is supported\n");
+               return -EBUSY;
+       }
+
+       ps3flash_dev = dev;
+
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv) {
+               error = -ENOMEM;
+               goto fail;
+       }
+
+       dev->sbd.core.driver_data = priv;
+       mutex_init(&priv->mutex);
+
+       dev->bounce_size = ps3flash_bounce_buffer.size;
+       dev->bounce_buf = ps3flash_bounce_buffer.address;
+
+       error = ps3stor_setup(dev, ps3flash_interrupt);
+       if (error)
+               goto fail_free_priv;
+
+       ps3flash_misc.parent = &dev->sbd.core;
+       error = misc_register(&ps3flash_misc);
+       if (error) {
+               dev_err(&dev->sbd.core, "%s:%u: misc_register failed %d\n",
+                       __func__, __LINE__, error);
+               goto fail_teardown;
+       }
+
+       dev_info(&dev->sbd.core, "%s:%u: registered misc device %d\n",
+                __func__, __LINE__, ps3flash_misc.minor);
+       return 0;
+
+fail_teardown:
+       ps3stor_teardown(dev);
+fail_free_priv:
+       kfree(priv);
+       dev->sbd.core.driver_data = NULL;
+fail:
+       ps3flash_dev = NULL;
+       return error;
+}
+
+static int ps3flash_remove(struct ps3_system_bus_device *_dev)
+{
+       struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
+
+       misc_deregister(&ps3flash_misc);
+       ps3stor_teardown(dev);
+       kfree(dev->sbd.core.driver_data);
+       dev->sbd.core.driver_data = NULL;
+       ps3flash_dev = NULL;
+       return 0;
+}
+
+
+static struct ps3_system_bus_driver ps3flash = {
+       .match_id       = PS3_MATCH_ID_STOR_FLASH,
+       .core.name      = DEVICE_NAME,
+       .core.owner     = THIS_MODULE,
+       .probe          = ps3flash_probe,
+       .remove         = ps3flash_remove,
+       .shutdown       = ps3flash_remove,
+};
+
+
+static int __init ps3flash_init(void)
+{
+       return ps3_system_bus_driver_register(&ps3flash);
+}
+
+static void __exit ps3flash_exit(void)
+{
+       ps3_system_bus_driver_unregister(&ps3flash);
+}
+
+module_init(ps3flash_init);
+module_exit(ps3flash_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("PS3 FLASH ROM Storage Driver");
+MODULE_AUTHOR("Sony Corporation");
+MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_FLASH);
index 30c3f54c7666ee5f7e666ec38ff125acfd0f2eeb..ec6b65ec69ea6f1726e400667c2462c5af7d5028 100644 (file)
@@ -82,7 +82,7 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
-#if defined(__i386__)
+#ifdef CONFIG_X86
 #include <asm/hpet.h>
 #endif
 
index ad5cc5f6862fdff08746a91d5068dad490124c8b..16fb23125e96acdab10d128adda7181830fd93ea 100644 (file)
@@ -187,6 +187,22 @@ config PNX4008_WATCHDOG
 
          Say N if you are unsure.
 
+config IOP_WATCHDOG
+       tristate "IOP Watchdog"
+       depends on WATCHDOG && PLAT_IOP
+       select WATCHDOG_NOWAYOUT if (ARCH_IOP32X || ARCH_IOP33X)
+       help
+         Say Y here if to include support for the watchdog timer
+         in the Intel IOP3XX & IOP13XX I/O Processors.  This driver can
+         be built as a module by choosing M. The module will
+         be called iop_wdt.
+
+         Note: The IOP13XX watchdog does an Internal Bus Reset which will
+         affect both cores and the peripherals of the IOP.  The ATU-X
+         and/or ATUe configuration registers will remain intact, but if
+         operating as an Root Complex and/or Central Resource, the PCI-X
+         and/or PCIe busses will also be reset.  THIS IS A VERY BIG HAMMER.
+
 # AVR32 Architecture
 
 config AT32AP700X_WDT
index 3907ec04a4e5f2ce729b90ac732eaa7c83ec9aec..bdb9d5e3bb41ece30f7924cc70adc3ca42518b71 100644 (file)
@@ -35,6 +35,7 @@ obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
 obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o
 obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o
 obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o
+obj-$(CONFIG_IOP_WATCHDOG) += iop_wdt.o
 
 # AVR32 Architecture
 obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
diff --git a/drivers/char/watchdog/iop_wdt.c b/drivers/char/watchdog/iop_wdt.c
new file mode 100644 (file)
index 0000000..bbbd91a
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * drivers/char/watchdog/iop_wdt.c
+ *
+ * WDT driver for Intel I/O Processors
+ * Copyright (C) 2005, Intel Corporation.
+ *
+ * Based on ixp4xx driver, Copyright 2004 (c) MontaVista, Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ *     Curt E Bruns <curt.e.bruns@intel.com>
+ *     Peter Milne <peter.milne@d-tacq.com>
+ *     Dan Williams <dan.j.williams@intel.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/uaccess.h>
+#include <asm/hardware.h>
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+static unsigned long wdt_status;
+static unsigned long boot_status;
+
+#define WDT_IN_USE             0
+#define WDT_OK_TO_CLOSE                1
+#define WDT_ENABLED            2
+
+static unsigned long iop_watchdog_timeout(void)
+{
+       return (0xffffffffUL / get_iop_tick_rate());
+}
+
+/**
+ * wdt_supports_disable - determine if we are accessing a iop13xx watchdog
+ * or iop3xx by whether it has a disable command
+ */
+static int wdt_supports_disable(void)
+{
+       int can_disable;
+
+       if (IOP_WDTCR_EN_ARM != IOP_WDTCR_DIS_ARM)
+               can_disable = 1;
+       else
+               can_disable = 0;
+
+       return can_disable;
+}
+
+static void wdt_enable(void)
+{
+       /* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF
+        * Takes approx. 10.7s to timeout
+        */
+       write_wdtcr(IOP_WDTCR_EN_ARM);
+       write_wdtcr(IOP_WDTCR_EN);
+}
+
+/* returns 0 if the timer was successfully disabled */
+static int wdt_disable(void)
+{
+       /* Stop Counting */
+       if (wdt_supports_disable()) {
+               write_wdtcr(IOP_WDTCR_DIS_ARM);
+               write_wdtcr(IOP_WDTCR_DIS);
+               clear_bit(WDT_ENABLED, &wdt_status);
+               printk(KERN_INFO "WATCHDOG: Disabled\n");
+               return 0;
+       } else
+               return 1;
+}
+
+static int iop_wdt_open(struct inode *inode, struct file *file)
+{
+       if (test_and_set_bit(WDT_IN_USE, &wdt_status))
+               return -EBUSY;
+
+       clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+       wdt_enable();
+
+       set_bit(WDT_ENABLED, &wdt_status);
+
+       return nonseekable_open(inode, file);
+}
+
+static ssize_t
+iop_wdt_write(struct file *file, const char *data, size_t len,
+                 loff_t *ppos)
+{
+       if (len) {
+               if (!nowayout) {
+                       size_t i;
+
+                       clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+                       for (i = 0; i != len; i++) {
+                               char c;
+
+                               if (get_user(c, data + i))
+                                       return -EFAULT;
+                               if (c == 'V')
+                                       set_bit(WDT_OK_TO_CLOSE, &wdt_status);
+                       }
+               }
+               wdt_enable();
+       }
+
+       return len;
+}
+
+static struct watchdog_info ident = {
+       .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
+       .identity = "iop watchdog",
+};
+
+static int
+iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+                 unsigned long arg)
+{
+       int options;
+       int ret = -ENOTTY;
+
+       switch (cmd) {
+       case WDIOC_GETSUPPORT:
+               if (copy_to_user
+                   ((struct watchdog_info *)arg, &ident, sizeof ident))
+                       ret = -EFAULT;
+               else
+                       ret = 0;
+               break;
+
+       case WDIOC_GETSTATUS:
+               ret = put_user(0, (int *)arg);
+               break;
+
+       case WDIOC_GETBOOTSTATUS:
+               ret = put_user(boot_status, (int *)arg);
+               break;
+
+       case WDIOC_GETTIMEOUT:
+               ret = put_user(iop_watchdog_timeout(), (int *)arg);
+               break;
+
+       case WDIOC_KEEPALIVE:
+               wdt_enable();
+               ret = 0;
+               break;
+
+       case WDIOC_SETOPTIONS:
+               if (get_user(options, (int *)arg))
+                       return -EFAULT;
+
+               if (options & WDIOS_DISABLECARD) {
+                       if (!nowayout) {
+                               if (wdt_disable() == 0) {
+                                       set_bit(WDT_OK_TO_CLOSE, &wdt_status);
+                                       ret = 0;
+                               } else
+                                       ret = -ENXIO;
+                       } else
+                               ret = 0;
+               }
+
+               if (options & WDIOS_ENABLECARD) {
+                       wdt_enable();
+                       ret = 0;
+               }
+               break;
+       }
+
+       return ret;
+}
+
+static int iop_wdt_release(struct inode *inode, struct file *file)
+{
+       int state = 1;
+       if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
+               if (test_bit(WDT_ENABLED, &wdt_status))
+                       state = wdt_disable();
+
+       /* if the timer is not disbaled reload and notify that we are still
+        * going down
+        */
+       if (state != 0) {
+               wdt_enable();
+               printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
+                      "reset in %lu seconds\n", iop_watchdog_timeout());
+       }
+
+       clear_bit(WDT_IN_USE, &wdt_status);
+       clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+       return 0;
+}
+
+static const struct file_operations iop_wdt_fops = {
+       .owner = THIS_MODULE,
+       .llseek = no_llseek,
+       .write = iop_wdt_write,
+       .ioctl = iop_wdt_ioctl,
+       .open = iop_wdt_open,
+       .release = iop_wdt_release,
+};
+
+static struct miscdevice iop_wdt_miscdev = {
+       .minor = WATCHDOG_MINOR,
+       .name = "watchdog",
+       .fops = &iop_wdt_fops,
+};
+
+static int __init iop_wdt_init(void)
+{
+       int ret;
+
+       ret = misc_register(&iop_wdt_miscdev);
+       if (ret == 0)
+               printk("iop watchdog timer: timeout %lu sec\n",
+                      iop_watchdog_timeout());
+
+       /* check if the reset was caused by the watchdog timer */
+       boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0;
+
+       /* Configure Watchdog Timeout to cause an Internal Bus (IB) Reset
+        * NOTE: An IB Reset will Reset both cores in the IOP342
+        */
+       write_wdtsr(IOP13XX_WDTCR_IB_RESET);
+
+       return ret;
+}
+
+static void __exit iop_wdt_exit(void)
+{
+       misc_deregister(&iop_wdt_miscdev);
+}
+
+module_init(iop_wdt_init);
+module_exit(iop_wdt_exit);
+
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
+
+MODULE_AUTHOR("Curt E Bruns <curt.e.bruns@intel.com>");
+MODULE_DESCRIPTION("iop watchdog timer driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
index e783dbf0f162fe736339366b6afea4af55ea6cc0..7b46faf22318c31f57072e73ae711d86afc7ba45 100644 (file)
@@ -71,7 +71,7 @@ static struct clocksource clocksource_acpi_pm = {
        .rating         = 200,
        .read           = acpi_pm_read,
        .mask           = (cycle_t)ACPI_PM_MASK,
-       .mult           = 0, /*to be caluclated*/
+       .mult           = 0, /*to be calculated*/
        .shift          = 22,
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 
index fc984474162c3c493cc78c06f9fe43a3071e634e..3e4a369d0057f4679dff2dcf23acedb4123ec454 100644 (file)
@@ -1160,7 +1160,7 @@ static struct device_attribute *sbp2_scsi_sysfs_attrs[] = {
 static struct scsi_host_template scsi_driver_template = {
        .module                 = THIS_MODULE,
        .name                   = "SBP-2 IEEE-1394",
-       .proc_name              = (char *)sbp2_driver_name,
+       .proc_name              = sbp2_driver_name,
        .queuecommand           = sbp2_scsi_queuecommand,
        .slave_alloc            = sbp2_scsi_slave_alloc,
        .slave_configure        = sbp2_scsi_slave_configure,
index 31989dcd922c58a09bd07619e9f6dd7abe5702ae..906bf5e8de89c568f243a7656fc82a3e93d8319c 100644 (file)
@@ -24,7 +24,12 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("PC Speaker beeper driver");
 MODULE_LICENSE("GPL");
 
-static DEFINE_SPINLOCK(i8253_beep_lock);
+#ifdef CONFIG_X86
+/* Use the global PIT lock ! */
+#include <asm/i8253.h>
+#else
+static DEFINE_SPINLOCK(i8253_lock);
+#endif
 
 static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
@@ -43,7 +48,7 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c
        if (value > 20 && value < 32767)
                count = PIT_TICK_RATE / value;
 
-       spin_lock_irqsave(&i8253_beep_lock, flags);
+       spin_lock_irqsave(&i8253_lock, flags);
 
        if (count) {
                /* enable counter 2 */
@@ -58,7 +63,7 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c
                outb(inb_p(0x61) & 0xFC, 0x61);
        }
 
-       spin_unlock_irqrestore(&i8253_beep_lock, flags);
+       spin_unlock_irqrestore(&i8253_lock, flags);
 
        return 0;
 }
index cf906c8cee4d3d8dae54c3b28ef7ec2ad80f8e99..66f946aa30b3fb0830b8a858e0ef91d9a47cfd73 100644 (file)
@@ -21,9 +21,7 @@ menuconfig ISDN
 
 if ISDN
 
-menu "Old ISDN4Linux"
-
-config ISDN_I4L
+menuconfig ISDN_I4L
        tristate "Old ISDN4Linux (deprecated)"
        ---help---
          This driver allows you to use an ISDN adapter for networking
@@ -45,12 +43,8 @@ if ISDN_I4L
 source "drivers/isdn/i4l/Kconfig"
 endif
 
-endmenu
-
-comment "CAPI subsystem"
-
-config ISDN_CAPI
-       tristate "CAPI2.0 support"
+menuconfig ISDN_CAPI
+       tristate "CAPI 2.0 subsystem"
        help
          This provides the CAPI (Common ISDN Application Programming
          Interface, a standard making it easy for programs to access ISDN
index 78e6ad8d57c5e7f8818b8dfac66ac29a7717afb2..3fc1a5434ef7a35b9f10d0a71079cc49ff2f4637 100644 (file)
@@ -3,7 +3,7 @@
 #
 config ISDN_DRV_ACT2000
        tristate "IBM Active 2000 support"
-       depends on ISDN_I4L && ISA
+       depends on ISA
        help
          Say Y here if you have an IBM Active 2000 ISDN card. In order to use
          this card, additional firmware is necessary, which has to be loaded
index bcbb6502a773da59d181e30255e48663318f8076..0017e50c6948d853438dc7fe1d80353693d6bf2f 100644 (file)
@@ -1,9 +1,5 @@
-menu "Siemens Gigaset"
-       depends on ISDN_I4L
-
-config ISDN_DRV_GIGASET
+menuconfig ISDN_DRV_GIGASET
        tristate "Siemens Gigaset support (isdn)"
-       depends on ISDN_I4L
        select CRC_CCITT
        select BITREVERSE
        help
@@ -55,6 +51,4 @@ config GIGASET_UNDOCREQ
          features like configuration mode of M105, say yes. If you
          care about your device, say no.
 
-endif
-
-endmenu
+endif # ISDN_DRV_GIGASET != n
index 12d91fb9f8cb9503d72bcb09adcd51ebe804fe11..a3b945ac32565be264096637b88901e1f6bfc0fe 100644 (file)
@@ -1,6 +1,5 @@
 
 menu "Passive cards"
-       depends on ISDN_I4L
 
 config ISDN_DRV_HISAX
        tristate "HiSax SiemensChipSet driver support"
index e91c187992dd0bafd74e31a00da0ce74c8154bd2..36778b270c303aa0a8ae57c4feb85966a3ebee92 100644 (file)
@@ -99,7 +99,6 @@ config ISDN_DRV_LOOP
 
 config ISDN_DIVERSION
        tristate "Support isdn diversion services"
-       depends on ISDN_I4L
        help
          This option allows you to use some supplementary diversion
          services in conjunction with the HiSax driver on an EURO/DSS1
@@ -119,13 +118,11 @@ config ISDN_DIVERSION
 endmenu
 
 comment "ISDN4Linux hardware drivers"
-       depends on ISDN_I4L
 
 source "drivers/isdn/hisax/Kconfig"
 
 
 menu "Active cards"
-       depends on ISDN_I4L!=n
 
 source "drivers/isdn/icn/Kconfig"
 
index fcb99f5f0b26a854f1dffcc054d92742764c5791..89d15eed765e2dde7a433972db459421c1657c3e 100644 (file)
@@ -3,7 +3,7 @@
 #
 config ISDN_DRV_ICN
        tristate "ICN 2B and 4B support"
-       depends on ISDN_I4L && ISA
+       depends on ISA
        help
          This enables support for two kinds of ISDN-cards made by a German
          company called ICN.  2B is the standard version for a single ISDN
index 0933881ab0c263f903985a7973cd6b17a3974e2a..ffba6eca1244f9b6ae01dc09853510cbdec0fbbe 100644 (file)
@@ -3,7 +3,7 @@
 #
 config ISDN_DRV_PCBIT
        tristate "PCBIT-D support"
-       depends on ISDN_I4L && ISA && (BROKEN || X86)
+       depends on ISA && (BROKEN || X86)
        help
          This enables support for the PCBIT ISDN-card.  This card is
          manufactured in Portugal by Octal.  For running this card,
index 5346e33d816cfdee9d1b48e36f52bfd7b23f59d0..e6510ca7bf4376fcccc85c93dbb17ba7f12a0dae 100644 (file)
@@ -3,7 +3,7 @@
 #
 config ISDN_DRV_SC
        tristate "Spellcaster support"
-       depends on ISDN_I4L && ISA
+       depends on ISA
        help
          This enables support for the Spellcaster BRI ISDN boards.  This
          driver currently builds only in a modularized version.
index 2f661e5f0dae67f37209879e34bbf50546d4486b..6cecc396e04064e6ca8f91ca766e02ea8842783e 100644 (file)
@@ -11,6 +11,7 @@ if VIRTUALIZATION
 config KVM
        tristate "Kernel-based Virtual Machine (KVM) support"
        depends on X86 && EXPERIMENTAL
+       select ANON_INODES
        ---help---
          Support hosting fully virtualized guest machines using hardware
          virtualization extensions.  You will need a fairly recent
index d99d2fe53dcaa2f081ef714cf1130e41f1434657..1a87ba9d515620986e079d64fd83ff546054a9b7 100644 (file)
@@ -244,7 +244,7 @@ static int mmu_topup_memory_cache_page(struct kvm_mmu_memory_cache *cache,
 static void mmu_free_memory_cache_page(struct kvm_mmu_memory_cache *mc)
 {
        while (mc->nobjs)
-               __free_page(mc->objects[--mc->nobjs]);
+               free_page((unsigned long)mc->objects[--mc->nobjs]);
 }
 
 static int __mmu_topup_memory_caches(struct kvm_vcpu *vcpu, gfp_t gfp_flags)
index 87d2046f866caa29b7e1b8f541b640789be3ec63..4468cb3a8d24fde7c2d0acfdd50d4f0c9d5acf91 100644 (file)
@@ -1,9 +1,6 @@
-
-menu "LED devices"
-       depends on HAS_IOMEM
-
-config NEW_LEDS
+menuconfig NEW_LEDS
        bool "LED Support"
+       depends on HAS_IOMEM
        help
          Say Y to enable Linux LED support.  This allows control of supported
          LEDs from both userspace and optionally, by kernel events (triggers).
@@ -11,9 +8,10 @@ config NEW_LEDS
          This is not related to standard keyboard LEDs which are controlled
          via the input system.
 
+if NEW_LEDS
+
 config LEDS_CLASS
        tristate "LED Class Support"
-       depends on NEW_LEDS
        help
          This option enables the led sysfs class in /sys/class/leds.  You'll
          need this to do anything useful with LEDs.  If unsure, say N.
@@ -95,11 +93,18 @@ config LEDS_COBALT
        help
          This option enables support for the front LED on Cobalt Server
 
+config LEDS_GPIO
+       tristate "LED Support for GPIO connected LEDs"
+       depends on LEDS_CLASS && GENERIC_GPIO
+       help
+         This option enables support for the LEDs connected to GPIO
+         outputs. To be useful the particular board must have LEDs
+         and they must be connected to the GPIO lines.
+
 comment "LED Triggers"
 
 config LEDS_TRIGGERS
        bool "LED Trigger support"
-       depends on NEW_LEDS
        help
          This option enables trigger support for the leds class.
          These triggers allow kernel events to drive the LEDs and can
@@ -128,5 +133,4 @@ config LEDS_TRIGGER_HEARTBEAT
          load average.
          If unsure, say Y.
 
-endmenu
-
+endif # NEW_LEDS
index aa2c18efa5b2f150dffbfbf81a96669bb9d4fb45..f8995c9bc2eaae764ff4212d596f2e460546ade4 100644 (file)
@@ -16,6 +16,7 @@ obj-$(CONFIG_LEDS_NET48XX)            += leds-net48xx.o
 obj-$(CONFIG_LEDS_WRAP)                        += leds-wrap.o
 obj-$(CONFIG_LEDS_H1940)               += leds-h1940.o
 obj-$(CONFIG_LEDS_COBALT)              += leds-cobalt.o
+obj-$(CONFIG_LEDS_GPIO)                        += leds-gpio.o
 
 # LED Triggers
 obj-$(CONFIG_LEDS_TRIGGER_TIMER)       += ledtrig-timer.o
index 3c1711210e38a375f7ec1064c6bd59aeb7d74206..4211293ce862d00e87fa05167f87f53f44b8cbc8 100644 (file)
@@ -2,7 +2,7 @@
  * LED Class Core
  *
  * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu>
- * Copyright (C) 2005-2006 Richard Purdie <rpurdie@openedhand.com>
+ * Copyright (C) 2005-2007 Richard Purdie <rpurdie@openedhand.com>
  *
  * 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
 
 static struct class *leds_class;
 
-static ssize_t led_brightness_show(struct class_device *dev, char *buf)
+static ssize_t led_brightness_show(struct device *dev, 
+               struct device_attribute *attr, char *buf)
 {
-       struct led_classdev *led_cdev = class_get_devdata(dev);
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
        ssize_t ret = 0;
 
        /* no lock needed for this */
@@ -36,10 +37,10 @@ static ssize_t led_brightness_show(struct class_device *dev, char *buf)
        return ret;
 }
 
-static ssize_t led_brightness_store(struct class_device *dev,
-                               const char *buf, size_t size)
+static ssize_t led_brightness_store(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t size)
 {
-       struct led_classdev *led_cdev = class_get_devdata(dev);
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
        ssize_t ret = -EINVAL;
        char *after;
        unsigned long state = simple_strtoul(buf, &after, 10);
@@ -56,10 +57,9 @@ static ssize_t led_brightness_store(struct class_device *dev,
        return ret;
 }
 
-static CLASS_DEVICE_ATTR(brightness, 0644, led_brightness_show,
-                       led_brightness_store);
+static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store);
 #ifdef CONFIG_LEDS_TRIGGERS
-static CLASS_DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
+static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
 #endif
 
 /**
@@ -93,16 +93,15 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
 {
        int rc;
 
-       led_cdev->class_dev = class_device_create(leds_class, NULL, 0,
-                                               parent, "%s", led_cdev->name);
-       if (unlikely(IS_ERR(led_cdev->class_dev)))
-               return PTR_ERR(led_cdev->class_dev);
+       led_cdev->dev = device_create(leds_class, parent, 0, "%s",
+                                           led_cdev->name);
+       if (unlikely(IS_ERR(led_cdev->dev)))
+               return PTR_ERR(led_cdev->dev);
 
-       class_set_devdata(led_cdev->class_dev, led_cdev);
+       dev_set_drvdata(led_cdev->dev, led_cdev);
 
        /* register the attributes */
-       rc = class_device_create_file(led_cdev->class_dev,
-                                     &class_device_attr_brightness);
+       rc = device_create_file(led_cdev->dev, &dev_attr_brightness);
        if (rc)
                goto err_out;
 
@@ -114,8 +113,7 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
 #ifdef CONFIG_LEDS_TRIGGERS
        rwlock_init(&led_cdev->trigger_lock);
 
-       rc = class_device_create_file(led_cdev->class_dev,
-                                     &class_device_attr_trigger);
+       rc = device_create_file(led_cdev->dev, &dev_attr_trigger);
        if (rc)
                goto err_out_led_list;
 
@@ -123,18 +121,17 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
 #endif
 
        printk(KERN_INFO "Registered led device: %s\n",
-                       led_cdev->class_dev->class_id);
+                       led_cdev->name);
 
        return 0;
 
 #ifdef CONFIG_LEDS_TRIGGERS
 err_out_led_list:
-       class_device_remove_file(led_cdev->class_dev,
-                               &class_device_attr_brightness);
+       device_remove_file(led_cdev->dev, &dev_attr_brightness);
        list_del(&led_cdev->node);
 #endif
 err_out:
-       class_device_unregister(led_cdev->class_dev);
+       device_unregister(led_cdev->dev);
        return rc;
 }
 EXPORT_SYMBOL_GPL(led_classdev_register);
@@ -147,18 +144,16 @@ EXPORT_SYMBOL_GPL(led_classdev_register);
  */
 void led_classdev_unregister(struct led_classdev *led_cdev)
 {
-       class_device_remove_file(led_cdev->class_dev,
-                               &class_device_attr_brightness);
+       device_remove_file(led_cdev->dev, &dev_attr_brightness);
 #ifdef CONFIG_LEDS_TRIGGERS
-       class_device_remove_file(led_cdev->class_dev,
-                               &class_device_attr_trigger);
+       device_remove_file(led_cdev->dev, &dev_attr_trigger);
        write_lock(&led_cdev->trigger_lock);
        if (led_cdev->trigger)
                led_trigger_set(led_cdev, NULL);
        write_unlock(&led_cdev->trigger_lock);
 #endif
 
-       class_device_unregister(led_cdev->class_dev);
+       device_unregister(led_cdev->dev);
 
        write_lock(&leds_list_lock);
        list_del(&led_cdev->node);
index 454fb0901f8211dc31ec6b86e6edac5bec774286..575368c2b100985830e157851305bb4b56a07dd5 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * LED Triggers Core
  *
- * Copyright 2005-2006 Openedhand Ltd.
+ * Copyright 2005-2007 Openedhand Ltd.
  *
  * Author: Richard Purdie <rpurdie@openedhand.com>
  *
 static DEFINE_RWLOCK(triggers_list_lock);
 static LIST_HEAD(trigger_list);
 
-ssize_t led_trigger_store(struct class_device *dev, const char *buf,
-                       size_t count)
+ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t count)
 {
-       struct led_classdev *led_cdev = class_get_devdata(dev);
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
        char trigger_name[TRIG_NAME_MAX];
        struct led_trigger *trig;
        size_t len;
@@ -67,9 +67,10 @@ ssize_t led_trigger_store(struct class_device *dev, const char *buf,
 }
 
 
-ssize_t led_trigger_show(struct class_device *dev, char *buf)
+ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr,
+               char *buf)
 {
-       struct led_classdev *led_cdev = class_get_devdata(dev);
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
        struct led_trigger *trig;
        int len = 0;
 
@@ -183,13 +184,20 @@ int led_trigger_register(struct led_trigger *trigger)
 void led_trigger_register_simple(const char *name, struct led_trigger **tp)
 {
        struct led_trigger *trigger;
+       int err;
 
        trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
 
        if (trigger) {
                trigger->name = name;
-               led_trigger_register(trigger);
-       }
+               err = led_trigger_register(trigger);
+               if (err < 0)
+                       printk(KERN_WARNING "LED trigger %s failed to register"
+                               " (%d)\n", name, err);
+       } else
+               printk(KERN_WARNING "LED trigger %s failed to register"
+                       " (no memory)\n", name);
+
        *tp = trigger;
 }
 
@@ -215,7 +223,8 @@ void led_trigger_unregister(struct led_trigger *trigger)
 
 void led_trigger_unregister_simple(struct led_trigger *trigger)
 {
-       led_trigger_unregister(trigger);
+       if (trigger)
+               led_trigger_unregister(trigger);
        kfree(trigger);
 }
 
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
new file mode 100644 (file)
index 0000000..47d90db
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * LEDs driver for GPIOs
+ *
+ * Copyright (C) 2007 8D Technologies inc.
+ * Raphael Assenat <raph@8d.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/workqueue.h>
+
+#include <asm/gpio.h>
+
+struct gpio_led_data {
+       struct led_classdev cdev;
+       unsigned gpio;
+       struct work_struct work;
+       u8 new_level;
+       u8 can_sleep;
+       u8 active_low;
+};
+
+static void gpio_led_work(struct work_struct *work)
+{
+       struct gpio_led_data    *led_dat =
+               container_of(work, struct gpio_led_data, work);
+
+       gpio_set_value_cansleep(led_dat->gpio, led_dat->new_level);
+}
+
+static void gpio_led_set(struct led_classdev *led_cdev,
+       enum led_brightness value)
+{
+       struct gpio_led_data *led_dat =
+               container_of(led_cdev, struct gpio_led_data, cdev);
+       int level;
+
+       if (value == LED_OFF)
+               level = 0;
+       else
+               level = 1;
+
+       if (led_dat->active_low)
+               level = !level;
+
+       /* setting GPIOs with I2C/etc requires a preemptible task context */
+       if (led_dat->can_sleep) {
+               if (preempt_count()) {
+                       led_dat->new_level = level;
+                       schedule_work(&led_dat->work);
+               } else
+                       gpio_set_value_cansleep(led_dat->gpio, level);
+       } else
+               gpio_set_value(led_dat->gpio, level);
+}
+
+static int __init gpio_led_probe(struct platform_device *pdev)
+{
+       struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
+       struct gpio_led *cur_led;
+       struct gpio_led_data *leds_data, *led_dat;
+       int i, ret = 0;
+
+       if (!pdata)
+               return -EBUSY;
+
+       leds_data = kzalloc(sizeof(struct gpio_led_data) * pdata->num_leds,
+                               GFP_KERNEL);
+       if (!leds_data)
+               return -ENOMEM;
+
+       for (i = 0; i < pdata->num_leds; i++) {
+               cur_led = &pdata->leds[i];
+               led_dat = &leds_data[i];
+
+               led_dat->cdev.name = cur_led->name;
+               led_dat->cdev.default_trigger = cur_led->default_trigger;
+               led_dat->gpio = cur_led->gpio;
+               led_dat->can_sleep = gpio_cansleep(cur_led->gpio);
+               led_dat->active_low = cur_led->active_low;
+               led_dat->cdev.brightness_set = gpio_led_set;
+               led_dat->cdev.brightness = cur_led->active_low ? LED_FULL : LED_OFF;
+
+               ret = gpio_request(led_dat->gpio, led_dat->cdev.name);
+               if (ret < 0)
+                       goto err;
+
+               gpio_direction_output(led_dat->gpio, led_dat->active_low);
+
+               ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
+               if (ret < 0) {
+                       gpio_free(led_dat->gpio);
+                       goto err;
+               }
+
+               INIT_WORK(&led_dat->work, gpio_led_work);
+       }
+
+       platform_set_drvdata(pdev, leds_data);
+
+       return 0;
+
+err:
+       if (i > 0) {
+               for (i = i - 1; i >= 0; i--) {
+                       led_classdev_unregister(&leds_data[i].cdev);
+                       gpio_free(leds_data[i].gpio);
+               }
+       }
+
+       flush_scheduled_work();
+       kfree(leds_data);
+
+       return ret;
+}
+
+static int __exit gpio_led_remove(struct platform_device *pdev)
+{
+       int i;
+       struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
+       struct gpio_led_data *leds_data;
+
+       leds_data = platform_get_drvdata(pdev);
+
+       for (i = 0; i < pdata->num_leds; i++) {
+               led_classdev_unregister(&leds_data[i].cdev);
+               gpio_free(leds_data[i].gpio);
+       }
+       
+       kfree(leds_data);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int gpio_led_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
+       struct gpio_led_data *leds_data;
+       int i;
+       
+       leds_data = platform_get_drvdata(pdev);
+
+       for (i = 0; i < pdata->num_leds; i++)
+               led_classdev_suspend(&leds_data[i].cdev);
+
+       return 0;
+}
+
+static int gpio_led_resume(struct platform_device *pdev)
+{
+       struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
+       struct gpio_led_data *leds_data;
+       int i;
+
+       leds_data = platform_get_drvdata(pdev);
+
+       for (i = 0; i < pdata->num_leds; i++)
+               led_classdev_resume(&leds_data[i].cdev);
+
+       return 0;
+}
+#else
+#define gpio_led_suspend NULL
+#define gpio_led_resume NULL
+#endif
+
+static struct platform_driver gpio_led_driver = {
+       .remove         = __exit_p(gpio_led_remove),
+       .suspend        = gpio_led_suspend,
+       .resume         = gpio_led_resume,
+       .driver         = {
+               .name   = "leds-gpio",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init gpio_led_init(void)
+{
+       return platform_driver_probe(&gpio_led_driver, gpio_led_probe);
+}
+
+static void __exit gpio_led_exit(void)
+{
+       platform_driver_unregister(&gpio_led_driver);
+}
+
+module_init(gpio_led_init);
+module_exit(gpio_led_exit);
+
+MODULE_AUTHOR("Raphael Assenat <raph@8d.com>");
+MODULE_DESCRIPTION("GPIO LED driver");
+MODULE_LICENSE("GPL");
index 6f2d449ba9836096b97fea92a4ff4cd8bcc46649..bfac499f3258f74fd2c96267c7e9b9a5361a72bf 100644 (file)
@@ -19,7 +19,7 @@
 static void locomoled_brightness_set(struct led_classdev *led_cdev,
                                enum led_brightness value, int offset)
 {
-       struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->class_dev->dev);
+       struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev);
        unsigned long flags;
 
        local_irq_save(flags);
index a715c4ed93ff0b9cb9f6a219e723ac2d75bbb3f8..f2f3884fe06314b01a3bb647821c6b4e0ea88e89 100644 (file)
@@ -13,6 +13,7 @@
 #ifndef __LEDS_H_INCLUDED
 #define __LEDS_H_INCLUDED
 
+#include <linux/device.h>
 #include <linux/leds.h>
 
 static inline void led_set_brightness(struct led_classdev *led_cdev,
@@ -37,8 +38,9 @@ void led_trigger_set(struct led_classdev *led_cdev,
 #define led_trigger_set(x, y) do {} while(0)
 #endif
 
-ssize_t led_trigger_store(struct class_device *dev, const char *buf,
-                       size_t count);
-ssize_t led_trigger_show(struct class_device *dev, char *buf);
+ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr,
+                       const char *buf, size_t count);
+ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr,
+                       char *buf);
 
 #endif /* __LEDS_H_INCLUDED */
index d756bdb01c59ab33eeb261d251bddecd45367f89..ed9ff02c77ea742c23c616a0f340c400770c33ec 100644 (file)
@@ -52,9 +52,10 @@ static void led_timer_function(unsigned long data)
        mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay));
 }
 
-static ssize_t led_delay_on_show(struct class_device *dev, char *buf)
+static ssize_t led_delay_on_show(struct device *dev, 
+               struct device_attribute *attr, char *buf)
 {
-       struct led_classdev *led_cdev = class_get_devdata(dev);
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
        struct timer_trig_data *timer_data = led_cdev->trigger_data;
 
        sprintf(buf, "%lu\n", timer_data->delay_on);
@@ -62,10 +63,10 @@ static ssize_t led_delay_on_show(struct class_device *dev, char *buf)
        return strlen(buf) + 1;
 }
 
-static ssize_t led_delay_on_store(struct class_device *dev, const char *buf,
-                               size_t size)
+static ssize_t led_delay_on_store(struct device *dev, 
+               struct device_attribute *attr, const char *buf, size_t size)
 {
-       struct led_classdev *led_cdev = class_get_devdata(dev);
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
        struct timer_trig_data *timer_data = led_cdev->trigger_data;
        int ret = -EINVAL;
        char *after;
@@ -84,9 +85,10 @@ static ssize_t led_delay_on_store(struct class_device *dev, const char *buf,
        return ret;
 }
 
-static ssize_t led_delay_off_show(struct class_device *dev, char *buf)
+static ssize_t led_delay_off_show(struct device *dev, 
+               struct device_attribute *attr, char *buf)
 {
-       struct led_classdev *led_cdev = class_get_devdata(dev);
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
        struct timer_trig_data *timer_data = led_cdev->trigger_data;
 
        sprintf(buf, "%lu\n", timer_data->delay_off);
@@ -94,10 +96,10 @@ static ssize_t led_delay_off_show(struct class_device *dev, char *buf)
        return strlen(buf) + 1;
 }
 
-static ssize_t led_delay_off_store(struct class_device *dev, const char *buf,
-                               size_t size)
+static ssize_t led_delay_off_store(struct device *dev, 
+               struct device_attribute *attr, const char *buf, size_t size)
 {
-       struct led_classdev *led_cdev = class_get_devdata(dev);
+       struct led_classdev *led_cdev = dev_get_drvdata(dev);
        struct timer_trig_data *timer_data = led_cdev->trigger_data;
        int ret = -EINVAL;
        char *after;
@@ -116,10 +118,8 @@ static ssize_t led_delay_off_store(struct class_device *dev, const char *buf,
        return ret;
 }
 
-static CLASS_DEVICE_ATTR(delay_on, 0644, led_delay_on_show,
-                       led_delay_on_store);
-static CLASS_DEVICE_ATTR(delay_off, 0644, led_delay_off_show,
-                       led_delay_off_store);
+static DEVICE_ATTR(delay_on, 0644, led_delay_on_show, led_delay_on_store);
+static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store);
 
 static void timer_trig_activate(struct led_classdev *led_cdev)
 {
@@ -136,18 +136,17 @@ static void timer_trig_activate(struct led_classdev *led_cdev)
        timer_data->timer.function = led_timer_function;
        timer_data->timer.data = (unsigned long) led_cdev;
 
-       rc = class_device_create_file(led_cdev->class_dev,
-                               &class_device_attr_delay_on);
-       if (rc) goto err_out;
-       rc = class_device_create_file(led_cdev->class_dev,
-                               &class_device_attr_delay_off);
-       if (rc) goto err_out_delayon;
+       rc = device_create_file(led_cdev->dev, &dev_attr_delay_on);
+       if (rc)
+               goto err_out;
+       rc = device_create_file(led_cdev->dev, &dev_attr_delay_off);
+       if (rc)
+               goto err_out_delayon;
 
        return;
 
 err_out_delayon:
-       class_device_remove_file(led_cdev->class_dev,
-                               &class_device_attr_delay_on);
+       device_remove_file(led_cdev->dev, &dev_attr_delay_on);
 err_out:
        led_cdev->trigger_data = NULL;
        kfree(timer_data);
@@ -158,10 +157,8 @@ static void timer_trig_deactivate(struct led_classdev *led_cdev)
        struct timer_trig_data *timer_data = led_cdev->trigger_data;
 
        if (timer_data) {
-               class_device_remove_file(led_cdev->class_dev,
-                                       &class_device_attr_delay_on);
-               class_device_remove_file(led_cdev->class_dev,
-                                       &class_device_attr_delay_off);
+               device_remove_file(led_cdev->dev, &dev_attr_delay_on);
+               device_remove_file(led_cdev->dev, &dev_attr_delay_off);
                del_timer_sync(&timer_data->timer);
                kfree(timer_data);
        }
index 434fea1e82f7626dc7933bfe9668d4a788fd395d..18dade06d4a9e8b92c2a2499dd74981c68b5d9c3 100644 (file)
@@ -398,6 +398,8 @@ static void lguest_clockevent_set_mode(enum clock_event_mode mode,
                break;
        case CLOCK_EVT_MODE_PERIODIC:
                BUG();
+       case CLOCK_EVT_MODE_RESUME:
+               break;
        }
 }
 
index 4177ff004753299152a4d79471b784184eb7efdb..2c21d4f25cc82e85ab138aca5e4490f4166865f3 100644 (file)
@@ -30,7 +30,6 @@
 #include <asm/machdep.h>
 #include <asm/pmac_feature.h>
 #include <asm/dbdma.h>
-#include <asm/dbdma.h>
 #include <asm/macio.h>
 #include <asm/keylargo.h>
 
index ba952a032598c2411bb3f7ff793f6d00baec92bc..bdc52d6922b7d998f27068cce53ededb302f0b09 100644 (file)
@@ -920,6 +920,8 @@ static void crypt_dtr(struct dm_target *ti)
 {
        struct crypt_config *cc = (struct crypt_config *) ti->private;
 
+       flush_workqueue(_kcryptd_workqueue);
+
        bioset_free(cc->bs);
        mempool_destroy(cc->page_pool);
        mempool_destroy(cc->io_pool);
index c88cc75ab49b7e807f30da88de8e4bf0bf776aba..4494e0fd36c623088858fd5c0f61bb14f050d41d 100644 (file)
@@ -37,6 +37,7 @@ config FUSION_FC
          LSIFC929
          LSIFC929X
          LSIFC929XL
+         Brocade FC 410/420
 
 config FUSION_SAS
        tristate "Fusion MPT ScsiHost drivers for SAS"
index 5a10c87239c22f0a57072d5b351859ad81236f4f..04f75e24dcecb2cd513a1275df597ed914ea7676 100644 (file)
@@ -161,6 +161,7 @@ static int  mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
 static void    mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
 static void    mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
 static void    mpt_timer_expired(unsigned long data);
+static void    mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
 static int     SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
 static int     SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
 static int     mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
@@ -1131,6 +1132,248 @@ mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
        return -1;
 }
 
+/**
+ *     mpt_get_product_name - returns product string
+ *     @vendor: pci vendor id
+ *     @device: pci device id
+ *     @revision: pci revision id
+ *     @prod_name: string returned
+ *
+ *     Returns product string displayed when driver loads,
+ *     in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
+ *
+ **/
+static void
+mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
+{
+       char *product_str = NULL;
+
+       if (vendor == PCI_VENDOR_ID_BROCADE) {
+               switch (device)
+               {
+               case MPI_MANUFACTPAGE_DEVICEID_FC949E:
+                       switch (revision)
+                       {
+                       case 0x00:
+                               product_str = "BRE040 A0";
+                               break;
+                       case 0x01:
+                               product_str = "BRE040 A1";
+                               break;
+                       default:
+                               product_str = "BRE040";
+                               break;
+                       }
+                       break;
+               }
+               goto out;
+       }
+
+       switch (device)
+       {
+       case MPI_MANUFACTPAGE_DEVICEID_FC909:
+               product_str = "LSIFC909 B1";
+               break;
+       case MPI_MANUFACTPAGE_DEVICEID_FC919:
+               product_str = "LSIFC919 B0";
+               break;
+       case MPI_MANUFACTPAGE_DEVICEID_FC929:
+               product_str = "LSIFC929 B0";
+               break;
+       case MPI_MANUFACTPAGE_DEVICEID_FC919X:
+               if (revision < 0x80)
+                       product_str = "LSIFC919X A0";
+               else
+                       product_str = "LSIFC919XL A1";
+               break;
+       case MPI_MANUFACTPAGE_DEVICEID_FC929X:
+               if (revision < 0x80)
+                       product_str = "LSIFC929X A0";
+               else
+                       product_str = "LSIFC929XL A1";
+               break;
+       case MPI_MANUFACTPAGE_DEVICEID_FC939X:
+               product_str = "LSIFC939X A1";
+               break;
+       case MPI_MANUFACTPAGE_DEVICEID_FC949X:
+               product_str = "LSIFC949X A1";
+               break;
+       case MPI_MANUFACTPAGE_DEVICEID_FC949E:
+               switch (revision)
+               {
+               case 0x00:
+                       product_str = "LSIFC949E A0";
+                       break;
+               case 0x01:
+                       product_str = "LSIFC949E A1";
+                       break;
+               default:
+                       product_str = "LSIFC949E";
+                       break;
+               }
+               break;
+       case MPI_MANUFACTPAGE_DEVID_53C1030:
+               switch (revision)
+               {
+               case 0x00:
+                       product_str = "LSI53C1030 A0";
+                       break;
+               case 0x01:
+                       product_str = "LSI53C1030 B0";
+                       break;
+               case 0x03:
+                       product_str = "LSI53C1030 B1";
+                       break;
+               case 0x07:
+                       product_str = "LSI53C1030 B2";
+                       break;
+               case 0x08:
+                       product_str = "LSI53C1030 C0";
+                       break;
+               case 0x80:
+                       product_str = "LSI53C1030T A0";
+                       break;
+               case 0x83:
+                       product_str = "LSI53C1030T A2";
+                       break;
+               case 0x87:
+                       product_str = "LSI53C1030T A3";
+                       break;
+               case 0xc1:
+                       product_str = "LSI53C1020A A1";
+                       break;
+               default:
+                       product_str = "LSI53C1030";
+                       break;
+               }
+               break;
+       case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
+               switch (revision)
+               {
+               case 0x03:
+                       product_str = "LSI53C1035 A2";
+                       break;
+               case 0x04:
+                       product_str = "LSI53C1035 B0";
+                       break;
+               default:
+                       product_str = "LSI53C1035";
+                       break;
+               }
+               break;
+       case MPI_MANUFACTPAGE_DEVID_SAS1064:
+               switch (revision)
+               {
+               case 0x00:
+                       product_str = "LSISAS1064 A1";
+                       break;
+               case 0x01:
+                       product_str = "LSISAS1064 A2";
+                       break;
+               case 0x02:
+                       product_str = "LSISAS1064 A3";
+                       break;
+               case 0x03:
+                       product_str = "LSISAS1064 A4";
+                       break;
+               default:
+                       product_str = "LSISAS1064";
+                       break;
+               }
+               break;
+       case MPI_MANUFACTPAGE_DEVID_SAS1064E:
+               switch (revision)
+               {
+               case 0x00:
+                       product_str = "LSISAS1064E A0";
+                       break;
+               case 0x01:
+                       product_str = "LSISAS1064E B0";
+                       break;
+               case 0x02:
+                       product_str = "LSISAS1064E B1";
+                       break;
+               case 0x04:
+                       product_str = "LSISAS1064E B2";
+                       break;
+               case 0x08:
+                       product_str = "LSISAS1064E B3";
+                       break;
+               default:
+                       product_str = "LSISAS1064E";
+                       break;
+               }
+               break;
+       case MPI_MANUFACTPAGE_DEVID_SAS1068:
+               switch (revision)
+               {
+               case 0x00:
+                       product_str = "LSISAS1068 A0";
+                       break;
+               case 0x01:
+                       product_str = "LSISAS1068 B0";
+                       break;
+               case 0x02:
+                       product_str = "LSISAS1068 B1";
+                       break;
+               default:
+                       product_str = "LSISAS1068";
+                       break;
+               }
+               break;
+       case MPI_MANUFACTPAGE_DEVID_SAS1068E:
+               switch (revision)
+               {
+               case 0x00:
+                       product_str = "LSISAS1068E A0";
+                       break;
+               case 0x01:
+                       product_str = "LSISAS1068E B0";
+                       break;
+               case 0x02:
+                       product_str = "LSISAS1068E B1";
+                       break;
+               case 0x04:
+                       product_str = "LSISAS1068E B2";
+                       break;
+               case 0x08:
+                       product_str = "LSISAS1068E B3";
+                       break;
+               default:
+                       product_str = "LSISAS1068E";
+                       break;
+               }
+               break;
+       case MPI_MANUFACTPAGE_DEVID_SAS1078:
+               switch (revision)
+               {
+               case 0x00:
+                       product_str = "LSISAS1078 A0";
+                       break;
+               case 0x01:
+                       product_str = "LSISAS1078 B0";
+                       break;
+               case 0x02:
+                       product_str = "LSISAS1078 C0";
+                       break;
+               case 0x03:
+                       product_str = "LSISAS1078 C1";
+                       break;
+               case 0x04:
+                       product_str = "LSISAS1078 C2";
+                       break;
+               default:
+                       product_str = "LSISAS1078";
+                       break;
+               }
+               break;
+       }
+
+ out:
+       if (product_str)
+               sprintf(prod_name, "%s", product_str);
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *     mpt_attach - Install a PCI intelligent MPT adapter.
@@ -1274,23 +1517,23 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
                ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
        }
 
-       if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
-               ioc->prod_name = "LSIFC909";
-               ioc->bus_type = FC;
-       }
-       else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
-               ioc->prod_name = "LSIFC929";
-               ioc->bus_type = FC;
-       }
-       else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
-               ioc->prod_name = "LSIFC919";
-               ioc->bus_type = FC;
-       }
-       else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
-               pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
+       pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
+       mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
+
+       switch (pdev->device)
+       {
+       case MPI_MANUFACTPAGE_DEVICEID_FC939X:
+       case MPI_MANUFACTPAGE_DEVICEID_FC949X:
+               ioc->errata_flag_1064 = 1;
+       case MPI_MANUFACTPAGE_DEVICEID_FC909:
+       case MPI_MANUFACTPAGE_DEVICEID_FC929:
+       case MPI_MANUFACTPAGE_DEVICEID_FC919:
+       case MPI_MANUFACTPAGE_DEVICEID_FC949E:
                ioc->bus_type = FC;
+               break;
+
+       case MPI_MANUFACTPAGE_DEVICEID_FC929X:
                if (revision < XL_929) {
-                       ioc->prod_name = "LSIFC929X";
                        /* 929X Chip Fix. Set Split transactions level
                        * for PCIX. Set MOST bits to zero.
                        */
@@ -1298,75 +1541,46 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
                        pcixcmd &= 0x8F;
                        pci_write_config_byte(pdev, 0x6a, pcixcmd);
                } else {
-                       ioc->prod_name = "LSIFC929XL";
                        /* 929XL Chip Fix. Set MMRBC to 0x08.
                        */
                        pci_read_config_byte(pdev, 0x6a, &pcixcmd);
                        pcixcmd |= 0x08;
                        pci_write_config_byte(pdev, 0x6a, pcixcmd);
                }
-       }
-       else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
-               ioc->prod_name = "LSIFC919X";
                ioc->bus_type = FC;
+               break;
+
+       case MPI_MANUFACTPAGE_DEVICEID_FC919X:
                /* 919X Chip Fix. Set Split transactions level
                 * for PCIX. Set MOST bits to zero.
                 */
                pci_read_config_byte(pdev, 0x6a, &pcixcmd);
                pcixcmd &= 0x8F;
                pci_write_config_byte(pdev, 0x6a, pcixcmd);
-       }
-       else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC939X) {
-               ioc->prod_name = "LSIFC939X";
-               ioc->bus_type = FC;
-               ioc->errata_flag_1064 = 1;
-       }
-       else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) {
-               ioc->prod_name = "LSIFC949X";
                ioc->bus_type = FC;
-               ioc->errata_flag_1064 = 1;
-       }
-       else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949E) {
-               ioc->prod_name = "LSIFC949E";
-               ioc->bus_type = FC;
-       }
-       else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
-               ioc->prod_name = "LSI53C1030";
-               ioc->bus_type = SPI;
+               break;
+
+       case MPI_MANUFACTPAGE_DEVID_53C1030:
                /* 1030 Chip Fix. Disable Split transactions
                 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
                 */
-               pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
                if (revision < C0_1030) {
                        pci_read_config_byte(pdev, 0x6a, &pcixcmd);
                        pcixcmd &= 0x8F;
                        pci_write_config_byte(pdev, 0x6a, pcixcmd);
                }
-       }
-       else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
-               ioc->prod_name = "LSI53C1035";
+
+       case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
                ioc->bus_type = SPI;
-       }
-       else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
-               ioc->prod_name = "LSISAS1064";
-               ioc->bus_type = SAS;
-               ioc->errata_flag_1064 = 1;
-       }
-       else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
-               ioc->prod_name = "LSISAS1068";
-               ioc->bus_type = SAS;
+               break;
+
+       case MPI_MANUFACTPAGE_DEVID_SAS1064:
+       case MPI_MANUFACTPAGE_DEVID_SAS1068:
                ioc->errata_flag_1064 = 1;
-       }
-       else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
-               ioc->prod_name = "LSISAS1064E";
-               ioc->bus_type = SAS;
-       }
-       else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
-               ioc->prod_name = "LSISAS1068E";
-               ioc->bus_type = SAS;
-       }
-       else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
-               ioc->prod_name = "LSISAS1078";
+
+       case MPI_MANUFACTPAGE_DEVID_SAS1064E:
+       case MPI_MANUFACTPAGE_DEVID_SAS1068E:
+       case MPI_MANUFACTPAGE_DEVID_SAS1078:
                ioc->bus_type = SAS;
        }
 
@@ -1880,6 +2094,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
                }
 
                GetIoUnitPage2(ioc);
+               mpt_get_manufacturing_pg_0(ioc);
        }
 
        /*
@@ -2138,8 +2353,8 @@ MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
        int i = 0;
 
        printk(KERN_INFO "%s: ", ioc->name);
-       if (ioc->prod_name && strlen(ioc->prod_name) > 3)
-               printk("%s: ", ioc->prod_name+3);
+       if (ioc->prod_name)
+               printk("%s: ", ioc->prod_name);
        printk("Capabilities={");
 
        if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
@@ -5190,6 +5405,49 @@ mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
        return;
 }
 
+static void
+mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
+{
+       CONFIGPARMS             cfg;
+       ConfigPageHeader_t      hdr;
+       dma_addr_t              buf_dma;
+       ManufacturingPage0_t    *pbuf = NULL;
+
+       memset(&cfg, 0 , sizeof(CONFIGPARMS));
+       memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
+
+       hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
+       cfg.cfghdr.hdr = &hdr;
+       cfg.physAddr = -1;
+       cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+       cfg.timeout = 10;
+
+       if (mpt_config(ioc, &cfg) != 0)
+               goto out;
+
+       if (!cfg.cfghdr.hdr->PageLength)
+               goto out;
+
+       cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+       pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
+       if (!pbuf)
+               goto out;
+
+       cfg.physAddr = buf_dma;
+
+       if (mpt_config(ioc, &cfg) != 0)
+               goto out;
+
+       memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
+       memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
+       memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
+
+       out:
+
+       if (pbuf)
+               pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *     SendEventNotification - Send EventNotification (on or off) request to adapter
index 05eb6e52875335213531a02fdd25ee483a636af0..98eb9c688e1794b3e8264016d2cf23ef4836128d 100644 (file)
@@ -537,7 +537,14 @@ typedef struct _MPT_ADAPTER
        int                      id;            /* Unique adapter id N {0,1,2,...} */
        int                      pci_irq;       /* This irq           */
        char                     name[MPT_NAME_LENGTH]; /* "iocN"             */
-       char                    *prod_name;     /* "LSIFC9x9"         */
+       char                     prod_name[MPT_NAME_LENGTH];    /* "LSIFC9x9"         */
+       char                     board_name[16];
+       char                     board_assembly[16];
+       char                     board_tracer[16];
+       u16                      nvdata_version_persistent;
+       u16                      nvdata_version_default;
+       u8                       io_missing_delay;
+       u8                       device_missing_delay;
        SYSIF_REGS __iomem      *chip;          /* == c8817000 (mmap) */
        SYSIF_REGS __iomem      *pio_chip;      /* Programmed IO (downloadboot) */
        u8                       bus_type;
index b766445f19aa30050fa60b18d502d1bb0a6ab5e3..f2ebaa9992febc19cee852c63542fe62b6f494f6 100644 (file)
@@ -130,6 +130,7 @@ static struct scsi_host_template mptfc_driver_template = {
        .max_sectors                    = 8192,
        .cmd_per_lun                    = 7,
        .use_clustering                 = ENABLE_CLUSTERING,
+       .shost_attrs                    = mptscsih_host_attrs,
 };
 
 /****************************************************************************
@@ -153,6 +154,8 @@ static struct pci_device_id mptfc_pci_table[] = {
                PCI_ANY_ID, PCI_ANY_ID },
        { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949E,
                PCI_ANY_ID, PCI_ANY_ID },
+       { PCI_VENDOR_ID_BROCADE, MPI_MANUFACTPAGE_DEVICEID_FC949E,
+               PCI_ANY_ID, PCI_ANY_ID },
        {0}     /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
index 9e5424e1871fb61987ea48c73f791245241f39fb..d5066464051221589bb4dab1f0a6de65f3200a42 100644 (file)
@@ -1119,6 +1119,7 @@ static struct scsi_host_template mptsas_driver_template = {
        .max_sectors                    = 8192,
        .cmd_per_lun                    = 7,
        .use_clustering                 = ENABLE_CLUSTERING,
+       .shost_attrs                    = mptscsih_host_attrs,
 };
 
 static int mptsas_get_linkerrors(struct sas_phy *phy)
@@ -1390,6 +1391,11 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
                goto out_free_consistent;
        }
 
+       ioc->nvdata_version_persistent =
+           le16_to_cpu(buffer->NvdataVersionPersistent);
+       ioc->nvdata_version_default =
+           le16_to_cpu(buffer->NvdataVersionDefault);
+
        for (i = 0; i < port_info->num_phys; i++) {
                mptsas_print_phy_data(&buffer->PhyData[i]);
                port_info->phy_info[i].phy_id = i;
@@ -1409,6 +1415,63 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
        return error;
 }
 
+static int
+mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
+{
+       ConfigExtendedPageHeader_t hdr;
+       CONFIGPARMS cfg;
+       SasIOUnitPage1_t *buffer;
+       dma_addr_t dma_handle;
+       int error;
+       u16 device_missing_delay;
+
+       memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
+       memset(&cfg, 0, sizeof(CONFIGPARMS));
+
+       cfg.cfghdr.ehdr = &hdr;
+       cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+       cfg.timeout = 10;
+       cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
+       cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
+       cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
+       cfg.cfghdr.ehdr->PageNumber = 1;
+
+       error = mpt_config(ioc, &cfg);
+       if (error)
+               goto out;
+       if (!hdr.ExtPageLength) {
+               error = -ENXIO;
+               goto out;
+       }
+
+       buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+                                           &dma_handle);
+       if (!buffer) {
+               error = -ENOMEM;
+               goto out;
+       }
+
+       cfg.physAddr = dma_handle;
+       cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+       error = mpt_config(ioc, &cfg);
+       if (error)
+               goto out_free_consistent;
+
+       ioc->io_missing_delay  =
+           le16_to_cpu(buffer->IODeviceMissingDelay);
+       device_missing_delay = le16_to_cpu(buffer->ReportDeviceMissingDelay);
+       ioc->device_missing_delay = (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_UNIT_16) ?
+           (device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK) * 16 :
+           device_missing_delay & MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK;
+
+ out_free_consistent:
+       pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
+                           buffer, dma_handle);
+ out:
+       return error;
+}
+
 static int
 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
                u32 form, u32 form_specific)
@@ -1990,6 +2053,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
        if (error)
                goto out_free_port_info;
 
+       mptsas_sas_io_unit_pg1(ioc);
        mutex_lock(&ioc->sas_topology_mutex);
        ioc->handle = hba->phy_info[0].handle;
        port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
@@ -3237,6 +3301,8 @@ static struct pci_driver mptsas_driver = {
 static int __init
 mptsas_init(void)
 {
+       int error;
+
        show_mptmod_ver(my_NAME, my_VERSION);
 
        mptsas_transport_template =
@@ -3260,7 +3326,11 @@ mptsas_init(void)
                  ": Registered for IOC reset notifications\n"));
        }
 
-       return pci_register_driver(&mptsas_driver);
+       error = pci_register_driver(&mptsas_driver);
+       if (error)
+               sas_release_transport(mptsas_transport_template);
+
+       return error;
 }
 
 static void __exit
index d35617376f8763568aa62922c7677c262eb5db50..fd3aa2619f427317c5d7afb1e73d472887bd2c7a 100644 (file)
@@ -3187,6 +3187,159 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
        mptscsih_do_cmd(hd, &iocmd);
 }
 
+static ssize_t
+mptscsih_version_fw_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
+           (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
+           (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
+           (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
+           ioc->facts.FWVersion.Word & 0x000000FF);
+}
+static CLASS_DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
+
+static ssize_t
+mptscsih_version_bios_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
+           (ioc->biosVersion & 0xFF000000) >> 24,
+           (ioc->biosVersion & 0x00FF0000) >> 16,
+           (ioc->biosVersion & 0x0000FF00) >> 8,
+           ioc->biosVersion & 0x000000FF);
+}
+static CLASS_DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
+
+static ssize_t
+mptscsih_version_mpi_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
+}
+static CLASS_DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
+
+static ssize_t
+mptscsih_version_product_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
+}
+static CLASS_DEVICE_ATTR(version_product, S_IRUGO,
+    mptscsih_version_product_show, NULL);
+
+static ssize_t
+mptscsih_version_nvdata_persistent_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%02xh\n",
+           ioc->nvdata_version_persistent);
+}
+static CLASS_DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
+    mptscsih_version_nvdata_persistent_show, NULL);
+
+static ssize_t
+mptscsih_version_nvdata_default_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
+}
+static CLASS_DEVICE_ATTR(version_nvdata_default, S_IRUGO,
+    mptscsih_version_nvdata_default_show, NULL);
+
+static ssize_t
+mptscsih_board_name_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
+}
+static CLASS_DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
+
+static ssize_t
+mptscsih_board_assembly_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
+}
+static CLASS_DEVICE_ATTR(board_assembly, S_IRUGO,
+    mptscsih_board_assembly_show, NULL);
+
+static ssize_t
+mptscsih_board_tracer_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
+}
+static CLASS_DEVICE_ATTR(board_tracer, S_IRUGO,
+    mptscsih_board_tracer_show, NULL);
+
+static ssize_t
+mptscsih_io_delay_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
+}
+static CLASS_DEVICE_ATTR(io_delay, S_IRUGO,
+    mptscsih_io_delay_show, NULL);
+
+static ssize_t
+mptscsih_device_delay_show(struct class_device *cdev, char *buf)
+{
+       struct Scsi_Host *host = class_to_shost(cdev);
+       MPT_SCSI_HOST   *hd = (MPT_SCSI_HOST *)host->hostdata;
+       MPT_ADAPTER *ioc = hd->ioc;
+
+       return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
+}
+static CLASS_DEVICE_ATTR(device_delay, S_IRUGO,
+    mptscsih_device_delay_show, NULL);
+
+struct class_device_attribute *mptscsih_host_attrs[] = {
+       &class_device_attr_version_fw,
+       &class_device_attr_version_bios,
+       &class_device_attr_version_mpi,
+       &class_device_attr_version_product,
+       &class_device_attr_version_nvdata_persistent,
+       &class_device_attr_version_nvdata_default,
+       &class_device_attr_board_name,
+       &class_device_attr_board_assembly,
+       &class_device_attr_board_tracer,
+       &class_device_attr_io_delay,
+       &class_device_attr_device_delay,
+       NULL,
+};
+EXPORT_SYMBOL(mptscsih_host_attrs);
+
 EXPORT_SYMBOL(mptscsih_remove);
 EXPORT_SYMBOL(mptscsih_shutdown);
 #ifdef CONFIG_PM
index 8eccdfe5701af91a169bc456c2f7e637474e7f17..67b088db2f109c2831afe3356108f23c4323f6b4 100644 (file)
@@ -129,3 +129,4 @@ extern void mptscsih_timer_expired(unsigned long data);
 extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout);
 extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id);
 extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id);
+extern struct class_device_attribute *mptscsih_host_attrs[];
index 6b3e0c00952b69566177fdb97d9d128cf0533a91..947fe29018002703b4b9dac91b6c2ef416fbbb9a 100644 (file)
@@ -821,6 +821,7 @@ static struct scsi_host_template mptspi_driver_template = {
        .max_sectors                    = 8192,
        .cmd_per_lun                    = 7,
        .use_clustering                 = ENABLE_CLUSTERING,
+       .shost_attrs                    = mptscsih_host_attrs,
 };
 
 static int mptspi_write_spi_device_pg1(struct scsi_target *starget,
@@ -1523,6 +1524,8 @@ static struct pci_driver mptspi_driver = {
 static int __init
 mptspi_init(void)
 {
+       int error;
+
        show_mptmod_ver(my_NAME, my_VERSION);
 
        mptspi_transport_template = spi_attach_transport(&mptspi_transport_functions);
@@ -1543,7 +1546,11 @@ mptspi_init(void)
                  ": Registered for IOC reset notifications\n"));
        }
 
-       return pci_register_driver(&mptspi_driver);
+       error = pci_register_driver(&mptspi_driver);
+       if (error)
+               spi_release_transport(mptspi_transport_template);
+
+       return error;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
index 1d516f24ba53696336b483ab0bd859be836cbb37..aaaa61ea4217a5013da3933b768da1e99d261ed3 100644 (file)
@@ -150,6 +150,7 @@ config THINKPAD_ACPI
        depends on X86 && ACPI
        select BACKLIGHT_CLASS_DEVICE
        select HWMON
+       select NVRAM
        ---help---
          This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
          support for Fn-Fx key combinations, Bluetooth control, video
@@ -196,4 +197,17 @@ config THINKPAD_ACPI_BAY
 
          If you are not sure, say Y here.
 
+config THINKPAD_ACPI_INPUT_ENABLED
+       bool "Enable input layer support by default"
+       depends on THINKPAD_ACPI
+       default y
+       ---help---
+         Enables hot key handling over the input layer by default.  If unset,
+         the driver does not enable any hot key handling by default, and also
+         starts up with a mostly empty keymap.
+
+         If you are not sure, say Y here.  Say N to retain the deprecated
+         behavior of ibm-acpi, and thinkpad-acpi for kernels up to 2.6.21.
+
+
 endif # MISC_DEVICES
index 9623eaf4f89fdf7cb479cb0ad0bc06bec915e206..303e48ca0e8ae77459bb72dcf9c66d096b344636 100644 (file)
@@ -142,43 +142,124 @@ struct sony_laptop_keypress {
        int key;
 };
 
-/* Correspondance table between sonypi events and input layer events */
-static struct {
-       int sonypiev;
-       int inputev;
-} sony_laptop_inputkeys[] = {
-       { SONYPI_EVENT_CAPTURE_PRESSED,         KEY_CAMERA },
-       { SONYPI_EVENT_FNKEY_ONLY,              KEY_FN },
-       { SONYPI_EVENT_FNKEY_ESC,               KEY_FN_ESC },
-       { SONYPI_EVENT_FNKEY_F1,                KEY_FN_F1 },
-       { SONYPI_EVENT_FNKEY_F2,                KEY_FN_F2 },
-       { SONYPI_EVENT_FNKEY_F3,                KEY_FN_F3 },
-       { SONYPI_EVENT_FNKEY_F4,                KEY_FN_F4 },
-       { SONYPI_EVENT_FNKEY_F5,                KEY_FN_F5 },
-       { SONYPI_EVENT_FNKEY_F6,                KEY_FN_F6 },
-       { SONYPI_EVENT_FNKEY_F7,                KEY_FN_F7 },
-       { SONYPI_EVENT_FNKEY_F8,                KEY_FN_F8 },
-       { SONYPI_EVENT_FNKEY_F9,                KEY_FN_F9 },
-       { SONYPI_EVENT_FNKEY_F10,               KEY_FN_F10 },
-       { SONYPI_EVENT_FNKEY_F11,               KEY_FN_F11 },
-       { SONYPI_EVENT_FNKEY_F12,               KEY_FN_F12 },
-       { SONYPI_EVENT_FNKEY_1,                 KEY_FN_1 },
-       { SONYPI_EVENT_FNKEY_2,                 KEY_FN_2 },
-       { SONYPI_EVENT_FNKEY_D,                 KEY_FN_D },
-       { SONYPI_EVENT_FNKEY_E,                 KEY_FN_E },
-       { SONYPI_EVENT_FNKEY_F,                 KEY_FN_F },
-       { SONYPI_EVENT_FNKEY_S,                 KEY_FN_S },
-       { SONYPI_EVENT_FNKEY_B,                 KEY_FN_B },
-       { SONYPI_EVENT_BLUETOOTH_PRESSED,       KEY_BLUE },
-       { SONYPI_EVENT_BLUETOOTH_ON,            KEY_BLUE },
-       { SONYPI_EVENT_PKEY_P1,                 KEY_PROG1 },
-       { SONYPI_EVENT_PKEY_P2,                 KEY_PROG2 },
-       { SONYPI_EVENT_PKEY_P3,                 KEY_PROG3 },
-       { SONYPI_EVENT_BACK_PRESSED,            KEY_BACK },
-       { SONYPI_EVENT_HELP_PRESSED,            KEY_HELP },
-       { SONYPI_EVENT_ZOOM_PRESSED,            KEY_ZOOM },
-       { SONYPI_EVENT_THUMBPHRASE_PRESSED,     BTN_THUMB },
-       { 0, 0 },
+/* Correspondance table between sonypi events
+ * and input layer indexes in the keymap
+ */
+static int sony_laptop_input_index[] = {
+       -1,     /* no event */
+       -1,     /* SONYPI_EVENT_JOGDIAL_DOWN */
+       -1,     /* SONYPI_EVENT_JOGDIAL_UP */
+       -1,     /* SONYPI_EVENT_JOGDIAL_DOWN_PRESSED */
+       -1,     /* SONYPI_EVENT_JOGDIAL_UP_PRESSED */
+       -1,     /* SONYPI_EVENT_JOGDIAL_PRESSED */
+       -1,     /* SONYPI_EVENT_JOGDIAL_RELEASED */
+        0,     /* SONYPI_EVENT_CAPTURE_PRESSED */
+        1,     /* SONYPI_EVENT_CAPTURE_RELEASED */
+        2,     /* SONYPI_EVENT_CAPTURE_PARTIALPRESSED */
+        3,     /* SONYPI_EVENT_CAPTURE_PARTIALRELEASED */
+        4,     /* SONYPI_EVENT_FNKEY_ESC */
+        5,     /* SONYPI_EVENT_FNKEY_F1 */
+        6,     /* SONYPI_EVENT_FNKEY_F2 */
+        7,     /* SONYPI_EVENT_FNKEY_F3 */
+        8,     /* SONYPI_EVENT_FNKEY_F4 */
+        9,     /* SONYPI_EVENT_FNKEY_F5 */
+       10,     /* SONYPI_EVENT_FNKEY_F6 */
+       11,     /* SONYPI_EVENT_FNKEY_F7 */
+       12,     /* SONYPI_EVENT_FNKEY_F8 */
+       13,     /* SONYPI_EVENT_FNKEY_F9 */
+       14,     /* SONYPI_EVENT_FNKEY_F10 */
+       15,     /* SONYPI_EVENT_FNKEY_F11 */
+       16,     /* SONYPI_EVENT_FNKEY_F12 */
+       17,     /* SONYPI_EVENT_FNKEY_1 */
+       18,     /* SONYPI_EVENT_FNKEY_2 */
+       19,     /* SONYPI_EVENT_FNKEY_D */
+       20,     /* SONYPI_EVENT_FNKEY_E */
+       21,     /* SONYPI_EVENT_FNKEY_F */
+       22,     /* SONYPI_EVENT_FNKEY_S */
+       23,     /* SONYPI_EVENT_FNKEY_B */
+       24,     /* SONYPI_EVENT_BLUETOOTH_PRESSED */
+       25,     /* SONYPI_EVENT_PKEY_P1 */
+       26,     /* SONYPI_EVENT_PKEY_P2 */
+       27,     /* SONYPI_EVENT_PKEY_P3 */
+       28,     /* SONYPI_EVENT_BACK_PRESSED */
+       -1,     /* SONYPI_EVENT_LID_CLOSED */
+       -1,     /* SONYPI_EVENT_LID_OPENED */
+       29,     /* SONYPI_EVENT_BLUETOOTH_ON */
+       30,     /* SONYPI_EVENT_BLUETOOTH_OFF */
+       31,     /* SONYPI_EVENT_HELP_PRESSED */
+       32,     /* SONYPI_EVENT_FNKEY_ONLY */
+       33,     /* SONYPI_EVENT_JOGDIAL_FAST_DOWN */
+       34,     /* SONYPI_EVENT_JOGDIAL_FAST_UP */
+       35,     /* SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */
+       36,     /* SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */
+       37,     /* SONYPI_EVENT_JOGDIAL_VFAST_DOWN */
+       38,     /* SONYPI_EVENT_JOGDIAL_VFAST_UP */
+       39,     /* SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */
+       40,     /* SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */
+       41,     /* SONYPI_EVENT_ZOOM_PRESSED */
+       42,     /* SONYPI_EVENT_THUMBPHRASE_PRESSED */
+       43,     /* SONYPI_EVENT_MEYE_FACE */
+       44,     /* SONYPI_EVENT_MEYE_OPPOSITE */
+       45,     /* SONYPI_EVENT_MEMORYSTICK_INSERT */
+       46,     /* SONYPI_EVENT_MEMORYSTICK_EJECT */
+       -1,     /* SONYPI_EVENT_ANYBUTTON_RELEASED */
+       -1,     /* SONYPI_EVENT_BATTERY_INSERT */
+       -1,     /* SONYPI_EVENT_BATTERY_REMOVE */
+       -1,     /* SONYPI_EVENT_FNKEY_RELEASED */
+       47,     /* SONYPI_EVENT_WIRELESS_ON */
+       48,     /* SONYPI_EVENT_WIRELESS_OFF */
+};
+
+static int sony_laptop_input_keycode_map[] = {
+       KEY_CAMERA,     /*  0 SONYPI_EVENT_CAPTURE_PRESSED */
+       KEY_RESERVED,   /*  1 SONYPI_EVENT_CAPTURE_RELEASED */
+       KEY_RESERVED,   /*  2 SONYPI_EVENT_CAPTURE_PARTIALPRESSED */
+       KEY_RESERVED,   /*  3 SONYPI_EVENT_CAPTURE_PARTIALRELEASED */
+       KEY_FN_ESC,     /*  4 SONYPI_EVENT_FNKEY_ESC */
+       KEY_FN_F1,      /*  5 SONYPI_EVENT_FNKEY_F1 */
+       KEY_FN_F2,      /*  6 SONYPI_EVENT_FNKEY_F2 */
+       KEY_FN_F3,      /*  7 SONYPI_EVENT_FNKEY_F3 */
+       KEY_FN_F4,      /*  8 SONYPI_EVENT_FNKEY_F4 */
+       KEY_FN_F5,      /*  9 SONYPI_EVENT_FNKEY_F5 */
+       KEY_FN_F6,      /* 10 SONYPI_EVENT_FNKEY_F6 */
+       KEY_FN_F7,      /* 11 SONYPI_EVENT_FNKEY_F7 */
+       KEY_FN_F8,      /* 12 SONYPI_EVENT_FNKEY_F8 */
+       KEY_FN_F9,      /* 13 SONYPI_EVENT_FNKEY_F9 */
+       KEY_FN_F10,     /* 14 SONYPI_EVENT_FNKEY_F10 */
+       KEY_FN_F11,     /* 15 SONYPI_EVENT_FNKEY_F11 */
+       KEY_FN_F12,     /* 16 SONYPI_EVENT_FNKEY_F12 */
+       KEY_FN_F1,      /* 17 SONYPI_EVENT_FNKEY_1 */
+       KEY_FN_F2,      /* 18 SONYPI_EVENT_FNKEY_2 */
+       KEY_FN_D,       /* 19 SONYPI_EVENT_FNKEY_D */
+       KEY_FN_E,       /* 20 SONYPI_EVENT_FNKEY_E */
+       KEY_FN_F,       /* 21 SONYPI_EVENT_FNKEY_F */
+       KEY_FN_S,       /* 22 SONYPI_EVENT_FNKEY_S */
+       KEY_FN_B,       /* 23 SONYPI_EVENT_FNKEY_B */
+       KEY_BLUETOOTH,  /* 24 SONYPI_EVENT_BLUETOOTH_PRESSED */
+       KEY_PROG1,      /* 25 SONYPI_EVENT_PKEY_P1 */
+       KEY_PROG2,      /* 26 SONYPI_EVENT_PKEY_P2 */
+       KEY_PROG3,      /* 27 SONYPI_EVENT_PKEY_P3 */
+       KEY_BACK,       /* 28 SONYPI_EVENT_BACK_PRESSED */
+       KEY_BLUETOOTH,  /* 29 SONYPI_EVENT_BLUETOOTH_ON */
+       KEY_BLUETOOTH,  /* 30 SONYPI_EVENT_BLUETOOTH_OFF */
+       KEY_HELP,       /* 31 SONYPI_EVENT_HELP_PRESSED */
+       KEY_FN,         /* 32 SONYPI_EVENT_FNKEY_ONLY */
+       KEY_RESERVED,   /* 33 SONYPI_EVENT_JOGDIAL_FAST_DOWN */
+       KEY_RESERVED,   /* 34 SONYPI_EVENT_JOGDIAL_FAST_UP */
+       KEY_RESERVED,   /* 35 SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */
+       KEY_RESERVED,   /* 36 SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */
+       KEY_RESERVED,   /* 37 SONYPI_EVENT_JOGDIAL_VFAST_DOWN */
+       KEY_RESERVED,   /* 38 SONYPI_EVENT_JOGDIAL_VFAST_UP */
+       KEY_RESERVED,   /* 39 SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */
+       KEY_RESERVED,   /* 40 SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */
+       KEY_ZOOM,       /* 41 SONYPI_EVENT_ZOOM_PRESSED */
+       BTN_THUMB,      /* 42 SONYPI_EVENT_THUMBPHRASE_PRESSED */
+       KEY_RESERVED,   /* 43 SONYPI_EVENT_MEYE_FACE */
+       KEY_RESERVED,   /* 44 SONYPI_EVENT_MEYE_OPPOSITE */
+       KEY_RESERVED,   /* 45 SONYPI_EVENT_MEMORYSTICK_INSERT */
+       KEY_RESERVED,   /* 46 SONYPI_EVENT_MEMORYSTICK_EJECT */
+       KEY_WLAN,       /* 47 SONYPI_EVENT_WIRELESS_ON */
+       KEY_WLAN,       /* 48 SONYPI_EVENT_WIRELESS_OFF */
 };
 
 /* release buttons after a short delay if pressed */
@@ -202,7 +283,6 @@ static void sony_laptop_report_input_event(u8 event)
        struct input_dev *jog_dev = sony_laptop_input.jog_dev;
        struct input_dev *key_dev = sony_laptop_input.key_dev;
        struct sony_laptop_keypress kp = { NULL };
-       int i;
 
        if (event == SONYPI_EVENT_FNKEY_RELEASED) {
                /* Nothing, not all VAIOs generate this event */
@@ -231,17 +311,22 @@ static void sony_laptop_report_input_event(u8 event)
                break;
 
        default:
-               for (i = 0; sony_laptop_inputkeys[i].sonypiev; i++)
-                       if (event == sony_laptop_inputkeys[i].sonypiev) {
+               if (event > ARRAY_SIZE (sony_laptop_input_keycode_map)) {
+                       dprintk("sony_laptop_report_input_event, event not known: %d\n", event);
+                       break;
+               }
+               if (sony_laptop_input_index[event] != -1) {
+                       kp.key = sony_laptop_input_keycode_map[sony_laptop_input_index[event]];
+                       if (kp.key != KEY_UNKNOWN)
                                kp.dev = key_dev;
-                               kp.key = sony_laptop_inputkeys[i].inputev;
-                               break;
-                       }
+               }
                break;
        }
 
        if (kp.dev) {
                input_report_key(kp.dev, kp.key, 1);
+               /* we emit the scancode so we can always remap the key */
+               input_event(kp.dev, EV_MSC, MSC_SCAN, event);
                input_sync(kp.dev);
                kfifo_put(sony_laptop_input.fifo,
                          (unsigned char *)&kp, sizeof(kp));
@@ -296,11 +381,18 @@ static int sony_laptop_setup_input(void)
        key_dev->id.vendor = PCI_VENDOR_ID_SONY;
 
        /* Initialize the Input Drivers: special keys */
-       key_dev->evbit[0] = BIT(EV_KEY);
-       for (i = 0; sony_laptop_inputkeys[i].sonypiev; i++)
-               if (sony_laptop_inputkeys[i].inputev)
-                       set_bit(sony_laptop_inputkeys[i].inputev,
-                                       key_dev->keybit);
+       set_bit(EV_KEY, key_dev->evbit);
+       set_bit(EV_MSC, key_dev->evbit);
+       set_bit(MSC_SCAN, key_dev->mscbit);
+       key_dev->keycodesize = sizeof(sony_laptop_input_keycode_map[0]);
+       key_dev->keycodemax = ARRAY_SIZE(sony_laptop_input_keycode_map);
+       key_dev->keycode = &sony_laptop_input_keycode_map;
+       for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++) {
+               if (sony_laptop_input_keycode_map[i] != KEY_RESERVED) {
+                       set_bit(sony_laptop_input_keycode_map[i],
+                               key_dev->keybit);
+               }
+       }
 
        error = input_register_device(key_dev);
        if (error)
@@ -487,6 +579,14 @@ SNC_HANDLE_NAMES(audiopower_set, "AZPW");
 SNC_HANDLE_NAMES(lanpower_get, "GLNP");
 SNC_HANDLE_NAMES(lanpower_set, "LNPW");
 
+SNC_HANDLE_NAMES(lidstate_get, "GLID");
+
+SNC_HANDLE_NAMES(indicatorlamp_get, "GILS");
+SNC_HANDLE_NAMES(indicatorlamp_set, "SILS");
+
+SNC_HANDLE_NAMES(gainbass_get, "GMGB");
+SNC_HANDLE_NAMES(gainbass_set, "CMGB");
+
 SNC_HANDLE_NAMES(PID_get, "GPID");
 
 SNC_HANDLE_NAMES(CTR_get, "GCTR");
@@ -507,6 +607,12 @@ static struct sony_nc_value sony_nc_values[] = {
                        boolean_validate, 0),
        SNC_HANDLE(lanpower, snc_lanpower_get, snc_lanpower_set,
                        boolean_validate, 1),
+       SNC_HANDLE(lidstate, snc_lidstate_get, NULL,
+                       boolean_validate, 0),
+       SNC_HANDLE(indicatorlamp, snc_indicatorlamp_get, snc_indicatorlamp_set,
+                       boolean_validate, 0),
+       SNC_HANDLE(gainbass, snc_gainbass_get, snc_gainbass_set,
+                       boolean_validate, 0),
        /* unknown methods */
        SNC_HANDLE(PID, snc_PID_get, NULL, NULL, 1),
        SNC_HANDLE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1),
@@ -688,14 +794,117 @@ static struct backlight_ops sony_backlight_ops = {
        .get_brightness = sony_backlight_get_brightness,
 };
 
+/*
+ * New SNC-only Vaios event mapping to driver known keys
+ */
+struct sony_nc_event {
+       u8      data;
+       u8      event;
+};
+
+static struct sony_nc_event *sony_nc_events;
+
+/* Vaio C* --maybe also FE*, N* and AR* ?-- special init sequence
+ * for Fn keys
+ */
+static int sony_nc_C_enable(struct dmi_system_id *id)
+{
+       int result = 0;
+
+       printk(KERN_NOTICE DRV_PFX "detected %s\n", id->ident);
+
+       sony_nc_events = id->driver_data;
+
+       if (acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x4, &result) < 0
+                       || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x2, &result) < 0
+                       || acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x10, &result) < 0
+                       || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x0, &result) < 0
+                       || acpi_callsetfunc(sony_nc_acpi_handle, "SN03", 0x2, &result) < 0
+                       || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x101, &result) < 0) {
+               printk(KERN_WARNING DRV_PFX "failed to initialize SNC, some "
+                               "functionalities may be missing\n");
+               return 1;
+       }
+       return 0;
+}
+
+static struct sony_nc_event sony_C_events[] = {
+       { 0x81, SONYPI_EVENT_FNKEY_F1 },
+       { 0x01, SONYPI_EVENT_FNKEY_RELEASED },
+       { 0x85, SONYPI_EVENT_FNKEY_F5 },
+       { 0x05, SONYPI_EVENT_FNKEY_RELEASED },
+       { 0x86, SONYPI_EVENT_FNKEY_F6 },
+       { 0x06, SONYPI_EVENT_FNKEY_RELEASED },
+       { 0x87, SONYPI_EVENT_FNKEY_F7 },
+       { 0x07, SONYPI_EVENT_FNKEY_RELEASED },
+       { 0x8A, SONYPI_EVENT_FNKEY_F10 },
+       { 0x0A, SONYPI_EVENT_FNKEY_RELEASED },
+       { 0x8C, SONYPI_EVENT_FNKEY_F12 },
+       { 0x0C, SONYPI_EVENT_FNKEY_RELEASED },
+       { 0, 0 },
+};
+
+/* SNC-only model map */
+struct dmi_system_id sony_nc_ids[] = {
+               {
+                       .ident = "Sony Vaio FE Series",
+                       .callback = sony_nc_C_enable,
+                       .driver_data = sony_C_events,
+                       .matches = {
+                               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+                               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FE"),
+                       },
+               },
+               {
+                       .ident = "Sony Vaio C Series",
+                       .callback = sony_nc_C_enable,
+                       .driver_data = sony_C_events,
+                       .matches = {
+                               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+                               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-C"),
+                       },
+               },
+               { }
+};
+
 /*
  * ACPI callbacks
  */
 static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
 {
-       dprintk("sony_acpi_notify, event: %d\n", event);
-       sony_laptop_report_input_event(event);
-       acpi_bus_generate_event(sony_nc_acpi_device, 1, event);
+       struct sony_nc_event *evmap;
+       u32 ev = event;
+       int result;
+
+       if (ev == 0x92) {
+               /* read the key pressed from EC.GECR
+                * A call to SN07 with 0x0202 will do it as well respecting
+                * the current protocol on different OSes
+                *
+                * Note: the path for GECR may be
+                *   \_SB.PCI0.LPCB.EC (C, FE, AR, N and friends)
+                *   \_SB.PCI0.PIB.EC0 (VGN-FR notifications are sent directly, no GECR)
+                *
+                * TODO: we may want to do the same for the older GHKE -need
+                *       dmi list- so this snippet may become one more callback.
+                */
+               if (acpi_callsetfunc(handle, "SN07", 0x0202, &result) < 0)
+                       dprintk("sony_acpi_notify, unable to decode event 0x%.2x\n", ev);
+               else
+                       ev = result & 0xFF;
+       }
+
+       if (sony_nc_events)
+               for (evmap = sony_nc_events; evmap->event; evmap++) {
+                       if (evmap->data == ev) {
+                               ev = evmap->event;
+                               break;
+                       }
+               }
+
+       dprintk("sony_acpi_notify, event: 0x%.2x\n", ev);
+       sony_laptop_report_input_event(ev);
+       acpi_bus_generate_event(sony_nc_acpi_device, 1, ev);
 }
 
 static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
@@ -732,6 +941,10 @@ static int sony_nc_resume(struct acpi_device *device)
                        break;
                }
        }
+
+       /* re-initialize models with specific requirements */
+       dmi_check_system(sony_nc_ids);
+
        return 0;
 }
 
@@ -750,6 +963,15 @@ static int sony_nc_add(struct acpi_device *device)
 
        sony_nc_acpi_handle = device->handle;
 
+       /* read device status */
+       result = acpi_bus_get_status(device);
+       /* bail IFF the above call was successful and the device is not present */
+       if (!result && !device->status.present) {
+               dprintk("Device not present\n");
+               result = -ENODEV;
+               goto outwalk;
+       }
+
        if (debug) {
                status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle,
                                             1, sony_walk_callback, NULL, NULL);
@@ -760,6 +982,15 @@ static int sony_nc_add(struct acpi_device *device)
                }
        }
 
+       /* try to _INI the device if such method exists (ACPI spec 3.0-6.5.1
+        * should be respected as we already checked for the device presence above */
+       if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, METHOD_NAME__INI, &handle))) {
+               dprintk("Invoking _INI\n");
+               if (ACPI_FAILURE(acpi_evaluate_object(sony_nc_acpi_handle, METHOD_NAME__INI,
+                                               NULL, NULL)))
+                       dprintk("_INI Method failed\n");
+       }
+
        /* setup input devices and helper fifo */
        result = sony_laptop_setup_input();
        if (result) {
@@ -772,7 +1003,7 @@ static int sony_nc_add(struct acpi_device *device)
                                             ACPI_DEVICE_NOTIFY,
                                             sony_acpi_notify, NULL);
        if (ACPI_FAILURE(status)) {
-               printk(KERN_WARNING DRV_PFX "unable to install notify handler\n");
+               printk(KERN_WARNING DRV_PFX "unable to install notify handler (%u)\n", status);
                result = -ENODEV;
                goto outinput;
        }
@@ -795,6 +1026,9 @@ static int sony_nc_add(struct acpi_device *device)
 
        }
 
+       /* initialize models with specific requirements */
+       dmi_check_system(sony_nc_ids);
+
        result = sony_pf_add();
        if (result)
                goto outbacklight;
@@ -908,7 +1142,9 @@ static struct acpi_driver sony_nc_driver = {
 #define SONYPI_DEVICE_TYPE2    0x00000002
 #define SONYPI_DEVICE_TYPE3    0x00000004
 
-#define SONY_PIC_EV_MASK       0xff
+#define SONYPI_TYPE1_OFFSET    0x04
+#define SONYPI_TYPE2_OFFSET    0x12
+#define SONYPI_TYPE3_OFFSET    0x12
 
 struct sony_pic_ioport {
        struct acpi_resource_io io;
@@ -922,6 +1158,7 @@ struct sony_pic_irq {
 
 struct sony_pic_dev {
        int                     model;
+       u16                     evport_offset;
        u8                      camera_power;
        u8                      bluetooth_power;
        u8                      wwan_power;
@@ -1999,20 +2236,17 @@ end:
 static irqreturn_t sony_pic_irq(int irq, void *dev_id)
 {
        int i, j;
-       u32 port_val = 0;
        u8 ev = 0;
        u8 data_mask = 0;
        u8 device_event = 0;
 
        struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id;
 
-       acpi_os_read_port(dev->cur_ioport->io.minimum, &port_val,
-                       dev->cur_ioport->io.address_length);
-       ev = port_val & SONY_PIC_EV_MASK;
-       data_mask = 0xff & (port_val >> (dev->cur_ioport->io.address_length - 8));
+       ev = inb_p(dev->cur_ioport->io.minimum);
+       data_mask = inb_p(dev->cur_ioport->io.minimum + dev->evport_offset);
 
-       dprintk("event (0x%.8x [%.2x] [%.2x]) at port 0x%.4x\n",
-                       port_val, ev, data_mask, dev->cur_ioport->io.minimum);
+       dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
+                       ev, data_mask, dev->cur_ioport->io.minimum, dev->evport_offset);
 
        if (ev == 0x00 || ev == 0xff)
                return IRQ_HANDLED;
@@ -2103,6 +2337,20 @@ static int sony_pic_add(struct acpi_device *device)
        spic_dev.model = sony_pic_detect_device_type();
        mutex_init(&spic_dev.lock);
 
+       /* model specific characteristics */
+       switch(spic_dev.model) {
+               case SONYPI_DEVICE_TYPE1:
+                       spic_dev.evport_offset = SONYPI_TYPE1_OFFSET;
+                       break;
+               case SONYPI_DEVICE_TYPE3:
+                       spic_dev.evport_offset = SONYPI_TYPE3_OFFSET;
+                       break;
+               case SONYPI_DEVICE_TYPE2:
+               default:
+                       spic_dev.evport_offset = SONYPI_TYPE2_OFFSET;
+                       break;
+       }
+
        /* read _PRS resources */
        result = sony_pic_possible_resources(device);
        if (result) {
index 95c0b96e83f2110b751d775c2a53e66d718c6564..f15a58f7403fd4b231ddd267ebb02f098d22957b 100644 (file)
@@ -21,8 +21,8 @@
  *  02110-1301, USA.
  */
 
-#define IBM_VERSION "0.14"
-#define TPACPI_SYSFS_VERSION 0x000100
+#define IBM_VERSION "0.15"
+#define TPACPI_SYSFS_VERSION 0x010000
 
 /*
  *  Changelog:
@@ -92,6 +92,29 @@ MODULE_LICENSE("GPL");
 /* Please remove this in year 2009 */
 MODULE_ALIAS("ibm_acpi");
 
+/*
+ * DMI matching for module autoloading
+ *
+ * See http://thinkwiki.org/wiki/List_of_DMI_IDs
+ * See http://thinkwiki.org/wiki/BIOS_Upgrade_Downloads
+ *
+ * Only models listed in thinkwiki will be supported, so add yours
+ * if it is not there yet.
+ */
+#define IBM_BIOS_MODULE_ALIAS(__type) \
+       MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW")
+
+/* Non-ancient thinkpads */
+MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*");
+MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*");
+
+/* Ancient thinkpad BIOSes have to be identified by
+ * BIOS type or model number, and there are far less
+ * BIOS types than model numbers... */
+IBM_BIOS_MODULE_ALIAS("I[B,D,H,I,M,N,O,T,W,V,Y,Z]");
+IBM_BIOS_MODULE_ALIAS("1[0,3,6,8,A-G,I,K,M-P,S,T]");
+IBM_BIOS_MODULE_ALIAS("K[U,X-Z]");
+
 #define __unused __attribute__ ((unused))
 
 /****************************************************************************
@@ -106,7 +129,7 @@ MODULE_ALIAS("ibm_acpi");
  * ACPI basic handles
  */
 
-static acpi_handle root_handle = NULL;
+static acpi_handle root_handle;
 
 #define IBM_HANDLE(object, parent, paths...)                   \
        static acpi_handle  object##_handle;                    \
@@ -487,19 +510,36 @@ static char *next_cmd(char **cmds)
 /****************************************************************************
  ****************************************************************************
  *
- * Device model: hwmon and platform
+ * Device model: input, hwmon and platform
  *
  ****************************************************************************
  ****************************************************************************/
 
-static struct platform_device *tpacpi_pdev = NULL;
-static struct class_device *tpacpi_hwmon = NULL;
+static struct platform_device *tpacpi_pdev;
+static struct class_device *tpacpi_hwmon;
+static struct input_dev *tpacpi_inputdev;
+
+
+static int tpacpi_resume_handler(struct platform_device *pdev)
+{
+       struct ibm_struct *ibm, *itmp;
+
+       list_for_each_entry_safe(ibm, itmp,
+                                &tpacpi_all_drivers,
+                                all_drivers) {
+               if (ibm->resume)
+                       (ibm->resume)();
+       }
+
+       return 0;
+}
 
 static struct platform_driver tpacpi_pdriver = {
        .driver = {
                .name = IBM_DRVR_NAME,
                .owner = THIS_MODULE,
        },
+       .resume = tpacpi_resume_handler,
 };
 
 
@@ -677,9 +717,19 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm)
        printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
        printk(IBM_INFO "%s\n", IBM_URL);
 
-       if (ibm_thinkpad_ec_found)
-               printk(IBM_INFO "ThinkPad EC firmware %s\n",
-                      ibm_thinkpad_ec_found);
+       printk(IBM_INFO "ThinkPad BIOS %s, EC %s\n",
+               (thinkpad_id.bios_version_str) ?
+                       thinkpad_id.bios_version_str : "unknown",
+               (thinkpad_id.ec_version_str) ?
+                       thinkpad_id.ec_version_str : "unknown");
+
+       if (thinkpad_id.vendor && thinkpad_id.model_str)
+               printk(IBM_INFO "%s %s\n",
+                       (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ?
+                               "IBM" : ((thinkpad_id.vendor ==
+                                               PCI_VENDOR_ID_LENOVO) ?
+                                       "Lenovo" : "Unknown vendor"),
+                       thinkpad_id.model_str);
 
        return 0;
 }
@@ -704,16 +754,28 @@ static struct ibm_struct thinkpad_acpi_driver_data = {
  */
 
 static int hotkey_orig_status;
-static int hotkey_orig_mask;
+static u32 hotkey_orig_mask;
+static u32 hotkey_all_mask;
+static u32 hotkey_reserved_mask;
+
+static u16 *hotkey_keycode_map;
 
-static struct attribute_set *hotkey_dev_attributes = NULL;
+static struct attribute_set *hotkey_dev_attributes;
+
+static int hotkey_get_wlsw(int *status)
+{
+       if (!acpi_evalf(hkey_handle, status, "WLSW", "d"))
+               return -EIO;
+       return 0;
+}
 
 /* sysfs hotkey enable ------------------------------------------------- */
 static ssize_t hotkey_enable_show(struct device *dev,
                           struct device_attribute *attr,
                           char *buf)
 {
-       int res, status, mask;
+       int res, status;
+       u32 mask;
 
        res = hotkey_get(&status, &mask);
        if (res)
@@ -727,7 +789,8 @@ static ssize_t hotkey_enable_store(struct device *dev,
                            const char *buf, size_t count)
 {
        unsigned long t;
-       int res, status, mask;
+       int res, status;
+       u32 mask;
 
        if (parse_strtoul(buf, 1, &t))
                return -EINVAL;
@@ -748,13 +811,14 @@ static ssize_t hotkey_mask_show(struct device *dev,
                           struct device_attribute *attr,
                           char *buf)
 {
-       int res, status, mask;
+       int res, status;
+       u32 mask;
 
        res = hotkey_get(&status, &mask);
        if (res)
                return res;
 
-       return snprintf(buf, PAGE_SIZE, "0x%04x\n", mask);
+       return snprintf(buf, PAGE_SIZE, "0x%08x\n", mask);
 }
 
 static ssize_t hotkey_mask_store(struct device *dev,
@@ -762,9 +826,10 @@ static ssize_t hotkey_mask_store(struct device *dev,
                            const char *buf, size_t count)
 {
        unsigned long t;
-       int res, status, mask;
+       int res, status;
+       u32 mask;
 
-       if (parse_strtoul(buf, 0xffff, &t))
+       if (parse_strtoul(buf, 0xffffffffUL, &t))
                return -EINVAL;
 
        res = hotkey_get(&status, &mask);
@@ -794,26 +859,123 @@ static ssize_t hotkey_bios_mask_show(struct device *dev,
                           struct device_attribute *attr,
                           char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "0x%04x\n", hotkey_orig_mask);
+       return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask);
 }
 
 static struct device_attribute dev_attr_hotkey_bios_mask =
        __ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL);
 
+/* sysfs hotkey all_mask ----------------------------------------------- */
+static ssize_t hotkey_all_mask_show(struct device *dev,
+                          struct device_attribute *attr,
+                          char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_all_mask);
+}
+
+static struct device_attribute dev_attr_hotkey_all_mask =
+       __ATTR(hotkey_all_mask, S_IRUGO, hotkey_all_mask_show, NULL);
+
+/* sysfs hotkey recommended_mask --------------------------------------- */
+static ssize_t hotkey_recommended_mask_show(struct device *dev,
+                                           struct device_attribute *attr,
+                                           char *buf)
+{
+       return snprintf(buf, PAGE_SIZE, "0x%08x\n",
+                       hotkey_all_mask & ~hotkey_reserved_mask);
+}
+
+static struct device_attribute dev_attr_hotkey_recommended_mask =
+       __ATTR(hotkey_recommended_mask, S_IRUGO,
+               hotkey_recommended_mask_show, NULL);
+
+/* sysfs hotkey radio_sw ----------------------------------------------- */
+static ssize_t hotkey_radio_sw_show(struct device *dev,
+                          struct device_attribute *attr,
+                          char *buf)
+{
+       int res, s;
+       res = hotkey_get_wlsw(&s);
+       if (res < 0)
+               return res;
+
+       return snprintf(buf, PAGE_SIZE, "%d\n", !!s);
+}
+
+static struct device_attribute dev_attr_hotkey_radio_sw =
+       __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL);
+
 /* --------------------------------------------------------------------- */
 
 static struct attribute *hotkey_mask_attributes[] = {
        &dev_attr_hotkey_mask.attr,
        &dev_attr_hotkey_bios_enabled.attr,
        &dev_attr_hotkey_bios_mask.attr,
+       &dev_attr_hotkey_all_mask.attr,
+       &dev_attr_hotkey_recommended_mask.attr,
 };
 
 static int __init hotkey_init(struct ibm_init_struct *iibm)
 {
-       int res;
+
+       static u16 ibm_keycode_map[] __initdata = {
+               /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
+               KEY_FN_F1,      KEY_FN_F2,      KEY_COFFEE,     KEY_SLEEP,
+               KEY_WLAN,       KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
+               KEY_FN_F9,      KEY_FN_F10,     KEY_FN_F11,     KEY_SUSPEND,
+               /* Scan codes 0x0C to 0x0F: Other ACPI HKEY hot keys */
+               KEY_UNKNOWN,    /* 0x0C: FN+BACKSPACE */
+               KEY_UNKNOWN,    /* 0x0D: FN+INSERT */
+               KEY_UNKNOWN,    /* 0x0E: FN+DELETE */
+               KEY_RESERVED,   /* 0x0F: FN+HOME (brightness up) */
+               /* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */
+               KEY_RESERVED,   /* 0x10: FN+END (brightness down) */
+               KEY_RESERVED,   /* 0x11: FN+PGUP (thinklight toggle) */
+               KEY_UNKNOWN,    /* 0x12: FN+PGDOWN */
+               KEY_ZOOM,       /* 0x13: FN+SPACE (zoom) */
+               KEY_RESERVED,   /* 0x14: VOLUME UP */
+               KEY_RESERVED,   /* 0x15: VOLUME DOWN */
+               KEY_RESERVED,   /* 0x16: MUTE */
+               KEY_VENDOR,     /* 0x17: Thinkpad/AccessIBM/Lenovo */
+               /* (assignments unknown, please report if found) */
+               KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
+               KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
+       };
+       static u16 lenovo_keycode_map[] __initdata = {
+               /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
+               KEY_FN_F1,      KEY_COFFEE,     KEY_BATTERY,    KEY_SLEEP,
+               KEY_WLAN,       KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
+               KEY_FN_F9,      KEY_FN_F10,     KEY_FN_F11,     KEY_SUSPEND,
+               /* Scan codes 0x0C to 0x0F: Other ACPI HKEY hot keys */
+               KEY_UNKNOWN,    /* 0x0C: FN+BACKSPACE */
+               KEY_UNKNOWN,    /* 0x0D: FN+INSERT */
+               KEY_UNKNOWN,    /* 0x0E: FN+DELETE */
+               KEY_BRIGHTNESSUP,       /* 0x0F: FN+HOME (brightness up) */
+               /* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */
+               KEY_BRIGHTNESSDOWN,     /* 0x10: FN+END (brightness down) */
+               KEY_RESERVED,   /* 0x11: FN+PGUP (thinklight toggle) */
+               KEY_UNKNOWN,    /* 0x12: FN+PGDOWN */
+               KEY_ZOOM,       /* 0x13: FN+SPACE (zoom) */
+               KEY_RESERVED,   /* 0x14: VOLUME UP */
+               KEY_RESERVED,   /* 0x15: VOLUME DOWN */
+               KEY_RESERVED,   /* 0x16: MUTE */
+               KEY_VENDOR,     /* 0x17: Thinkpad/AccessIBM/Lenovo */
+               /* (assignments unknown, please report if found) */
+               KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
+               KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
+       };
+
+#define TPACPI_HOTKEY_MAP_LEN          ARRAY_SIZE(ibm_keycode_map)
+#define TPACPI_HOTKEY_MAP_SIZE         sizeof(ibm_keycode_map)
+#define TPACPI_HOTKEY_MAP_TYPESIZE     sizeof(ibm_keycode_map[0])
+
+       int res, i;
+       int status;
 
        vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
 
+       BUG_ON(!tpacpi_inputdev);
+
        IBM_ACPIHANDLE_INIT(hkey);
        mutex_init(&hotkey_mutex);
 
@@ -824,7 +986,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
                str_supported(tp_features.hotkey));
 
        if (tp_features.hotkey) {
-               hotkey_dev_attributes = create_attr_set(4, NULL);
+               hotkey_dev_attributes = create_attr_set(7, NULL);
                if (!hotkey_dev_attributes)
                        return -ENOMEM;
                res = add_to_attr_set(hotkey_dev_attributes,
@@ -840,19 +1002,92 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
                vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
                        str_supported(tp_features.hotkey_mask));
 
+               if (tp_features.hotkey_mask) {
+                       /* MHKA available in A31, R40, R40e, T4x, X31, and later */
+                       if (!acpi_evalf(hkey_handle, &hotkey_all_mask,
+                                       "MHKA", "qd"))
+                               hotkey_all_mask = 0x080cU; /* FN+F12, FN+F4, FN+F3 */
+               }
+
                res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask);
                if (!res && tp_features.hotkey_mask) {
                        res = add_many_to_attr_set(hotkey_dev_attributes,
                                hotkey_mask_attributes,
                                ARRAY_SIZE(hotkey_mask_attributes));
                }
+
+               /* Not all thinkpads have a hardware radio switch */
+               if (!res && acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {
+                       tp_features.hotkey_wlsw = 1;
+                       printk(IBM_INFO
+                               "radio switch found; radios are %s\n",
+                               enabled(status, 0));
+                       res = add_to_attr_set(hotkey_dev_attributes,
+                                       &dev_attr_hotkey_radio_sw.attr);
+               }
+
                if (!res)
                        res = register_attr_set_with_sysfs(
                                        hotkey_dev_attributes,
                                        &tpacpi_pdev->dev.kobj);
+               if (res)
+                       return res;
+
+               /* Set up key map */
+
+               hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,
+                                               GFP_KERNEL);
+               if (!hotkey_keycode_map) {
+                       printk(IBM_ERR "failed to allocate memory for key map\n");
+                       return -ENOMEM;
+               }
+
+               if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
+                       dbg_printk(TPACPI_DBG_INIT,
+                                  "using Lenovo default hot key map\n");
+                       memcpy(hotkey_keycode_map, &lenovo_keycode_map,
+                               TPACPI_HOTKEY_MAP_SIZE);
+               } else {
+                       dbg_printk(TPACPI_DBG_INIT,
+                                  "using IBM default hot key map\n");
+                       memcpy(hotkey_keycode_map, &ibm_keycode_map,
+                               TPACPI_HOTKEY_MAP_SIZE);
+               }
 
+#ifndef CONFIG_THINKPAD_ACPI_INPUT_ENABLED
+               for (i = 0; i < 12; i++)
+                       hotkey_keycode_map[i] = KEY_UNKNOWN;
+#endif /* ! CONFIG_THINKPAD_ACPI_INPUT_ENABLED */
+
+               set_bit(EV_KEY, tpacpi_inputdev->evbit);
+               set_bit(EV_MSC, tpacpi_inputdev->evbit);
+               set_bit(MSC_SCAN, tpacpi_inputdev->mscbit);
+               tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
+               tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN;
+               tpacpi_inputdev->keycode = hotkey_keycode_map;
+               for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) {
+                       if (hotkey_keycode_map[i] != KEY_RESERVED) {
+                               set_bit(hotkey_keycode_map[i],
+                                       tpacpi_inputdev->keybit);
+                       } else {
+                               if (i < sizeof(hotkey_reserved_mask)*8)
+                                       hotkey_reserved_mask |= 1 << i;
+                       }
+               }
+
+               if (tp_features.hotkey_wlsw) {
+                       set_bit(EV_SW, tpacpi_inputdev->evbit);
+                       set_bit(SW_RADIO, tpacpi_inputdev->swbit);
+               }
+
+#ifdef CONFIG_THINKPAD_ACPI_INPUT_ENABLED
+               dbg_printk(TPACPI_DBG_INIT,
+                               "enabling hot key handling\n");
+               res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask)
+                                       | hotkey_orig_mask);
                if (res)
                        return res;
+#endif /* CONFIG_THINKPAD_ACPI_INPUT_ENABLED */
        }
 
        return (tp_features.hotkey)? 0 : 1;
@@ -875,22 +1110,101 @@ static void hotkey_exit(void)
        }
 }
 
+static void tpacpi_input_send_key(unsigned int scancode,
+                                 unsigned int keycode)
+{
+       if (keycode != KEY_RESERVED) {
+               input_report_key(tpacpi_inputdev, keycode, 1);
+               if (keycode == KEY_UNKNOWN)
+                       input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
+                                   scancode);
+               input_sync(tpacpi_inputdev);
+
+               input_report_key(tpacpi_inputdev, keycode, 0);
+               if (keycode == KEY_UNKNOWN)
+                       input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
+                                   scancode);
+               input_sync(tpacpi_inputdev);
+       }
+}
+
+static void tpacpi_input_send_radiosw(void)
+{
+       int wlsw;
+
+       if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw))
+               input_report_switch(tpacpi_inputdev,
+                                   SW_RADIO, !!wlsw);
+}
+
 static void hotkey_notify(struct ibm_struct *ibm, u32 event)
 {
-       int hkey;
+       u32 hkey;
+       unsigned int keycode, scancode;
+       int sendacpi = 1;
+
+       if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
+               if (tpacpi_inputdev->users > 0) {
+                       switch (hkey >> 12) {
+                       case 1:
+                               /* 0x1000-0x1FFF: key presses */
+                               scancode = hkey & 0xfff;
+                               if (scancode > 0 && scancode < 0x21) {
+                                       scancode--;
+                                       keycode = hotkey_keycode_map[scancode];
+                                       tpacpi_input_send_key(scancode, keycode);
+                                       sendacpi = (keycode == KEY_RESERVED
+                                               || keycode == KEY_UNKNOWN);
+                               } else {
+                                       printk(IBM_ERR
+                                              "hotkey 0x%04x out of range for keyboard map\n",
+                                              hkey);
+                               }
+                               break;
+                       case 5:
+                               /* 0x5000-0x5FFF: LID */
+                               /* we don't handle it through this path, just
+                                * eat up known LID events */
+                               if (hkey != 0x5001 && hkey != 0x5002) {
+                                       printk(IBM_ERR
+                                               "unknown LID-related hotkey event: 0x%04x\n",
+                                               hkey);
+                               }
+                               break;
+                       case 7:
+                               /* 0x7000-0x7FFF: misc */
+                               if (tp_features.hotkey_wlsw && hkey == 0x7000) {
+                                               tpacpi_input_send_radiosw();
+                                               sendacpi = 0;
+                                       break;
+                               }
+                               /* fallthrough to default */
+                       default:
+                               /* case 2: dock-related */
+                               /*      0x2305 - T43 waking up due to bay lever eject while aslept */
+                               /* case 3: ultra-bay related. maybe bay in dock? */
+                               /*      0x3003 - T43 after wake up by bay lever eject (0x2305) */
+                               printk(IBM_NOTICE "unhandled hotkey event 0x%04x\n", hkey);
+                       }
+               }
 
-       if (acpi_evalf(hkey_handle, &hkey, "MHKP", "d"))
-               acpi_bus_generate_event(ibm->acpi->device, event, hkey);
-       else {
-               printk(IBM_ERR "unknown hotkey event %d\n", event);
+               if (sendacpi)
+                       acpi_bus_generate_event(ibm->acpi->device, event, hkey);
+       else {
+               printk(IBM_ERR "unknown hotkey notification event %d\n", event);
                acpi_bus_generate_event(ibm->acpi->device, event, 0);
        }
 }
 
+static void hotkey_resume(void)
+{
+       tpacpi_input_send_radiosw();
+}
+
 /*
  * Call with hotkey_mutex held
  */
-static int hotkey_get(int *status, int *mask)
+static int hotkey_get(int *status, u32 *mask)
 {
        if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
                return -EIO;
@@ -905,7 +1219,7 @@ static int hotkey_get(int *status, int *mask)
 /*
  * Call with hotkey_mutex held
  */
-static int hotkey_set(int status, int mask)
+static int hotkey_set(int status, u32 mask)
 {
        int i;
 
@@ -926,7 +1240,8 @@ static int hotkey_set(int status, int mask)
 /* procfs -------------------------------------------------------------- */
 static int hotkey_read(char *p)
 {
-       int res, status, mask;
+       int res, status;
+       u32 mask;
        int len = 0;
 
        if (!tp_features.hotkey) {
@@ -944,7 +1259,7 @@ static int hotkey_read(char *p)
 
        len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0));
        if (tp_features.hotkey_mask) {
-               len += sprintf(p + len, "mask:\t\t0x%04x\n", mask);
+               len += sprintf(p + len, "mask:\t\t0x%08x\n", mask);
                len += sprintf(p + len,
                               "commands:\tenable, disable, reset, <mask>\n");
        } else {
@@ -957,7 +1272,8 @@ static int hotkey_read(char *p)
 
 static int hotkey_write(char *buf)
 {
-       int res, status, mask;
+       int res, status;
+       u32 mask;
        char *cmd;
        int do_cmd = 0;
 
@@ -1012,6 +1328,7 @@ static struct ibm_struct hotkey_driver_data = {
        .read = hotkey_read,
        .write = hotkey_write,
        .exit = hotkey_exit,
+       .resume = hotkey_resume,
        .acpi = &ibm_hotkey_acpidriver,
 };
 
@@ -1770,7 +2087,10 @@ static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = {
         .type = ACPI_SYSTEM_NOTIFY,
        },
        {
-        .hid = IBM_PCI_HID,
+       /* THIS ONE MUST NEVER BE USED FOR DRIVER AUTOLOADING.
+        * We just use it to get notifications of dock hotplug
+        * in very old thinkpads */
+        .hid = PCI_ROOT_HID_STRING,
         .notify = dock_notify,
         .handle = &pci_handle,
         .type = ACPI_SYSTEM_NOTIFY,
@@ -1829,7 +2149,7 @@ static int __init dock_init2(struct ibm_init_struct *iibm)
 static void dock_notify(struct ibm_struct *ibm, u32 event)
 {
        int docked = dock_docked();
-       int pci = ibm->acpi->hid && strstr(ibm->acpi->hid, IBM_PCI_HID);
+       int pci = ibm->acpi->hid && strstr(ibm->acpi->hid, PCI_ROOT_HID_STRING);
 
        if (event == 1 && !pci) /* 570 */
                acpi_bus_generate_event(ibm->acpi->device, event, 1);   /* button */
@@ -2389,7 +2709,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
 
        acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
 
-       if (ibm_thinkpad_ec_found && experimental) {
+       if (thinkpad_id.ec_model) {
                /*
                 * Direct EC access mode: sensors at registers
                 * 0x78-0x7F, 0xC0-0xC7.  Registers return 0x00 for
@@ -2533,6 +2853,8 @@ static int thermal_get_sensor(int idx, s32 *value)
                        snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);
                        if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
                                return -EIO;
+                       if (t > 127 || t < -127)
+                               t = TP_EC_THERMAL_TMP_NA;
                        *value = t * 1000;
                        return 0;
                }
@@ -2671,22 +2993,39 @@ static struct ibm_struct ecdump_driver_data = {
  * Backlight/brightness subdriver
  */
 
-static struct backlight_device *ibm_backlight_device = NULL;
+static struct backlight_device *ibm_backlight_device;
 
 static struct backlight_ops ibm_backlight_data = {
         .get_brightness = brightness_get,
         .update_status  = brightness_update_status,
 };
 
+static struct mutex brightness_mutex;
+
 static int __init brightness_init(struct ibm_init_struct *iibm)
 {
        int b;
 
        vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n");
 
+       mutex_init(&brightness_mutex);
+
+       if (!brightness_mode) {
+               if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
+                       brightness_mode = 2;
+               else
+                       brightness_mode = 3;
+
+               dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n",
+                       brightness_mode);
+       }
+
+       if (brightness_mode > 3)
+               return -EINVAL;
+
        b = brightness_get(NULL);
        if (b < 0)
-               return b;
+               return 1;
 
        ibm_backlight_device = backlight_device_register(
                                        TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL,
@@ -2722,34 +3061,79 @@ static int brightness_update_status(struct backlight_device *bd)
                                bd->props.brightness : 0);
 }
 
+/*
+ * ThinkPads can read brightness from two places: EC 0x31, or
+ * CMOS NVRAM byte 0x5E, bits 0-3.
+ */
 static int brightness_get(struct backlight_device *bd)
 {
-       u8 level;
-       if (!acpi_ec_read(brightness_offset, &level))
-               return -EIO;
+       u8 lec = 0, lcmos = 0, level = 0;
 
-       level &= 0x7;
+       if (brightness_mode & 1) {
+               if (!acpi_ec_read(brightness_offset, &lec))
+                       return -EIO;
+               lec &= 7;
+               level = lec;
+       };
+       if (brightness_mode & 2) {
+               lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
+                        & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
+                       >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
+               level = lcmos;
+       }
+
+       if (brightness_mode == 3 && lec != lcmos) {
+               printk(IBM_ERR
+                       "CMOS NVRAM (%u) and EC (%u) do not agree "
+                       "on display brightness level\n",
+                       (unsigned int) lcmos,
+                       (unsigned int) lec);
+               return -EIO;
+       }
 
        return level;
 }
 
 static int brightness_set(int value)
 {
-       int cmos_cmd, inc, i;
-       int current_value = brightness_get(NULL);
+       int cmos_cmd, inc, i, res;
+       int current_value;
+
+       if (value > 7)
+               return -EINVAL;
 
-       value &= 7;
+       res = mutex_lock_interruptible(&brightness_mutex);
+       if (res < 0)
+               return res;
+
+       current_value = brightness_get(NULL);
+       if (current_value < 0) {
+               res = current_value;
+               goto errout;
+       }
 
-       cmos_cmd = value > current_value ? TP_CMOS_BRIGHTNESS_UP : TP_CMOS_BRIGHTNESS_DOWN;
+       cmos_cmd = value > current_value ?
+                       TP_CMOS_BRIGHTNESS_UP :
+                       TP_CMOS_BRIGHTNESS_DOWN;
        inc = value > current_value ? 1 : -1;
+
+       res = 0;
        for (i = current_value; i != value; i += inc) {
-               if (issue_thinkpad_cmos_command(cmos_cmd))
-                       return -EIO;
-               if (!acpi_ec_write(brightness_offset, i + inc))
-                       return -EIO;
+               if ((brightness_mode & 2) &&
+                   issue_thinkpad_cmos_command(cmos_cmd)) {
+                       res = -EIO;
+                       goto errout;
+               }
+               if ((brightness_mode & 1) &&
+                   !acpi_ec_write(brightness_offset, i + inc)) {
+                       res = -EIO;
+                       goto errout;;
+               }
        }
 
-       return 0;
+errout:
+       mutex_unlock(&brightness_mutex);
+       return res;
 }
 
 static int brightness_read(char *p)
@@ -3273,20 +3657,19 @@ static int __init fan_init(struct ibm_init_struct *iibm)
                         * Enable for TP-1Y (T43), TP-78 (R51e),
                         * TP-76 (R52), TP-70 (T43, R52), which are known
                         * to be buggy. */
-                       if (fan_control_initial_status == 0x07 &&
-                           ibm_thinkpad_ec_found &&
-                           ((ibm_thinkpad_ec_found[0] == '1' &&
-                             ibm_thinkpad_ec_found[1] == 'Y') ||
-                            (ibm_thinkpad_ec_found[0] == '7' &&
-                             (ibm_thinkpad_ec_found[1] == '6' ||
-                              ibm_thinkpad_ec_found[1] == '8' ||
-                              ibm_thinkpad_ec_found[1] == '0'))
-                           )) {
-                               printk(IBM_NOTICE
-                                      "fan_init: initial fan status is "
-                                      "unknown, assuming it is in auto "
-                                      "mode\n");
-                               tp_features.fan_ctrl_status_undef = 1;
+                       if (fan_control_initial_status == 0x07) {
+                               switch (thinkpad_id.ec_model) {
+                               case 0x5931: /* TP-1Y */
+                               case 0x3837: /* TP-78 */
+                               case 0x3637: /* TP-76 */
+                               case 0x3037: /* TP-70 */
+                                       printk(IBM_NOTICE
+                                              "fan_init: initial fan status is "
+                                              "unknown, assuming it is in auto "
+                                              "mode\n");
+                                       tp_features.fan_ctrl_status_undef = 1;
+                                       ;;
+                               }
                        }
                } else {
                        printk(IBM_ERR
@@ -3474,7 +3857,7 @@ static void fan_watchdog_fire(struct work_struct *ignored)
 
 static void fan_watchdog_reset(void)
 {
-       static int fan_watchdog_active = 0;
+       static int fan_watchdog_active;
 
        if (fan_control_access_mode == TPACPI_FAN_WR_NONE)
                return;
@@ -3877,7 +4260,7 @@ static struct ibm_struct fan_driver_data = {
  ****************************************************************************/
 
 /* /proc support */
-static struct proc_dir_entry *proc_dir = NULL;
+static struct proc_dir_entry *proc_dir;
 
 /* Subdriver registry */
 static LIST_HEAD(tpacpi_all_drivers);
@@ -4020,13 +4403,30 @@ static void ibm_exit(struct ibm_struct *ibm)
 
 /* Probing */
 
-static char *ibm_thinkpad_ec_found = NULL;
-
-static char* __init check_dmi_for_ec(void)
+static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp)
 {
        struct dmi_device *dev = NULL;
        char ec_fw_string[18];
 
+       if (!tp)
+               return;
+
+       memset(tp, 0, sizeof(*tp));
+
+       if (dmi_name_in_vendors("IBM"))
+               tp->vendor = PCI_VENDOR_ID_IBM;
+       else if (dmi_name_in_vendors("LENOVO"))
+               tp->vendor = PCI_VENDOR_ID_LENOVO;
+       else
+               return;
+
+       tp->bios_version_str = kstrdup(dmi_get_system_info(DMI_BIOS_VERSION),
+                                       GFP_KERNEL);
+       if (!tp->bios_version_str)
+               return;
+       tp->bios_model = tp->bios_version_str[0]
+                        | (tp->bios_version_str[1] << 8);
+
        /*
         * ThinkPad T23 or newer, A31 or newer, R50e or newer,
         * X32 or newer, all Z series;  Some models must have an
@@ -4040,10 +4440,20 @@ static char* __init check_dmi_for_ec(void)
                           ec_fw_string) == 1) {
                        ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
                        ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
-                       return kstrdup(ec_fw_string, GFP_KERNEL);
+
+                       tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL);
+                       tp->ec_model = ec_fw_string[0]
+                                       | (ec_fw_string[1] << 8);
+                       break;
                }
        }
-       return NULL;
+
+       tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION),
+                                       GFP_KERNEL);
+       if (strnicmp(tp->model_str, "ThinkPad", 8) != 0) {
+               kfree(tp->model_str);
+               tp->model_str = NULL;
+       }
 }
 
 static int __init probe_for_thinkpad(void)
@@ -4057,7 +4467,7 @@ static int __init probe_for_thinkpad(void)
         * Non-ancient models have better DMI tagging, but very old models
         * don't.
         */
-       is_thinkpad = dmi_name_in_vendors("ThinkPad");
+       is_thinkpad = (thinkpad_id.model_str != NULL);
 
        /* ec is required because many other handles are relative to it */
        IBM_ACPIHANDLE_INIT(ec);
@@ -4073,7 +4483,7 @@ static int __init probe_for_thinkpad(void)
         * false positives a damn great deal
         */
        if (!is_thinkpad)
-               is_thinkpad = dmi_name_in_vendors("IBM");
+               is_thinkpad = (thinkpad_id.vendor == PCI_VENDOR_ID_IBM);
 
        if (!is_thinkpad && !force_load)
                return -ENODEV;
@@ -4185,10 +4595,13 @@ static u32 dbg_level;
 module_param_named(debug, dbg_level, uint, 0);
 
 static int force_load;
-module_param(force_load, int, 0);
+module_param(force_load, bool, 0);
 
 static int fan_control_allowed;
-module_param_named(fan_control, fan_control_allowed, int, 0);
+module_param_named(fan_control, fan_control_allowed, bool, 0);
+
+static int brightness_mode;
+module_param_named(brightness_mode, brightness_mode, int, 0);
 
 #define IBM_PARAM(feature) \
        module_param_call(feature, set_ibm_param, NULL, NULL, 0)
@@ -4216,12 +4629,16 @@ static int __init thinkpad_acpi_module_init(void)
        int ret, i;
 
        /* Driver-level probe */
+
+       get_thinkpad_model_data(&thinkpad_id);
        ret = probe_for_thinkpad();
-       if (ret)
+       if (ret) {
+               thinkpad_acpi_module_exit();
                return ret;
+       }
 
        /* Driver initialization */
-       ibm_thinkpad_ec_found = check_dmi_for_ec();
+
        IBM_ACPIHANDLE_INIT(ecrd);
        IBM_ACPIHANDLE_INIT(ecwr);
 
@@ -4265,6 +4682,22 @@ static int __init thinkpad_acpi_module_init(void)
                thinkpad_acpi_module_exit();
                return ret;
        }
+       tpacpi_inputdev = input_allocate_device();
+       if (!tpacpi_inputdev) {
+               printk(IBM_ERR "unable to allocate input device\n");
+               thinkpad_acpi_module_exit();
+               return -ENOMEM;
+       } else {
+               /* Prepare input device, but don't register */
+               tpacpi_inputdev->name = "ThinkPad Extra Buttons";
+               tpacpi_inputdev->phys = IBM_DRVR_NAME "/input0";
+               tpacpi_inputdev->id.bustype = BUS_HOST;
+               tpacpi_inputdev->id.vendor = (thinkpad_id.vendor) ?
+                                               thinkpad_id.vendor :
+                                               PCI_VENDOR_ID_IBM;
+               tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT;
+               tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION;
+       }
        for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
                ret = ibm_init(&ibms_init[i]);
                if (ret >= 0 && *ibms_init[i].param)
@@ -4274,6 +4707,14 @@ static int __init thinkpad_acpi_module_init(void)
                        return ret;
                }
        }
+       ret = input_register_device(tpacpi_inputdev);
+       if (ret < 0) {
+               printk(IBM_ERR "unable to register input device\n");
+               thinkpad_acpi_module_exit();
+               return ret;
+       } else {
+               tp_features.input_device_registered = 1;
+       }
 
        return 0;
 }
@@ -4290,6 +4731,13 @@ static void thinkpad_acpi_module_exit(void)
 
        dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n");
 
+       if (tpacpi_inputdev) {
+               if (tp_features.input_device_registered)
+                       input_unregister_device(tpacpi_inputdev);
+               else
+                       input_free_device(tpacpi_inputdev);
+       }
+
        if (tpacpi_hwmon)
                hwmon_device_unregister(tpacpi_hwmon);
 
@@ -4302,7 +4750,9 @@ static void thinkpad_acpi_module_exit(void)
        if (proc_dir)
                remove_proc_entry(IBM_PROC_DIR, acpi_root_dir);
 
-       kfree(ibm_thinkpad_ec_found);
+       kfree(thinkpad_id.bios_version_str);
+       kfree(thinkpad_id.ec_version_str);
+       kfree(thinkpad_id.model_str);
 }
 
 module_init(thinkpad_acpi_module_init);
index 72d62f2dabb976069ef26dabb4be6abad030be57..b7a4a888cc8b5d209e7a562f633001f37c8119ff 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/list.h>
 #include <linux/mutex.h>
 
+#include <linux/nvram.h>
 #include <linux/proc_fs.h>
 #include <linux/sysfs.h>
 #include <linux/backlight.h>
@@ -39,6 +40,7 @@
 #include <linux/platform_device.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/input.h>
 #include <asm/uaccess.h>
 
 #include <linux/dmi.h>
@@ -48,6 +50,7 @@
 #include <acpi/acpi_drivers.h>
 #include <acpi/acnamesp.h>
 
+#include <linux/pci_ids.h>
 
 /****************************************************************************
  * Main driver
 #define TP_CMOS_BRIGHTNESS_UP  4
 #define TP_CMOS_BRIGHTNESS_DOWN        5
 
+/* ThinkPad CMOS NVRAM constants */
+#define TP_NVRAM_ADDR_BRIGHTNESS       0x5e
+#define TP_NVRAM_MASK_LEVEL_BRIGHTNESS 0x07
+#define TP_NVRAM_POS_LEVEL_BRIGHTNESS 0
+
 #define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off")
 #define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
 #define strlencmp(a,b) (strncmp((a), (b), strlen(b)))
@@ -98,9 +106,13 @@ static const char *str_supported(int is_supported);
 #define vdbg_printk(a_dbg_level, format, arg...)
 #endif
 
+/* Input IDs */
+#define TPACPI_HKEY_INPUT_VENDOR       PCI_VENDOR_ID_IBM
+#define TPACPI_HKEY_INPUT_PRODUCT      0x5054 /* "TP" */
+#define TPACPI_HKEY_INPUT_VERSION      0x4101
+
 /* ACPI HIDs */
 #define IBM_HKEY_HID    "IBM0068"
-#define IBM_PCI_HID     "PNP0A03"
 
 /* ACPI helpers */
 static int __must_check acpi_evalf(acpi_handle handle,
@@ -161,6 +173,7 @@ static int parse_strtoul(const char *buf, unsigned long max,
 static struct platform_device *tpacpi_pdev;
 static struct class_device *tpacpi_hwmon;
 static struct platform_driver tpacpi_pdriver;
+static struct input_dev *tpacpi_inputdev;
 static int tpacpi_create_driver_attributes(struct device_driver *drv);
 static void tpacpi_remove_driver_attributes(struct device_driver *drv);
 
@@ -168,9 +181,7 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv);
 static int experimental;
 static u32 dbg_level;
 static int force_load;
-static char *ibm_thinkpad_ec_found;
 
-static char* check_dmi_for_ec(void);
 static int thinkpad_acpi_module_init(void);
 static void thinkpad_acpi_module_exit(void);
 
@@ -197,6 +208,7 @@ struct ibm_struct {
        int (*read) (char *);
        int (*write) (char *);
        void (*exit) (void);
+       void (*resume) (void);
 
        struct list_head all_drivers;
 
@@ -228,12 +240,29 @@ static struct {
        u16 bluetooth:1;
        u16 hotkey:1;
        u16 hotkey_mask:1;
+       u16 hotkey_wlsw:1;
        u16 light:1;
        u16 light_status:1;
        u16 wan:1;
        u16 fan_ctrl_status_undef:1;
+       u16 input_device_registered:1;
 } tp_features;
 
+struct thinkpad_id_data {
+       unsigned int vendor;    /* ThinkPad vendor:
+                                * PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */
+
+       char *bios_version_str; /* Something like 1ZET51WW (1.03z) */
+       char *ec_version_str;   /* Something like 1ZHT51WW-1.04a */
+
+       u16 bios_model;         /* Big Endian, TP-1Y = 0x5931, 0 = unknown */
+       u16 ec_model;
+
+       char *model_str;
+};
+
+static struct thinkpad_id_data thinkpad_id;
+
 static struct list_head tpacpi_all_drivers;
 
 static struct ibm_init_struct ibms_init[];
@@ -300,6 +329,7 @@ static int bluetooth_write(char *buf);
 
 static struct backlight_device *ibm_backlight_device;
 static int brightness_offset = 0x31;
+static int brightness_mode;
 
 static int brightness_init(struct ibm_init_struct *iibm);
 static void brightness_exit(void);
@@ -415,14 +445,14 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc);
  */
 
 static int hotkey_orig_status;
-static int hotkey_orig_mask;
+static u32 hotkey_orig_mask;
 
 static struct mutex hotkey_mutex;
 
 static int hotkey_init(struct ibm_init_struct *iibm);
 static void hotkey_exit(void);
-static int hotkey_get(int *status, int *mask);
-static int hotkey_set(int status, int mask);
+static int hotkey_get(int *status, u32 *mask);
+static int hotkey_set(int status, u32 mask);
 static void hotkey_notify(struct ibm_struct *ibm, u32 event);
 static int hotkey_read(char *p);
 static int hotkey_write(char *buf);
index 28c881895ab79c42a154481644cae2366d5bd47b..15aab374127ee1d625aab1a9c39ea58286eb7430 100644 (file)
@@ -903,8 +903,10 @@ static int __init at91_mci_probe(struct platform_device *pdev)
        /*
         * Add host to MMC layer
         */
-       if (host->board->det_pin)
+       if (host->board->det_pin) {
                host->present = !at91_get_gpio_value(host->board->det_pin);
+               device_init_wakeup(&pdev->dev, 1);
+       }
        else
                host->present = -1;
 
@@ -940,6 +942,7 @@ static int __exit at91_mci_remove(struct platform_device *pdev)
        host = mmc_priv(mmc);
 
        if (host->present != -1) {
+               device_init_wakeup(&pdev->dev, 0);
                free_irq(host->board->det_pin, host);
                cancel_delayed_work(&host->mmc->detect);
        }
@@ -966,8 +969,12 @@ static int __exit at91_mci_remove(struct platform_device *pdev)
 static int at91_mci_suspend(struct platform_device *pdev, pm_message_t state)
 {
        struct mmc_host *mmc = platform_get_drvdata(pdev);
+       struct at91mci_host *host = mmc_priv(mmc);
        int ret = 0;
 
+       if (device_may_wakeup(&pdev->dev))
+               enable_irq_wake(host->board->det_pin);
+
        if (mmc)
                ret = mmc_suspend_host(mmc, state);
 
@@ -977,8 +984,12 @@ static int at91_mci_suspend(struct platform_device *pdev, pm_message_t state)
 static int at91_mci_resume(struct platform_device *pdev)
 {
        struct mmc_host *mmc = platform_get_drvdata(pdev);
+       struct at91mci_host *host = mmc_priv(mmc);
        int ret = 0;
 
+       if (device_may_wakeup(&pdev->dev))
+               disable_irq_wake(host->board->det_pin);
+
        if (mmc)
                ret = mmc_resume_host(mmc);
 
index 10d15c39d003a58e372f306c53c3f5d3aba76787..4a24db028d87f1902ce2b27628a3f90dff29852f 100644 (file)
@@ -1024,6 +1024,8 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
 
        intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK);
 
+       intmask &= ~SDHCI_INT_ERROR;
+
        if (intmask & SDHCI_INT_BUS_POWER) {
                printk(KERN_ERR "%s: Card is consuming too much power!\n",
                        mmc_hostname(host->mmc));
index 7400f4bc114f7c18a1c921e71de2fd199757bc41..a6c870480b8a02700cde756566e05926f5284fd5 100644 (file)
 #define  SDHCI_INT_CARD_INSERT 0x00000040
 #define  SDHCI_INT_CARD_REMOVE 0x00000080
 #define  SDHCI_INT_CARD_INT    0x00000100
+#define  SDHCI_INT_ERROR       0x00008000
 #define  SDHCI_INT_TIMEOUT     0x00010000
 #define  SDHCI_INT_CRC         0x00020000
 #define  SDHCI_INT_END_BIT     0x00040000
index 3073f679584b9cd229c99dd60926cb2569c5d5ee..f8a602caabcb9595d249065569eb0dbc03a3aef4 100644 (file)
@@ -5,6 +5,7 @@
 
 menuconfig NETDEVICES
        default y if UML
+       depends on NET
        bool "Network device support"
        ---help---
          You can say N here if you don't intend to connect your Linux box to
index f21148e7b579ec3e2242b77394d3431e0a0d3700..80f33b6d57138145b6cc41a2a9654803cc0db045 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/types.h>
 #include <linux/fcntl.h>
 #include <linux/interrupt.h>
-#include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
 #include <linux/slab.h>
@@ -75,7 +74,7 @@ static void ether1_timeout(struct net_device *dev);
 
 /* ------------------------------------------------------------------------- */
 
-static char version[] __initdata = "ether1 ethernet driver (c) 2000 Russell King v1.07\n";
+static char version[] __devinitdata = "ether1 ethernet driver (c) 2000 Russell King v1.07\n";
 
 #define BUS_16 16
 #define BUS_8  8
index a7cac695a9bddca757bcd5e22a590f44a2882a6a..3805506a3ab8475f0bf84629b687a2b2da8d7ac1 100644 (file)
@@ -51,7 +51,6 @@
 #include <linux/types.h>
 #include <linux/fcntl.h>
 #include <linux/interrupt.h>
-#include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
 #include <linux/slab.h>
@@ -69,7 +68,7 @@
 #include <asm/ecard.h>
 #include <asm/io.h>
 
-static char version[] __initdata = "ether3 ethernet driver (c) 1995-2000 R.M.King v1.17\n";
+static char version[] __devinitdata = "ether3 ethernet driver (c) 1995-2000 R.M.King v1.17\n";
 
 #include "ether3.h"
 
index 769ba69451f4f7887037d2c43fea94b4295a61db..0d37d9d1fd787e2631c53b6982137fe38c6496d2 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/types.h>
 #include <linux/fcntl.h>
 #include <linux/interrupt.h>
-#include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
 #include <linux/slab.h>
index 829da9a1d113e01768dd6ae3973a672bc3fd09ed..2098d0af8ff5fee635ea8fdbddcc378209d5f754 100644 (file)
@@ -155,6 +155,15 @@ config KINGSUN_DONGLE
          To compile it as a module, choose M here: the module will be called
          kingsun-sir.
 
+config EP7211_DONGLE
+       tristate "EP7211 I/R support"
+       depends on IRTTY_SIR && ARCH_EP7211 && IRDA && EXPERIMENTAL
+       help
+         Say Y here if you want to build support for the Cirrus logic
+         EP7211 chipset's infrared module.
+
+
+
 comment "Old SIR device drivers"
 
 config IRPORT_SIR
@@ -355,7 +364,7 @@ config WINBOND_FIR
 
 config TOSHIBA_FIR
        tristate "Toshiba Type-O IR Port"
-       depends on IRDA && PCI && !64BIT
+       depends on IRDA && PCI && !64BIT && VIRT_TO_BUS
        help
          Say Y here if you want to build support for the Toshiba Type-O IR
          and Donau oboe chipsets. These chipsets are used by the Toshiba
index 233a2f9237307835934ecbde083ec2e82e149ad4..2808ef5c7b79187ac93cdf5a1f00da70c3e2abd0 100644 (file)
@@ -45,6 +45,7 @@ obj-$(CONFIG_MCP2120_DONGLE)  += mcp2120-sir.o
 obj-$(CONFIG_ACT200L_DONGLE)   += act200l-sir.o
 obj-$(CONFIG_MA600_DONGLE)     += ma600-sir.o
 obj-$(CONFIG_TOIM3232_DONGLE)  += toim3232-sir.o
+obj-$(CONFIG_EP7211_DONGLE)    += ep7211-sir.o
 obj-$(CONFIG_KINGSUN_DONGLE)   += kingsun-sir.o
 
 # The SIR helper module
diff --git a/drivers/net/irda/ep7211-sir.c b/drivers/net/irda/ep7211-sir.c
new file mode 100644 (file)
index 0000000..8315724
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * IR port driver for the Cirrus Logic EP7211 processor.
+ *
+ * Copyright 2001, Blue Mug Inc.  All rights reserved.
+ * Copyright 2007, Samuel Ortiz <samuel@sortiz.org>
+ */
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/tty.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <net/irda/irda.h>
+#include <net/irda/irda_device.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+#include "sir-dev.h"
+
+#define MIN_DELAY 25      /* 15 us, but wait a little more to be sure */
+#define MAX_DELAY 10000   /* 1 ms */
+
+static int ep7211_open(struct sir_dev *dev);
+static int ep7211_close(struct sir_dev *dev);
+static int ep7211_change_speed(struct sir_dev *dev, unsigned speed);
+static int ep7211_reset(struct sir_dev *dev);
+
+static struct dongle_driver ep7211 = {
+       .owner          = THIS_MODULE,
+       .driver_name    = "EP7211 IR driver",
+       .type           = IRDA_EP7211_DONGLE,
+       .open           = ep7211_open,
+       .close          = ep7211_close,
+       .reset          = ep7211_reset,
+       .set_speed      = ep7211_change_speed,
+};
+
+static int __init ep7211_sir_init(void)
+{
+       return irda_register_dongle(&ep7211);
+}
+
+static void __exit ep7211_sir_cleanup(void)
+{
+       irda_unregister_dongle(&ep7211);
+}
+
+static int ep7211_open(struct sir_dev *dev)
+{
+       unsigned int syscon;
+
+       /* Turn on the SIR encoder. */
+       syscon = clps_readl(SYSCON1);
+       syscon |= SYSCON1_SIREN;
+       clps_writel(syscon, SYSCON1);
+
+       return 0;
+}
+
+static int ep7211_close(struct sir_dev *dev)
+{
+       unsigned int syscon;
+
+       /* Turn off the SIR encoder. */
+       syscon = clps_readl(SYSCON1);
+       syscon &= ~SYSCON1_SIREN;
+       clps_writel(syscon, SYSCON1);
+
+       return 0;
+}
+
+static int ep7211_change_speed(struct sir_dev *dev, unsigned speed)
+{
+       return 0;
+}
+
+static int ep7211_reset(struct sir_dev *dev)
+{
+       return 0;
+}
+
+MODULE_AUTHOR("Samuel Ortiz <samuel@sortiz.org>");
+MODULE_DESCRIPTION("EP7211 IR dongle driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("irda-dongle-13"); /* IRDA_EP7211_DONGLE */
+
+module_init(ep7211_sir_init);
+module_exit(ep7211_sir_cleanup);
index 3c45142c40b2f0f8421cf488440ada36dd3b67f2..b01985498460f926d0f6e920d900b10fb1b59cb8 100644 (file)
@@ -1316,7 +1316,7 @@ static struct of_device_id m8xx_pcmcia_match[] = {
 MODULE_DEVICE_TABLE(of, m8xx_pcmcia_match);
 
 static struct of_platform_driver m8xx_pcmcia_driver = {
-       .name = (char *)driver_name,
+       .name = driver_name,
        .match_table = m8xx_pcmcia_match,
        .probe = m8xx_probe,
        .remove = m8xx_remove,
index 35f34665e3c44f06e01c103226462023cdaa5aab..9d8d40d5c8f77f1c8f969805de31f640bac12c31 100644 (file)
@@ -38,6 +38,9 @@ config RTC_HCTOSYS_DEVICE
          clock, usually rtc0.  Initialization is done when the system
          starts up, and when it resumes from a low power state.
 
+         The driver for this RTC device must be loaded before late_initcall
+         functions run, so it must usually be statically linked.
+
          This clock should be battery-backed, so that it reads the correct
          time when the system boots from a power-off state.  Otherwise, your
          system will need an external clock source (like an NTP server).
@@ -305,6 +308,16 @@ config RTC_DRV_DS1553
          This driver can also be built as a module. If so, the module
          will be called rtc-ds1553.
 
+config RTC_DRV_STK17TA8
+       tristate "Simtek STK17TA8"
+       depends on RTC_CLASS
+       help
+         If you say yes here you get support for the
+         Simtek STK17TA8 timekeeping chip.
+
+         This driver can also be built as a module. If so, the module
+         will be called rtc-stk17ta8.
+
 config RTC_DRV_DS1742
        tristate "Dallas DS1742/1743"
        depends on RTC_CLASS
index 3109af9a16517706750e5b8732ed3333e3aef7c7..7ede9e7253607de74244cae1e979150037f40a40 100644 (file)
@@ -32,6 +32,7 @@ obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o
 obj-$(CONFIG_RTC_DRV_M41T80)   += rtc-m41t80.o
 obj-$(CONFIG_RTC_DRV_M48T86)   += rtc-m48t86.o
 obj-$(CONFIG_RTC_DRV_DS1553)   += rtc-ds1553.o
+obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o
 obj-$(CONFIG_RTC_DRV_RS5C313)  += rtc-rs5c313.o
 obj-$(CONFIG_RTC_DRV_EP93XX)   += rtc-ep93xx.o
 obj-$(CONFIG_RTC_DRV_SA1100)   += rtc-sa1100.o
index f98a83a11aaeb66411a9083f78f887807528e732..46da5714932c3e15f9607058a4855aeba02f6e3d 100644 (file)
@@ -407,7 +407,7 @@ static __init int ds1553_init(void)
 
 static __exit void ds1553_exit(void)
 {
-       return platform_driver_unregister(&ds1553_rtc_driver);
+       platform_driver_unregister(&ds1553_rtc_driver);
 }
 
 module_init(ds1553_init);
index d1778ae8bca58c6e9b8a45dc534e4345b21cc7a8..b2e5481ba3b610766eee9936170c6e3455d03d21 100644 (file)
@@ -263,7 +263,7 @@ static __init int ds1742_init(void)
 
 static __exit void ds1742_exit(void)
 {
-       return platform_driver_unregister(&ds1742_rtc_driver);
+       platform_driver_unregister(&ds1742_rtc_driver);
 }
 
 module_init(ds1742_init);
index eee4ee5bb75af15a9688072b46616b80d5949857..a1cd448639c958d927b5be9634c9ccc3367e9ee1 100644 (file)
 #define MAX6900_REG_DW                 5       /* day of week   1-7  */
 #define MAX6900_REG_YR                 6       /* year         00-99 */
 #define MAX6900_REG_CT                 7       /* control */
-#define MAX6900_REG_LEN                        8
+                                               /* register 8 is undocumented */
+#define MAX6900_REG_CENTURY            9       /* century */
+#define MAX6900_REG_LEN                        10
+
+#define MAX6900_BURST_LEN              8       /* can burst r/w first 8 regs */
 
 #define MAX6900_REG_CT_WP              (1 << 7)        /* Write Protect */
 
+
 /*
  * register read/write commands
  */
 #define MAX6900_REG_CONTROL_WRITE      0x8e
-#define MAX6900_REG_BURST_READ         0xbf
-#define MAX6900_REG_BURST_WRITE                0xbe
+#define MAX6900_REG_CENTURY_WRITE      0x92
+#define MAX6900_REG_CENTURY_READ       0x93
 #define MAX6900_REG_RESERVED_READ      0x96
+#define MAX6900_REG_BURST_WRITE                0xbe
+#define MAX6900_REG_BURST_READ         0xbf
 
 #define MAX6900_IDLE_TIME_AFTER_WRITE  3       /* specification says 2.5 mS */
 
@@ -58,19 +65,32 @@ static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind);
 
 static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf)
 {
-       u8 reg_addr[1] = { MAX6900_REG_BURST_READ };
-       struct i2c_msg msgs[2] = {
+       u8 reg_burst_read[1] = { MAX6900_REG_BURST_READ };
+       u8 reg_century_read[1] = { MAX6900_REG_CENTURY_READ };
+       struct i2c_msg msgs[4] = {
                {
                        .addr   = client->addr,
                        .flags  = 0, /* write */
-                       .len    = sizeof(reg_addr),
-                       .buf    = reg_addr
+                       .len    = sizeof(reg_burst_read),
+                       .buf    = reg_burst_read
                },
                {
                        .addr   = client->addr,
                        .flags  = I2C_M_RD,
-                       .len    = MAX6900_REG_LEN,
+                       .len    = MAX6900_BURST_LEN,
                        .buf    = buf
+               },
+               {
+                       .addr   = client->addr,
+                       .flags  = 0, /* write */
+                       .len    = sizeof(reg_century_read),
+                       .buf    = reg_century_read
+               },
+               {
+                       .addr   = client->addr,
+                       .flags  = I2C_M_RD,
+                       .len    = sizeof(buf[MAX6900_REG_CENTURY]),
+                       .buf    = &buf[MAX6900_REG_CENTURY]
                }
        };
        int rc;
@@ -86,33 +106,58 @@ static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf)
 
 static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf)
 {
-       u8 i2c_buf[MAX6900_REG_LEN + 1] = { MAX6900_REG_BURST_WRITE };
-       struct i2c_msg msgs[1] = {
+       u8 i2c_century_buf[1 + 1] = { MAX6900_REG_CENTURY_WRITE };
+       struct i2c_msg century_msgs[1] = {
                {
                        .addr   = client->addr,
                        .flags  = 0, /* write */
-                       .len    = MAX6900_REG_LEN + 1,
-                       .buf    = i2c_buf
+                       .len    = sizeof(i2c_century_buf),
+                       .buf    = i2c_century_buf
+               }
+       };
+       u8 i2c_burst_buf[MAX6900_BURST_LEN + 1] = { MAX6900_REG_BURST_WRITE };
+       struct i2c_msg burst_msgs[1] = {
+               {
+                       .addr   = client->addr,
+                       .flags  = 0, /* write */
+                       .len    = sizeof(i2c_burst_buf),
+                       .buf    = i2c_burst_buf
                }
        };
        int rc;
 
-       memcpy(&i2c_buf[1], buf, MAX6900_REG_LEN);
+       /*
+        * We have to make separate calls to i2c_transfer because of
+        * the need to delay after each write to the chip.  Also,
+        * we write the century byte first, since we set the write-protect
+        * bit as part of the burst write.
+        */
+       i2c_century_buf[1] = buf[MAX6900_REG_CENTURY];
+       rc = i2c_transfer(client->adapter, century_msgs,
+                         ARRAY_SIZE(century_msgs));
+       if (rc != ARRAY_SIZE(century_msgs))
+               goto write_failed;
+       msleep(MAX6900_IDLE_TIME_AFTER_WRITE);
 
-       rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
-       if (rc != ARRAY_SIZE(msgs)) {
-               dev_err(&client->dev, "%s: register write failed\n",
-                       __FUNCTION__);
-               return -EIO;
-       }
+       memcpy(&i2c_burst_buf[1], buf, MAX6900_BURST_LEN);
+
+       rc = i2c_transfer(client->adapter, burst_msgs, ARRAY_SIZE(burst_msgs));
+       if (rc != ARRAY_SIZE(burst_msgs))
+               goto write_failed;
        msleep(MAX6900_IDLE_TIME_AFTER_WRITE);
+
        return 0;
+
+write_failed:
+       dev_err(&client->dev, "%s: register write failed\n",
+               __FUNCTION__);
+       return -EIO;
 }
 
 static int max6900_i2c_validate_client(struct i2c_client *client)
 {
        u8 regs[MAX6900_REG_LEN];
-       u8 zero_mask[MAX6900_REG_LEN] = {
+       u8 zero_mask[] = {
                0x80,   /* seconds */
                0x80,   /* minutes */
                0x40,   /* hours */
@@ -134,7 +179,7 @@ static int max6900_i2c_validate_client(struct i2c_client *client)
        if (rc < 0)
                return rc;
 
-       for (i = 0; i < MAX6900_REG_LEN; ++i) {
+       for (i = 0; i < ARRAY_SIZE(zero_mask); ++i) {
                if (regs[i] & zero_mask[i])
                        return -ENODEV;
        }
@@ -156,7 +201,8 @@ static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
        tm->tm_hour = BCD2BIN(regs[MAX6900_REG_HR] & 0x3f);
        tm->tm_mday = BCD2BIN(regs[MAX6900_REG_DT]);
        tm->tm_mon = BCD2BIN(regs[MAX6900_REG_MO]) - 1;
-       tm->tm_year = BCD2BIN(regs[MAX6900_REG_YR]) + 100;
+       tm->tm_year = BCD2BIN(regs[MAX6900_REG_YR]) +
+                     BCD2BIN(regs[MAX6900_REG_CENTURY]) * 100 - 1900;
        tm->tm_wday = BCD2BIN(regs[MAX6900_REG_DW]);
 
        return 0;
@@ -189,9 +235,11 @@ static int max6900_i2c_set_time(struct i2c_client *client,
        regs[MAX6900_REG_HR] = BIN2BCD(tm->tm_hour);
        regs[MAX6900_REG_DT] = BIN2BCD(tm->tm_mday);
        regs[MAX6900_REG_MO] = BIN2BCD(tm->tm_mon + 1);
-       regs[MAX6900_REG_YR] = BIN2BCD(tm->tm_year - 100);
        regs[MAX6900_REG_DW] = BIN2BCD(tm->tm_wday);
-       regs[MAX6900_REG_CT] = MAX6900_REG_CT_WP;       /* set write protect */
+       regs[MAX6900_REG_YR] = BIN2BCD(tm->tm_year % 100);
+       regs[MAX6900_REG_CENTURY] = BIN2BCD((tm->tm_year + 1900) / 100);
+       /* set write protect */
+       regs[MAX6900_REG_CT] = MAX6900_REG_CT_WP;
 
        rc = max6900_i2c_write_regs(client, regs);
        if (rc < 0)
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c
new file mode 100644 (file)
index 0000000..f10d3fa
--- /dev/null
@@ -0,0 +1,420 @@
+/*
+ * A RTC driver for the Simtek STK17TA8
+ *
+ * By Thomas Hommel <thomas.hommel@gefanuc.com>
+ *
+ * Based on the DS1553 driver from
+ * Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/bcd.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/interrupt.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#define DRV_VERSION "0.1"
+
+#define RTC_REG_SIZE           0x20000
+#define RTC_OFFSET             0x1fff0
+
+#define RTC_FLAGS              (RTC_OFFSET + 0)
+#define RTC_CENTURY            (RTC_OFFSET + 1)
+#define RTC_SECONDS_ALARM      (RTC_OFFSET + 2)
+#define RTC_MINUTES_ALARM      (RTC_OFFSET + 3)
+#define RTC_HOURS_ALARM                (RTC_OFFSET + 4)
+#define RTC_DATE_ALARM         (RTC_OFFSET + 5)
+#define RTC_INTERRUPTS         (RTC_OFFSET + 6)
+#define RTC_WATCHDOG           (RTC_OFFSET + 7)
+#define RTC_CALIBRATION                (RTC_OFFSET + 8)
+#define RTC_SECONDS            (RTC_OFFSET + 9)
+#define RTC_MINUTES            (RTC_OFFSET + 10)
+#define RTC_HOURS              (RTC_OFFSET + 11)
+#define RTC_DAY                        (RTC_OFFSET + 12)
+#define RTC_DATE               (RTC_OFFSET + 13)
+#define RTC_MONTH              (RTC_OFFSET + 14)
+#define RTC_YEAR               (RTC_OFFSET + 15)
+
+#define RTC_SECONDS_MASK       0x7f
+#define RTC_DAY_MASK           0x07
+#define RTC_CAL_MASK           0x3f
+
+/* Bits in the Calibration register */
+#define RTC_STOP               0x80
+
+/* Bits in the Flags register */
+#define RTC_FLAGS_AF           0x40
+#define RTC_FLAGS_PF           0x20
+#define RTC_WRITE              0x02
+#define RTC_READ               0x01
+
+/* Bits in the Interrupts register */
+#define RTC_INTS_AIE           0x40
+
+struct rtc_plat_data {
+       struct rtc_device *rtc;
+       void __iomem *ioaddr;
+       unsigned long baseaddr;
+       unsigned long last_jiffies;
+       int irq;
+       unsigned int irqen;
+       int alrm_sec;
+       int alrm_min;
+       int alrm_hour;
+       int alrm_mday;
+};
+
+static int stk17ta8_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+       void __iomem *ioaddr = pdata->ioaddr;
+       u8 flags;
+
+       flags = readb(pdata->ioaddr + RTC_FLAGS);
+       writeb(flags | RTC_WRITE, pdata->ioaddr + RTC_FLAGS);
+
+       writeb(BIN2BCD(tm->tm_year % 100), ioaddr + RTC_YEAR);
+       writeb(BIN2BCD(tm->tm_mon + 1), ioaddr + RTC_MONTH);
+       writeb(BIN2BCD(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY);
+       writeb(BIN2BCD(tm->tm_mday), ioaddr + RTC_DATE);
+       writeb(BIN2BCD(tm->tm_hour), ioaddr + RTC_HOURS);
+       writeb(BIN2BCD(tm->tm_min), ioaddr + RTC_MINUTES);
+       writeb(BIN2BCD(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS);
+       writeb(BIN2BCD((tm->tm_year + 1900) / 100), ioaddr + RTC_CENTURY);
+
+       writeb(flags & ~RTC_WRITE, pdata->ioaddr + RTC_FLAGS);
+       return 0;
+}
+
+static int stk17ta8_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+       void __iomem *ioaddr = pdata->ioaddr;
+       unsigned int year, month, day, hour, minute, second, week;
+       unsigned int century;
+       u8 flags;
+
+       /* give enough time to update RTC in case of continuous read */
+       if (pdata->last_jiffies == jiffies)
+               msleep(1);
+       pdata->last_jiffies = jiffies;
+
+       flags = readb(pdata->ioaddr + RTC_FLAGS);
+       writeb(flags | RTC_READ, ioaddr + RTC_FLAGS);
+       second = readb(ioaddr + RTC_SECONDS) & RTC_SECONDS_MASK;
+       minute = readb(ioaddr + RTC_MINUTES);
+       hour = readb(ioaddr + RTC_HOURS);
+       day = readb(ioaddr + RTC_DATE);
+       week = readb(ioaddr + RTC_DAY) & RTC_DAY_MASK;
+       month = readb(ioaddr + RTC_MONTH);
+       year = readb(ioaddr + RTC_YEAR);
+       century = readb(ioaddr + RTC_CENTURY);
+       writeb(flags & ~RTC_READ, ioaddr + RTC_FLAGS);
+       tm->tm_sec = BCD2BIN(second);
+       tm->tm_min = BCD2BIN(minute);
+       tm->tm_hour = BCD2BIN(hour);
+       tm->tm_mday = BCD2BIN(day);
+       tm->tm_wday = BCD2BIN(week);
+       tm->tm_mon = BCD2BIN(month) - 1;
+       /* year is 1900 + tm->tm_year */
+       tm->tm_year = BCD2BIN(year) + BCD2BIN(century) * 100 - 1900;
+
+       if (rtc_valid_tm(tm) < 0) {
+               dev_err(dev, "retrieved date/time is not valid.\n");
+               rtc_time_to_tm(0, tm);
+       }
+       return 0;
+}
+
+static void stk17ta8_rtc_update_alarm(struct rtc_plat_data *pdata)
+{
+       void __iomem *ioaddr = pdata->ioaddr;
+       unsigned long irqflags;
+       u8 flags;
+
+       spin_lock_irqsave(&pdata->rtc->irq_lock, irqflags);
+
+       flags = readb(ioaddr + RTC_FLAGS);
+       writeb(flags | RTC_WRITE, ioaddr + RTC_FLAGS);
+
+       writeb(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ?
+              0x80 : BIN2BCD(pdata->alrm_mday),
+              ioaddr + RTC_DATE_ALARM);
+       writeb(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ?
+              0x80 : BIN2BCD(pdata->alrm_hour),
+              ioaddr + RTC_HOURS_ALARM);
+       writeb(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ?
+              0x80 : BIN2BCD(pdata->alrm_min),
+              ioaddr + RTC_MINUTES_ALARM);
+       writeb(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ?
+              0x80 : BIN2BCD(pdata->alrm_sec),
+              ioaddr + RTC_SECONDS_ALARM);
+       writeb(pdata->irqen ? RTC_INTS_AIE : 0, ioaddr + RTC_INTERRUPTS);
+       readb(ioaddr + RTC_FLAGS);      /* clear interrupts */
+       writeb(flags & ~RTC_WRITE, ioaddr + RTC_FLAGS);
+       spin_unlock_irqrestore(&pdata->rtc->irq_lock, irqflags);
+}
+
+static int stk17ta8_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+
+       if (pdata->irq < 0)
+               return -EINVAL;
+       pdata->alrm_mday = alrm->time.tm_mday;
+       pdata->alrm_hour = alrm->time.tm_hour;
+       pdata->alrm_min = alrm->time.tm_min;
+       pdata->alrm_sec = alrm->time.tm_sec;
+       if (alrm->enabled)
+               pdata->irqen |= RTC_AF;
+       stk17ta8_rtc_update_alarm(pdata);
+       return 0;
+}
+
+static int stk17ta8_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+
+       if (pdata->irq < 0)
+               return -EINVAL;
+       alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday;
+       alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour;
+       alrm->time.tm_min = pdata->alrm_min < 0 ? 0 : pdata->alrm_min;
+       alrm->time.tm_sec = pdata->alrm_sec < 0 ? 0 : pdata->alrm_sec;
+       alrm->enabled = (pdata->irqen & RTC_AF) ? 1 : 0;
+       return 0;
+}
+
+static irqreturn_t stk17ta8_rtc_interrupt(int irq, void *dev_id)
+{
+       struct platform_device *pdev = dev_id;
+       struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+       void __iomem *ioaddr = pdata->ioaddr;
+       unsigned long events = RTC_IRQF;
+
+       /* read and clear interrupt */
+       if (!(readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_AF))
+               return IRQ_NONE;
+       if (readb(ioaddr + RTC_SECONDS_ALARM) & 0x80)
+               events |= RTC_UF;
+       else
+               events |= RTC_AF;
+       rtc_update_irq(pdata->rtc, 1, events);
+       return IRQ_HANDLED;
+}
+
+static void stk17ta8_rtc_release(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+
+       if (pdata->irq >= 0) {
+               pdata->irqen = 0;
+               stk17ta8_rtc_update_alarm(pdata);
+       }
+}
+
+static int stk17ta8_rtc_ioctl(struct device *dev, unsigned int cmd,
+                           unsigned long arg)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+
+       if (pdata->irq < 0)
+               return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */
+       switch (cmd) {
+       case RTC_AIE_OFF:
+               pdata->irqen &= ~RTC_AF;
+               stk17ta8_rtc_update_alarm(pdata);
+               break;
+       case RTC_AIE_ON:
+               pdata->irqen |= RTC_AF;
+               stk17ta8_rtc_update_alarm(pdata);
+               break;
+       default:
+               return -ENOIOCTLCMD;
+       }
+       return 0;
+}
+
+static const struct rtc_class_ops stk17ta8_rtc_ops = {
+       .read_time      = stk17ta8_rtc_read_time,
+       .set_time       = stk17ta8_rtc_set_time,
+       .read_alarm     = stk17ta8_rtc_read_alarm,
+       .set_alarm      = stk17ta8_rtc_set_alarm,
+       .release        = stk17ta8_rtc_release,
+       .ioctl          = stk17ta8_rtc_ioctl,
+};
+
+static ssize_t stk17ta8_nvram_read(struct kobject *kobj, char *buf,
+                                loff_t pos, size_t size)
+{
+       struct platform_device *pdev =
+               to_platform_device(container_of(kobj, struct device, kobj));
+       struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+       void __iomem *ioaddr = pdata->ioaddr;
+       ssize_t count;
+
+       for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--)
+               *buf++ = readb(ioaddr + pos++);
+       return count;
+}
+
+static ssize_t stk17ta8_nvram_write(struct kobject *kobj, char *buf,
+                                 loff_t pos, size_t size)
+{
+       struct platform_device *pdev =
+               to_platform_device(container_of(kobj, struct device, kobj));
+       struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+       void __iomem *ioaddr = pdata->ioaddr;
+       ssize_t count;
+
+       for (count = 0; size > 0 && pos < RTC_OFFSET; count++, size--)
+               writeb(*buf++, ioaddr + pos++);
+       return count;
+}
+
+static struct bin_attribute stk17ta8_nvram_attr = {
+       .attr = {
+               .name = "nvram",
+               .mode = S_IRUGO | S_IWUGO,
+               .owner = THIS_MODULE,
+       },
+       .size = RTC_OFFSET,
+       .read = stk17ta8_nvram_read,
+       .write = stk17ta8_nvram_write,
+};
+
+static int __init stk17ta8_rtc_probe(struct platform_device *pdev)
+{
+       struct rtc_device *rtc;
+       struct resource *res;
+       unsigned int cal;
+       unsigned int flags;
+       struct rtc_plat_data *pdata;
+       void __iomem *ioaddr = NULL;
+       int ret = 0;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENODEV;
+
+       pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return -ENOMEM;
+       pdata->irq = -1;
+       if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) {
+               ret = -EBUSY;
+               goto out;
+       }
+       pdata->baseaddr = res->start;
+       ioaddr = ioremap(pdata->baseaddr, RTC_REG_SIZE);
+       if (!ioaddr) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       pdata->ioaddr = ioaddr;
+       pdata->irq = platform_get_irq(pdev, 0);
+
+       /* turn RTC on if it was not on */
+       cal = readb(ioaddr + RTC_CALIBRATION);
+       if (cal & RTC_STOP) {
+               cal &= RTC_CAL_MASK;
+               flags = readb(ioaddr + RTC_FLAGS);
+               writeb(flags | RTC_WRITE, ioaddr + RTC_FLAGS);
+               writeb(cal, ioaddr + RTC_CALIBRATION);
+               writeb(flags & ~RTC_WRITE, ioaddr + RTC_FLAGS);
+       }
+       if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_PF)
+               dev_warn(&pdev->dev, "voltage-low detected.\n");
+
+       if (pdata->irq >= 0) {
+               writeb(0, ioaddr + RTC_INTERRUPTS);
+               if (request_irq(pdata->irq, stk17ta8_rtc_interrupt,
+                               IRQF_DISABLED | IRQF_SHARED,
+                               pdev->name, pdev) < 0) {
+                       dev_warn(&pdev->dev, "interrupt not available.\n");
+                       pdata->irq = -1;
+               }
+       }
+
+       rtc = rtc_device_register(pdev->name, &pdev->dev,
+                                 &stk17ta8_rtc_ops, THIS_MODULE);
+       if (IS_ERR(rtc)) {
+               ret = PTR_ERR(rtc);
+               goto out;
+       }
+       pdata->rtc = rtc;
+       pdata->last_jiffies = jiffies;
+       platform_set_drvdata(pdev, pdata);
+       ret = sysfs_create_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr);
+       if (ret)
+               goto out;
+       return 0;
+ out:
+       if (pdata->rtc)
+               rtc_device_unregister(pdata->rtc);
+       if (pdata->irq >= 0)
+               free_irq(pdata->irq, pdev);
+       if (ioaddr)
+               iounmap(ioaddr);
+       if (pdata->baseaddr)
+               release_mem_region(pdata->baseaddr, RTC_REG_SIZE);
+       kfree(pdata);
+       return ret;
+}
+
+static int __devexit stk17ta8_rtc_remove(struct platform_device *pdev)
+{
+       struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+
+       sysfs_remove_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr);
+       rtc_device_unregister(pdata->rtc);
+       if (pdata->irq >= 0) {
+               writeb(0, pdata->ioaddr + RTC_INTERRUPTS);
+               free_irq(pdata->irq, pdev);
+       }
+       iounmap(pdata->ioaddr);
+       release_mem_region(pdata->baseaddr, RTC_REG_SIZE);
+       kfree(pdata);
+       return 0;
+}
+
+static struct platform_driver stk17ta8_rtc_driver = {
+       .probe          = stk17ta8_rtc_probe,
+       .remove         = __devexit_p(stk17ta8_rtc_remove),
+       .driver         = {
+               .name   = "stk17ta8",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static __init int stk17ta8_init(void)
+{
+       return platform_driver_register(&stk17ta8_rtc_driver);
+}
+
+static __exit void stk17ta8_exit(void)
+{
+       return platform_driver_unregister(&stk17ta8_rtc_driver);
+}
+
+module_init(stk17ta8_init);
+module_exit(stk17ta8_exit);
+
+MODULE_AUTHOR("Thomas Hommel <thomas.hommel@gefanuc.com>");
+MODULE_DESCRIPTION("Simtek STK17TA8 RTC driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
index 9726261c367df820fe78c044e21eda69e10559ca..ab5ec1feaf4efc62990fd8f406f29894c866216c 100644 (file)
@@ -1526,15 +1526,12 @@ zfcp_gid_pn_buffers_alloc(struct zfcp_gid_pn_data **gid_pn, mempool_t *pool)
  * zfcp_gid_pn_buffers_free - free buffers for GID_PN nameserver request
  * @gid_pn: pointer to struct zfcp_gid_pn_data which has to be freed
  */
-static void
-zfcp_gid_pn_buffers_free(struct zfcp_gid_pn_data *gid_pn)
+static void zfcp_gid_pn_buffers_free(struct zfcp_gid_pn_data *gid_pn)
 {
-        if ((gid_pn->ct.pool != 0))
+       if (gid_pn->ct.pool)
                mempool_free(gid_pn, gid_pn->ct.pool);
        else
-                kfree(gid_pn);
-
-       return;
+               kfree(gid_pn);
 }
 
 /**
index 22649639230b25fc8a326ab0eb3938070a9fdb26..b36dfc40d9fa26b41ee3aca598eabe3a9c999bd0 100644 (file)
@@ -126,6 +126,7 @@ zfcp_address_to_sg(void *address, struct scatterlist *list)
 #define ZFCP_MIN_OUTPUT_THRESHOLD      1       /* ignored by QDIO layer */
 
 #define QDIO_SCSI_QFMT                 1       /* 1 for FSF */
+#define QBUFF_PER_PAGE                 (PAGE_SIZE / sizeof(struct qdio_buffer))
 
 /********************* FSF SPECIFIC DEFINES *********************************/
 
index 4e7cb6dc4d348443c1a4a901dd359e03fcc5588d..d8cd75ce2d9a37c1675d3c29af6fc9884dc00b66 100644 (file)
@@ -1626,7 +1626,7 @@ zfcp_erp_schedule_work(struct zfcp_unit *unit)
 {
        struct zfcp_erp_add_work *p;
 
-       p = kmalloc(sizeof(*p), GFP_KERNEL);
+       p = kzalloc(sizeof(*p), GFP_KERNEL);
        if (!p) {
                ZFCP_LOG_NORMAL("error: Out of resources. Could not register "
                                "the FCP-LUN 0x%Lx connected to "
@@ -1639,7 +1639,6 @@ zfcp_erp_schedule_work(struct zfcp_unit *unit)
        }
 
        zfcp_unit_get(unit);
-       memset(p, 0, sizeof(*p));
        atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status);
        INIT_WORK(&p->work, zfcp_erp_scsi_scan);
        p->unit = unit;
index 0eb31e162b159604b5e6d7cfca9c4e646486b062..b240800b78d7af56c31dbbf2a187b26506453fd6 100644 (file)
@@ -1930,7 +1930,7 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req)
 skip_fsfstatus:
        send_els->status = retval;
 
-       if (send_els->handler != 0)
+       if (send_els->handler)
                send_els->handler(send_els->handler_data);
 
        return retval;
index bdf5782b8a7acd175dac262d45514d7035a21bbb..c408badd2ae966c20917bf286951c3b347efb056 100644 (file)
@@ -47,103 +47,56 @@ static int zfcp_qdio_handler_error_check(struct zfcp_adapter *,
 #define ZFCP_LOG_AREA                   ZFCP_LOG_AREA_QDIO
 
 /*
- * Allocates BUFFER memory to each of the pointers of the qdio_buffer_t 
- * array in the adapter struct.
- * Cur_buf is the pointer array and count can be any number of required 
- * buffers, the page-fitting arithmetic is done entirely within this funciton.
+ * Frees BUFFER memory for each of the pointers of the struct qdio_buffer array
+ * in the adapter struct sbuf is the pointer array.
  *
- * returns:    number of buffers allocated
  * locks:       must only be called with zfcp_data.config_sema taken
  */
-static int
-zfcp_qdio_buffers_enqueue(struct qdio_buffer **cur_buf, int count)
+static void
+zfcp_qdio_buffers_dequeue(struct qdio_buffer **sbuf)
 {
-       int buf_pos;
-       int qdio_buffers_per_page;
-       int page_pos = 0;
-       struct qdio_buffer *first_in_page = NULL;
-
-       qdio_buffers_per_page = PAGE_SIZE / sizeof (struct qdio_buffer);
-       ZFCP_LOG_TRACE("buffers_per_page=%d\n", qdio_buffers_per_page);
-
-       for (buf_pos = 0; buf_pos < count; buf_pos++) {
-               if (page_pos == 0) {
-                       cur_buf[buf_pos] = (struct qdio_buffer *)
-                           get_zeroed_page(GFP_KERNEL);
-                       if (cur_buf[buf_pos] == NULL) {
-                               ZFCP_LOG_INFO("error: allocation of "
-                                             "QDIO buffer failed \n");
-                               goto out;
-                       }
-                       first_in_page = cur_buf[buf_pos];
-               } else {
-                       cur_buf[buf_pos] = first_in_page + page_pos;
+       int pos;
 
-               }
-               /* was initialised to zero */
-               page_pos++;
-               page_pos %= qdio_buffers_per_page;
-       }
- out:
-       return buf_pos;
+       for (pos = 0; pos < QDIO_MAX_BUFFERS_PER_Q; pos += QBUFF_PER_PAGE)
+               free_page((unsigned long) sbuf[pos]);
 }
 
 /*
- * Frees BUFFER memory for each of the pointers of the struct qdio_buffer array
- * in the adapter struct cur_buf is the pointer array and count can be any
- * number of buffers in the array that should be freed starting from buffer 0
+ * Allocates BUFFER memory to each of the pointers of the qdio_buffer_t
+ * array in the adapter struct.
+ * Cur_buf is the pointer array
  *
+ * returns:    zero on success else -ENOMEM
  * locks:       must only be called with zfcp_data.config_sema taken
  */
-static void
-zfcp_qdio_buffers_dequeue(struct qdio_buffer **cur_buf, int count)
+static int
+zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbuf)
 {
-       int buf_pos;
-       int qdio_buffers_per_page;
-
-       qdio_buffers_per_page = PAGE_SIZE / sizeof (struct qdio_buffer);
-       ZFCP_LOG_TRACE("buffers_per_page=%d\n", qdio_buffers_per_page);
+       int pos;
 
-       for (buf_pos = 0; buf_pos < count; buf_pos += qdio_buffers_per_page)
-               free_page((unsigned long) cur_buf[buf_pos]);
-       return;
+       for (pos = 0; pos < QDIO_MAX_BUFFERS_PER_Q; pos += QBUFF_PER_PAGE) {
+               sbuf[pos] = (struct qdio_buffer *) get_zeroed_page(GFP_KERNEL);
+               if (!sbuf[pos]) {
+                       zfcp_qdio_buffers_dequeue(sbuf);
+                       return -ENOMEM;
+               }
+       }
+       for (pos = 0; pos < QDIO_MAX_BUFFERS_PER_Q; pos++)
+               if (pos % QBUFF_PER_PAGE)
+                       sbuf[pos] = sbuf[pos - 1] + 1;
+       return 0;
 }
 
 /* locks:       must only be called with zfcp_data.config_sema taken */
 int
 zfcp_qdio_allocate_queues(struct zfcp_adapter *adapter)
 {
-       int buffer_count;
-       int retval = 0;
+       int ret;
 
-       buffer_count =
-           zfcp_qdio_buffers_enqueue(&(adapter->request_queue.buffer[0]),
-                                     QDIO_MAX_BUFFERS_PER_Q);
-       if (buffer_count < QDIO_MAX_BUFFERS_PER_Q) {
-               ZFCP_LOG_DEBUG("only %d QDIO buffers allocated for request "
-                              "queue\n", buffer_count);
-               zfcp_qdio_buffers_dequeue(&(adapter->request_queue.buffer[0]),
-                                         buffer_count);
-               retval = -ENOMEM;
-               goto out;
-       }
-
-       buffer_count =
-           zfcp_qdio_buffers_enqueue(&(adapter->response_queue.buffer[0]),
-                                     QDIO_MAX_BUFFERS_PER_Q);
-       if (buffer_count < QDIO_MAX_BUFFERS_PER_Q) {
-               ZFCP_LOG_DEBUG("only %d QDIO buffers allocated for response "
-                              "queue", buffer_count);
-               zfcp_qdio_buffers_dequeue(&(adapter->response_queue.buffer[0]),
-                                         buffer_count);
-               ZFCP_LOG_TRACE("freeing request_queue buffers\n");
-               zfcp_qdio_buffers_dequeue(&(adapter->request_queue.buffer[0]),
-                                         QDIO_MAX_BUFFERS_PER_Q);
-               retval = -ENOMEM;
-               goto out;
-       }
- out:
-       return retval;
+       ret = zfcp_qdio_buffers_enqueue(adapter->request_queue.buffer);
+       if (ret)
+               return ret;
+       return zfcp_qdio_buffers_enqueue(adapter->response_queue.buffer);
 }
 
 /* locks:       must only be called with zfcp_data.config_sema taken */
@@ -151,12 +104,10 @@ void
 zfcp_qdio_free_queues(struct zfcp_adapter *adapter)
 {
        ZFCP_LOG_TRACE("freeing request_queue buffers\n");
-       zfcp_qdio_buffers_dequeue(&(adapter->request_queue.buffer[0]),
-                                 QDIO_MAX_BUFFERS_PER_Q);
+       zfcp_qdio_buffers_dequeue(adapter->request_queue.buffer);
 
        ZFCP_LOG_TRACE("freeing response_queue buffers\n");
-       zfcp_qdio_buffers_dequeue(&(adapter->response_queue.buffer[0]),
-                                 QDIO_MAX_BUFFERS_PER_Q);
+       zfcp_qdio_buffers_dequeue(adapter->response_queue.buffer);
 }
 
 int
index 6b49f6a2524d44b982d6f08c1eb059e1cfe2be87..efd9d8d3a890c60ead2c5b5d547ff636cde73cfb 100644 (file)
@@ -4,7 +4,7 @@
    Written By: Adam Radford <linuxraid@amcc.com>
    Modifications By: Tom Couch <linuxraid@amcc.com>
 
-   Copyright (C) 2004-2006 Applied Micro Circuits Corporation.
+   Copyright (C) 2004-2007 Applied Micro Circuits Corporation.
 
    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
@@ -69,6 +69,8 @@
    2.26.02.008 - Free irq handler in __twa_shutdown().
                  Serialize reset code.
                  Add support for 9650SE controllers.
+   2.26.02.009 - Fix dma mask setting to fallback to 32-bit if 64-bit fails.
+   2.26.02.010 - Add support for 9690SA controllers.
 */
 
 #include <linux/module.h>
@@ -92,7 +94,7 @@
 #include "3w-9xxx.h"
 
 /* Globals */
-#define TW_DRIVER_VERSION "2.26.02.008"
+#define TW_DRIVER_VERSION "2.26.02.010"
 static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
 static unsigned int twa_device_extension_count;
 static int twa_major = -1;
@@ -124,11 +126,11 @@ static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
                              unsigned short *fw_on_ctlr_branch, 
                              unsigned short *fw_on_ctlr_build, 
                              u32 *init_connect_result);
-static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length);
+static void twa_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length);
 static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds);
 static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds);
 static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal);
-static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset);
+static int twa_reset_device_extension(TW_Device_Extension *tw_dev);
 static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset);
 static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg);
 static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id);
@@ -683,7 +685,7 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int
                full_command_packet = &tw_ioctl->firmware_command;
 
                /* Load request id and sglist for both command types */
-               twa_load_sgl(full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
+               twa_load_sgl(tw_dev, full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
 
                memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
 
@@ -700,10 +702,10 @@ static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int
                if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
                        /* Now we need to reset the board */
                        printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
-                              tw_dev->host->host_no, TW_DRIVER, 0xc,
+                              tw_dev->host->host_no, TW_DRIVER, 0x37,
                               cmd);
                        retval = TW_IOCTL_ERROR_OS_EIO;
-                       twa_reset_device_extension(tw_dev, 1);
+                       twa_reset_device_extension(tw_dev);
                        goto out3;
                }
 
@@ -890,7 +892,9 @@ static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value)
        }
 
        if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
-               if ((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) || (!test_bit(TW_IN_RESET, &tw_dev->flags)))
+               if (((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) &&
+                    (tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9690SA)) ||
+                   (!test_bit(TW_IN_RESET, &tw_dev->flags)))
                        TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing");
                writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
        }
@@ -935,8 +939,7 @@ static int twa_empty_response_queue_large(TW_Device_Extension *tw_dev)
        unsigned long before;
        int retval = 1;
 
-       if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) ||
-           (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE)) {
+       if (tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9000) {
                before = jiffies;
                while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) {
                        response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev));
@@ -1195,7 +1198,6 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance)
        u32 status_reg_value;
        TW_Response_Queue response_que;
        TW_Command_Full *full_command_packet;
-       TW_Command *command_packet;
        TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
        int handled = 0;
 
@@ -1273,7 +1275,6 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance)
                        request_id = TW_RESID_OUT(response_que.response_id);
                        full_command_packet = tw_dev->command_packet_virt[request_id];
                        error = 0;
-                       command_packet = &full_command_packet->command.oldcommand;
                        /* Check for command packet errors */
                        if (full_command_packet->command.newcommand.status != 0) {
                                if (tw_dev->srb[request_id] != 0) {
@@ -1352,11 +1353,15 @@ twa_interrupt_bail:
 } /* End twa_interrupt() */
 
 /* This function will load the request id and various sgls for ioctls */
-static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length)
+static void twa_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length)
 {
        TW_Command *oldcommand;
        TW_Command_Apache *newcommand;
        TW_SG_Entry *sgl;
+       unsigned int pae = 0;
+
+       if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
+               pae = 1;
 
        if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
                newcommand = &full_command_packet->command.newcommand;
@@ -1372,12 +1377,14 @@ static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, d
 
                if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
                        /* Load the sg list */
-                       sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset));
+                       if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)
+                               sgl = (TW_SG_Entry *)((u32 *)oldcommand+oldcommand->size - (sizeof(TW_SG_Entry)/4) + pae);
+                       else
+                               sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset));
                        sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
                        sgl->length = cpu_to_le32(length);
 
-                       if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
-                               oldcommand->size += 1;
+                       oldcommand->size += pae;
                }
        }
 } /* End twa_load_sgl() */
@@ -1506,7 +1513,8 @@ static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id,
        command_que_value = tw_dev->command_packet_phys[request_id];
 
        /* For 9650SE write low 4 bytes first */
-       if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) {
+       if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) ||
+           (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)) {
                command_que_value += TW_COMMAND_OFFSET;
                writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev));
        }
@@ -1537,7 +1545,8 @@ static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id,
                TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
                goto out;
        } else {
-               if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) {
+               if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) ||
+                   (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)) {
                        /* Now write upper 4 bytes */
                        writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev) + 0x4);
                } else {
@@ -1561,7 +1570,7 @@ out:
 } /* End twa_post_command_packet() */
 
 /* This function will reset a device extension */
-static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset)
+static int twa_reset_device_extension(TW_Device_Extension *tw_dev)
 {
        int i = 0;
        int retval = 1;
@@ -1719,7 +1728,7 @@ static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt)
        mutex_lock(&tw_dev->ioctl_lock);
 
        /* Now reset the card and some of the device extension data */
-       if (twa_reset_device_extension(tw_dev, 0)) {
+       if (twa_reset_device_extension(tw_dev)) {
                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset");
                goto out;
        }
@@ -2001,11 +2010,14 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id
 
        pci_set_master(pdev);
 
-       retval = pci_set_dma_mask(pdev, sizeof(dma_addr_t) > 4 ? DMA_64BIT_MASK : DMA_32BIT_MASK);
-       if (retval) {
-               TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask");
-               goto out_disable_device;
-       }
+       if (pci_set_dma_mask(pdev, DMA_64BIT_MASK)
+           || pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
+               if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)
+                   || pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+                       TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask");
+                       retval = -ENODEV;
+                       goto out_disable_device;
+               }
 
        host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
        if (!host) {
@@ -2053,7 +2065,8 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id
                goto out_iounmap;
 
        /* Set host specific parameters */
-       if (pdev->device == PCI_DEVICE_ID_3WARE_9650SE)
+       if ((pdev->device == PCI_DEVICE_ID_3WARE_9650SE) ||
+           (pdev->device == PCI_DEVICE_ID_3WARE_9690SA))
                host->max_id = TW_MAX_UNITS_9650SE;
        else
                host->max_id = TW_MAX_UNITS;
@@ -2160,6 +2173,8 @@ static struct pci_device_id twa_pci_tbl[] __devinitdata = {
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9650SE,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9690SA,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { }
 };
 MODULE_DEVICE_TABLE(pci, twa_pci_tbl);
index 7901517d4513db19bad2ed487cb8a648d92a4a08..d14a9479e3895edf2dea95800128073b8a686954 100644 (file)
@@ -4,7 +4,7 @@
    Written By: Adam Radford <linuxraid@amcc.com>
    Modifications By: Tom Couch <linuxraid@amcc.com>
 
-   Copyright (C) 2004-2006 Applied Micro Circuits Corporation.
+   Copyright (C) 2004-2007 Applied Micro Circuits Corporation.
 
    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
@@ -419,6 +419,9 @@ static twa_message_type twa_error_table[] = {
 #ifndef PCI_DEVICE_ID_3WARE_9650SE
 #define PCI_DEVICE_ID_3WARE_9650SE 0x1004
 #endif
+#ifndef PCI_DEVICE_ID_3WARE_9690SA
+#define PCI_DEVICE_ID_3WARE_9690SA 0x1005
+#endif
 
 /* Bitmask macros to eliminate bitfields */
 
index a947257b89646d8d7e99e5320ab0eaa04fbd62ab..d2b3898b750a2ba1d2c1452d09deec3c31c7cf54 100644 (file)
@@ -282,7 +282,7 @@ config SCSI_ISCSI_ATTRS
 
 config SCSI_SAS_ATTRS
        tristate "SAS Transport Attributes"
-       depends on SCSI
+       depends on SCSI && BLK_DEV_BSG
        help
          If you wish to export transport-specific information about
          each attached SAS device to sysfs, say Y.
@@ -291,8 +291,12 @@ source "drivers/scsi/libsas/Kconfig"
 
 endmenu
 
-menu "SCSI low-level drivers"
+menuconfig SCSI_LOWLEVEL
+       bool "SCSI low-level drivers"
        depends on SCSI!=n
+       default y
+
+if SCSI_LOWLEVEL
 
 config ISCSI_TCP
        tristate "iSCSI Initiator over TCP/IP"
@@ -1800,7 +1804,7 @@ config SCSI_SRP
          To compile this driver as a module, choose M here: the
          module will be called libsrp.
 
-endmenu
+endif # SCSI_LOWLEVEL
 
 source "drivers/scsi/pcmcia/Kconfig"
 
index 0f8689557158563d14507cf682b0917bd5c59339..86a7ba7bad63f4f7b9e3c005e45381a0c351d2db 100644 (file)
@@ -132,6 +132,7 @@ obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/
 obj-$(CONFIG_SCSI_IBMVSCSIS)   += ibmvscsi/
 obj-$(CONFIG_SCSI_HPTIOP)      += hptiop.o
 obj-$(CONFIG_SCSI_STEX)                += stex.o
+obj-$(CONFIG_PS3_ROM)          += ps3rom.o
 
 obj-$(CONFIG_ARM)              += arm/
 
index 6a5784683ed3eb226ae05105309ac824197274e6..0c758d1452baa3196010a12f266d3a67d7d17c5e 100644 (file)
@@ -79,6 +79,7 @@ static int __devinit a4000t_probe(struct device *dev)
                goto out_put_host;
        }
 
+       dev_set_drvdata(dev, host);
        scsi_scan_host(host);
 
        return 0;
@@ -95,7 +96,7 @@ static int __devinit a4000t_probe(struct device *dev)
 
 static __devexit int a4000t_device_remove(struct device *dev)
 {
-       struct Scsi_Host *host = dev_to_shost(dev);
+       struct Scsi_Host *host = dev_get_drvdata(dev);
        struct NCR_700_Host_Parameters *hostdata = shost_priv(host);
 
        scsi_remove_host(host);
index 0b6fd0b654d26cedca1ae9fdfb497b9c2fa3f3a2..a26baab09dbfb8e7edde8a99c02c8a8f291c17da 100644 (file)
@@ -751,6 +751,101 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex)
        inqstrcpy ("V1.0", str->prl);
 }
 
+static void get_container_serial_callback(void *context, struct fib * fibptr)
+{
+       struct aac_get_serial_resp * get_serial_reply;
+       struct scsi_cmnd * scsicmd;
+
+       BUG_ON(fibptr == NULL);
+
+       scsicmd = (struct scsi_cmnd *) context;
+       if (!aac_valid_context(scsicmd, fibptr))
+               return;
+
+       get_serial_reply = (struct aac_get_serial_resp *) fib_data(fibptr);
+       /* Failure is irrelevant, using default value instead */
+       if (le32_to_cpu(get_serial_reply->status) == CT_OK) {
+               char sp[13];
+               /* EVPD bit set */
+               sp[0] = INQD_PDT_DA;
+               sp[1] = scsicmd->cmnd[2];
+               sp[2] = 0;
+               sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X",
+                 le32_to_cpu(get_serial_reply->uid));
+               aac_internal_transfer(scsicmd, sp, 0, sizeof(sp));
+       }
+
+       scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+
+       aac_fib_complete(fibptr);
+       aac_fib_free(fibptr);
+       scsicmd->scsi_done(scsicmd);
+}
+
+/**
+ *     aac_get_container_serial - get container serial, none blocking.
+ */
+static int aac_get_container_serial(struct scsi_cmnd * scsicmd)
+{
+       int status;
+       struct aac_get_serial *dinfo;
+       struct fib * cmd_fibcontext;
+       struct aac_dev * dev;
+
+       dev = (struct aac_dev *)scsicmd->device->host->hostdata;
+
+       if (!(cmd_fibcontext = aac_fib_alloc(dev)))
+               return -ENOMEM;
+
+       aac_fib_init(cmd_fibcontext);
+       dinfo = (struct aac_get_serial *) fib_data(cmd_fibcontext);
+
+       dinfo->command = cpu_to_le32(VM_ContainerConfig);
+       dinfo->type = cpu_to_le32(CT_CID_TO_32BITS_UID);
+       dinfo->cid = cpu_to_le32(scmd_id(scsicmd));
+
+       status = aac_fib_send(ContainerCommand,
+                 cmd_fibcontext,
+                 sizeof (struct aac_get_serial),
+                 FsaNormal,
+                 0, 1,
+                 (fib_callback) get_container_serial_callback,
+                 (void *) scsicmd);
+
+       /*
+        *      Check that the command queued to the controller
+        */
+       if (status == -EINPROGRESS) {
+               scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+               return 0;
+       }
+
+       printk(KERN_WARNING "aac_get_container_serial: aac_fib_send failed with status: %d.\n", status);
+       aac_fib_complete(cmd_fibcontext);
+       aac_fib_free(cmd_fibcontext);
+       return -1;
+}
+
+/* Function: setinqserial
+ *
+ * Arguments: [1] pointer to void [1] int
+ *
+ * Purpose: Sets SCSI Unit Serial number.
+ *          This is a fake. We should read a proper
+ *          serial number from the container. <SuSE>But
+ *          without docs it's quite hard to do it :-)
+ *          So this will have to do in the meantime.</SuSE>
+ */
+
+static int setinqserial(struct aac_dev *dev, void *data, int cid)
+{
+       /*
+        *      This breaks array migration.
+        */
+       return snprintf((char *)(data), sizeof(struct scsi_inq) - 4, "%08X%02X",
+                       le32_to_cpu(dev->adapter_info.serial[0]), cid);
+}
+
 static void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code,
                      u8 a_sense_code, u8 incorrect_length,
                      u8 bit_pointer, u16 field_pointer,
@@ -1798,6 +1893,49 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
                dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", cid));
                memset(&inq_data, 0, sizeof (struct inquiry_data));
 
+               if (scsicmd->cmnd[1] & 0x1 ) {
+                       char *arr = (char *)&inq_data;
+
+                       /* EVPD bit set */
+                       arr[0] = (scmd_id(scsicmd) == host->this_id) ?
+                         INQD_PDT_PROC : INQD_PDT_DA;
+                       if (scsicmd->cmnd[2] == 0) {
+                               /* supported vital product data pages */
+                               arr[3] = 2;
+                               arr[4] = 0x0;
+                               arr[5] = 0x80;
+                               arr[1] = scsicmd->cmnd[2];
+                               aac_internal_transfer(scsicmd, &inq_data, 0,
+                                 sizeof(inq_data));
+                               scsicmd->result = DID_OK << 16 |
+                                 COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+                       } else if (scsicmd->cmnd[2] == 0x80) {
+                               /* unit serial number page */
+                               arr[3] = setinqserial(dev, &arr[4],
+                                 scmd_id(scsicmd));
+                               arr[1] = scsicmd->cmnd[2];
+                               aac_internal_transfer(scsicmd, &inq_data, 0,
+                                 sizeof(inq_data));
+                               return aac_get_container_serial(scsicmd);
+                       } else {
+                               /* vpd page not implemented */
+                               scsicmd->result = DID_OK << 16 |
+                                 COMMAND_COMPLETE << 8 |
+                                 SAM_STAT_CHECK_CONDITION;
+                               set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
+                                 ILLEGAL_REQUEST,
+                                 SENCODE_INVALID_CDB_FIELD,
+                                 ASENCODE_NO_SENSE, 0, 7, 2, 0);
+                               memcpy(scsicmd->sense_buffer,
+                                 &dev->fsa_dev[cid].sense_data,
+                                 (sizeof(dev->fsa_dev[cid].sense_data) >
+                                   sizeof(scsicmd->sense_buffer))
+                                      ? sizeof(scsicmd->sense_buffer)
+                                      : sizeof(dev->fsa_dev[cid].sense_data));
+                       }
+                       scsicmd->scsi_done(scsicmd);
+                       return 0;
+               }
                inq_data.inqd_ver = 2;  /* claim compliance to SCSI-2 */
                inq_data.inqd_rdf = 2;  /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */
                inq_data.inqd_len = 31;
@@ -2070,7 +2208,7 @@ static int query_disk(struct aac_dev *dev, void __user *arg)
        }
        else return -EINVAL;
 
-       qd.valid = fsa_dev_ptr[qd.cnum].valid;
+       qd.valid = fsa_dev_ptr[qd.cnum].valid != 0;
        qd.locked = fsa_dev_ptr[qd.cnum].locked;
        qd.deleted = fsa_dev_ptr[qd.cnum].deleted;
 
index f1d3b66af879563c65cc382d77a3c9be048f16b2..400d03403cd547d84415d05ebceaa267a2a5b7db 100644 (file)
@@ -1567,6 +1567,20 @@ struct aac_get_name_resp {
        u8              data[16];
 };
 
+#define CT_CID_TO_32BITS_UID 165
+struct aac_get_serial {
+       __le32          command;        /* VM_ContainerConfig */
+       __le32          type;           /* CT_CID_TO_32BITS_UID */
+       __le32          cid;
+};
+
+struct aac_get_serial_resp {
+       __le32          dummy0;
+       __le32          dummy1;
+       __le32          status; /* CT_OK */
+       __le32          uid;
+};
+
 /*
  * The following command is sent to shut down each container.
  */
index d510839c0bb2c20e4e74e483fab34966b8a1ccb8..bb870906b4cf72fa15ec8243403bf13812a1c824 100644 (file)
@@ -80,7 +80,11 @@ static int fib_map_alloc(struct aac_dev *dev)
 
 void aac_fib_map_free(struct aac_dev *dev)
 {
-       pci_free_consistent(dev->pdev, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), dev->hw_fib_va, dev->hw_fib_pa);
+       pci_free_consistent(dev->pdev,
+         dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB),
+         dev->hw_fib_va, dev->hw_fib_pa);
+       dev->hw_fib_va = NULL;
+       dev->hw_fib_pa = 0;
 }
 
 /**
@@ -1087,8 +1091,6 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced)
         * case.
         */
        aac_fib_map_free(aac);
-       aac->hw_fib_va = NULL;
-       aac->hw_fib_pa = 0;
        pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys);
        aac->comm_addr = NULL;
        aac->comm_phys = 0;
@@ -1098,12 +1100,12 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced)
        kfree(aac->fsa_dev);
        aac->fsa_dev = NULL;
        if (aac_get_driver_ident(index)->quirks & AAC_QUIRK_31BIT) {
-               if (((retval = pci_set_dma_mask(aac->pdev, DMA_32BIT_MASK))) ||
-                 ((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_32BIT_MASK))))
+               if (((retval = pci_set_dma_mask(aac->pdev, DMA_31BIT_MASK))) ||
+                 ((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_31BIT_MASK))))
                        goto out;
        } else {
-               if (((retval = pci_set_dma_mask(aac->pdev, 0x7FFFFFFFULL))) ||
-                 ((retval = pci_set_consistent_dma_mask(aac->pdev, 0x7FFFFFFFULL))))
+               if (((retval = pci_set_dma_mask(aac->pdev, DMA_32BIT_MASK))) ||
+                 ((retval = pci_set_consistent_dma_mask(aac->pdev, DMA_32BIT_MASK))))
                        goto out;
        }
        if ((retval = (*(aac_get_driver_ident(index)->init))(aac)))
index c520e5b41fb52288982d73ac2ce46362407938d5..3dce618bf4148c293f4eff51b7f2ac27c1c22277 100644 (file)
@@ -126,7 +126,7 @@ static inline int asd_init_sata(struct domain_device *dev)
                if (w76 & 0x100) /* NCQ? */
                        qdepth = (w75 & 0x1F) + 1;
                asd_ddbsite_write_dword(asd_ha, ddb, SATA_TAG_ALLOC_MASK,
-                                       (1<<qdepth)-1);
+                                       (1ULL<<qdepth)-1);
                asd_ddbsite_write_byte(asd_ha, ddb, NUM_SATA_TAGS, qdepth);
        }
        if (dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM ||
index b8c6810090d54a4981bc68db13b274090c79eacc..ab00aecc5466ec018d621e7a9ab60466de37d5d9 100644 (file)
@@ -81,6 +81,9 @@ static struct scsi_host_template aic94xx_sht = {
        .use_clustering         = ENABLE_CLUSTERING,
        .eh_device_reset_handler        = sas_eh_device_reset_handler,
        .eh_bus_reset_handler   = sas_eh_bus_reset_handler,
+       .slave_alloc            = sas_slave_alloc,
+       .target_destroy         = sas_target_destroy,
+       .ioctl                  = sas_ioctl,
 };
 
 static int __devinit asd_map_memio(struct asd_ha_struct *asd_ha)
index e2ad5bed94035c0dd594c237e0c59a8dba3dd1c1..d5d8caba35605f3643b165211d84aa583f29bbd4 100644 (file)
@@ -74,8 +74,13 @@ static inline int asd_map_scatterlist(struct sas_task *task,
                return 0;
        }
 
-       num_sg = pci_map_sg(asd_ha->pcidev, task->scatter, task->num_scatter,
-                           task->data_dir);
+       /* STP tasks come from libata which has already mapped
+        * the SG list */
+       if (sas_protocol_ata(task->task_proto))
+               num_sg = task->num_scatter;
+       else
+               num_sg = pci_map_sg(asd_ha->pcidev, task->scatter,
+                                   task->num_scatter, task->data_dir);
        if (num_sg == 0)
                return -ENOMEM;
 
@@ -120,8 +125,9 @@ static inline int asd_map_scatterlist(struct sas_task *task,
 
        return 0;
 err_unmap:
-       pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter,
-                    task->data_dir);
+       if (sas_protocol_ata(task->task_proto))
+               pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter,
+                            task->data_dir);
        return res;
 }
 
@@ -142,8 +148,9 @@ static inline void asd_unmap_scatterlist(struct asd_ascb *ascb)
        }
 
        asd_free_coherent(asd_ha, ascb->sg_arr);
-       pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter,
-                    task->data_dir);
+       if (task->task_proto != SAS_PROTOCOL_STP)
+               pci_unmap_sg(asd_ha->pcidev, task->scatter, task->num_scatter,
+                            task->data_dir);
 }
 
 /* ---------- Task complete tasklet ---------- */
@@ -391,7 +398,6 @@ static int asd_build_ata_ascb(struct asd_ascb *ascb, struct sas_task *task,
 
        scb->ata_task.total_xfer_len = cpu_to_le32(task->total_xfer_len);
        scb->ata_task.fis = task->ata_task.fis;
-       scb->ata_task.fis.fis_type = 0x27;
        if (likely(!task->ata_task.device_control_reg_update))
                scb->ata_task.fis.flags |= 0x80; /* C=1: update ATA cmd reg */
        scb->ata_task.fis.flags &= 0xF0; /* PM_PORT field shall be 0 */
index cf9a21cea6d9309b88aa4cb69b2d2addc53aa7a1..49d838e90a241260ea6e2a907b5c7d45c6839753 100644 (file)
@@ -24,7 +24,7 @@
 
 #define CUMANASCSI_PUBLIC_RELEASE 1
 
-#define NCR5380_implementation_fields  int port, ctrl
+#define priv(host)                     ((struct NCR5380_hostdata *)(host)->hostdata)
 #define NCR5380_local_declare()                struct Scsi_Host *_instance
 #define NCR5380_setup(instance)                _instance = instance
 #define NCR5380_read(reg)              cumanascsi_read(_instance, reg)
 #define NCR5380_queue_command          cumanascsi_queue_command
 #define NCR5380_proc_info              cumanascsi_proc_info
 
+#define NCR5380_implementation_fields  \
+       unsigned ctrl;                  \
+       void __iomem *base;             \
+       void __iomem *dma
+
 #define BOARD_NORMAL   0
 #define BOARD_NCR53C400        1
 
@@ -47,192 +52,162 @@ const char *cumanascsi_info(struct Scsi_Host *spnt)
        return "";
 }
 
-#ifdef NOT_EFFICIENT
-#define CTRL(p,v)     outb(*ctrl = (v), (p) - 577)
-#define STAT(p)       inb((p)+1)
-#define IN(p)         inb((p))
-#define OUT(v,p)      outb((v), (p))
-#else
-#define CTRL(p,v)      (p[-2308] = (*ctrl = (v)))
-#define STAT(p)                (p[4])
-#define IN(p)          (*(p))
-#define IN2(p)         ((unsigned short)(*(volatile unsigned long *)(p)))
-#define OUT(v,p)       (*(p) = (v))
-#define OUT2(v,p)      (*((volatile unsigned long *)(p)) = (v))
-#endif
-#define L(v)           (((v)<<16)|((v) & 0x0000ffff))
-#define H(v)           (((v)>>16)|((v) & 0xffff0000))
+#define CTRL   0x16fc
+#define STAT   0x2004
+#define L(v)   (((v)<<16)|((v) & 0x0000ffff))
+#define H(v)   (((v)>>16)|((v) & 0xffff0000))
 
 static inline int
-NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr, int len)
+NCR5380_pwrite(struct Scsi_Host *host, unsigned char *addr, int len)
 {
-  int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
-  int oldctrl = *ctrl;
   unsigned long *laddr;
-#ifdef NOT_EFFICIENT
-  int iobase = instance->io_port;
-  int dma_io = iobase & ~(0x3C0000>>2);
-#else
-  volatile unsigned char *iobase = (unsigned char *)ioaddr(instance->io_port);
-  volatile unsigned char *dma_io = (unsigned char *)((int)iobase & ~0x3C0000);
-#endif
+  void __iomem *dma = priv(host)->dma + 0x2000;
 
   if(!len) return 0;
 
-  CTRL(iobase, 0x02);
+  writeb(0x02, priv(host)->base + CTRL);
   laddr = (unsigned long *)addr;
   while(len >= 32)
   {
-    int status;
+    unsigned int status;
     unsigned long v;
-    status = STAT(iobase);
+    status = readb(priv(host)->base + STAT);
     if(status & 0x80)
       goto end;
     if(!(status & 0x40))
       continue;
-    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
-    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
-    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
-    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
-    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
-    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
-    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
-    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
+    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
+    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
+    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
+    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
+    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
+    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
+    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
+    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
     len -= 32;
     if(len == 0)
       break;
   }
 
   addr = (unsigned char *)laddr;
-  CTRL(iobase, 0x12);
+  writeb(0x12, priv(host)->base + CTRL);
+
   while(len > 0)
   {
-    int status;
-    status = STAT(iobase);
+    unsigned int status;
+    status = readb(priv(host)->base + STAT);
     if(status & 0x80)
       goto end;
     if(status & 0x40)
     {
-      OUT(*addr++, dma_io);
+      writeb(*addr++, dma);
       if(--len == 0)
         break;
     }
 
-    status = STAT(iobase);
+    status = readb(priv(host)->base + STAT);
     if(status & 0x80)
       goto end;
     if(status & 0x40)
     {
-      OUT(*addr++, dma_io);
+      writeb(*addr++, dma);
       if(--len == 0)
         break;
     }
   }
 end:
-  CTRL(iobase, oldctrl|0x40);
+  writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL);
   return len;
 }
 
 static inline int
-NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr, int len)
+NCR5380_pread(struct Scsi_Host *host, unsigned char *addr, int len)
 {
-  int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
-  int oldctrl = *ctrl;
   unsigned long *laddr;
-#ifdef NOT_EFFICIENT
-  int iobase = instance->io_port;
-  int dma_io = iobase & ~(0x3C0000>>2);
-#else
-  volatile unsigned char *iobase = (unsigned char *)ioaddr(instance->io_port);
-  volatile unsigned char *dma_io = (unsigned char *)((int)iobase & ~0x3C0000);
-#endif
+  void __iomem *dma = priv(host)->dma + 0x2000;
 
   if(!len) return 0;
 
-  CTRL(iobase, 0x00);
+  writeb(0x00, priv(host)->base + CTRL);
   laddr = (unsigned long *)addr;
   while(len >= 32)
   {
-    int status;
-    status = STAT(iobase);
+    unsigned int status;
+    status = readb(priv(host)->base + STAT);
     if(status & 0x80)
       goto end;
     if(!(status & 0x40))
       continue;
-    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
-    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
-    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
-    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
-    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
-    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
-    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
-    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
+    *laddr++ = readw(dma) | (readw(dma) << 16);
+    *laddr++ = readw(dma) | (readw(dma) << 16);
+    *laddr++ = readw(dma) | (readw(dma) << 16);
+    *laddr++ = readw(dma) | (readw(dma) << 16);
+    *laddr++ = readw(dma) | (readw(dma) << 16);
+    *laddr++ = readw(dma) | (readw(dma) << 16);
+    *laddr++ = readw(dma) | (readw(dma) << 16);
+    *laddr++ = readw(dma) | (readw(dma) << 16);
     len -= 32;
     if(len == 0)
       break;
   }
 
   addr = (unsigned char *)laddr;
-  CTRL(iobase, 0x10);
+  writeb(0x10, priv(host)->base + CTRL);
+
   while(len > 0)
   {
-    int status;
-    status = STAT(iobase);
+    unsigned int status;
+    status = readb(priv(host)->base + STAT);
     if(status & 0x80)
       goto end;
     if(status & 0x40)
     {
-      *addr++ = IN(dma_io);
+      *addr++ = readb(dma);
       if(--len == 0)
         break;
     }
 
-    status = STAT(iobase);
+    status = readb(priv(host)->base + STAT);
     if(status & 0x80)
       goto end;
     if(status & 0x40)
     {
-      *addr++ = IN(dma_io);
+      *addr++ = readb(dma);
       if(--len == 0)
         break;
     }
   }
 end:
-  CTRL(iobase, oldctrl|0x40);
+  writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL);
   return len;
 }
 
-#undef STAT
-#undef CTRL
-#undef IN
-#undef OUT
+static unsigned char cumanascsi_read(struct Scsi_Host *host, unsigned int reg)
+{
+       void __iomem *base = priv(host)->base;
+       unsigned char val;
 
-#define CTRL(p,v) outb(*ctrl = (v), (p) - 577)
+       writeb(0, base + CTRL);
 
-static char cumanascsi_read(struct Scsi_Host *instance, int reg)
-{
-       unsigned int iobase = instance->io_port;
-       int i;
-       int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
+       val = readb(base + 0x2100 + (reg << 2));
 
-       CTRL(iobase, 0);
-       i = inb(iobase + 64 + reg);
-       CTRL(iobase, 0x40);
+       priv(host)->ctrl = 0x40;
+       writeb(0x40, base + CTRL);
 
-       return i;
+       return val;
 }
 
-static void cumanascsi_write(struct Scsi_Host *instance, int reg, int value)
+static void cumanascsi_write(struct Scsi_Host *host, unsigned int reg, unsigned int value)
 {
-       int iobase = instance->io_port;
-       int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
+       void __iomem *base = priv(host)->base;
 
-       CTRL(iobase, 0);
-       outb(value, iobase + 64 + reg);
-       CTRL(iobase, 0x40);
-}
+       writeb(0, base + CTRL);
 
-#undef CTRL
+       writeb(value, base + 0x2100 + (reg << 2));
+
+       priv(host)->ctrl = 0x40;
+       writeb(0x40, base + CTRL);
+}
 
 #include "../NCR5380.c"
 
@@ -256,32 +231,46 @@ static int __devinit
 cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id)
 {
        struct Scsi_Host *host;
-       int ret = -ENOMEM;
+       int ret;
 
-       host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata));
-       if (!host)
+       ret = ecard_request_resources(ec);
+       if (ret)
                goto out;
 
-        host->io_port = ecard_address(ec, ECARD_IOC, ECARD_SLOW) + 0x800;
+       host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata));
+       if (!host) {
+               ret = -ENOMEM;
+               goto out_release;
+       }
+
+       priv(host)->base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCSLOW),
+                                  ecard_resource_len(ec, ECARD_RES_IOCSLOW));
+       priv(host)->dma = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
+                                 ecard_resource_len(ec, ECARD_RES_MEMC));
+       if (!priv(host)->base || !priv(host)->dma) {
+               ret = -ENOMEM;
+               goto out_unmap;
+       }
+
        host->irq = ec->irq;
 
        NCR5380_init(host, 0);
 
+        priv(host)->ctrl = 0;
+        writeb(0, priv(host)->base + CTRL);
+
        host->n_io_port = 255;
        if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) {
                ret = -EBUSY;
-               goto out_free;
+               goto out_unmap;
        }
 
-        ((struct NCR5380_hostdata *)host->hostdata)->ctrl = 0;
-        outb(0x00, host->io_port - 577);
-
        ret = request_irq(host->irq, cumanascsi_intr, IRQF_DISABLED,
                          "CumanaSCSI-1", host);
        if (ret) {
                printk("scsi%d: IRQ%d not free: %d\n",
                    host->host_no, host->irq, ret);
-               goto out_release;
+               goto out_unmap;
        }
 
        printk("scsi%d: at port 0x%08lx irq %d",
@@ -301,10 +290,12 @@ cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id)
 
  out_free_irq:
        free_irq(host->irq, host);
- out_release:
-       release_region(host->io_port, host->n_io_port);
- out_free:
+ out_unmap:
+       iounmap(priv(host)->base);
+       iounmap(priv(host)->dma);
        scsi_host_put(host);
+ out_release:
+       ecard_release_resources(ec);
  out:
        return ret;
 }
@@ -318,8 +309,10 @@ static void __devexit cumanascsi1_remove(struct expansion_card *ec)
        scsi_remove_host(host);
        free_irq(host->irq, host);
        NCR5380_exit(host);
-       release_region(host->io_port, host->n_io_port);
+       iounmap(priv(host)->base);
+       iounmap(priv(host)->dma);
        scsi_host_put(host);
+       ecard_release_resources(ec);
 }
 
 static const struct ecard_id cumanascsi1_cids[] = {
index 378e7af0c5d6760750fe18c9105b1707fdf05527..5265a9884338b90e0d5e8e551f7d0487e6b7c61f 100644 (file)
 #include "../scsi.h"
 #include <scsi/scsi_host.h>
 
-#define NCR5380_implementation_fields  int port, ctrl
-#define NCR5380_local_declare()                struct Scsi_Host *_instance
-#define NCR5380_setup(instance)                _instance = instance
+#define priv(host)                     ((struct NCR5380_hostdata *)(host)->hostdata)
 
-#define NCR5380_read(reg)              ecoscsi_read(_instance, reg)
-#define NCR5380_write(reg, value)      ecoscsi_write(_instance, reg, value)
+#define NCR5380_local_declare()                void __iomem *_base
+#define NCR5380_setup(host)            _base = priv(host)->base
+
+#define NCR5380_read(reg)              ({ writeb(reg | 8, _base); readb(_base + 4); })
+#define NCR5380_write(reg, value)      ({ writeb(reg | 8, _base); writeb(value, _base + 4); })
 
 #define NCR5380_intr                   ecoscsi_intr
 #define NCR5380_queue_command          ecoscsi_queue_command
 #define NCR5380_proc_info              ecoscsi_proc_info
 
+#define NCR5380_implementation_fields  \
+       void __iomem *base
+
 #include "../NCR5380.h"
 
 #define ECOSCSI_PUBLIC_RELEASE 1
 
-static char ecoscsi_read(struct Scsi_Host *instance, int reg)
-{
-  int iobase = instance->io_port;
-  outb(reg | 8, iobase);
-  return inb(iobase + 1);
-}
-
-static void ecoscsi_write(struct Scsi_Host *instance, int reg, int value)
-{
-  int iobase = instance->io_port;
-  outb(reg | 8, iobase);
-  outb(value, iobase + 1);
-}
-
 /*
  * Function : ecoscsi_setup(char *str, int *ints)
  *
@@ -82,73 +72,6 @@ const char * ecoscsi_info (struct Scsi_Host *spnt)
        return "";
 }
 
-#if 0
-#define STAT(p) inw(p + 144)
-
-static inline int NCR5380_pwrite(struct Scsi_Host *host, unsigned char *addr,
-              int len)
-{
-  int iobase = host->io_port;
-printk("writing %p len %d\n",addr, len);
-  if(!len) return -1;
-
-  while(1)
-  {
-    int status;
-    while(((status = STAT(iobase)) & 0x100)==0);
-  }
-}
-
-static inline int NCR5380_pread(struct Scsi_Host *host, unsigned char *addr,
-              int len)
-{
-  int iobase = host->io_port;
-  int iobase2= host->io_port + 0x100;
-  unsigned char *start = addr;
-  int s;
-printk("reading %p len %d\n",addr, len);
-  outb(inb(iobase + 128), iobase + 135);
-  while(len > 0)
-  {
-    int status,b,i, timeout;
-    timeout = 0x07FFFFFF;
-    while(((status = STAT(iobase)) & 0x100)==0)
-    {
-      timeout--;
-      if(status & 0x200 || !timeout)
-      {
-        printk("status = %p\n",status);
-        outb(0, iobase + 135);
-        return 1;
-      }
-    }
-    if(len >= 128)
-    {
-      for(i=0; i<64; i++)
-      {
-        b = inw(iobase + 136);
-        *addr++ = b;
-        *addr++ = b>>8;
-      }
-      len -= 128;
-    }
-    else
-    {
-      b = inw(iobase + 136);
-      *addr ++ = b;
-      len -= 1;
-      if(len)
-        *addr ++ = b>>8;
-      len -= 1;
-    }
-  }
-  outb(0, iobase + 135);
-  printk("first bytes = %02X %02X %02X %20X %02X %02X %02X\n",*start, start[1], start[2], start[3], start[4], start[5], start[6]);
-  return 1;
-}
-#endif
-#undef STAT
-
 #define BOARD_NORMAL   0
 #define BOARD_NCR53C400        1
 
@@ -173,25 +96,36 @@ static struct Scsi_Host *host;
 
 static int __init ecoscsi_init(void)
 {
+       void __iomem *_base;
+       int ret;
 
-       host = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata));
-       if (!host)
-               return 0;
+       if (!request_mem_region(0x33a0000, 4096, "ecoscsi")) {
+               ret = -EBUSY;
+               goto out;
+       }
 
-       host->io_port = 0x80ce8000;
-       host->n_io_port = 144;
-       host->irq = IRQ_NONE;
+       _base = ioremap(0x33a0000, 4096);
+       if (!_base) {
+               ret = -ENOMEM;
+               goto out_release;
+       }
 
-       if (!(request_region(host->io_port, host->n_io_port, "ecoscsi")) )
-               goto unregister_scsi;
+       NCR5380_write(MODE_REG, 0x20);          /* Is it really SCSI? */
+       if (NCR5380_read(MODE_REG) != 0x20)     /* Write to a reg.    */
+               goto out_unmap;
 
-       ecoscsi_write(host, MODE_REG, 0x20);            /* Is it really SCSI? */
-       if (ecoscsi_read(host, MODE_REG) != 0x20) /* Write to a reg.    */
-               goto release_reg;
+       NCR5380_write(MODE_REG, 0x00);          /* it back.           */
+       if (NCR5380_read(MODE_REG) != 0x00)
+               goto out_unmap;
 
-       ecoscsi_write(host, MODE_REG, 0x00 );           /* it back.           */
-       if (ecoscsi_read(host, MODE_REG) != 0x00)
-               goto release_reg;
+       host = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata));
+       if (!host) {
+               ret = -ENOMEM;
+               goto out_unmap;
+       }
+
+       priv(host)->base = _base;
+       host->irq = IRQ_NONE;
 
        NCR5380_init(host, 0);
 
@@ -206,24 +140,20 @@ static int __init ecoscsi_init(void)
        scsi_scan_host(host);
        return 0;
 
-release_reg:
-       release_region(host->io_port, host->n_io_port);
-unregister_scsi:
-       scsi_host_put(host);
-       return -ENODEV;
+ out_unmap:
+       iounmap(_base);
+ out_release:
+       release_mem_region(0x33a0000, 4096);
+ out:
+       return ret;
 }
 
 static void __exit ecoscsi_exit(void)
 {
        scsi_remove_host(host);
-
-       if (shpnt->irq != IRQ_NONE)
-               free_irq(shpnt->irq, NULL);
        NCR5380_exit(host);
-       if (shpnt->io_port)
-               release_region(shpnt->io_port, shpnt->n_io_port);
-
        scsi_host_put(host);
+       release_mem_region(0x33a0000, 4096);
        return 0;
 }
 
index c21b8392c92837ec2af15d43acbb8acdd1bbe22d..849cdf89f7bbdcada963da8678d4b6a5291a4ea5 100644 (file)
 
 #define OAKSCSI_PUBLIC_RELEASE 1
 
-#define NCR5380_read(reg)              oakscsi_read(_instance, reg)
-#define NCR5380_write(reg, value)      oakscsi_write(_instance, reg, value)
+#define priv(host)                     ((struct NCR5380_hostdata *)(host)->hostdata)
+#define NCR5380_local_declare()                void __iomem *_base
+#define NCR5380_setup(host)            _base = priv(host)->base
+
+#define NCR5380_read(reg)              readb(_base + ((reg) << 2))
+#define NCR5380_write(reg, value)      writeb(value, _base + ((reg) << 2))
 #define NCR5380_intr                   oakscsi_intr
 #define NCR5380_queue_command          oakscsi_queue_command
 #define NCR5380_proc_info              oakscsi_proc_info
 
-#define NCR5380_implementation_fields  int port, ctrl
-#define NCR5380_local_declare()                struct Scsi_Host *_instance
-#define NCR5380_setup(instance)                _instance = instance
+#define NCR5380_implementation_fields  \
+       void __iomem *base
 
 #define BOARD_NORMAL   0
 #define BOARD_NCR53C400        1
 #include "../NCR5380.h"
 
 #undef START_DMA_INITIATOR_RECEIVE_REG
-#define START_DMA_INITIATOR_RECEIVE_REG (7 + 128)
+#define START_DMA_INITIATOR_RECEIVE_REG        (128 + 7)
 
 const char * oakscsi_info (struct Scsi_Host *spnt)
 {
        return "";
 }
 
-#define STAT(p)   inw(p + 144)
-extern void inswb(int from, void *to, int len);
+#define STAT   ((128 + 16) << 2)
+#define DATA   ((128 + 8) << 2)
 
 static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr,
               int len)
 {
-  int iobase = instance->io_port;
+  void __iomem *base = priv(instance)->base;
+
 printk("writing %p len %d\n",addr, len);
   if(!len) return -1;
 
   while(1)
   {
     int status;
-    while(((status = STAT(iobase)) & 0x100)==0);
+    while (((status = readw(base + STAT)) & 0x100)==0);
   }
 }
 
 static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr,
               int len)
 {
-  int iobase = instance->io_port;
+  void __iomem *base = priv(instance)->base;
 printk("reading %p len %d\n", addr, len);
   while(len > 0)
   {
-    int status, timeout;
+    unsigned int status, timeout;
     unsigned long b;
     
     timeout = 0x01FFFFFF;
     
-    while(((status = STAT(iobase)) & 0x100)==0)
+    while (((status = readw(base + STAT)) & 0x100)==0)
     {
       timeout--;
       if(status & 0x200 || !timeout)
       {
-        printk("status = %08X\n",status);
+        printk("status = %08X\n", status);
         return 1;
       }
     }
+
     if(len >= 128)
     {
-      inswb(iobase + 136, addr, 128);
+      readsw(base + DATA, addr, 128);
       addr += 128;
       len -= 128;
     }
     else
     {
-      b = (unsigned long) inw(iobase + 136);
+      b = (unsigned long) readw(base + DATA);
       *addr ++ = b;
       len -= 1;
       if(len)
@@ -103,10 +108,8 @@ printk("reading %p len %d\n", addr, len);
   return 0;
 }
 
-#define oakscsi_read(instance,reg)     (inb((instance)->io_port + (reg)))
-#define oakscsi_write(instance,reg,val)        (outb((val), (instance)->io_port + (reg)))
-
 #undef STAT
+#undef DATA
 
 #include "../NCR5380.c"
 
@@ -132,18 +135,26 @@ oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
        struct Scsi_Host *host;
        int ret = -ENOMEM;
 
-       host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata));
-       if (!host)
+       ret = ecard_request_resources(ec);
+       if (ret)
                goto out;
 
-       host->io_port = ecard_address(ec, ECARD_MEMC, 0);
+       host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata));
+       if (!host) {
+               ret = -ENOMEM;
+               goto release;
+       }
+
+       priv(host)->base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
+                                  ecard_resource_len(ec, ECARD_RES_MEMC));
+       if (!priv(host)->base) {
+               ret = -ENOMEM;
+               goto unreg;
+       }
+
        host->irq = IRQ_NONE;
        host->n_io_port = 255;
 
-       ret = -EBUSY;
-       if (!request_region (host->io_port, host->n_io_port, "Oak SCSI"))
-               goto unreg;
-
        NCR5380_init(host, 0);
 
        printk("scsi%d: at port 0x%08lx irqs disabled",
@@ -156,15 +167,17 @@ oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
 
        ret = scsi_add_host(host, &ec->dev);
        if (ret)
-               goto out_release;
+               goto out_unmap;
 
        scsi_scan_host(host);
        goto out;
 
- out_release:
-       release_region(host->io_port, host->n_io_port);
+ out_unmap:
+       iounmap(priv(host)->base);
  unreg:
        scsi_host_put(host);
+ release:
+       ecard_release_resources(ec);
  out:
        return ret;
 }
@@ -177,8 +190,9 @@ static void __devexit oakscsi_remove(struct expansion_card *ec)
        scsi_remove_host(host);
 
        NCR5380_exit(host);
-       release_region(host->io_port, host->n_io_port);
+       iounmap(priv(host)->base);
        scsi_host_put(host);
+       ecard_release_resources(ec);
 }
 
 static const struct ecard_id oakscsi_cids[] = {
index 012cdea7946d3dd8f98f8aa49b1dd122bbfd4387..cac354086737e9b937062dab6e026a52c9289614 100644 (file)
@@ -74,6 +74,7 @@ bvme6000_probe(struct device *dev)
                goto out_put_host;
        }
 
+       dev_set_drvdata(dev, host);
        scsi_scan_host(host);
 
        return 0;
@@ -89,7 +90,7 @@ bvme6000_probe(struct device *dev)
 static __devexit int
 bvme6000_device_remove(struct device *dev)
 {
-       struct Scsi_Host *host = dev_to_shost(dev);
+       struct Scsi_Host *host = dev_get_drvdata(dev);
        struct NCR_700_Host_Parameters *hostdata = shost_priv(host);
 
        scsi_remove_host(host);
index d5576d54ce768f6e801e174c29f69901f36bc111..856e38b14861c6614bb72a81cc0a88a236e00db7 100644 (file)
 #define ESP_BUSID_RESELID     0x10
 #define ESP_BUSID_CTR32BIT    0x40
 
-#define ESP_BUS_TIMEOUT        250     /* In milli-seconds */
+#define ESP_BUS_TIMEOUT        275     /* In milli-seconds */
 #define ESP_TIMEO_CONST       8192
 #define ESP_NEG_DEFP(mhz, cfact) \
         ((ESP_BUS_TIMEOUT * ((mhz) / 1000)) / (8192 * (cfact)))
index aafdc92f83123a2611a92db295bf10ee571c55cc..3a3c1ac9c6cdcd495d477e7219d4eddc0f51bbc8 100644 (file)
@@ -30,6 +30,13 @@ config SCSI_SAS_LIBSAS
          This provides transport specific helpers for SAS drivers which
          use the domain device construct (like the aic94xxx).
 
+config SCSI_SAS_ATA
+       bool "ATA support for libsas (requires libata)"
+       depends on SCSI_SAS_LIBSAS && ATA
+       help
+               Builds in ATA support into libsas.  Will necessitate
+               the loading of libata along with libsas.
+
 config SCSI_SAS_LIBSAS_DEBUG
        bool "Compile the SAS Domain Transport Attributes in debug mode"
        default y
index 44d972a3b4bda38777f379437cbb76542ee6a938..fd387b91856edf97c6a84b6106ab6329e4c599ab 100644 (file)
@@ -34,3 +34,4 @@ libsas-y +=  sas_init.o     \
                sas_discover.o \
                sas_expander.o \
                sas_scsi_host.o
+libsas-$(CONFIG_SCSI_SAS_ATA) +=       sas_ata.o
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
new file mode 100644 (file)
index 0000000..ced2de3
--- /dev/null
@@ -0,0 +1,817 @@
+/*
+ * Support for SATA devices on Serial Attached SCSI (SAS) controllers
+ *
+ * Copyright (C) 2006 IBM Corporation
+ *
+ * Written by: Darrick J. Wong <djwong@us.ibm.com>, IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include <linux/scatterlist.h>
+
+#include <scsi/sas_ata.h>
+#include "sas_internal.h"
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_sas.h>
+#include "../scsi_sas_internal.h"
+#include "../scsi_transport_api.h"
+#include <scsi/scsi_eh.h>
+
+static enum ata_completion_errors sas_to_ata_err(struct task_status_struct *ts)
+{
+       /* Cheesy attempt to translate SAS errors into ATA.  Hah! */
+
+       /* transport error */
+       if (ts->resp == SAS_TASK_UNDELIVERED)
+               return AC_ERR_ATA_BUS;
+
+       /* ts->resp == SAS_TASK_COMPLETE */
+       /* task delivered, what happened afterwards? */
+       switch (ts->stat) {
+               case SAS_DEV_NO_RESPONSE:
+                       return AC_ERR_TIMEOUT;
+
+               case SAS_INTERRUPTED:
+               case SAS_PHY_DOWN:
+               case SAS_NAK_R_ERR:
+                       return AC_ERR_ATA_BUS;
+
+
+               case SAS_DATA_UNDERRUN:
+                       /*
+                        * Some programs that use the taskfile interface
+                        * (smartctl in particular) can cause underrun
+                        * problems.  Ignore these errors, perhaps at our
+                        * peril.
+                        */
+                       return 0;
+
+               case SAS_DATA_OVERRUN:
+               case SAS_QUEUE_FULL:
+               case SAS_DEVICE_UNKNOWN:
+               case SAS_SG_ERR:
+                       return AC_ERR_INVALID;
+
+               case SAM_CHECK_COND:
+               case SAS_OPEN_TO:
+               case SAS_OPEN_REJECT:
+                       SAS_DPRINTK("%s: Saw error %d.  What to do?\n",
+                                   __FUNCTION__, ts->stat);
+                       return AC_ERR_OTHER;
+
+               case SAS_ABORTED_TASK:
+                       return AC_ERR_DEV;
+
+               case SAS_PROTO_RESPONSE:
+                       /* This means the ending_fis has the error
+                        * value; return 0 here to collect it */
+                       return 0;
+               default:
+                       return 0;
+       }
+}
+
+static void sas_ata_task_done(struct sas_task *task)
+{
+       struct ata_queued_cmd *qc = task->uldd_task;
+       struct domain_device *dev;
+       struct task_status_struct *stat = &task->task_status;
+       struct ata_task_resp *resp = (struct ata_task_resp *)stat->buf;
+       struct sas_ha_struct *sas_ha;
+       enum ata_completion_errors ac;
+       unsigned long flags;
+
+       if (!qc)
+               goto qc_already_gone;
+
+       dev = qc->ap->private_data;
+       sas_ha = dev->port->ha;
+
+       spin_lock_irqsave(dev->sata_dev.ap->lock, flags);
+       if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_GOOD) {
+               ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf);
+               qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command);
+               dev->sata_dev.sstatus = resp->sstatus;
+               dev->sata_dev.serror = resp->serror;
+               dev->sata_dev.scontrol = resp->scontrol;
+       } else if (stat->stat != SAM_STAT_GOOD) {
+               ac = sas_to_ata_err(stat);
+               if (ac) {
+                       SAS_DPRINTK("%s: SAS error %x\n", __FUNCTION__,
+                                   stat->stat);
+                       /* We saw a SAS error. Send a vague error. */
+                       qc->err_mask = ac;
+                       dev->sata_dev.tf.feature = 0x04; /* status err */
+                       dev->sata_dev.tf.command = ATA_ERR;
+               }
+       }
+
+       qc->lldd_task = NULL;
+       if (qc->scsicmd)
+               ASSIGN_SAS_TASK(qc->scsicmd, NULL);
+       ata_qc_complete(qc);
+       spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags);
+
+       /*
+        * If the sas_task has an ata qc, a scsi_cmnd and the aborted
+        * flag is set, then we must have come in via the libsas EH
+        * functions.  When we exit this function, we need to put the
+        * scsi_cmnd on the list of finished errors.  The ata_qc_complete
+        * call cleans up the libata side of things but we're protected
+        * from the scsi_cmnd going away because the scsi_cmnd is owned
+        * by the EH, making libata's call to scsi_done a NOP.
+        */
+       spin_lock_irqsave(&task->task_state_lock, flags);
+       if (qc->scsicmd && task->task_state_flags & SAS_TASK_STATE_ABORTED)
+               scsi_eh_finish_cmd(qc->scsicmd, &sas_ha->eh_done_q);
+       spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+qc_already_gone:
+       list_del_init(&task->list);
+       sas_free_task(task);
+}
+
+static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
+{
+       int res;
+       struct sas_task *task;
+       struct domain_device *dev = qc->ap->private_data;
+       struct sas_ha_struct *sas_ha = dev->port->ha;
+       struct Scsi_Host *host = sas_ha->core.shost;
+       struct sas_internal *i = to_sas_internal(host->transportt);
+       struct scatterlist *sg;
+       unsigned int num = 0;
+       unsigned int xfer = 0;
+
+       task = sas_alloc_task(GFP_ATOMIC);
+       if (!task)
+               return AC_ERR_SYSTEM;
+       task->dev = dev;
+       task->task_proto = SAS_PROTOCOL_STP;
+       task->task_done = sas_ata_task_done;
+
+       if (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
+           qc->tf.command == ATA_CMD_FPDMA_READ) {
+               /* Need to zero out the tag libata assigned us */
+               qc->tf.nsect = 0;
+       }
+
+       ata_tf_to_fis(&qc->tf, 1, 0, (u8*)&task->ata_task.fis);
+       task->uldd_task = qc;
+       if (is_atapi_taskfile(&qc->tf)) {
+               memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len);
+               task->total_xfer_len = qc->nbytes + qc->pad_len;
+               task->num_scatter = qc->pad_len ? qc->n_elem + 1 : qc->n_elem;
+       } else {
+               ata_for_each_sg(sg, qc) {
+                       num++;
+                       xfer += sg->length;
+               }
+
+               task->total_xfer_len = xfer;
+               task->num_scatter = num;
+       }
+
+       task->data_dir = qc->dma_dir;
+       task->scatter = qc->__sg;
+       task->ata_task.retry_count = 1;
+       task->task_state_flags = SAS_TASK_STATE_PENDING;
+       qc->lldd_task = task;
+
+       switch (qc->tf.protocol) {
+       case ATA_PROT_NCQ:
+               task->ata_task.use_ncq = 1;
+               /* fall through */
+       case ATA_PROT_ATAPI_DMA:
+       case ATA_PROT_DMA:
+               task->ata_task.dma_xfer = 1;
+               break;
+       }
+
+       if (qc->scsicmd)
+               ASSIGN_SAS_TASK(qc->scsicmd, task);
+
+       if (sas_ha->lldd_max_execute_num < 2)
+               res = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC);
+       else
+               res = sas_queue_up(task);
+
+       /* Examine */
+       if (res) {
+               SAS_DPRINTK("lldd_execute_task returned: %d\n", res);
+
+               if (qc->scsicmd)
+                       ASSIGN_SAS_TASK(qc->scsicmd, NULL);
+               sas_free_task(task);
+               return AC_ERR_SYSTEM;
+       }
+
+       return 0;
+}
+
+static u8 sas_ata_check_status(struct ata_port *ap)
+{
+       struct domain_device *dev = ap->private_data;
+       return dev->sata_dev.tf.command;
+}
+
+static void sas_ata_phy_reset(struct ata_port *ap)
+{
+       struct domain_device *dev = ap->private_data;
+       struct sas_internal *i =
+               to_sas_internal(dev->port->ha->core.shost->transportt);
+       int res = 0;
+
+       if (i->dft->lldd_I_T_nexus_reset)
+               res = i->dft->lldd_I_T_nexus_reset(dev);
+
+       if (res)
+               SAS_DPRINTK("%s: Unable to reset I T nexus?\n", __FUNCTION__);
+
+       switch (dev->sata_dev.command_set) {
+               case ATA_COMMAND_SET:
+                       SAS_DPRINTK("%s: Found ATA device.\n", __FUNCTION__);
+                       ap->device[0].class = ATA_DEV_ATA;
+                       break;
+               case ATAPI_COMMAND_SET:
+                       SAS_DPRINTK("%s: Found ATAPI device.\n", __FUNCTION__);
+                       ap->device[0].class = ATA_DEV_ATAPI;
+                       break;
+               default:
+                       SAS_DPRINTK("%s: Unknown SATA command set: %d.\n",
+                                   __FUNCTION__,
+                                   dev->sata_dev.command_set);
+                       ap->device[0].class = ATA_DEV_UNKNOWN;
+                       break;
+       }
+
+       ap->cbl = ATA_CBL_SATA;
+}
+
+static void sas_ata_post_internal(struct ata_queued_cmd *qc)
+{
+       if (qc->flags & ATA_QCFLAG_FAILED)
+               qc->err_mask |= AC_ERR_OTHER;
+
+       if (qc->err_mask) {
+               /*
+                * Find the sas_task and kill it.  By this point,
+                * libata has decided to kill the qc, so we needn't
+                * bother with sas_ata_task_done.  But we still
+                * ought to abort the task.
+                */
+               struct sas_task *task = qc->lldd_task;
+               unsigned long flags;
+
+               qc->lldd_task = NULL;
+               if (task) {
+                       /* Should this be a AT(API) device reset? */
+                       spin_lock_irqsave(&task->task_state_lock, flags);
+                       task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
+                       spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+                       task->uldd_task = NULL;
+                       __sas_task_abort(task);
+               }
+       }
+}
+
+static void sas_ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+       struct domain_device *dev = ap->private_data;
+       memcpy(tf, &dev->sata_dev.tf, sizeof (*tf));
+}
+
+static int sas_ata_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
+                             u32 val)
+{
+       struct domain_device *dev = ap->private_data;
+
+       SAS_DPRINTK("STUB %s\n", __FUNCTION__);
+       switch (sc_reg_in) {
+               case SCR_STATUS:
+                       dev->sata_dev.sstatus = val;
+                       break;
+               case SCR_CONTROL:
+                       dev->sata_dev.scontrol = val;
+                       break;
+               case SCR_ERROR:
+                       dev->sata_dev.serror = val;
+                       break;
+               case SCR_ACTIVE:
+                       dev->sata_dev.ap->sactive = val;
+                       break;
+               default:
+                       return -EINVAL;
+       }
+       return 0;
+}
+
+static int sas_ata_scr_read(struct ata_port *ap, unsigned int sc_reg_in,
+                           u32 *val)
+{
+       struct domain_device *dev = ap->private_data;
+
+       SAS_DPRINTK("STUB %s\n", __FUNCTION__);
+       switch (sc_reg_in) {
+               case SCR_STATUS:
+                       *val = dev->sata_dev.sstatus;
+                       return 0;
+               case SCR_CONTROL:
+                       *val = dev->sata_dev.scontrol;
+                       return 0;
+               case SCR_ERROR:
+                       *val = dev->sata_dev.serror;
+                       return 0;
+               case SCR_ACTIVE:
+                       *val = dev->sata_dev.ap->sactive;
+                       return 0;
+               default:
+                       return -EINVAL;
+       }
+}
+
+static struct ata_port_operations sas_sata_ops = {
+       .port_disable           = ata_port_disable,
+       .check_status           = sas_ata_check_status,
+       .check_altstatus        = sas_ata_check_status,
+       .dev_select             = ata_noop_dev_select,
+       .phy_reset              = sas_ata_phy_reset,
+       .post_internal_cmd      = sas_ata_post_internal,
+       .tf_read                = sas_ata_tf_read,
+       .qc_prep                = ata_noop_qc_prep,
+       .qc_issue               = sas_ata_qc_issue,
+       .port_start             = ata_sas_port_start,
+       .port_stop              = ata_sas_port_stop,
+       .scr_read               = sas_ata_scr_read,
+       .scr_write              = sas_ata_scr_write
+};
+
+static struct ata_port_info sata_port_info = {
+       .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_SATA_RESET |
+               ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | ATA_FLAG_NCQ,
+       .pio_mask = 0x1f, /* PIO0-4 */
+       .mwdma_mask = 0x07, /* MWDMA0-2 */
+       .udma_mask = ATA_UDMA6,
+       .port_ops = &sas_sata_ops
+};
+
+int sas_ata_init_host_and_port(struct domain_device *found_dev,
+                              struct scsi_target *starget)
+{
+       struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+       struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
+       struct ata_port *ap;
+
+       ata_host_init(&found_dev->sata_dev.ata_host,
+                     &ha->pcidev->dev,
+                     sata_port_info.flags,
+                     &sas_sata_ops);
+       ap = ata_sas_port_alloc(&found_dev->sata_dev.ata_host,
+                               &sata_port_info,
+                               shost);
+       if (!ap) {
+               SAS_DPRINTK("ata_sas_port_alloc failed.\n");
+               return -ENODEV;
+       }
+
+       ap->private_data = found_dev;
+       ap->cbl = ATA_CBL_SATA;
+       ap->scsi_host = shost;
+       found_dev->sata_dev.ap = ap;
+
+       return 0;
+}
+
+void sas_ata_task_abort(struct sas_task *task)
+{
+       struct ata_queued_cmd *qc = task->uldd_task;
+       struct completion *waiting;
+
+       /* Bounce SCSI-initiated commands to the SCSI EH */
+       if (qc->scsicmd) {
+               scsi_req_abort_cmd(qc->scsicmd);
+               scsi_schedule_eh(qc->scsicmd->device->host);
+               return;
+       }
+
+       /* Internal command, fake a timeout and complete. */
+       qc->flags &= ~ATA_QCFLAG_ACTIVE;
+       qc->flags |= ATA_QCFLAG_FAILED;
+       qc->err_mask |= AC_ERR_TIMEOUT;
+       waiting = qc->private_data;
+       complete(waiting);
+}
+
+static void sas_task_timedout(unsigned long _task)
+{
+       struct sas_task *task = (void *) _task;
+       unsigned long flags;
+
+       spin_lock_irqsave(&task->task_state_lock, flags);
+       if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
+               task->task_state_flags |= SAS_TASK_STATE_ABORTED;
+       spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+       complete(&task->completion);
+}
+
+static void sas_disc_task_done(struct sas_task *task)
+{
+       if (!del_timer(&task->timer))
+               return;
+       complete(&task->completion);
+}
+
+#define SAS_DEV_TIMEOUT 10
+
+/**
+ * sas_execute_task -- Basic task processing for discovery
+ * @task: the task to be executed
+ * @buffer: pointer to buffer to do I/O
+ * @size: size of @buffer
+ * @pci_dma_dir: PCI_DMA_...
+ */
+static int sas_execute_task(struct sas_task *task, void *buffer, int size,
+                           int pci_dma_dir)
+{
+       int res = 0;
+       struct scatterlist *scatter = NULL;
+       struct task_status_struct *ts = &task->task_status;
+       int num_scatter = 0;
+       int retries = 0;
+       struct sas_internal *i =
+               to_sas_internal(task->dev->port->ha->core.shost->transportt);
+
+       if (pci_dma_dir != PCI_DMA_NONE) {
+               scatter = kzalloc(sizeof(*scatter), GFP_KERNEL);
+               if (!scatter)
+                       goto out;
+
+               sg_init_one(scatter, buffer, size);
+               num_scatter = 1;
+       }
+
+       task->task_proto = task->dev->tproto;
+       task->scatter = scatter;
+       task->num_scatter = num_scatter;
+       task->total_xfer_len = size;
+       task->data_dir = pci_dma_dir;
+       task->task_done = sas_disc_task_done;
+       if (pci_dma_dir != PCI_DMA_NONE &&
+           sas_protocol_ata(task->task_proto)) {
+               task->num_scatter = pci_map_sg(task->dev->port->ha->pcidev,
+                                              task->scatter,
+                                              task->num_scatter,
+                                              task->data_dir);
+       }
+
+       for (retries = 0; retries < 5; retries++) {
+               task->task_state_flags = SAS_TASK_STATE_PENDING;
+               init_completion(&task->completion);
+
+               task->timer.data = (unsigned long) task;
+               task->timer.function = sas_task_timedout;
+               task->timer.expires = jiffies + SAS_DEV_TIMEOUT*HZ;
+               add_timer(&task->timer);
+
+               res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
+               if (res) {
+                       del_timer(&task->timer);
+                       SAS_DPRINTK("executing SAS discovery task failed:%d\n",
+                                   res);
+                       goto ex_err;
+               }
+               wait_for_completion(&task->completion);
+               res = -ETASK;
+               if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
+                       int res2;
+                       SAS_DPRINTK("task aborted, flags:0x%x\n",
+                                   task->task_state_flags);
+                       res2 = i->dft->lldd_abort_task(task);
+                       SAS_DPRINTK("came back from abort task\n");
+                       if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
+                               if (res2 == TMF_RESP_FUNC_COMPLETE)
+                                       continue; /* Retry the task */
+                               else
+                                       goto ex_err;
+                       }
+               }
+               if (task->task_status.stat == SAM_BUSY ||
+                          task->task_status.stat == SAM_TASK_SET_FULL ||
+                          task->task_status.stat == SAS_QUEUE_FULL) {
+                       SAS_DPRINTK("task: q busy, sleeping...\n");
+                       schedule_timeout_interruptible(HZ);
+               } else if (task->task_status.stat == SAM_CHECK_COND) {
+                       struct scsi_sense_hdr shdr;
+
+                       if (!scsi_normalize_sense(ts->buf, ts->buf_valid_size,
+                                                 &shdr)) {
+                               SAS_DPRINTK("couldn't normalize sense\n");
+                               continue;
+                       }
+                       if ((shdr.sense_key == 6 && shdr.asc == 0x29) ||
+                           (shdr.sense_key == 2 && shdr.asc == 4 &&
+                            shdr.ascq == 1)) {
+                               SAS_DPRINTK("device %016llx LUN: %016llx "
+                                           "powering up or not ready yet, "
+                                           "sleeping...\n",
+                                           SAS_ADDR(task->dev->sas_addr),
+                                           SAS_ADDR(task->ssp_task.LUN));
+
+                               schedule_timeout_interruptible(5*HZ);
+                       } else if (shdr.sense_key == 1) {
+                               res = 0;
+                               break;
+                       } else if (shdr.sense_key == 5) {
+                               break;
+                       } else {
+                               SAS_DPRINTK("dev %016llx LUN: %016llx "
+                                           "sense key:0x%x ASC:0x%x ASCQ:0x%x"
+                                           "\n",
+                                           SAS_ADDR(task->dev->sas_addr),
+                                           SAS_ADDR(task->ssp_task.LUN),
+                                           shdr.sense_key,
+                                           shdr.asc, shdr.ascq);
+                       }
+               } else if (task->task_status.resp != SAS_TASK_COMPLETE ||
+                          task->task_status.stat != SAM_GOOD) {
+                       SAS_DPRINTK("task finished with resp:0x%x, "
+                                   "stat:0x%x\n",
+                                   task->task_status.resp,
+                                   task->task_status.stat);
+                       goto ex_err;
+               } else {
+                       res = 0;
+                       break;
+               }
+       }
+ex_err:
+       if (pci_dma_dir != PCI_DMA_NONE) {
+               if (sas_protocol_ata(task->task_proto))
+                       pci_unmap_sg(task->dev->port->ha->pcidev,
+                                    task->scatter, task->num_scatter,
+                                    task->data_dir);
+               kfree(scatter);
+       }
+out:
+       return res;
+}
+
+/* ---------- SATA ---------- */
+
+static void sas_get_ata_command_set(struct domain_device *dev)
+{
+       struct dev_to_host_fis *fis =
+               (struct dev_to_host_fis *) dev->frame_rcvd;
+
+       if ((fis->sector_count == 1 && /* ATA */
+            fis->lbal         == 1 &&
+            fis->lbam         == 0 &&
+            fis->lbah         == 0 &&
+            fis->device       == 0)
+           ||
+           (fis->sector_count == 0 && /* CE-ATA (mATA) */
+            fis->lbal         == 0 &&
+            fis->lbam         == 0xCE &&
+            fis->lbah         == 0xAA &&
+            (fis->device & ~0x10) == 0))
+
+               dev->sata_dev.command_set = ATA_COMMAND_SET;
+
+       else if ((fis->interrupt_reason == 1 && /* ATAPI */
+                 fis->lbal             == 1 &&
+                 fis->byte_count_low   == 0x14 &&
+                 fis->byte_count_high  == 0xEB &&
+                 (fis->device & ~0x10) == 0))
+
+               dev->sata_dev.command_set = ATAPI_COMMAND_SET;
+
+       else if ((fis->sector_count == 1 && /* SEMB */
+                 fis->lbal         == 1 &&
+                 fis->lbam         == 0x3C &&
+                 fis->lbah         == 0xC3 &&
+                 fis->device       == 0)
+               ||
+                (fis->interrupt_reason == 1 && /* SATA PM */
+                 fis->lbal             == 1 &&
+                 fis->byte_count_low   == 0x69 &&
+                 fis->byte_count_high  == 0x96 &&
+                 (fis->device & ~0x10) == 0))
+
+               /* Treat it as a superset? */
+               dev->sata_dev.command_set = ATAPI_COMMAND_SET;
+}
+
+/**
+ * sas_issue_ata_cmd -- Basic SATA command processing for discovery
+ * @dev: the device to send the command to
+ * @command: the command register
+ * @features: the features register
+ * @buffer: pointer to buffer to do I/O
+ * @size: size of @buffer
+ * @pci_dma_dir: PCI_DMA_...
+ */
+static int sas_issue_ata_cmd(struct domain_device *dev, u8 command,
+                            u8 features, void *buffer, int size,
+                            int pci_dma_dir)
+{
+       int res = 0;
+       struct sas_task *task;
+       struct dev_to_host_fis *d2h_fis = (struct dev_to_host_fis *)
+               &dev->frame_rcvd[0];
+
+       res = -ENOMEM;
+       task = sas_alloc_task(GFP_KERNEL);
+       if (!task)
+               goto out;
+
+       task->dev = dev;
+
+       task->ata_task.fis.fis_type = 0x27;
+       task->ata_task.fis.command = command;
+       task->ata_task.fis.features = features;
+       task->ata_task.fis.device = d2h_fis->device;
+       task->ata_task.retry_count = 1;
+
+       res = sas_execute_task(task, buffer, size, pci_dma_dir);
+
+       sas_free_task(task);
+out:
+       return res;
+}
+
+static void sas_sata_propagate_sas_addr(struct domain_device *dev)
+{
+       unsigned long flags;
+       struct asd_sas_port *port = dev->port;
+       struct asd_sas_phy  *phy;
+
+       BUG_ON(dev->parent);
+
+       memcpy(port->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
+       spin_lock_irqsave(&port->phy_list_lock, flags);
+       list_for_each_entry(phy, &port->phy_list, port_phy_el)
+               memcpy(phy->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
+       spin_unlock_irqrestore(&port->phy_list_lock, flags);
+}
+
+#define ATA_IDENTIFY_DEV         0xEC
+#define ATA_IDENTIFY_PACKET_DEV  0xA1
+#define ATA_SET_FEATURES         0xEF
+#define ATA_FEATURE_PUP_STBY_SPIN_UP 0x07
+
+/**
+ * sas_discover_sata_dev -- discover a STP/SATA device (SATA_DEV)
+ * @dev: STP/SATA device of interest (ATA/ATAPI)
+ *
+ * The LLDD has already been notified of this device, so that we can
+ * send FISes to it.  Here we try to get IDENTIFY DEVICE or IDENTIFY
+ * PACKET DEVICE, if ATAPI device, so that the LLDD can fine-tune its
+ * performance for this device.
+ */
+static int sas_discover_sata_dev(struct domain_device *dev)
+{
+       int     res;
+       __le16  *identify_x;
+       u8      command;
+
+       identify_x = kzalloc(512, GFP_KERNEL);
+       if (!identify_x)
+               return -ENOMEM;
+
+       if (dev->sata_dev.command_set == ATA_COMMAND_SET) {
+               dev->sata_dev.identify_device = identify_x;
+               command = ATA_IDENTIFY_DEV;
+       } else {
+               dev->sata_dev.identify_packet_device = identify_x;
+               command = ATA_IDENTIFY_PACKET_DEV;
+       }
+
+       res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512,
+                               PCI_DMA_FROMDEVICE);
+       if (res)
+               goto out_err;
+
+       /* lives on the media? */
+       if (le16_to_cpu(identify_x[0]) & 4) {
+               /* incomplete response */
+               SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to "
+                           "dev %llx\n", SAS_ADDR(dev->sas_addr));
+               if (!le16_to_cpu(identify_x[83] & (1<<6)))
+                       goto cont1;
+               res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES,
+                                       ATA_FEATURE_PUP_STBY_SPIN_UP,
+                                       NULL, 0, PCI_DMA_NONE);
+               if (res)
+                       goto cont1;
+
+               schedule_timeout_interruptible(5*HZ); /* More time? */
+               res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512,
+                                       PCI_DMA_FROMDEVICE);
+               if (res)
+                       goto out_err;
+       }
+cont1:
+       /* Get WWN */
+       if (dev->port->oob_mode != SATA_OOB_MODE) {
+               memcpy(dev->sas_addr, dev->sata_dev.rps_resp.rps.stp_sas_addr,
+                      SAS_ADDR_SIZE);
+       } else if (dev->sata_dev.command_set == ATA_COMMAND_SET &&
+                  (le16_to_cpu(dev->sata_dev.identify_device[108]) & 0xF000)
+                  == 0x5000) {
+               int i;
+
+               for (i = 0; i < 4; i++) {
+                       dev->sas_addr[2*i] =
+            (le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0xFF00) >> 8;
+                       dev->sas_addr[2*i+1] =
+             le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0x00FF;
+               }
+       }
+       sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr);
+       if (!dev->parent)
+               sas_sata_propagate_sas_addr(dev);
+
+       /* XXX Hint: register this SATA device with SATL.
+          When this returns, dev->sata_dev->lu is alive and
+          present.
+       sas_satl_register_dev(dev);
+       */
+
+       sas_fill_in_rphy(dev, dev->rphy);
+
+       return 0;
+out_err:
+       dev->sata_dev.identify_packet_device = NULL;
+       dev->sata_dev.identify_device = NULL;
+       kfree(identify_x);
+       return res;
+}
+
+static int sas_discover_sata_pm(struct domain_device *dev)
+{
+       return -ENODEV;
+}
+
+/**
+ * sas_discover_sata -- discover an STP/SATA domain device
+ * @dev: pointer to struct domain_device of interest
+ *
+ * First we notify the LLDD of this device, so we can send frames to
+ * it.  Then depending on the type of device we call the appropriate
+ * discover functions.  Once device discover is done, we notify the
+ * LLDD so that it can fine-tune its parameters for the device, by
+ * removing it and then adding it.  That is, the second time around,
+ * the driver would have certain fields, that it is looking at, set.
+ * Finally we initialize the kobj so that the device can be added to
+ * the system at registration time.  Devices directly attached to a HA
+ * port, have no parents.  All other devices do, and should have their
+ * "parent" pointer set appropriately before calling this function.
+ */
+int sas_discover_sata(struct domain_device *dev)
+{
+       int res;
+
+       sas_get_ata_command_set(dev);
+
+       res = sas_notify_lldd_dev_found(dev);
+       if (res)
+               return res;
+
+       switch (dev->dev_type) {
+       case SATA_DEV:
+               res = sas_discover_sata_dev(dev);
+               break;
+       case SATA_PM:
+               res = sas_discover_sata_pm(dev);
+               break;
+       default:
+               break;
+       }
+       sas_notify_lldd_dev_gone(dev);
+       if (!res) {
+               sas_notify_lldd_dev_found(dev);
+               res = sas_rphy_add(dev->rphy);
+       }
+
+       return res;
+}
index a65598b1e5363b386c6a235f8d7c3e61ffe834bb..6ac9f61d006a5616c4f882088eaac4948a5c6d4e 100644 (file)
@@ -55,149 +55,6 @@ void sas_init_dev(struct domain_device *dev)
         }
 }
 
-static void sas_task_timedout(unsigned long _task)
-{
-       struct sas_task *task = (void *) _task;
-       unsigned long flags;
-
-       spin_lock_irqsave(&task->task_state_lock, flags);
-       if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
-               task->task_state_flags |= SAS_TASK_STATE_ABORTED;
-       spin_unlock_irqrestore(&task->task_state_lock, flags);
-
-       complete(&task->completion);
-}
-
-static void sas_disc_task_done(struct sas_task *task)
-{
-       if (!del_timer(&task->timer))
-               return;
-       complete(&task->completion);
-}
-
-#define SAS_DEV_TIMEOUT 10
-
-/**
- * sas_execute_task -- Basic task processing for discovery
- * @task: the task to be executed
- * @buffer: pointer to buffer to do I/O
- * @size: size of @buffer
- * @pci_dma_dir: PCI_DMA_...
- */
-static int sas_execute_task(struct sas_task *task, void *buffer, int size,
-                           int pci_dma_dir)
-{
-       int res = 0;
-       struct scatterlist *scatter = NULL;
-       struct task_status_struct *ts = &task->task_status;
-       int num_scatter = 0;
-       int retries = 0;
-       struct sas_internal *i =
-               to_sas_internal(task->dev->port->ha->core.shost->transportt);
-
-       if (pci_dma_dir != PCI_DMA_NONE) {
-               scatter = kzalloc(sizeof(*scatter), GFP_KERNEL);
-               if (!scatter)
-                       goto out;
-
-               sg_init_one(scatter, buffer, size);
-               num_scatter = 1;
-       }
-
-       task->task_proto = task->dev->tproto;
-       task->scatter = scatter;
-       task->num_scatter = num_scatter;
-       task->total_xfer_len = size;
-       task->data_dir = pci_dma_dir;
-       task->task_done = sas_disc_task_done;
-
-       for (retries = 0; retries < 5; retries++) {
-               task->task_state_flags = SAS_TASK_STATE_PENDING;
-               init_completion(&task->completion);
-
-               task->timer.data = (unsigned long) task;
-               task->timer.function = sas_task_timedout;
-               task->timer.expires = jiffies + SAS_DEV_TIMEOUT*HZ;
-               add_timer(&task->timer);
-
-               res = i->dft->lldd_execute_task(task, 1, GFP_KERNEL);
-               if (res) {
-                       del_timer(&task->timer);
-                       SAS_DPRINTK("executing SAS discovery task failed:%d\n",
-                                   res);
-                       goto ex_err;
-               }
-               wait_for_completion(&task->completion);
-               res = -ETASK;
-               if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
-                       int res2;
-                       SAS_DPRINTK("task aborted, flags:0x%x\n",
-                                   task->task_state_flags);
-                       res2 = i->dft->lldd_abort_task(task);
-                       SAS_DPRINTK("came back from abort task\n");
-                       if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
-                               if (res2 == TMF_RESP_FUNC_COMPLETE)
-                                       continue; /* Retry the task */
-                               else
-                                       goto ex_err;
-                       }
-               }
-               if (task->task_status.stat == SAM_BUSY ||
-                          task->task_status.stat == SAM_TASK_SET_FULL ||
-                          task->task_status.stat == SAS_QUEUE_FULL) {
-                       SAS_DPRINTK("task: q busy, sleeping...\n");
-                       schedule_timeout_interruptible(HZ);
-               } else if (task->task_status.stat == SAM_CHECK_COND) {
-                       struct scsi_sense_hdr shdr;
-
-                       if (!scsi_normalize_sense(ts->buf, ts->buf_valid_size,
-                                                 &shdr)) {
-                               SAS_DPRINTK("couldn't normalize sense\n");
-                               continue;
-                       }
-                       if ((shdr.sense_key == 6 && shdr.asc == 0x29) ||
-                           (shdr.sense_key == 2 && shdr.asc == 4 &&
-                            shdr.ascq == 1)) {
-                               SAS_DPRINTK("device %016llx LUN: %016llx "
-                                           "powering up or not ready yet, "
-                                           "sleeping...\n",
-                                           SAS_ADDR(task->dev->sas_addr),
-                                           SAS_ADDR(task->ssp_task.LUN));
-
-                               schedule_timeout_interruptible(5*HZ);
-                       } else if (shdr.sense_key == 1) {
-                               res = 0;
-                               break;
-                       } else if (shdr.sense_key == 5) {
-                               break;
-                       } else {
-                               SAS_DPRINTK("dev %016llx LUN: %016llx "
-                                           "sense key:0x%x ASC:0x%x ASCQ:0x%x"
-                                           "\n",
-                                           SAS_ADDR(task->dev->sas_addr),
-                                           SAS_ADDR(task->ssp_task.LUN),
-                                           shdr.sense_key,
-                                           shdr.asc, shdr.ascq);
-                       }
-               } else if (task->task_status.resp != SAS_TASK_COMPLETE ||
-                          task->task_status.stat != SAM_GOOD) {
-                       SAS_DPRINTK("task finished with resp:0x%x, "
-                                   "stat:0x%x\n",
-                                   task->task_status.resp,
-                                   task->task_status.stat);
-                       goto ex_err;
-               } else {
-                       res = 0;
-                       break;
-               }
-       }
-ex_err:
-       if (pci_dma_dir != PCI_DMA_NONE)
-               kfree(scatter);
-out:
-       return res;
-}
-
 /* ---------- Domain device discovery ---------- */
 
 /**
@@ -255,6 +112,7 @@ static int sas_get_port_device(struct asd_sas_port *port)
 
        switch (dev->dev_type) {
        case SAS_END_DEV:
+       case SATA_DEV:
                rphy = sas_end_device_alloc(port->port);
                break;
        case EDGE_DEV:
@@ -265,7 +123,6 @@ static int sas_get_port_device(struct asd_sas_port *port)
                rphy = sas_expander_alloc(port->port,
                                          SAS_FANOUT_EXPANDER_DEVICE);
                break;
-       case SATA_DEV:
        default:
                printk("ERROR: Unidentified device type %d\n", dev->dev_type);
                rphy = NULL;
@@ -292,207 +149,15 @@ static int sas_get_port_device(struct asd_sas_port *port)
        port->disc.max_level = 0;
 
        dev->rphy = rphy;
-       spin_lock(&port->dev_list_lock);
+       spin_lock_irq(&port->dev_list_lock);
        list_add_tail(&dev->dev_list_node, &port->dev_list);
-       spin_unlock(&port->dev_list_lock);
+       spin_unlock_irq(&port->dev_list_lock);
 
        return 0;
 }
 
 /* ---------- Discover and Revalidate ---------- */
 
-/* ---------- SATA ---------- */
-
-static void sas_get_ata_command_set(struct domain_device *dev)
-{
-       struct dev_to_host_fis *fis =
-               (struct dev_to_host_fis *) dev->frame_rcvd;
-
-       if ((fis->sector_count == 1 && /* ATA */
-            fis->lbal         == 1 &&
-            fis->lbam         == 0 &&
-            fis->lbah         == 0 &&
-            fis->device       == 0)
-           ||
-           (fis->sector_count == 0 && /* CE-ATA (mATA) */
-            fis->lbal         == 0 &&
-            fis->lbam         == 0xCE &&
-            fis->lbah         == 0xAA &&
-            (fis->device & ~0x10) == 0))
-
-               dev->sata_dev.command_set = ATA_COMMAND_SET;
-
-       else if ((fis->interrupt_reason == 1 && /* ATAPI */
-                 fis->lbal             == 1 &&
-                 fis->byte_count_low   == 0x14 &&
-                 fis->byte_count_high  == 0xEB &&
-                 (fis->device & ~0x10) == 0))
-
-               dev->sata_dev.command_set = ATAPI_COMMAND_SET;
-
-       else if ((fis->sector_count == 1 && /* SEMB */
-                 fis->lbal         == 1 &&
-                 fis->lbam         == 0x3C &&
-                 fis->lbah         == 0xC3 &&
-                 fis->device       == 0)
-               ||
-                (fis->interrupt_reason == 1 && /* SATA PM */
-                 fis->lbal             == 1 &&
-                 fis->byte_count_low   == 0x69 &&
-                 fis->byte_count_high  == 0x96 &&
-                 (fis->device & ~0x10) == 0))
-
-               /* Treat it as a superset? */
-               dev->sata_dev.command_set = ATAPI_COMMAND_SET;
-}
-
-/**
- * sas_issue_ata_cmd -- Basic SATA command processing for discovery
- * @dev: the device to send the command to
- * @command: the command register
- * @features: the features register
- * @buffer: pointer to buffer to do I/O
- * @size: size of @buffer
- * @pci_dma_dir: PCI_DMA_...
- */
-static int sas_issue_ata_cmd(struct domain_device *dev, u8 command,
-                            u8 features, void *buffer, int size,
-                            int pci_dma_dir)
-{
-       int res = 0;
-       struct sas_task *task;
-       struct dev_to_host_fis *d2h_fis = (struct dev_to_host_fis *)
-               &dev->frame_rcvd[0];
-
-       res = -ENOMEM;
-       task = sas_alloc_task(GFP_KERNEL);
-       if (!task)
-               goto out;
-
-       task->dev = dev;
-
-       task->ata_task.fis.command = command;
-       task->ata_task.fis.features = features;
-       task->ata_task.fis.device = d2h_fis->device;
-       task->ata_task.retry_count = 1;
-
-       res = sas_execute_task(task, buffer, size, pci_dma_dir);
-
-       sas_free_task(task);
-out:
-       return res;
-}
-
-static void sas_sata_propagate_sas_addr(struct domain_device *dev)
-{
-       unsigned long flags;
-       struct asd_sas_port *port = dev->port;
-       struct asd_sas_phy  *phy;
-
-       BUG_ON(dev->parent);
-
-       memcpy(port->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
-       spin_lock_irqsave(&port->phy_list_lock, flags);
-       list_for_each_entry(phy, &port->phy_list, port_phy_el)
-               memcpy(phy->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
-       spin_unlock_irqrestore(&port->phy_list_lock, flags);
-}
-
-#define ATA_IDENTIFY_DEV         0xEC
-#define ATA_IDENTIFY_PACKET_DEV  0xA1
-#define ATA_SET_FEATURES         0xEF
-#define ATA_FEATURE_PUP_STBY_SPIN_UP 0x07
-
-/**
- * sas_discover_sata_dev -- discover a STP/SATA device (SATA_DEV)
- * @dev: STP/SATA device of interest (ATA/ATAPI)
- *
- * The LLDD has already been notified of this device, so that we can
- * send FISes to it.  Here we try to get IDENTIFY DEVICE or IDENTIFY
- * PACKET DEVICE, if ATAPI device, so that the LLDD can fine-tune its
- * performance for this device.
- */
-static int sas_discover_sata_dev(struct domain_device *dev)
-{
-       int     res;
-       __le16  *identify_x;
-       u8      command;
-
-       identify_x = kzalloc(512, GFP_KERNEL);
-       if (!identify_x)
-               return -ENOMEM;
-
-       if (dev->sata_dev.command_set == ATA_COMMAND_SET) {
-               dev->sata_dev.identify_device = identify_x;
-               command = ATA_IDENTIFY_DEV;
-       } else {
-               dev->sata_dev.identify_packet_device = identify_x;
-               command = ATA_IDENTIFY_PACKET_DEV;
-       }
-
-       res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512,
-                               PCI_DMA_FROMDEVICE);
-       if (res)
-               goto out_err;
-
-       /* lives on the media? */
-       if (le16_to_cpu(identify_x[0]) & 4) {
-               /* incomplete response */
-               SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to "
-                           "dev %llx\n", SAS_ADDR(dev->sas_addr));
-               if (!le16_to_cpu(identify_x[83] & (1<<6)))
-                       goto cont1;
-               res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES,
-                                       ATA_FEATURE_PUP_STBY_SPIN_UP,
-                                       NULL, 0, PCI_DMA_NONE);
-               if (res)
-                       goto cont1;
-
-               schedule_timeout_interruptible(5*HZ); /* More time? */
-               res = sas_issue_ata_cmd(dev, command, 0, identify_x, 512,
-                                       PCI_DMA_FROMDEVICE);
-               if (res)
-                       goto out_err;
-       }
-cont1:
-       /* Get WWN */
-       if (dev->port->oob_mode != SATA_OOB_MODE) {
-               memcpy(dev->sas_addr, dev->sata_dev.rps_resp.rps.stp_sas_addr,
-                      SAS_ADDR_SIZE);
-       } else if (dev->sata_dev.command_set == ATA_COMMAND_SET &&
-                  (le16_to_cpu(dev->sata_dev.identify_device[108]) & 0xF000)
-                  == 0x5000) {
-               int i;
-
-               for (i = 0; i < 4; i++) {
-                       dev->sas_addr[2*i] =
-            (le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0xFF00) >> 8;
-                       dev->sas_addr[2*i+1] =
-             le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0x00FF;
-               }
-       }
-       sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr);
-       if (!dev->parent)
-               sas_sata_propagate_sas_addr(dev);
-
-       /* XXX Hint: register this SATA device with SATL.
-          When this returns, dev->sata_dev->lu is alive and
-          present.
-       sas_satl_register_dev(dev);
-       */
-       return 0;
-out_err:
-       dev->sata_dev.identify_packet_device = NULL;
-       dev->sata_dev.identify_device = NULL;
-       kfree(identify_x);
-       return res;
-}
-
-static int sas_discover_sata_pm(struct domain_device *dev)
-{
-       return -ENODEV;
-}
-
 int sas_notify_lldd_dev_found(struct domain_device *dev)
 {
        int res = 0;
@@ -525,60 +190,6 @@ void sas_notify_lldd_dev_gone(struct domain_device *dev)
 
 /* ---------- Common/dispatchers ---------- */
 
-/**
- * sas_discover_sata -- discover an STP/SATA domain device
- * @dev: pointer to struct domain_device of interest
- *
- * First we notify the LLDD of this device, so we can send frames to
- * it.  Then depending on the type of device we call the appropriate
- * discover functions.  Once device discover is done, we notify the
- * LLDD so that it can fine-tune its parameters for the device, by
- * removing it and then adding it.  That is, the second time around,
- * the driver would have certain fields, that it is looking at, set.
- * Finally we initialize the kobj so that the device can be added to
- * the system at registration time.  Devices directly attached to a HA
- * port, have no parents.  All other devices do, and should have their
- * "parent" pointer set appropriately before calling this function.
- */
-int sas_discover_sata(struct domain_device *dev)
-{
-       int res;
-
-       sas_get_ata_command_set(dev);
-
-       res = sas_notify_lldd_dev_found(dev);
-       if (res)
-               goto out_err2;
-
-       switch (dev->dev_type) {
-       case SATA_DEV:
-               res = sas_discover_sata_dev(dev);
-               break;
-       case SATA_PM:
-               res = sas_discover_sata_pm(dev);
-               break;
-       default:
-               break;
-       }
-       if (res)
-               goto out_err;
-
-       sas_notify_lldd_dev_gone(dev);
-       res = sas_notify_lldd_dev_found(dev);
-       if (res)
-               goto out_err2;
-
-       res = sas_rphy_add(dev->rphy);
-       if (res)
-               goto out_err;
-
-       return res;
-
-out_err:
-       sas_notify_lldd_dev_gone(dev);
-out_err2:
-       return res;
-}
 
 /**
  * sas_discover_end_dev -- discover an end device (SSP, etc)
@@ -685,11 +296,14 @@ static void sas_discover_domain(struct work_struct *work)
        case FANOUT_DEV:
                error = sas_discover_root_expander(dev);
                break;
+#ifdef CONFIG_SCSI_SAS_ATA
        case SATA_DEV:
        case SATA_PM:
                error = sas_discover_sata(dev);
                break;
+#endif
        default:
+               error = -ENXIO;
                SAS_DPRINTK("unhandled device %d\n", dev->dev_type);
                break;
        }
@@ -698,9 +312,9 @@ static void sas_discover_domain(struct work_struct *work)
                sas_rphy_free(dev->rphy);
                dev->rphy = NULL;
 
-               spin_lock(&port->dev_list_lock);
+               spin_lock_irq(&port->dev_list_lock);
                list_del_init(&dev->dev_list_node);
-               spin_unlock(&port->dev_list_lock);
+               spin_unlock_irq(&port->dev_list_lock);
 
                kfree(dev); /* not kobject_register-ed yet */
                port->port_dev = NULL;
index 23e90c5f8f352be326ad3b9f6ec351cac7955ad0..b500f0c1449c5d7da0a8b9005541556d4b757ac3 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/scatterlist.h>
+#include <linux/blkdev.h>
 
 #include "sas_internal.h"
 
@@ -36,14 +37,6 @@ static int sas_configure_phy(struct domain_device *dev, int phy_id,
                             u8 *sas_addr, int include);
 static int sas_disable_routing(struct domain_device *dev,  u8 *sas_addr);
 
-#if 0
-/* FIXME: smp needs to migrate into the sas class */
-static ssize_t smp_portal_read(struct kobject *, struct bin_attribute *,
-                              char *, loff_t, size_t);
-static ssize_t smp_portal_write(struct kobject *, struct bin_attribute *,
-                               char *, loff_t, size_t);
-#endif
-
 /* ---------- SMP task management ---------- */
 
 static void smp_task_timedout(unsigned long _task)
@@ -220,6 +213,36 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
 #define DISCOVER_REQ_SIZE  16
 #define DISCOVER_RESP_SIZE 56
 
+static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req,
+                                     u8 *disc_resp, int single)
+{
+       int i, res;
+
+       disc_req[9] = single;
+       for (i = 1 ; i < 3; i++) {
+               struct discover_resp *dr;
+
+               res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
+                                      disc_resp, DISCOVER_RESP_SIZE);
+               if (res)
+                       return res;
+               /* This is detecting a failure to transmit inital
+                * dev to host FIS as described in section G.5 of
+                * sas-2 r 04b */
+               dr = &((struct smp_resp *)disc_resp)->disc;
+               if (!(dr->attached_dev_type == 0 &&
+                     dr->attached_sata_dev))
+                       break;
+               /* In order to generate the dev to host FIS, we
+                * send a link reset to the expander port */
+               sas_smp_phy_control(dev, single, PHY_FUNC_LINK_RESET, NULL);
+               /* Wait for the reset to trigger the negotiation */
+               msleep(500);
+       }
+       sas_set_ex_phy(dev, single, disc_resp);
+       return 0;
+}
+
 static int sas_ex_phy_discover(struct domain_device *dev, int single)
 {
        struct expander_device *ex = &dev->ex_dev;
@@ -240,23 +263,15 @@ static int sas_ex_phy_discover(struct domain_device *dev, int single)
        disc_req[1] = SMP_DISCOVER;
 
        if (0 <= single && single < ex->num_phys) {
-               disc_req[9] = single;
-               res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
-                                      disc_resp, DISCOVER_RESP_SIZE);
-               if (res)
-                       goto out_err;
-               sas_set_ex_phy(dev, single, disc_resp);
+               res = sas_ex_phy_discover_helper(dev, disc_req, disc_resp, single);
        } else {
                int i;
 
                for (i = 0; i < ex->num_phys; i++) {
-                       disc_req[9] = i;
-                       res = smp_execute_task(dev, disc_req,
-                                              DISCOVER_REQ_SIZE, disc_resp,
-                                              DISCOVER_RESP_SIZE);
+                       res = sas_ex_phy_discover_helper(dev, disc_req,
+                                                        disc_resp, i);
                        if (res)
                                goto out_err;
-                       sas_set_ex_phy(dev, i, disc_resp);
                }
        }
 out_err:
@@ -520,6 +535,8 @@ int sas_smp_get_phy_events(struct sas_phy *phy)
 
 }
 
+#ifdef CONFIG_SCSI_SAS_ATA
+
 #define RPS_REQ_SIZE  16
 #define RPS_RESP_SIZE 60
 
@@ -529,6 +546,7 @@ static int sas_get_report_phy_sata(struct domain_device *dev,
 {
        int res;
        u8 *rps_req = alloc_smp_req(RPS_REQ_SIZE);
+       u8 *resp = (u8 *)rps_resp;
 
        if (!rps_req)
                return -ENOMEM;
@@ -539,9 +557,30 @@ static int sas_get_report_phy_sata(struct domain_device *dev,
        res = smp_execute_task(dev, rps_req, RPS_REQ_SIZE,
                                    rps_resp, RPS_RESP_SIZE);
 
+       /* 0x34 is the FIS type for the D2H fis.  There's a potential
+        * standards cockup here.  sas-2 explicitly specifies the FIS
+        * should be encoded so that FIS type is in resp[24].
+        * However, some expanders endian reverse this.  Undo the
+        * reversal here */
+       if (!res && resp[27] == 0x34 && resp[24] != 0x34) {
+               int i;
+
+               for (i = 0; i < 5; i++) {
+                       int j = 24 + (i*4);
+                       u8 a, b;
+                       a = resp[j + 0];
+                       b = resp[j + 1];
+                       resp[j + 0] = resp[j + 3];
+                       resp[j + 1] = resp[j + 2];
+                       resp[j + 2] = b;
+                       resp[j + 3] = a;
+               }
+       }
+
        kfree(rps_req);
-       return 0;
+       return res;
 }
+#endif
 
 static void sas_ex_get_linkrate(struct domain_device *parent,
                                       struct domain_device *child,
@@ -609,6 +648,7 @@ static struct domain_device *sas_ex_discover_end_dev(
        }
        sas_ex_get_linkrate(parent, child, phy);
 
+#ifdef CONFIG_SCSI_SAS_ATA
        if ((phy->attached_tproto & SAS_PROTO_STP) || phy->attached_sata_dev) {
                child->dev_type = SATA_DEV;
                if (phy->attached_tproto & SAS_PROTO_STP)
@@ -625,16 +665,30 @@ static struct domain_device *sas_ex_discover_end_dev(
                }
                memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis,
                       sizeof(struct dev_to_host_fis));
+
+               rphy = sas_end_device_alloc(phy->port);
+               if (unlikely(!rphy))
+                       goto out_free;
+
                sas_init_dev(child);
+
+               child->rphy = rphy;
+
+               spin_lock_irq(&parent->port->dev_list_lock);
+               list_add_tail(&child->dev_list_node, &parent->port->dev_list);
+               spin_unlock_irq(&parent->port->dev_list_lock);
+
                res = sas_discover_sata(child);
                if (res) {
                        SAS_DPRINTK("sas_discover_sata() for device %16llx at "
                                    "%016llx:0x%x returned 0x%x\n",
                                    SAS_ADDR(child->sas_addr),
                                    SAS_ADDR(parent->sas_addr), phy_id, res);
-                       goto out_free;
+                       goto out_list_del;
                }
-       } else if (phy->attached_tproto & SAS_PROTO_SSP) {
+       } else
+#endif
+         if (phy->attached_tproto & SAS_PROTO_SSP) {
                child->dev_type = SAS_END_DEV;
                rphy = sas_end_device_alloc(phy->port);
                /* FIXME: error handling */
@@ -646,9 +700,9 @@ static struct domain_device *sas_ex_discover_end_dev(
                child->rphy = rphy;
                sas_fill_in_rphy(child, rphy);
 
-               spin_lock(&parent->port->dev_list_lock);
+               spin_lock_irq(&parent->port->dev_list_lock);
                list_add_tail(&child->dev_list_node, &parent->port->dev_list);
-               spin_unlock(&parent->port->dev_list_lock);
+               spin_unlock_irq(&parent->port->dev_list_lock);
 
                res = sas_discover_end_dev(child);
                if (res) {
@@ -662,6 +716,7 @@ static struct domain_device *sas_ex_discover_end_dev(
                SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n",
                            phy->attached_tproto, SAS_ADDR(parent->sas_addr),
                            phy_id);
+               goto out_free;
        }
 
        list_add_tail(&child->siblings, &parent_ex->children);
@@ -761,9 +816,9 @@ static struct domain_device *sas_ex_discover_expander(
        sas_fill_in_rphy(child, rphy);
        sas_rphy_add(rphy);
 
-       spin_lock(&parent->port->dev_list_lock);
+       spin_lock_irq(&parent->port->dev_list_lock);
        list_add_tail(&child->dev_list_node, &parent->port->dev_list);
-       spin_unlock(&parent->port->dev_list_lock);
+       spin_unlock_irq(&parent->port->dev_list_lock);
 
        res = sas_discover_expander(child);
        if (res) {
@@ -1359,30 +1414,6 @@ static int sas_disable_routing(struct domain_device *dev,  u8 *sas_addr)
        return 0;
 }
 
-#if 0
-#define SMP_BIN_ATTR_NAME "smp_portal"
-
-static void sas_ex_smp_hook(struct domain_device *dev)
-{
-       struct expander_device *ex_dev = &dev->ex_dev;
-       struct bin_attribute *bin_attr = &ex_dev->smp_bin_attr;
-
-       memset(bin_attr, 0, sizeof(*bin_attr));
-
-       bin_attr->attr.name = SMP_BIN_ATTR_NAME;
-       bin_attr->attr.mode = 0600;
-
-       bin_attr->size = 0;
-       bin_attr->private = NULL;
-       bin_attr->read = smp_portal_read;
-       bin_attr->write= smp_portal_write;
-       bin_attr->mmap = NULL;
-
-       ex_dev->smp_portal_pid = -1;
-       init_MUTEX(&ex_dev->smp_sema);
-}
-#endif
-
 /**
  * sas_discover_expander -- expander discovery
  * @ex: pointer to expander domain device
@@ -1844,76 +1875,49 @@ out:
        return res;
 }
 
-#if 0
-/* ---------- SMP portal ---------- */
-
-static ssize_t smp_portal_write(struct kobject *kobj,
-                               struct bin_attribute *bin_attr,
-                               char *buf, loff_t offs, size_t size)
+int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
+                   struct request *req)
 {
-       struct domain_device *dev = to_dom_device(kobj);
-       struct expander_device *ex = &dev->ex_dev;
-
-       if (offs != 0)
-               return -EFBIG;
-       else if (size == 0)
-               return 0;
+       struct domain_device *dev;
+       int ret, type = rphy->identify.device_type;
+       struct request *rsp = req->next_rq;
 
-       down_interruptible(&ex->smp_sema);
-       if (ex->smp_req)
-               kfree(ex->smp_req);
-       ex->smp_req = kzalloc(size, GFP_USER);
-       if (!ex->smp_req) {
-               up(&ex->smp_sema);
-               return -ENOMEM;
+       if (!rsp) {
+               printk("%s: space for a smp response is missing\n",
+                      __FUNCTION__);
+               return -EINVAL;
        }
-       memcpy(ex->smp_req, buf, size);
-       ex->smp_req_size = size;
-       ex->smp_portal_pid = current->pid;
-       up(&ex->smp_sema);
 
-       return size;
-}
-
-static ssize_t smp_portal_read(struct kobject *kobj,
-                              struct bin_attribute *bin_attr,
-                              char *buf, loff_t offs, size_t size)
-{
-       struct domain_device *dev = to_dom_device(kobj);
-       struct expander_device *ex = &dev->ex_dev;
-       u8 *smp_resp;
-       int res = -EINVAL;
-
-       /* XXX: sysfs gives us an offset of 0x10 or 0x8 while in fact
-        *  it should be 0.
-        */
+       /* seems aic94xx doesn't support */
+       if (!rphy) {
+               printk("%s: can we send a smp request to a host?\n",
+                      __FUNCTION__);
+               return -EINVAL;
+       }
 
-       down_interruptible(&ex->smp_sema);
-       if (!ex->smp_req || ex->smp_portal_pid != current->pid)
-               goto out;
+       if (type != SAS_EDGE_EXPANDER_DEVICE &&
+           type != SAS_FANOUT_EXPANDER_DEVICE) {
+               printk("%s: can we send a smp request to a device?\n",
+                      __FUNCTION__);
+               return -EINVAL;
+       }
 
-       res = 0;
-       if (size == 0)
-               goto out;
+       dev = sas_find_dev_by_rphy(rphy);
+       if (!dev) {
+               printk("%s: fail to find a domain_device?\n", __FUNCTION__);
+               return -EINVAL;
+       }
 
-       res = -ENOMEM;
-       smp_resp = alloc_smp_resp(size);
-       if (!smp_resp)
-               goto out;
-       res = smp_execute_task(dev, ex->smp_req, ex->smp_req_size,
-                              smp_resp, size);
-       if (!res) {
-               memcpy(buf, smp_resp, size);
-               res = size;
+       /* do we need to support multiple segments? */
+       if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
+               printk("%s: multiple segments req %u %u, rsp %u %u\n",
+                      __FUNCTION__, req->bio->bi_vcnt, req->data_len,
+                      rsp->bio->bi_vcnt, rsp->data_len);
+               return -EINVAL;
        }
 
-       kfree(smp_resp);
-out:
-       kfree(ex->smp_req);
-       ex->smp_req = NULL;
-       ex->smp_req_size = 0;
-       ex->smp_portal_pid = -1;
-       up(&ex->smp_sema);
-       return res;
+       ret = smp_execute_task(dev, bio_data(req->bio), req->data_len,
+                              bio_data(rsp->bio), rsp->data_len);
+
+       return ret;
 }
-#endif
index 1396c83b0c9ccbfd1a15b2b198ee45a6ab55aee6..9cd5abe9e714e3f243ffddce6cda0500f3257f92 100644 (file)
@@ -259,6 +259,7 @@ static struct sas_function_template sft = {
        .phy_reset = sas_phy_reset,
        .set_phy_speed = sas_set_phy_speed,
        .get_linkerrors = sas_get_linkerrors,
+       .smp_handler = sas_smp_handler,
 };
 
 struct scsi_transport_template *
index a78638df2018dd50cb8fb420076052252f130ffc..2b8213b1832dae44a778a176063aee2286f626eb 100644 (file)
@@ -39,6 +39,9 @@
 #define SAS_DPRINTK(fmt, ...)
 #endif
 
+#define TO_SAS_TASK(_scsi_cmd)  ((void *)(_scsi_cmd)->host_scribble)
+#define ASSIGN_SAS_TASK(_sc, _t) do { (_sc)->host_scribble = (void *) _t; } while (0)
+
 void sas_scsi_recover_host(struct Scsi_Host *shost);
 
 int sas_show_class(enum sas_class class, char *buf);
index 9c5342e7a69c6a7b9e6625d5d6c69e64b48c874c..7663841eb4cfe7af81a3ae186f332ffcf34531e4 100644 (file)
@@ -34,6 +34,7 @@
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_transport.h>
 #include <scsi/scsi_transport_sas.h>
+#include <scsi/sas_ata.h>
 #include "../scsi_sas_internal.h"
 #include "../scsi_transport_api.h"
 #include "../scsi_priv.h"
 #include <linux/blkdev.h>
 #include <linux/freezer.h>
 #include <linux/scatterlist.h>
+#include <linux/libata.h>
 
 /* ---------- SCSI Host glue ---------- */
 
-#define TO_SAS_TASK(_scsi_cmd)  ((void *)(_scsi_cmd)->host_scribble)
-#define ASSIGN_SAS_TASK(_sc, _t) do { (_sc)->host_scribble = (void *) _t; } while (0)
-
 static void sas_scsi_task_done(struct sas_task *task)
 {
        struct task_status_struct *ts = &task->task_status;
@@ -172,7 +171,7 @@ static struct sas_task *sas_create_task(struct scsi_cmnd *cmd,
        return task;
 }
 
-static int sas_queue_up(struct sas_task *task)
+int sas_queue_up(struct sas_task *task)
 {
        struct sas_ha_struct *sas_ha = task->dev->port->ha;
        struct scsi_core *core = &sas_ha->core;
@@ -213,6 +212,16 @@ int sas_queuecommand(struct scsi_cmnd *cmd,
                struct sas_ha_struct *sas_ha = dev->port->ha;
                struct sas_task *task;
 
+               if (dev_is_sata(dev)) {
+                       unsigned long flags;
+
+                       spin_lock_irqsave(dev->sata_dev.ap->lock, flags);
+                       res = ata_sas_queuecmd(cmd, scsi_done,
+                                              dev->sata_dev.ap);
+                       spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags);
+                       goto out;
+               }
+
                res = -ENOMEM;
                task = sas_create_task(cmd, dev, GFP_ATOMIC);
                if (!task)
@@ -684,6 +693,16 @@ enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd)
        return EH_NOT_HANDLED;
 }
 
+int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
+{
+       struct domain_device *dev = sdev_to_domain_dev(sdev);
+
+       if (dev_is_sata(dev))
+               return ata_scsi_ioctl(sdev, cmd, arg);
+
+       return -EINVAL;
+}
+
 struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy)
 {
        struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent);
@@ -723,10 +742,17 @@ static inline struct domain_device *sas_find_target(struct scsi_target *starget)
 int sas_target_alloc(struct scsi_target *starget)
 {
        struct domain_device *found_dev = sas_find_target(starget);
+       int res;
 
        if (!found_dev)
                return -ENODEV;
 
+       if (dev_is_sata(found_dev)) {
+               res = sas_ata_init_host_and_port(found_dev, starget);
+               if (res)
+                       return res;
+       }
+
        starget->hostdata = found_dev;
        return 0;
 }
@@ -741,6 +767,11 @@ int sas_slave_configure(struct scsi_device *scsi_dev)
 
        BUG_ON(dev->rphy->identify.device_type != SAS_END_DEVICE);
 
+       if (dev_is_sata(dev)) {
+               ata_sas_slave_configure(scsi_dev, dev->sata_dev.ap);
+               return 0;
+       }
+
        sas_ha = dev->port->ha;
 
        sas_read_port_mode_page(scsi_dev);
@@ -764,6 +795,10 @@ int sas_slave_configure(struct scsi_device *scsi_dev)
 
 void sas_slave_destroy(struct scsi_device *scsi_dev)
 {
+       struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
+
+       if (dev_is_sata(dev))
+               ata_port_disable(dev->sata_dev.ap);
 }
 
 int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth)
@@ -980,10 +1015,38 @@ void sas_task_abort(struct sas_task *task)
                return;
        }
 
+       if (dev_is_sata(task->dev)) {
+               sas_ata_task_abort(task);
+               return;
+       }
+
        scsi_req_abort_cmd(sc);
        scsi_schedule_eh(sc->device->host);
 }
 
+int sas_slave_alloc(struct scsi_device *scsi_dev)
+{
+       struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
+
+       if (dev_is_sata(dev))
+               return ata_sas_port_init(dev->sata_dev.ap);
+
+       return 0;
+}
+
+void sas_target_destroy(struct scsi_target *starget)
+{
+       struct domain_device *found_dev = sas_find_target(starget);
+
+       if (!found_dev)
+               return;
+
+       if (dev_is_sata(found_dev))
+               ata_sas_port_destroy(found_dev->sata_dev.ap);
+
+       return;
+}
+
 EXPORT_SYMBOL_GPL(sas_queuecommand);
 EXPORT_SYMBOL_GPL(sas_target_alloc);
 EXPORT_SYMBOL_GPL(sas_slave_configure);
@@ -997,3 +1060,6 @@ EXPORT_SYMBOL_GPL(sas_phy_reset);
 EXPORT_SYMBOL_GPL(sas_phy_enable);
 EXPORT_SYMBOL_GPL(sas_eh_device_reset_handler);
 EXPORT_SYMBOL_GPL(sas_eh_bus_reset_handler);
+EXPORT_SYMBOL_GPL(sas_slave_alloc);
+EXPORT_SYMBOL_GPL(sas_target_destroy);
+EXPORT_SYMBOL_GPL(sas_ioctl);
index d6ef22a941c47af57b3325ff1bc36966297be197..1bdddad48571d812895ae6824689ab7fa25bc4dc 100644 (file)
@@ -89,6 +89,7 @@ mvme16x_probe(struct device *dev)
                out_be32(0xfff4202c, v);
        }
 
+       dev_set_drvdata(dev, host);
        scsi_scan_host(host);
 
        return 0;
@@ -104,7 +105,7 @@ mvme16x_probe(struct device *dev)
 static __devexit int
 mvme16x_device_remove(struct device *dev)
 {
-       struct Scsi_Host *host = dev_to_shost(dev);
+       struct Scsi_Host *host = dev_get_drvdata(dev);
        struct NCR_700_Host_Parameters *hostdata = shost_priv(host);
 
        /* Disable scsi chip ints */
index 7dd787f6ab273a315f69ae84f50d992fc879ec37..fa481b515ead0e745a74de03bb014724ec8b2a20 100644 (file)
@@ -2,9 +2,12 @@
 # PCMCIA SCSI adapter configuration
 #
 
-menu "PCMCIA SCSI adapter support"
+menuconfig SCSI_LOWLEVEL_PCMCIA
+       bool "PCMCIA SCSI adapter support"
        depends on SCSI!=n && PCMCIA!=n
 
+if SCSI_LOWLEVEL_PCMCIA && SCSI && PCMCIA
+
 config PCMCIA_AHA152X
        tristate "Adaptec AHA152X PCMCIA support"
        depends on !64BIT
@@ -77,4 +80,4 @@ config PCMCIA_SYM53C500
          To compile this driver as a module, choose M here: the
          module will be called sym53c500_cs.
 
-endmenu
+endif # SCSI_LOWLEVEL_PCMCIA
diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c
new file mode 100644 (file)
index 0000000..b50f1e1
--- /dev/null
@@ -0,0 +1,533 @@
+/*
+ * PS3 BD/DVD/CD-ROM Storage Driver
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2007 Sony Corp.
+ *
+ * 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 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/cdrom.h>
+#include <linux/highmem.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_dbg.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+
+#include <asm/lv1call.h>
+#include <asm/ps3stor.h>
+
+
+#define DEVICE_NAME                    "ps3rom"
+
+#define BOUNCE_SIZE                    (64*1024)
+
+#define PS3ROM_MAX_SECTORS             (BOUNCE_SIZE / CD_FRAMESIZE)
+
+
+struct ps3rom_private {
+       struct ps3_storage_device *dev;
+       struct scsi_cmnd *curr_cmd;
+};
+
+
+#define LV1_STORAGE_SEND_ATAPI_COMMAND (1)
+
+struct lv1_atapi_cmnd_block {
+       u8      pkt[32];        /* packet command block           */
+       u32     pktlen;         /* should be 12 for ATAPI 8020    */
+       u32     blocks;
+       u32     block_size;
+       u32     proto;          /* transfer mode                  */
+       u32     in_out;         /* transfer direction             */
+       u64     buffer;         /* parameter except command block */
+       u32     arglen;         /* length above                   */
+};
+
+enum lv1_atapi_proto {
+       NON_DATA_PROTO     = 0,
+       PIO_DATA_IN_PROTO  = 1,
+       PIO_DATA_OUT_PROTO = 2,
+       DMA_PROTO = 3
+};
+
+enum lv1_atapi_in_out {
+       DIR_WRITE = 0,          /* memory -> device */
+       DIR_READ = 1            /* device -> memory */
+};
+
+
+static int ps3rom_slave_configure(struct scsi_device *scsi_dev)
+{
+       struct ps3rom_private *priv = shost_priv(scsi_dev->host);
+       struct ps3_storage_device *dev = priv->dev;
+
+       dev_dbg(&dev->sbd.core, "%s:%u: id %u, lun %u, channel %u\n", __func__,
+               __LINE__, scsi_dev->id, scsi_dev->lun, scsi_dev->channel);
+
+       /*
+        * ATAPI SFF8020 devices use MODE_SENSE_10,
+        * so we can prohibit MODE_SENSE_6
+        */
+       scsi_dev->use_10_for_ms = 1;
+
+       /* we don't support {READ,WRITE}_6 */
+       scsi_dev->use_10_for_rw = 1;
+
+       return 0;
+}
+
+/*
+ * copy data from device into scatter/gather buffer
+ */
+static int fill_from_dev_buffer(struct scsi_cmnd *cmd, const void *buf)
+{
+       int k, req_len, act_len, len, active;
+       void *kaddr;
+       struct scatterlist *sgpnt;
+       unsigned int buflen;
+
+       buflen = cmd->request_bufflen;
+       if (!buflen)
+               return 0;
+
+       if (!cmd->request_buffer)
+               return -1;
+
+       sgpnt = cmd->request_buffer;
+       active = 1;
+       for (k = 0, req_len = 0, act_len = 0; k < cmd->use_sg; ++k, ++sgpnt) {
+               if (active) {
+                       kaddr = kmap_atomic(sgpnt->page, KM_IRQ0);
+                       len = sgpnt->length;
+                       if ((req_len + len) > buflen) {
+                               active = 0;
+                               len = buflen - req_len;
+                       }
+                       memcpy(kaddr + sgpnt->offset, buf + req_len, len);
+                       flush_kernel_dcache_page(sgpnt->page);
+                       kunmap_atomic(kaddr, KM_IRQ0);
+                       act_len += len;
+               }
+               req_len += sgpnt->length;
+       }
+       cmd->resid = req_len - act_len;
+       return 0;
+}
+
+/*
+ * copy data from scatter/gather into device's buffer
+ */
+static int fetch_to_dev_buffer(struct scsi_cmnd *cmd, void *buf)
+{
+       int k, req_len, len, fin;
+       void *kaddr;
+       struct scatterlist *sgpnt;
+       unsigned int buflen;
+
+       buflen = cmd->request_bufflen;
+       if (!buflen)
+               return 0;
+
+       if (!cmd->request_buffer)
+               return -1;
+
+       sgpnt = cmd->request_buffer;
+       for (k = 0, req_len = 0, fin = 0; k < cmd->use_sg; ++k, ++sgpnt) {
+               kaddr = kmap_atomic(sgpnt->page, KM_IRQ0);
+               len = sgpnt->length;
+               if ((req_len + len) > buflen) {
+                       len = buflen - req_len;
+                       fin = 1;
+               }
+               memcpy(buf + req_len, kaddr + sgpnt->offset, len);
+               kunmap_atomic(kaddr, KM_IRQ0);
+               if (fin)
+                       return req_len + len;
+               req_len += sgpnt->length;
+       }
+       return req_len;
+}
+
+static int ps3rom_atapi_request(struct ps3_storage_device *dev,
+                               struct scsi_cmnd *cmd)
+{
+       struct lv1_atapi_cmnd_block atapi_cmnd;
+       unsigned char opcode = cmd->cmnd[0];
+       int res;
+       u64 lpar;
+
+       dev_dbg(&dev->sbd.core, "%s:%u: send ATAPI command 0x%02x\n", __func__,
+               __LINE__, opcode);
+
+       memset(&atapi_cmnd, 0, sizeof(struct lv1_atapi_cmnd_block));
+       memcpy(&atapi_cmnd.pkt, cmd->cmnd, 12);
+       atapi_cmnd.pktlen = 12;
+       atapi_cmnd.block_size = 1; /* transfer size is block_size * blocks */
+       atapi_cmnd.blocks = atapi_cmnd.arglen = cmd->request_bufflen;
+       atapi_cmnd.buffer = dev->bounce_lpar;
+
+       switch (cmd->sc_data_direction) {
+       case DMA_FROM_DEVICE:
+               if (cmd->request_bufflen >= CD_FRAMESIZE)
+                       atapi_cmnd.proto = DMA_PROTO;
+               else
+                       atapi_cmnd.proto = PIO_DATA_IN_PROTO;
+               atapi_cmnd.in_out = DIR_READ;
+               break;
+
+       case DMA_TO_DEVICE:
+               if (cmd->request_bufflen >= CD_FRAMESIZE)
+                       atapi_cmnd.proto = DMA_PROTO;
+               else
+                       atapi_cmnd.proto = PIO_DATA_OUT_PROTO;
+               atapi_cmnd.in_out = DIR_WRITE;
+               res = fetch_to_dev_buffer(cmd, dev->bounce_buf);
+               if (res < 0)
+                       return DID_ERROR << 16;
+               break;
+
+       default:
+               atapi_cmnd.proto = NON_DATA_PROTO;
+               break;
+       }
+
+       lpar = ps3_mm_phys_to_lpar(__pa(&atapi_cmnd));
+       res = lv1_storage_send_device_command(dev->sbd.dev_id,
+                                             LV1_STORAGE_SEND_ATAPI_COMMAND,
+                                             lpar, sizeof(atapi_cmnd),
+                                             atapi_cmnd.buffer,
+                                             atapi_cmnd.arglen, &dev->tag);
+       if (res == LV1_DENIED_BY_POLICY) {
+               dev_dbg(&dev->sbd.core,
+                       "%s:%u: ATAPI command 0x%02x denied by policy\n",
+                       __func__, __LINE__, opcode);
+               return DID_ERROR << 16;
+       }
+
+       if (res) {
+               dev_err(&dev->sbd.core,
+                       "%s:%u: ATAPI command 0x%02x failed %d\n", __func__,
+                       __LINE__, opcode, res);
+               return DID_ERROR << 16;
+       }
+
+       return 0;
+}
+
+static inline unsigned int srb10_lba(const struct scsi_cmnd *cmd)
+{
+       return cmd->cmnd[2] << 24 | cmd->cmnd[3] << 16 | cmd->cmnd[4] << 8 |
+              cmd->cmnd[5];
+}
+
+static inline unsigned int srb10_len(const struct scsi_cmnd *cmd)
+{
+       return cmd->cmnd[7] << 8 | cmd->cmnd[8];
+}
+
+static int ps3rom_read_request(struct ps3_storage_device *dev,
+                              struct scsi_cmnd *cmd, u32 start_sector,
+                              u32 sectors)
+{
+       int res;
+
+       dev_dbg(&dev->sbd.core, "%s:%u: read %u sectors starting at %u\n",
+               __func__, __LINE__, sectors, start_sector);
+
+       res = lv1_storage_read(dev->sbd.dev_id,
+                              dev->regions[dev->region_idx].id, start_sector,
+                              sectors, 0, dev->bounce_lpar, &dev->tag);
+       if (res) {
+               dev_err(&dev->sbd.core, "%s:%u: read failed %d\n", __func__,
+                       __LINE__, res);
+               return DID_ERROR << 16;
+       }
+
+       return 0;
+}
+
+static int ps3rom_write_request(struct ps3_storage_device *dev,
+                               struct scsi_cmnd *cmd, u32 start_sector,
+                               u32 sectors)
+{
+       int res;
+
+       dev_dbg(&dev->sbd.core, "%s:%u: write %u sectors starting at %u\n",
+               __func__, __LINE__, sectors, start_sector);
+
+       res = fetch_to_dev_buffer(cmd, dev->bounce_buf);
+       if (res < 0)
+               return DID_ERROR << 16;
+
+       res = lv1_storage_write(dev->sbd.dev_id,
+                               dev->regions[dev->region_idx].id, start_sector,
+                               sectors, 0, dev->bounce_lpar, &dev->tag);
+       if (res) {
+               dev_err(&dev->sbd.core, "%s:%u: write failed %d\n", __func__,
+                       __LINE__, res);
+               return DID_ERROR << 16;
+       }
+
+       return 0;
+}
+
+static int ps3rom_queuecommand(struct scsi_cmnd *cmd,
+                              void (*done)(struct scsi_cmnd *))
+{
+       struct ps3rom_private *priv = shost_priv(cmd->device->host);
+       struct ps3_storage_device *dev = priv->dev;
+       unsigned char opcode;
+       int res;
+
+#ifdef DEBUG
+       scsi_print_command(cmd);
+#endif
+
+       priv->curr_cmd = cmd;
+       cmd->scsi_done = done;
+
+       opcode = cmd->cmnd[0];
+       /*
+        * While we can submit READ/WRITE SCSI commands as ATAPI commands,
+        * it's recommended for various reasons (performance, error handling,
+        * ...) to use lv1_storage_{read,write}() instead
+        */
+       switch (opcode) {
+       case READ_10:
+               res = ps3rom_read_request(dev, cmd, srb10_lba(cmd),
+                                         srb10_len(cmd));
+               break;
+
+       case WRITE_10:
+               res = ps3rom_write_request(dev, cmd, srb10_lba(cmd),
+                                          srb10_len(cmd));
+               break;
+
+       default:
+               res = ps3rom_atapi_request(dev, cmd);
+               break;
+       }
+
+       if (res) {
+               memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
+               cmd->result = res;
+               cmd->sense_buffer[0] = 0x70;
+               cmd->sense_buffer[2] = ILLEGAL_REQUEST;
+               priv->curr_cmd = NULL;
+               cmd->scsi_done(cmd);
+       }
+
+       return 0;
+}
+
+static int decode_lv1_status(u64 status, unsigned char *sense_key,
+                            unsigned char *asc, unsigned char *ascq)
+{
+       if (((status >> 24) & 0xff) != SAM_STAT_CHECK_CONDITION)
+               return -1;
+
+       *sense_key = (status >> 16) & 0xff;
+       *asc       = (status >>  8) & 0xff;
+       *ascq      =  status        & 0xff;
+       return 0;
+}
+
+static irqreturn_t ps3rom_interrupt(int irq, void *data)
+{
+       struct ps3_storage_device *dev = data;
+       struct Scsi_Host *host;
+       struct ps3rom_private *priv;
+       struct scsi_cmnd *cmd;
+       int res;
+       u64 tag, status;
+       unsigned char sense_key, asc, ascq;
+
+       res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status);
+       /*
+        * status = -1 may mean that ATAPI transport completed OK, but
+        * ATAPI command itself resulted CHECK CONDITION
+        * so, upper layer should issue REQUEST_SENSE to check the sense data
+        */
+
+       if (tag != dev->tag)
+               dev_err(&dev->sbd.core,
+                       "%s:%u: tag mismatch, got %lx, expected %lx\n",
+                       __func__, __LINE__, tag, dev->tag);
+
+       if (res) {
+               dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%lx\n",
+                       __func__, __LINE__, res, status);
+               return IRQ_HANDLED;
+       }
+
+       host = dev->sbd.core.driver_data;
+       priv = shost_priv(host);
+       cmd = priv->curr_cmd;
+
+       if (!status) {
+               /* OK, completed */
+               if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
+                       res = fill_from_dev_buffer(cmd, dev->bounce_buf);
+                       if (res) {
+                               cmd->result = DID_ERROR << 16;
+                               goto done;
+                       }
+               }
+               cmd->result = DID_OK << 16;
+               goto done;
+       }
+
+       if (cmd->cmnd[0] == REQUEST_SENSE) {
+               /* SCSI spec says request sense should never get error */
+               dev_err(&dev->sbd.core, "%s:%u: end error without autosense\n",
+                       __func__, __LINE__);
+               cmd->result = DID_ERROR << 16 | SAM_STAT_CHECK_CONDITION;
+               goto done;
+       }
+
+       if (decode_lv1_status(status, &sense_key, &asc, &ascq)) {
+               cmd->result = DID_ERROR << 16;
+               goto done;
+       }
+
+       cmd->sense_buffer[0]  = 0x70;
+       cmd->sense_buffer[2]  = sense_key;
+       cmd->sense_buffer[7]  = 16 - 6;
+       cmd->sense_buffer[12] = asc;
+       cmd->sense_buffer[13] = ascq;
+       cmd->result = SAM_STAT_CHECK_CONDITION;
+
+done:
+       priv->curr_cmd = NULL;
+       cmd->scsi_done(cmd);
+       return IRQ_HANDLED;
+}
+
+static struct scsi_host_template ps3rom_host_template = {
+       .name =                 DEVICE_NAME,
+       .slave_configure =      ps3rom_slave_configure,
+       .queuecommand =         ps3rom_queuecommand,
+       .can_queue =            1,
+       .this_id =              7,
+       .sg_tablesize =         SG_ALL,
+       .cmd_per_lun =          1,
+       .emulated =             1,              /* only sg driver uses this */
+       .max_sectors =          PS3ROM_MAX_SECTORS,
+       .use_clustering =       ENABLE_CLUSTERING,
+       .module =               THIS_MODULE,
+};
+
+
+static int __devinit ps3rom_probe(struct ps3_system_bus_device *_dev)
+{
+       struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
+       int error;
+       struct Scsi_Host *host;
+       struct ps3rom_private *priv;
+
+       if (dev->blk_size != CD_FRAMESIZE) {
+               dev_err(&dev->sbd.core,
+                       "%s:%u: cannot handle block size %lu\n", __func__,
+                       __LINE__, dev->blk_size);
+               return -EINVAL;
+       }
+
+       dev->bounce_size = BOUNCE_SIZE;
+       dev->bounce_buf = kmalloc(BOUNCE_SIZE, GFP_DMA);
+       if (!dev->bounce_buf)
+               return -ENOMEM;
+
+       error = ps3stor_setup(dev, ps3rom_interrupt);
+       if (error)
+               goto fail_free_bounce;
+
+       host = scsi_host_alloc(&ps3rom_host_template,
+                              sizeof(struct ps3rom_private));
+       if (!host) {
+               dev_err(&dev->sbd.core, "%s:%u: scsi_host_alloc failed\n",
+                       __func__, __LINE__);
+               goto fail_teardown;
+       }
+
+       priv = shost_priv(host);
+       dev->sbd.core.driver_data = host;
+       priv->dev = dev;
+
+       /* One device/LUN per SCSI bus */
+       host->max_id = 1;
+       host->max_lun = 1;
+
+       error = scsi_add_host(host, &dev->sbd.core);
+       if (error) {
+               dev_err(&dev->sbd.core, "%s:%u: scsi_host_alloc failed %d\n",
+                       __func__, __LINE__, error);
+               error = -ENODEV;
+               goto fail_host_put;
+       }
+
+       scsi_scan_host(host);
+       return 0;
+
+fail_host_put:
+       scsi_host_put(host);
+       dev->sbd.core.driver_data = NULL;
+fail_teardown:
+       ps3stor_teardown(dev);
+fail_free_bounce:
+       kfree(dev->bounce_buf);
+       return error;
+}
+
+static int ps3rom_remove(struct ps3_system_bus_device *_dev)
+{
+       struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
+       struct Scsi_Host *host = dev->sbd.core.driver_data;
+
+       scsi_remove_host(host);
+       ps3stor_teardown(dev);
+       scsi_host_put(host);
+       dev->sbd.core.driver_data = NULL;
+       kfree(dev->bounce_buf);
+       return 0;
+}
+
+static struct ps3_system_bus_driver ps3rom = {
+       .match_id       = PS3_MATCH_ID_STOR_ROM,
+       .core.name      = DEVICE_NAME,
+       .core.owner     = THIS_MODULE,
+       .probe          = ps3rom_probe,
+       .remove         = ps3rom_remove
+};
+
+
+static int __init ps3rom_init(void)
+{
+       return ps3_system_bus_driver_register(&ps3rom);
+}
+
+static void __exit ps3rom_exit(void)
+{
+       ps3_system_bus_driver_unregister(&ps3rom);
+}
+
+module_init(ps3rom_init);
+module_exit(ps3rom_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("PS3 BD/DVD/CD-ROM Storage Driver");
+MODULE_AUTHOR("Sony Corporation");
+MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_ROM);
index 3eb2208675aef00d164bd6889aa6089f0d8cf1b9..1612f9200a524f575b01f017f870668752594c8a 100644 (file)
@@ -98,7 +98,7 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj,
 
        /* Read NVRAM. */
        spin_lock_irqsave(&ha->hardware_lock, flags);
-       ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->nvram_base,
+       ha->isp_ops->read_nvram(ha, (uint8_t *)buf, ha->nvram_base,
            ha->nvram_size);
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
@@ -119,7 +119,7 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
                return 0;
 
        /* Checksum NVRAM. */
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (IS_FWI2_CAPABLE(ha)) {
                uint32_t *iter;
                uint32_t chksum;
 
@@ -143,7 +143,7 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
 
        /* Write NVRAM. */
        spin_lock_irqsave(&ha->hardware_lock, flags);
-       ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count);
+       ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count);
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
        set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
@@ -206,7 +206,7 @@ static struct bin_attribute sysfs_optrom_attr = {
                .name = "optrom",
                .mode = S_IRUSR | S_IWUSR,
        },
-       .size = OPTROM_SIZE_24XX,
+       .size = 0,
        .read = qla2x00_sysfs_read_optrom,
        .write = qla2x00_sysfs_write_optrom,
 };
@@ -252,7 +252,7 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
                }
 
                memset(ha->optrom_buffer, 0, ha->optrom_size);
-               ha->isp_ops.read_optrom(ha, ha->optrom_buffer, 0,
+               ha->isp_ops->read_optrom(ha, ha->optrom_buffer, 0,
                    ha->optrom_size);
                break;
        case 2:
@@ -275,7 +275,7 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
                if (ha->optrom_state != QLA_SWRITING)
                        break;
 
-               ha->isp_ops.write_optrom(ha, ha->optrom_buffer, 0,
+               ha->isp_ops->write_optrom(ha, ha->optrom_buffer, 0,
                    ha->optrom_size);
                break;
        }
@@ -305,7 +305,8 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj,
 
        /* Read NVRAM. */
        spin_lock_irqsave(&ha->hardware_lock, flags);
-       ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->vpd_base, ha->vpd_size);
+       ha->isp_ops->read_nvram(ha, (uint8_t *)buf, ha->vpd_base,
+           ha->vpd_size);
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
        return ha->vpd_size;
@@ -325,7 +326,7 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj,
 
        /* Write NVRAM. */
        spin_lock_irqsave(&ha->hardware_lock, flags);
-       ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count);
+       ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count);
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
        return count;
@@ -410,7 +411,7 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha)
        int ret;
 
        for (iter = bin_file_entries; iter->name; iter++) {
-               if (iter->is4GBp_only && (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)))
+               if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha))
                        continue;
 
                ret = sysfs_create_bin_file(&host->shost_gendev.kobj,
@@ -429,7 +430,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha)
        struct sysfs_entry *iter;
 
        for (iter = bin_file_entries; iter->name; iter++) {
-               if (iter->is4GBp_only && (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)))
+               if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha))
                        continue;
 
                sysfs_remove_bin_file(&host->shost_gendev.kobj,
@@ -437,7 +438,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha)
        }
 
        if (ha->beacon_blink_led == 1)
-               ha->isp_ops.beacon_off(ha);
+               ha->isp_ops->beacon_off(ha);
 }
 
 /* Scsi_Host attributes. */
@@ -455,7 +456,7 @@ qla2x00_fw_version_show(struct class_device *cdev, char *buf)
        char fw_str[30];
 
        return snprintf(buf, PAGE_SIZE, "%s\n",
-           ha->isp_ops.fw_version_str(ha, fw_str));
+           ha->isp_ops->fw_version_str(ha, fw_str));
 }
 
 static ssize_t
@@ -507,7 +508,7 @@ qla2x00_pci_info_show(struct class_device *cdev, char *buf)
        char pci_info[30];
 
        return snprintf(buf, PAGE_SIZE, "%s\n",
-           ha->isp_ops.pci_info_str(ha, pci_info));
+           ha->isp_ops->pci_info_str(ha, pci_info));
 }
 
 static ssize_t
@@ -652,9 +653,9 @@ qla2x00_beacon_store(struct class_device *cdev, const char *buf,
                return -EINVAL;
 
        if (val)
-               rval = ha->isp_ops.beacon_on(ha);
+               rval = ha->isp_ops->beacon_on(ha);
        else
-               rval = ha->isp_ops.beacon_off(ha);
+               rval = ha->isp_ops->beacon_off(ha);
 
        if (rval != QLA_SUCCESS)
                count = 0;
@@ -898,7 +899,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
        pfc_host_stat = &ha->fc_host_stat;
        memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics));
 
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (IS_FWI2_CAPABLE(ha)) {
                rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf,
                    sizeof(stat_buf) / 4, mb_stat);
        } else if (atomic_read(&ha->loop_state) == LOOP_READY &&
index 996c47a6307406d653ee095e1cacbd3cd24c0918..563d18f4ff50994fb568c8cab90ef1d192cc4e42 100644 (file)
@@ -37,6 +37,121 @@ qla2xxx_copy_queues(scsi_qla_host_t *ha, void *ptr)
        return ptr + (ha->response_q_length * sizeof(response_t));
 }
 
+static int
+qla2xxx_dump_memory(scsi_qla_host_t *ha, uint32_t *code_ram,
+    uint32_t cram_size, uint32_t *ext_mem, void **nxt)
+{
+       int rval;
+       uint32_t cnt, stat, timer, risc_address, ext_mem_cnt;
+       uint16_t mb[4];
+       struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+       rval = QLA_SUCCESS;
+       risc_address = ext_mem_cnt = 0;
+       memset(mb, 0, sizeof(mb));
+
+       /* Code RAM. */
+       risc_address = 0x20000;
+       WRT_REG_WORD(&reg->mailbox0, MBC_READ_RAM_EXTENDED);
+       clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
+
+       for (cnt = 0; cnt < cram_size / 4 && rval == QLA_SUCCESS;
+           cnt++, risc_address++) {
+               WRT_REG_WORD(&reg->mailbox1, LSW(risc_address));
+               WRT_REG_WORD(&reg->mailbox8, MSW(risc_address));
+               RD_REG_WORD(&reg->mailbox8);
+               WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
+
+               for (timer = 6000000; timer; timer--) {
+                       /* Check for pending interrupts. */
+                       stat = RD_REG_DWORD(&reg->host_status);
+                       if (stat & HSRX_RISC_INT) {
+                               stat &= 0xff;
+
+                               if (stat == 0x1 || stat == 0x2 ||
+                                   stat == 0x10 || stat == 0x11) {
+                                       set_bit(MBX_INTERRUPT,
+                                           &ha->mbx_cmd_flags);
+
+                                       mb[0] = RD_REG_WORD(&reg->mailbox0);
+                                       mb[2] = RD_REG_WORD(&reg->mailbox2);
+                                       mb[3] = RD_REG_WORD(&reg->mailbox3);
+
+                                       WRT_REG_DWORD(&reg->hccr,
+                                           HCCRX_CLR_RISC_INT);
+                                       RD_REG_DWORD(&reg->hccr);
+                                       break;
+                               }
+
+                               /* Clear this intr; it wasn't a mailbox intr */
+                               WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
+                               RD_REG_DWORD(&reg->hccr);
+                       }
+                       udelay(5);
+               }
+
+               if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
+                       rval = mb[0] & MBS_MASK;
+                       code_ram[cnt] = htonl((mb[3] << 16) | mb[2]);
+               } else {
+                       rval = QLA_FUNCTION_FAILED;
+               }
+       }
+
+       if (rval == QLA_SUCCESS) {
+               /* External Memory. */
+               risc_address = 0x100000;
+               ext_mem_cnt = ha->fw_memory_size - 0x100000 + 1;
+               WRT_REG_WORD(&reg->mailbox0, MBC_READ_RAM_EXTENDED);
+               clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
+       }
+       for (cnt = 0; cnt < ext_mem_cnt && rval == QLA_SUCCESS;
+           cnt++, risc_address++) {
+               WRT_REG_WORD(&reg->mailbox1, LSW(risc_address));
+               WRT_REG_WORD(&reg->mailbox8, MSW(risc_address));
+               RD_REG_WORD(&reg->mailbox8);
+               WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
+
+               for (timer = 6000000; timer; timer--) {
+                       /* Check for pending interrupts. */
+                       stat = RD_REG_DWORD(&reg->host_status);
+                       if (stat & HSRX_RISC_INT) {
+                               stat &= 0xff;
+
+                               if (stat == 0x1 || stat == 0x2 ||
+                                   stat == 0x10 || stat == 0x11) {
+                                       set_bit(MBX_INTERRUPT,
+                                           &ha->mbx_cmd_flags);
+
+                                       mb[0] = RD_REG_WORD(&reg->mailbox0);
+                                       mb[2] = RD_REG_WORD(&reg->mailbox2);
+                                       mb[3] = RD_REG_WORD(&reg->mailbox3);
+
+                                       WRT_REG_DWORD(&reg->hccr,
+                                           HCCRX_CLR_RISC_INT);
+                                       RD_REG_DWORD(&reg->hccr);
+                                       break;
+                               }
+
+                               /* Clear this intr; it wasn't a mailbox intr */
+                               WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
+                               RD_REG_DWORD(&reg->hccr);
+                       }
+                       udelay(5);
+               }
+
+               if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
+                       rval = mb[0] & MBS_MASK;
+                       ext_mem[cnt] = htonl((mb[3] << 16) | mb[2]);
+               } else {
+                       rval = QLA_FUNCTION_FAILED;
+               }
+       }
+
+       *nxt = rval == QLA_SUCCESS ? &ext_mem[cnt]: NULL;
+       return rval;
+}
+
 /**
  * qla2300_fw_dump() - Dumps binary data from the 2300 firmware.
  * @ha: HA context
@@ -633,11 +748,10 @@ void
 qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
 {
        int             rval;
-       uint32_t        cnt, timer;
+       uint32_t        cnt;
        uint32_t        risc_address;
-       uint16_t        mb[4], wd;
+       uint16_t        mb0, wd;
 
-       uint32_t        stat;
        struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
        uint32_t __iomem *dmp_reg;
        uint32_t        *iter_reg;
@@ -645,10 +759,9 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
        unsigned long   flags;
        struct qla24xx_fw_dump *fw;
        uint32_t        ext_mem_cnt;
-       void            *eft;
+       void            *nxt;
 
        risc_address = ext_mem_cnt = 0;
-       memset(mb, 0, sizeof(mb));
        flags = 0;
 
        if (!hardware_locked)
@@ -701,250 +814,236 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
                /* Shadow registers. */
                WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
                RD_REG_DWORD(&reg->iobase_addr);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
-               WRT_REG_DWORD(dmp_reg, 0xB0000000);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
-               fw->shadow_reg[0] = htonl(RD_REG_DWORD(dmp_reg));
-
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
-               WRT_REG_DWORD(dmp_reg, 0xB0100000);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
-               fw->shadow_reg[1] = htonl(RD_REG_DWORD(dmp_reg));
-
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
-               WRT_REG_DWORD(dmp_reg, 0xB0200000);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
-               fw->shadow_reg[2] = htonl(RD_REG_DWORD(dmp_reg));
-
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
-               WRT_REG_DWORD(dmp_reg, 0xB0300000);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
-               fw->shadow_reg[3] = htonl(RD_REG_DWORD(dmp_reg));
-
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
-               WRT_REG_DWORD(dmp_reg, 0xB0400000);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
-               fw->shadow_reg[4] = htonl(RD_REG_DWORD(dmp_reg));
-
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
-               WRT_REG_DWORD(dmp_reg, 0xB0500000);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
-               fw->shadow_reg[5] = htonl(RD_REG_DWORD(dmp_reg));
-
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
-               WRT_REG_DWORD(dmp_reg, 0xB0600000);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
-               fw->shadow_reg[6] = htonl(RD_REG_DWORD(dmp_reg));
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0000000);
+               fw->shadow_reg[0] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0100000);
+               fw->shadow_reg[1] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0200000);
+               fw->shadow_reg[2] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0300000);
+               fw->shadow_reg[3] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0400000);
+               fw->shadow_reg[4] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0500000);
+               fw->shadow_reg[5] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0600000);
+               fw->shadow_reg[6] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
 
                /* Mailbox registers. */
-               mbx_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
+               mbx_reg = &reg->mailbox0;
                for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
                        fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++));
 
                /* Transfer sequence registers. */
                iter_reg = fw->xseq_gp_reg;
                WRT_REG_DWORD(&reg->iobase_addr, 0xBF00);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xBF10);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xBF20);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xBF30);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xBF40);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xBF50);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xBF60);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xBF70);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xBFE0);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++)
                        fw->xseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xBFF0);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++)
                        fw->xseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
 
                /* Receive sequence registers. */
                iter_reg = fw->rseq_gp_reg;
                WRT_REG_DWORD(&reg->iobase_addr, 0xFF00);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xFF10);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xFF20);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xFF30);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xFF40);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xFF50);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xFF60);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xFF70);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xFFD0);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++)
                        fw->rseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xFFE0);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++)
                        fw->rseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0xFFF0);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++)
                        fw->rseq_2_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
 
                /* Command DMA registers. */
                WRT_REG_DWORD(&reg->iobase_addr, 0x7100);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++)
                        fw->cmd_dma_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
 
                /* Queues. */
                iter_reg = fw->req0_dma_reg;
                WRT_REG_DWORD(&reg->iobase_addr, 0x7200);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 8; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4);
+               dmp_reg = &reg->iobase_q;
                for (cnt = 0; cnt < 7; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                iter_reg = fw->resp0_dma_reg;
                WRT_REG_DWORD(&reg->iobase_addr, 0x7300);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 8; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4);
+               dmp_reg = &reg->iobase_q;
                for (cnt = 0; cnt < 7; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                iter_reg = fw->req1_dma_reg;
                WRT_REG_DWORD(&reg->iobase_addr, 0x7400);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 8; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4);
+               dmp_reg = &reg->iobase_q;
                for (cnt = 0; cnt < 7; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                /* Transmit DMA registers. */
                iter_reg = fw->xmt0_dma_reg;
                WRT_REG_DWORD(&reg->iobase_addr, 0x7600);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x7610);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                iter_reg = fw->xmt1_dma_reg;
                WRT_REG_DWORD(&reg->iobase_addr, 0x7620);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x7630);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                iter_reg = fw->xmt2_dma_reg;
                WRT_REG_DWORD(&reg->iobase_addr, 0x7640);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x7650);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                iter_reg = fw->xmt3_dma_reg;
                WRT_REG_DWORD(&reg->iobase_addr, 0x7660);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x7670);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                iter_reg = fw->xmt4_dma_reg;
                WRT_REG_DWORD(&reg->iobase_addr, 0x7680);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x7690);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x76A0);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++)
                        fw->xmt_data_dma_reg[cnt] =
                            htonl(RD_REG_DWORD(dmp_reg++));
@@ -952,221 +1051,221 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
                /* Receive DMA registers. */
                iter_reg = fw->rcvt0_data_dma_reg;
                WRT_REG_DWORD(&reg->iobase_addr, 0x7700);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x7710);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                iter_reg = fw->rcvt1_data_dma_reg;
                WRT_REG_DWORD(&reg->iobase_addr, 0x7720);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x7730);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                /* RISC registers. */
                iter_reg = fw->risc_gp_reg;
                WRT_REG_DWORD(&reg->iobase_addr, 0x0F00);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x0F10);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x0F20);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x0F30);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x0F40);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x0F50);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x0F60);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                /* Local memory controller registers. */
                iter_reg = fw->lmc_reg;
                WRT_REG_DWORD(&reg->iobase_addr, 0x3000);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x3010);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x3020);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x3030);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x3040);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x3050);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x3060);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                /* Fibre Protocol Module registers. */
                iter_reg = fw->fpm_hdw_reg;
                WRT_REG_DWORD(&reg->iobase_addr, 0x4000);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x4010);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x4020);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x4030);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x4040);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x4050);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x4060);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x4070);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x4080);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x4090);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x40A0);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x40B0);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                /* Frame Buffer registers. */
                iter_reg = fw->fb_hdw_reg;
                WRT_REG_DWORD(&reg->iobase_addr, 0x6000);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x6010);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x6020);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x6030);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x6040);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x6100);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x6130);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x6150);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x6170);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x6190);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
                WRT_REG_DWORD(&reg->iobase_addr, 0x61B0);
-               dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+               dmp_reg = &reg->iobase_window;
                for (cnt = 0; cnt < 16; cnt++)
                        *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
 
@@ -1187,10 +1286,10 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
 
                udelay(100);
                /* Wait for firmware to complete NVRAM accesses. */
-               mb[0] = (uint32_t) RD_REG_WORD(&reg->mailbox0);
-               for (cnt = 10000 ; cnt && mb[0]; cnt--) {
+               mb0 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
+               for (cnt = 10000 ; cnt && mb0; cnt--) {
                        udelay(5);
-                       mb[0] = (uint32_t) RD_REG_WORD(&reg->mailbox0);
+                       mb0 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
                        barrier();
                }
 
@@ -1214,116 +1313,723 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
                        rval = QLA_FUNCTION_TIMEOUT;
        }
 
-       /* Memory. */
+       if (rval == QLA_SUCCESS)
+               rval = qla2xxx_dump_memory(ha, fw->code_ram,
+                   sizeof(fw->code_ram), fw->ext_mem, &nxt);
+
        if (rval == QLA_SUCCESS) {
-               /* Code RAM. */
-               risc_address = 0x20000;
-               WRT_REG_WORD(&reg->mailbox0, MBC_READ_RAM_EXTENDED);
-               clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
+               nxt = qla2xxx_copy_queues(ha, nxt);
+               if (ha->eft)
+                       memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size));
        }
-       for (cnt = 0; cnt < sizeof(fw->code_ram) / 4 && rval == QLA_SUCCESS;
-           cnt++, risc_address++) {
-               WRT_REG_WORD(&reg->mailbox1, LSW(risc_address));
-               WRT_REG_WORD(&reg->mailbox8, MSW(risc_address));
-               RD_REG_WORD(&reg->mailbox8);
-               WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
-
-               for (timer = 6000000; timer; timer--) {
-                       /* Check for pending interrupts. */
-                       stat = RD_REG_DWORD(&reg->host_status);
-                       if (stat & HSRX_RISC_INT) {
-                               stat &= 0xff;
-
-                               if (stat == 0x1 || stat == 0x2 ||
-                                   stat == 0x10 || stat == 0x11) {
-                                       set_bit(MBX_INTERRUPT,
-                                           &ha->mbx_cmd_flags);
 
-                                       mb[0] = RD_REG_WORD(&reg->mailbox0);
-                                       mb[2] = RD_REG_WORD(&reg->mailbox2);
-                                       mb[3] = RD_REG_WORD(&reg->mailbox3);
+       if (rval != QLA_SUCCESS) {
+               qla_printk(KERN_WARNING, ha,
+                   "Failed to dump firmware (%x)!!!\n", rval);
+               ha->fw_dumped = 0;
 
-                                       WRT_REG_DWORD(&reg->hccr,
-                                           HCCRX_CLR_RISC_INT);
-                                       RD_REG_DWORD(&reg->hccr);
-                                       break;
-                               }
+       } else {
+               qla_printk(KERN_INFO, ha,
+                   "Firmware dump saved to temp buffer (%ld/%p).\n",
+                   ha->host_no, ha->fw_dump);
+               ha->fw_dumped = 1;
+       }
 
-                               /* Clear this intr; it wasn't a mailbox intr */
-                               WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
-                               RD_REG_DWORD(&reg->hccr);
-                       }
-                       udelay(5);
-               }
+qla24xx_fw_dump_failed:
+       if (!hardware_locked)
+               spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
 
-               if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
-                       rval = mb[0] & MBS_MASK;
-                       fw->code_ram[cnt] = htonl((mb[3] << 16) | mb[2]);
-               } else {
-                       rval = QLA_FUNCTION_FAILED;
-               }
-       }
+void
+qla25xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
+{
+       int             rval;
+       uint32_t        cnt;
+       uint32_t        risc_address;
+       uint16_t        mb0, wd;
 
-       if (rval == QLA_SUCCESS) {
-               /* External Memory. */
-               risc_address = 0x100000;
-               ext_mem_cnt = ha->fw_memory_size - 0x100000 + 1;
-               WRT_REG_WORD(&reg->mailbox0, MBC_READ_RAM_EXTENDED);
-               clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
-       }
-       for (cnt = 0; cnt < ext_mem_cnt && rval == QLA_SUCCESS;
-           cnt++, risc_address++) {
-               WRT_REG_WORD(&reg->mailbox1, LSW(risc_address));
-               WRT_REG_WORD(&reg->mailbox8, MSW(risc_address));
-               RD_REG_WORD(&reg->mailbox8);
-               WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
+       struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+       uint32_t __iomem *dmp_reg;
+       uint32_t        *iter_reg;
+       uint16_t __iomem *mbx_reg;
+       unsigned long   flags;
+       struct qla25xx_fw_dump *fw;
+       uint32_t        ext_mem_cnt;
+       void            *nxt;
 
-               for (timer = 6000000; timer; timer--) {
-                       /* Check for pending interrupts. */
-                       stat = RD_REG_DWORD(&reg->host_status);
-                       if (stat & HSRX_RISC_INT) {
-                               stat &= 0xff;
+       risc_address = ext_mem_cnt = 0;
+       flags = 0;
 
-                               if (stat == 0x1 || stat == 0x2 ||
-                                   stat == 0x10 || stat == 0x11) {
-                                       set_bit(MBX_INTERRUPT,
-                                           &ha->mbx_cmd_flags);
+       if (!hardware_locked)
+               spin_lock_irqsave(&ha->hardware_lock, flags);
 
-                                       mb[0] = RD_REG_WORD(&reg->mailbox0);
-                                       mb[2] = RD_REG_WORD(&reg->mailbox2);
-                                       mb[3] = RD_REG_WORD(&reg->mailbox3);
+       if (!ha->fw_dump) {
+               qla_printk(KERN_WARNING, ha,
+                   "No buffer available for dump!!!\n");
+               goto qla25xx_fw_dump_failed;
+       }
 
-                                       WRT_REG_DWORD(&reg->hccr,
-                                           HCCRX_CLR_RISC_INT);
-                                       RD_REG_DWORD(&reg->hccr);
-                                       break;
-                               }
+       if (ha->fw_dumped) {
+               qla_printk(KERN_WARNING, ha,
+                   "Firmware has been previously dumped (%p) -- ignoring "
+                   "request...\n", ha->fw_dump);
+               goto qla25xx_fw_dump_failed;
+       }
+       fw = &ha->fw_dump->isp.isp25;
+       qla2xxx_prep_dump(ha, ha->fw_dump);
 
-                               /* Clear this intr; it wasn't a mailbox intr */
-                               WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
-                               RD_REG_DWORD(&reg->hccr);
-                       }
-                       udelay(5);
-               }
+       rval = QLA_SUCCESS;
+       fw->host_status = htonl(RD_REG_DWORD(&reg->host_status));
 
-               if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
-                       rval = mb[0] & MBS_MASK;
-                       fw->ext_mem[cnt] = htonl((mb[3] << 16) | mb[2]);
-               } else {
-                       rval = QLA_FUNCTION_FAILED;
+       /* Pause RISC. */
+       if ((RD_REG_DWORD(&reg->hccr) & HCCRX_RISC_PAUSE) == 0) {
+               WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET |
+                   HCCRX_CLR_HOST_INT);
+               RD_REG_DWORD(&reg->hccr);               /* PCI Posting. */
+               WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
+               for (cnt = 30000;
+                   (RD_REG_DWORD(&reg->hccr) & HCCRX_RISC_PAUSE) == 0 &&
+                   rval == QLA_SUCCESS; cnt--) {
+                       if (cnt)
+                               udelay(100);
+                       else
+                               rval = QLA_FUNCTION_TIMEOUT;
                }
        }
 
        if (rval == QLA_SUCCESS) {
-               eft = qla2xxx_copy_queues(ha, &fw->ext_mem[cnt]);
-               if (ha->eft)
-                       memcpy(eft, ha->eft, ntohl(ha->fw_dump->eft_size));
-       }
+               /* Host interface registers. */
+               dmp_reg = (uint32_t __iomem *)(reg + 0);
+               for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
+                       fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
 
-       if (rval != QLA_SUCCESS) {
-               qla_printk(KERN_WARNING, ha,
-                   "Failed to dump firmware (%x)!!!\n", rval);
-               ha->fw_dumped = 0;
+               /* Disable interrupts. */
+               WRT_REG_DWORD(&reg->ictrl, 0);
+               RD_REG_DWORD(&reg->ictrl);
+
+               /* Shadow registers. */
+               WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
+               RD_REG_DWORD(&reg->iobase_addr);
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0000000);
+               fw->shadow_reg[0] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0100000);
+               fw->shadow_reg[1] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0200000);
+               fw->shadow_reg[2] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0300000);
+               fw->shadow_reg[3] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0400000);
+               fw->shadow_reg[4] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0500000);
+               fw->shadow_reg[5] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0600000);
+               fw->shadow_reg[6] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0700000);
+               fw->shadow_reg[7] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0800000);
+               fw->shadow_reg[8] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0900000);
+               fw->shadow_reg[9] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+               WRT_REG_DWORD(&reg->iobase_select, 0xB0A00000);
+               fw->shadow_reg[10] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
+
+               /* RISC I/O register. */
+               WRT_REG_DWORD(&reg->iobase_addr, 0x0010);
+               RD_REG_DWORD(&reg->iobase_addr);
+               fw->risc_io_reg = htonl(RD_REG_DWORD(&reg->iobase_window));
+
+               /* Mailbox registers. */
+               mbx_reg = &reg->mailbox0;
+               for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
+                       fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++));
+
+               /* Transfer sequence registers. */
+               iter_reg = fw->xseq_gp_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0xBF00);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xBF10);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xBF20);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xBF30);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xBF40);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xBF50);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xBF60);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xBF70);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               iter_reg = fw->xseq_0_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0xBFC0);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xBFD0);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xBFE0);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xBFF0);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++)
+                       fw->xseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
+
+               /* Receive sequence registers. */
+               iter_reg = fw->rseq_gp_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0xFF00);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xFF10);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xFF20);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xFF30);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xFF40);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xFF50);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xFF60);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xFF70);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               iter_reg = fw->rseq_0_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0xFFC0);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xFFD0);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xFFE0);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++)
+                       fw->rseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xFFF0);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++)
+                       fw->rseq_2_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
+
+               /* Auxiliary sequence registers. */
+               iter_reg = fw->aseq_gp_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0xB000);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xB010);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xB020);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xB030);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xB040);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xB050);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xB060);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xB070);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               iter_reg = fw->aseq_0_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0xB0C0);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xB0D0);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xB0E0);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < sizeof(fw->aseq_1_reg) / 4; cnt++)
+                       fw->aseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0xB0F0);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < sizeof(fw->aseq_2_reg) / 4; cnt++)
+                       fw->aseq_2_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
+
+               /* Command DMA registers. */
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7100);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++)
+                       fw->cmd_dma_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
+
+               /* Queues. */
+               iter_reg = fw->req0_dma_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7200);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 8; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               dmp_reg = &reg->iobase_q;
+               for (cnt = 0; cnt < 7; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               iter_reg = fw->resp0_dma_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7300);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 8; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               dmp_reg = &reg->iobase_q;
+               for (cnt = 0; cnt < 7; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               iter_reg = fw->req1_dma_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7400);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 8; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               dmp_reg = &reg->iobase_q;
+               for (cnt = 0; cnt < 7; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               /* Transmit DMA registers. */
+               iter_reg = fw->xmt0_dma_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7600);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7610);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               iter_reg = fw->xmt1_dma_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7620);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7630);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               iter_reg = fw->xmt2_dma_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7640);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7650);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               iter_reg = fw->xmt3_dma_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7660);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7670);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               iter_reg = fw->xmt4_dma_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7680);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7690);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x76A0);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++)
+                       fw->xmt_data_dma_reg[cnt] =
+                           htonl(RD_REG_DWORD(dmp_reg++));
+
+               /* Receive DMA registers. */
+               iter_reg = fw->rcvt0_data_dma_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7700);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7710);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               iter_reg = fw->rcvt1_data_dma_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7720);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x7730);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               /* RISC registers. */
+               iter_reg = fw->risc_gp_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0x0F00);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x0F10);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x0F20);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x0F30);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x0F40);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x0F50);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x0F60);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               /* Local memory controller registers. */
+               iter_reg = fw->lmc_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0x3000);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x3010);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x3020);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x3030);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x3040);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x3050);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x3060);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x3070);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               /* Fibre Protocol Module registers. */
+               iter_reg = fw->fpm_hdw_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0x4000);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x4010);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x4020);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x4030);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x4040);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x4050);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x4060);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x4070);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x4080);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x4090);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x40A0);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x40B0);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               /* Frame Buffer registers. */
+               iter_reg = fw->fb_hdw_reg;
+               WRT_REG_DWORD(&reg->iobase_addr, 0x6000);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x6010);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x6020);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x6030);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x6040);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x6100);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x6130);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x6150);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x6170);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x6190);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x61B0);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               WRT_REG_DWORD(&reg->iobase_addr, 0x6F00);
+               dmp_reg = &reg->iobase_window;
+               for (cnt = 0; cnt < 16; cnt++)
+                       *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
+
+               /* Reset RISC. */
+               WRT_REG_DWORD(&reg->ctrl_status,
+                   CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
+               for (cnt = 0; cnt < 30000; cnt++) {
+                       if ((RD_REG_DWORD(&reg->ctrl_status) &
+                           CSRX_DMA_ACTIVE) == 0)
+                               break;
+
+                       udelay(10);
+               }
+
+               WRT_REG_DWORD(&reg->ctrl_status,
+                   CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
+               pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);
+
+               udelay(100);
+               /* Wait for firmware to complete NVRAM accesses. */
+               mb0 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
+               for (cnt = 10000 ; cnt && mb0; cnt--) {
+                       udelay(5);
+                       mb0 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
+                       barrier();
+               }
+
+               /* Wait for soft-reset to complete. */
+               for (cnt = 0; cnt < 30000; cnt++) {
+                       if ((RD_REG_DWORD(&reg->ctrl_status) &
+                           CSRX_ISP_SOFT_RESET) == 0)
+                               break;
+
+                       udelay(10);
+               }
+               WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_RESET);
+               RD_REG_DWORD(&reg->hccr);             /* PCI Posting. */
+       }
+
+       for (cnt = 30000; RD_REG_WORD(&reg->mailbox0) != 0 &&
+           rval == QLA_SUCCESS; cnt--) {
+               if (cnt)
+                       udelay(100);
+               else
+                       rval = QLA_FUNCTION_TIMEOUT;
+       }
+
+       if (rval == QLA_SUCCESS)
+               rval = qla2xxx_dump_memory(ha, fw->code_ram,
+                   sizeof(fw->code_ram), fw->ext_mem, &nxt);
+
+       if (rval == QLA_SUCCESS) {
+               nxt = qla2xxx_copy_queues(ha, nxt);
+               if (ha->eft)
+                       memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size));
+       }
+
+       if (rval != QLA_SUCCESS) {
+               qla_printk(KERN_WARNING, ha,
+                   "Failed to dump firmware (%x)!!!\n", rval);
+               ha->fw_dumped = 0;
 
        } else {
                qla_printk(KERN_INFO, ha,
@@ -1332,7 +2038,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
                ha->fw_dumped = 1;
        }
 
-qla24xx_fw_dump_failed:
+qla25xx_fw_dump_failed:
        if (!hardware_locked)
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
 }
index 49dffeb785121dfa01bb458f74fe14359dd0ad2f..cca4b0d8253eae3c164f73adb57dc8ec68ce20bb 100644 (file)
@@ -213,6 +213,43 @@ struct qla24xx_fw_dump {
        uint32_t ext_mem[1];
 };
 
+struct qla25xx_fw_dump {
+       uint32_t host_status;
+       uint32_t host_reg[32];
+       uint32_t shadow_reg[11];
+       uint32_t risc_io_reg;
+       uint16_t mailbox_reg[32];
+       uint32_t xseq_gp_reg[128];
+       uint32_t xseq_0_reg[48];
+       uint32_t xseq_1_reg[16];
+       uint32_t rseq_gp_reg[128];
+       uint32_t rseq_0_reg[32];
+       uint32_t rseq_1_reg[16];
+       uint32_t rseq_2_reg[16];
+       uint32_t aseq_gp_reg[128];
+       uint32_t aseq_0_reg[32];
+       uint32_t aseq_1_reg[16];
+       uint32_t aseq_2_reg[16];
+       uint32_t cmd_dma_reg[16];
+       uint32_t req0_dma_reg[15];
+       uint32_t resp0_dma_reg[15];
+       uint32_t req1_dma_reg[15];
+       uint32_t xmt0_dma_reg[32];
+       uint32_t xmt1_dma_reg[32];
+       uint32_t xmt2_dma_reg[32];
+       uint32_t xmt3_dma_reg[32];
+       uint32_t xmt4_dma_reg[32];
+       uint32_t xmt_data_dma_reg[16];
+       uint32_t rcvt0_data_dma_reg[32];
+       uint32_t rcvt1_data_dma_reg[32];
+       uint32_t risc_gp_reg[128];
+       uint32_t lmc_reg[128];
+       uint32_t fpm_hdw_reg[192];
+       uint32_t fb_hdw_reg[192];
+       uint32_t code_ram[0x2000];
+       uint32_t ext_mem[1];
+};
+
 #define EFT_NUM_BUFFERS                4
 #define EFT_BYTES_PER_BUFFER   0x4000
 #define EFT_SIZE               ((EFT_BYTES_PER_BUFFER) * (EFT_NUM_BUFFERS))
@@ -246,5 +283,6 @@ struct qla2xxx_fw_dump {
                struct qla2100_fw_dump isp21;
                struct qla2300_fw_dump isp23;
                struct qla24xx_fw_dump isp24;
+               struct qla25xx_fw_dump isp25;
        } isp;
 };
index a1ca590ba447c22c8c9ae615a36d3f8ef914dab8..0c9f36c8a24870dadd6c20f8e61bf099686a0562 100644 (file)
@@ -1711,6 +1711,14 @@ struct ct_fdmi_hba_attributes {
 #define FDMI_PORT_OS_DEVICE_NAME       5
 #define FDMI_PORT_HOST_NAME            6
 
+#define FDMI_PORT_SPEED_1GB            0x1
+#define FDMI_PORT_SPEED_2GB            0x2
+#define FDMI_PORT_SPEED_10GB           0x4
+#define FDMI_PORT_SPEED_4GB            0x8
+#define FDMI_PORT_SPEED_8GB            0x10
+#define FDMI_PORT_SPEED_16GB           0x20
+#define FDMI_PORT_SPEED_UNKNOWN                0x8000
+
 struct ct_fdmi_port_attr {
        uint16_t type;
        uint16_t len;
@@ -2201,6 +2209,7 @@ typedef struct scsi_qla_host {
 #define        SWITCH_FOUND                    BIT_3
 #define        DFLG_NO_CABLE                   BIT_4
 
+#define PCI_DEVICE_ID_QLOGIC_ISP2532   0x2532
        uint32_t        device_type;
 #define DT_ISP2100                     BIT_0
 #define DT_ISP2200                     BIT_1
@@ -2213,8 +2222,11 @@ typedef struct scsi_qla_host {
 #define DT_ISP2432                     BIT_8
 #define DT_ISP5422                     BIT_9
 #define DT_ISP5432                     BIT_10
-#define DT_ISP_LAST                    (DT_ISP5432 << 1)
+#define DT_ISP2532                     BIT_11
+#define DT_ISP_LAST                    (DT_ISP2532 << 1)
 
+#define DT_IIDMA                       BIT_26
+#define DT_FWI2                                BIT_27
 #define DT_ZIO_SUPPORTED               BIT_28
 #define DT_OEM_001                     BIT_29
 #define DT_ISP2200A                    BIT_30
@@ -2232,12 +2244,16 @@ typedef struct scsi_qla_host {
 #define IS_QLA2432(ha) (DT_MASK(ha) & DT_ISP2432)
 #define IS_QLA5422(ha) (DT_MASK(ha) & DT_ISP5422)
 #define IS_QLA5432(ha) (DT_MASK(ha) & DT_ISP5432)
+#define IS_QLA2532(ha) (DT_MASK(ha) & DT_ISP2532)
 
 #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
                         IS_QLA6312(ha) || IS_QLA6322(ha))
 #define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha))
 #define IS_QLA54XX(ha) (IS_QLA5422(ha) || IS_QLA5432(ha))
+#define IS_QLA25XX(ha) (IS_QLA2532(ha))
 
+#define IS_IIDMA_CAPABLE(ha)   ((ha)->device_type & DT_IIDMA)
+#define IS_FWI2_CAPABLE(ha)    ((ha)->device_type & DT_FWI2)
 #define IS_ZIO_SUPPORTED(ha)   ((ha)->device_type & DT_ZIO_SUPPORTED)
 #define IS_OEM_001(ha)         ((ha)->device_type & DT_OEM_001)
 #define HAS_EXTENDED_IDS(ha)   ((ha)->device_type & DT_EXTENDED_IDS)
@@ -2274,7 +2290,7 @@ typedef struct scsi_qla_host {
        uint16_t        rsp_ring_index;     /* Current index. */
        uint16_t        response_q_length;
 
-       struct isp_operations isp_ops;
+       struct isp_operations *isp_ops;
 
        /* Outstandings ISP commands. */
        srb_t           *outstanding_cmds[MAX_OUTSTANDING_COMMANDS];
@@ -2298,6 +2314,7 @@ typedef struct scsi_qla_host {
 #define PORT_SPEED_1GB 0x00
 #define PORT_SPEED_2GB 0x01
 #define PORT_SPEED_4GB 0x03
+#define PORT_SPEED_8GB 0x04
        uint16_t        link_data_rate;         /* F/W operating speed */
 
        uint8_t         current_topology;
@@ -2564,6 +2581,7 @@ typedef struct scsi_qla_host {
 #define OPTROM_SIZE_2300       0x20000
 #define OPTROM_SIZE_2322       0x100000
 #define OPTROM_SIZE_24XX       0x100000
+#define OPTROM_SIZE_25XX       0x200000
 
 #include "qla_gbl.h"
 #include "qla_dbg.h"
index 63a11fef5d1bcf8d048bc0f6d6056b9ab9f8fcc9..99fe49618d6134c5342478755e701ac4d6f32b76 100644 (file)
@@ -8,14 +8,17 @@
 #define __QLA_FW_H
 
 #define MBS_CHECKSUM_ERROR     0x4010
+#define MBS_INVALID_PRODUCT_KEY        0x4020
 
 /*
  * Firmware Options.
  */
 #define FO1_ENABLE_PUREX       BIT_10
 #define FO1_DISABLE_LED_CTRL   BIT_6
+#define FO1_ENABLE_8016                BIT_0
 #define FO2_ENABLE_SEL_CLASS2  BIT_5
 #define FO3_NO_ABTS_ON_LINKDOWN        BIT_14
+#define FO3_HOLD_STS_IOCB      BIT_12
 
 /*
  * Port Database structure definition for ISP 24xx.
@@ -341,7 +344,9 @@ struct init_cb_24xx {
         * BIT 10 = Reserved
         * BIT 11 = Enable FC-SP Security
         * BIT 12 = FC Tape Enable
-        * BIT 13-31 = Reserved
+        * BIT 13 = Reserved
+        * BIT 14 = Enable Target PRLI Control
+        * BIT 15-31 = Reserved
         */
        uint32_t firmware_options_2;
 
@@ -363,7 +368,8 @@ struct init_cb_24xx {
         * BIT 13 = Data Rate bit 0
         * BIT 14 = Data Rate bit 1
         * BIT 15 = Data Rate bit 2
-        * BIT 16-31 = Reserved
+        * BIT 16 = Enable 75 ohm Termination Select
+        * BIT 17-31 = Reserved
         */
        uint32_t firmware_options_3;
 
@@ -435,6 +441,7 @@ struct cmd_type_7 {
 #define TMF_LUN_RESET          BIT_12
 #define TMF_CLEAR_TASK_SET     BIT_10
 #define TMF_ABORT_TASK_SET     BIT_9
+#define TMF_DSD_LIST_ENABLE    BIT_2
 #define TMF_READ_DATA          BIT_1
 #define TMF_WRITE_DATA         BIT_0
 
@@ -589,7 +596,7 @@ struct els_entry_24xx {
 #define EST_SOFI3              (1 << 4)
 #define EST_SOFI2              (3 << 4)
 
-       uint32_t rx_xchg_address[2];    /* Receive exchange address. */
+       uint32_t rx_xchg_address;       /* Receive exchange address. */
        uint16_t rx_dsd_count;
 
        uint8_t opcode;
@@ -650,6 +657,7 @@ struct logio_entry_24xx {
 
        uint16_t control_flags;         /* Control flags. */
                                        /* Modifiers. */
+#define LCF_INCLUDE_SNS                BIT_10  /* Include SNS (FFFFFC) during LOGO. */
 #define LCF_FCP2_OVERRIDE      BIT_9   /* Set/Reset word 3 of PRLI. */
 #define LCF_CLASS_2            BIT_8   /* Enable class 2 during PLOGI. */
 #define LCF_FREE_NPORT         BIT_7   /* Release NPORT handle after LOGO. */
@@ -779,6 +787,15 @@ struct device_reg_24xx {
 #define FA_RISC_CODE_ADDR      0x20000
 #define FA_RISC_CODE_SEGMENTS  2
 
+#define FA_FW_AREA_ADDR                0x40000
+#define FA_VPD_NVRAM_ADDR      0x48000
+#define FA_FEATURE_ADDR                0x4C000
+#define FA_FLASH_DESCR_ADDR    0x50000
+#define FA_HW_EVENT_ADDR       0x54000
+#define FA_BOOT_LOG_ADDR       0x58000
+#define FA_FW_DUMP0_ADDR       0x60000
+#define FA_FW_DUMP1_ADDR       0x70000
+
        uint32_t flash_data;            /* Flash/NVRAM BIOS data. */
 
        uint32_t ctrl_status;           /* Control/Status. */
@@ -859,10 +876,13 @@ struct device_reg_24xx {
 #define HCCRX_CLR_RISC_INT     0xA0000000
 
        uint32_t gpiod;                 /* GPIO Data register. */
+
                                        /* LED update mask. */
 #define GPDX_LED_UPDATE_MASK   (BIT_20|BIT_19|BIT_18)
                                        /* Data update mask. */
 #define GPDX_DATA_UPDATE_MASK  (BIT_17|BIT_16)
+                                       /* Data update mask. */
+#define GPDX_DATA_UPDATE_2_MASK        (BIT_28|BIT_27|BIT_26|BIT_17|BIT_16)
                                        /* LED control mask. */
 #define GPDX_LED_COLOR_MASK    (BIT_4|BIT_3|BIT_2)
                                        /* LED bit values. Color names as
@@ -877,6 +897,8 @@ struct device_reg_24xx {
        uint32_t gpioe;                 /* GPIO Enable register. */
                                        /* Enable update mask. */
 #define GPEX_ENABLE_UPDATE_MASK        (BIT_17|BIT_16)
+                                       /* Enable update mask. */
+#define GPEX_ENABLE_UPDATE_2_MASK (BIT_28|BIT_27|BIT_26|BIT_17|BIT_16)
                                        /* Enable. */
 #define GPEX_ENABLE            (BIT_1|BIT_0)
 
@@ -916,6 +938,14 @@ struct device_reg_24xx {
        uint16_t mailbox29;
        uint16_t mailbox30;
        uint16_t mailbox31;
+
+       uint32_t iobase_window;
+       uint32_t unused_4[8];           /* Gap. */
+       uint32_t iobase_q;
+       uint32_t unused_5[2];           /* Gap. */
+       uint32_t iobase_select;
+       uint32_t unused_6[2];           /* Gap. */
+       uint32_t iobase_sdata;
 };
 
 /* MID Support ***************************************************************/
index b44eff2803ce01bd717fcf0ef46c2ddbb5fd6d73..aa1e41152283dee8992c3df86391c187b9c087e8 100644 (file)
@@ -17,6 +17,7 @@ extern int qla2x00_initialize_adapter(scsi_qla_host_t *);
 extern int qla2100_pci_config(struct scsi_qla_host *);
 extern int qla2300_pci_config(struct scsi_qla_host *);
 extern int qla24xx_pci_config(scsi_qla_host_t *);
+extern int qla25xx_pci_config(scsi_qla_host_t *);
 extern void qla2x00_reset_chip(struct scsi_qla_host *);
 extern void qla24xx_reset_chip(struct scsi_qla_host *);
 extern int qla2x00_chip_diag(struct scsi_qla_host *);
@@ -281,6 +282,10 @@ extern int qla2x00_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
     uint32_t);
 extern int qla24xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
     uint32_t);
+extern uint8_t *qla25xx_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
+    uint32_t);
+extern int qla25xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
+    uint32_t);
 
 extern int qla2x00_beacon_on(struct scsi_qla_host *);
 extern int qla2x00_beacon_off(struct scsi_qla_host *);
@@ -307,6 +312,7 @@ extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *);
 extern void qla2100_fw_dump(scsi_qla_host_t *, int);
 extern void qla2300_fw_dump(scsi_qla_host_t *, int);
 extern void qla24xx_fw_dump(scsi_qla_host_t *, int);
+extern void qla25xx_fw_dump(scsi_qla_host_t *, int);
 extern void qla2x00_dump_regs(scsi_qla_host_t *);
 extern void qla2x00_dump_buffer(uint8_t *, uint32_t);
 extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *);
index a086b3f0df653bfe542e5b1ec43e0f6bc0b37b9b..b06cbb8580d3d67dd5d825616918ec1164f0351f 100644 (file)
@@ -127,7 +127,7 @@ qla2x00_chk_ms_status(scsi_qla_host_t *ha, ms_iocb_entry_t *ms_pkt,
                DEBUG2_3(printk("scsi(%ld): %s failed, error status (%x).\n",
                    ha->host_no, routine, ms_pkt->entry_status));
        } else {
-               if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
+               if (IS_FWI2_CAPABLE(ha))
                        comp_status = le16_to_cpu(
                            ((struct ct_entry_24xx *)ms_pkt)->comp_status);
                else
@@ -180,7 +180,8 @@ qla2x00_ga_nxt(scsi_qla_host_t *ha, fc_port_t *fcport)
 
        /* Issue GA_NXT */
        /* Prepare common MS IOCB */
-       ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GA_NXT_REQ_SIZE, GA_NXT_RSP_SIZE);
+       ms_pkt = ha->isp_ops->prep_ms_iocb(ha, GA_NXT_REQ_SIZE,
+           GA_NXT_RSP_SIZE);
 
        /* Prepare CT request */
        ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GA_NXT_CMD,
@@ -266,7 +267,8 @@ qla2x00_gid_pt(scsi_qla_host_t *ha, sw_info_t *list)
 
        /* Issue GID_PT */
        /* Prepare common MS IOCB */
-       ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GID_PT_REQ_SIZE, GID_PT_RSP_SIZE);
+       ms_pkt = ha->isp_ops->prep_ms_iocb(ha, GID_PT_REQ_SIZE,
+           GID_PT_RSP_SIZE);
 
        /* Prepare CT request */
        ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GID_PT_CMD,
@@ -338,7 +340,7 @@ qla2x00_gpn_id(scsi_qla_host_t *ha, sw_info_t *list)
        for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
                /* Issue GPN_ID */
                /* Prepare common MS IOCB */
-               ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GPN_ID_REQ_SIZE,
+               ms_pkt = ha->isp_ops->prep_ms_iocb(ha, GPN_ID_REQ_SIZE,
                    GPN_ID_RSP_SIZE);
 
                /* Prepare CT request */
@@ -399,7 +401,7 @@ qla2x00_gnn_id(scsi_qla_host_t *ha, sw_info_t *list)
        for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
                /* Issue GNN_ID */
                /* Prepare common MS IOCB */
-               ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GNN_ID_REQ_SIZE,
+               ms_pkt = ha->isp_ops->prep_ms_iocb(ha, GNN_ID_REQ_SIZE,
                    GNN_ID_RSP_SIZE);
 
                /* Prepare CT request */
@@ -473,7 +475,8 @@ qla2x00_rft_id(scsi_qla_host_t *ha)
 
        /* Issue RFT_ID */
        /* Prepare common MS IOCB */
-       ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RFT_ID_REQ_SIZE, RFT_ID_RSP_SIZE);
+       ms_pkt = ha->isp_ops->prep_ms_iocb(ha, RFT_ID_REQ_SIZE,
+           RFT_ID_RSP_SIZE);
 
        /* Prepare CT request */
        ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFT_ID_CMD,
@@ -528,7 +531,8 @@ qla2x00_rff_id(scsi_qla_host_t *ha)
 
        /* Issue RFF_ID */
        /* Prepare common MS IOCB */
-       ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RFF_ID_REQ_SIZE, RFF_ID_RSP_SIZE);
+       ms_pkt = ha->isp_ops->prep_ms_iocb(ha, RFF_ID_REQ_SIZE,
+           RFF_ID_RSP_SIZE);
 
        /* Prepare CT request */
        ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFF_ID_CMD,
@@ -582,7 +586,8 @@ qla2x00_rnn_id(scsi_qla_host_t *ha)
 
        /* Issue RNN_ID */
        /* Prepare common MS IOCB */
-       ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RNN_ID_REQ_SIZE, RNN_ID_RSP_SIZE);
+       ms_pkt = ha->isp_ops->prep_ms_iocb(ha, RNN_ID_REQ_SIZE,
+           RNN_ID_RSP_SIZE);
 
        /* Prepare CT request */
        ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RNN_ID_CMD,
@@ -645,7 +650,7 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha)
        /* Issue RSNN_NN */
        /* Prepare common MS IOCB */
        /*   Request size adjusted after CT preparation */
-       ms_pkt = ha->isp_ops.prep_ms_iocb(ha, 0, RSNN_NN_RSP_SIZE);
+       ms_pkt = ha->isp_ops->prep_ms_iocb(ha, 0, RSNN_NN_RSP_SIZE);
 
        /* Prepare CT request */
        ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RSNN_NN_CMD,
@@ -1102,7 +1107,7 @@ qla2x00_mgmt_svr_login(scsi_qla_host_t *ha)
        if (ha->flags.management_server_logged_in)
                return ret;
 
-       ha->isp_ops.fabric_login(ha, ha->mgmt_svr_loop_id, 0xff, 0xff, 0xfa,
+       ha->isp_ops->fabric_login(ha, ha->mgmt_svr_loop_id, 0xff, 0xff, 0xfa,
            mb, BIT_1);
        if (mb[0] != MBS_COMMAND_COMPLETE) {
                DEBUG2_13(printk("%s(%ld): Failed MANAGEMENT_SERVER login: "
@@ -1198,7 +1203,7 @@ qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size)
        ms_iocb_entry_t *ms_pkt = ha->ms_iocb;
        struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
 
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (IS_FWI2_CAPABLE(ha)) {
                ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
                ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
        } else {
@@ -1253,7 +1258,7 @@ qla2x00_fdmi_rhba(scsi_qla_host_t *ha)
        /* Issue RHBA */
        /* Prepare common MS IOCB */
        /*   Request size adjusted after CT preparation */
-       ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, 0, RHBA_RSP_SIZE);
+       ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(ha, 0, RHBA_RSP_SIZE);
 
        /* Prepare CT request */
        ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RHBA_CMD,
@@ -1373,7 +1378,7 @@ qla2x00_fdmi_rhba(scsi_qla_host_t *ha)
        /* Firmware version */
        eiter = (struct ct_fdmi_hba_attr *) (entries + size);
        eiter->type = __constant_cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION);
-       ha->isp_ops.fw_version_str(ha, eiter->a.fw_version);
+       ha->isp_ops->fw_version_str(ha, eiter->a.fw_version);
        alen = strlen(eiter->a.fw_version);
        alen += (alen & 3) ? (4 - (alen & 3)) : 4;
        eiter->len = cpu_to_be16(4 + alen);
@@ -1439,7 +1444,7 @@ qla2x00_fdmi_dhba(scsi_qla_host_t *ha)
 
        /* Issue RPA */
        /* Prepare common MS IOCB */
-       ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, DHBA_REQ_SIZE,
+       ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(ha, DHBA_REQ_SIZE,
            DHBA_RSP_SIZE);
 
        /* Prepare CT request */
@@ -1497,7 +1502,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
        /* Issue RPA */
        /* Prepare common MS IOCB */
        /*   Request size adjusted after CT preparation */
-       ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, 0, RPA_RSP_SIZE);
+       ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(ha, 0, RPA_RSP_SIZE);
 
        /* Prepare CT request */
        ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RPA_CMD,
@@ -1527,12 +1532,20 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
        eiter = (struct ct_fdmi_port_attr *) (entries + size);
        eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
        eiter->len = __constant_cpu_to_be16(4 + 4);
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
-               eiter->a.sup_speed = __constant_cpu_to_be32(4);
+       if (IS_QLA25XX(ha))
+               eiter->a.sup_speed = __constant_cpu_to_be32(
+                   FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
+                   FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB);
+       else if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
+               eiter->a.sup_speed = __constant_cpu_to_be32(
+                   FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
+                   FDMI_PORT_SPEED_4GB);
        else if (IS_QLA23XX(ha))
-               eiter->a.sup_speed = __constant_cpu_to_be32(2);
+               eiter->a.sup_speed =__constant_cpu_to_be32(
+                   FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB);
        else
-               eiter->a.sup_speed = __constant_cpu_to_be32(1);
+               eiter->a.sup_speed = __constant_cpu_to_be32(
+                   FDMI_PORT_SPEED_1GB);
        size += 4 + 4;
 
        DEBUG13(printk("%s(%ld): SUPPORTED_SPEED=%x.\n", __func__, ha->host_no,
@@ -1543,14 +1556,25 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
        eiter->type = __constant_cpu_to_be16(FDMI_PORT_CURRENT_SPEED);
        eiter->len = __constant_cpu_to_be16(4 + 4);
        switch (ha->link_data_rate) {
-       case 0:
-               eiter->a.cur_speed = __constant_cpu_to_be32(1);
+       case PORT_SPEED_1GB:
+               eiter->a.cur_speed =
+                   __constant_cpu_to_be32(FDMI_PORT_SPEED_1GB);
+               break;
+       case PORT_SPEED_2GB:
+               eiter->a.cur_speed =
+                   __constant_cpu_to_be32(FDMI_PORT_SPEED_2GB);
+               break;
+       case PORT_SPEED_4GB:
+               eiter->a.cur_speed =
+                   __constant_cpu_to_be32(FDMI_PORT_SPEED_4GB);
                break;
-       case 1:
-               eiter->a.cur_speed = __constant_cpu_to_be32(2);
+       case PORT_SPEED_8GB:
+               eiter->a.cur_speed =
+                   __constant_cpu_to_be32(FDMI_PORT_SPEED_8GB);
                break;
-       case 3:
-               eiter->a.cur_speed = __constant_cpu_to_be32(4);
+       default:
+               eiter->a.cur_speed =
+                   __constant_cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN);
                break;
        }
        size += 4 + 4;
@@ -1562,7 +1586,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
        eiter = (struct ct_fdmi_port_attr *) (entries + size);
        eiter->type = __constant_cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
        eiter->len = __constant_cpu_to_be16(4 + 4);
-       max_frame_size = IS_QLA24XX(ha) || IS_QLA54XX(ha) ?
+       max_frame_size = IS_FWI2_CAPABLE(ha) ?
                (uint32_t) icb24->frame_payload_size:
                (uint32_t) ha->init_cb->frame_payload_size;
        eiter->a.max_frame_size = cpu_to_be32(max_frame_size);
@@ -1678,7 +1702,7 @@ qla2x00_gfpn_id(scsi_qla_host_t *ha, sw_info_t *list)
        struct ct_sns_req       *ct_req;
        struct ct_sns_rsp       *ct_rsp;
 
-       if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
+       if (!IS_IIDMA_CAPABLE(ha))
                return QLA_FUNCTION_FAILED;
 
        for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
@@ -1686,7 +1710,7 @@ qla2x00_gfpn_id(scsi_qla_host_t *ha, sw_info_t *list)
                memset(list[i].fabric_port_name, 0, WWN_SIZE);
 
                /* Prepare common MS IOCB */
-               ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GFPN_ID_REQ_SIZE,
+               ms_pkt = ha->isp_ops->prep_ms_iocb(ha, GFPN_ID_REQ_SIZE,
                    GFPN_ID_RSP_SIZE);
 
                /* Prepare CT request */
@@ -1786,7 +1810,7 @@ qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list)
        struct ct_sns_req       *ct_req;
        struct ct_sns_rsp       *ct_rsp;
 
-       if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
+       if (!IS_IIDMA_CAPABLE(ha))
                return QLA_FUNCTION_FAILED;
        if (!ha->flags.gpsc_supported)
                return QLA_FUNCTION_FAILED;
index cc6ebb609e987447ef91154265039496b58458d0..5ec798c2bf13d4f0404d10d3b4409db9ec3a07e6 100644 (file)
@@ -79,20 +79,20 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
        set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
 
        qla_printk(KERN_INFO, ha, "Configuring PCI space...\n");
-       rval = ha->isp_ops.pci_config(ha);
+       rval = ha->isp_ops->pci_config(ha);
        if (rval) {
                DEBUG2(printk("scsi(%ld): Unable to configure PCI space.\n",
                    ha->host_no));
                return (rval);
        }
 
-       ha->isp_ops.reset_chip(ha);
+       ha->isp_ops->reset_chip(ha);
 
-       ha->isp_ops.get_flash_version(ha, ha->request_ring);
+       ha->isp_ops->get_flash_version(ha, ha->request_ring);
 
        qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n");
 
-       ha->isp_ops.nvram_config(ha);
+       ha->isp_ops->nvram_config(ha);
 
        if (ha->flags.disable_serdes) {
                /* Mask HBA via NVRAM settings? */
@@ -108,7 +108,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
        qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n");
 
        if (qla2x00_isp_firmware(ha) != QLA_SUCCESS) {
-               rval = ha->isp_ops.chip_diag(ha);
+               rval = ha->isp_ops->chip_diag(ha);
                if (rval)
                        return (rval);
                rval = qla2x00_setup_chip(ha);
@@ -129,14 +129,13 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
 int
 qla2100_pci_config(scsi_qla_host_t *ha)
 {
-       int ret;
        uint16_t w;
        uint32_t d;
        unsigned long flags;
        struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
        pci_set_master(ha->pdev);
-       ret = pci_set_mwi(ha->pdev);
+       pci_try_set_mwi(ha->pdev);
 
        pci_read_config_word(ha->pdev, PCI_COMMAND, &w);
        w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
@@ -164,7 +163,6 @@ qla2100_pci_config(scsi_qla_host_t *ha)
 int
 qla2300_pci_config(scsi_qla_host_t *ha)
 {
-       int             ret;
        uint16_t        w;
        uint32_t        d;
        unsigned long   flags = 0;
@@ -172,7 +170,7 @@ qla2300_pci_config(scsi_qla_host_t *ha)
        struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
        pci_set_master(ha->pdev);
-       ret = pci_set_mwi(ha->pdev);
+       pci_try_set_mwi(ha->pdev);
 
        pci_read_config_word(ha->pdev, PCI_COMMAND, &w);
        w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
@@ -250,15 +248,13 @@ qla2300_pci_config(scsi_qla_host_t *ha)
 int
 qla24xx_pci_config(scsi_qla_host_t *ha)
 {
-       int ret;
        uint16_t w;
        uint32_t d;
        unsigned long flags = 0;
        struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
-       int pcix_cmd_reg, pcie_dctl_reg;
 
        pci_set_master(ha->pdev);
-       ret = pci_set_mwi(ha->pdev);
+       pci_try_set_mwi(ha->pdev);
 
        pci_read_config_word(ha->pdev, PCI_COMMAND, &w);
        w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
@@ -268,28 +264,12 @@ qla24xx_pci_config(scsi_qla_host_t *ha)
        pci_write_config_byte(ha->pdev, PCI_LATENCY_TIMER, 0x80);
 
        /* PCI-X -- adjust Maximum Memory Read Byte Count (2048). */
-       pcix_cmd_reg = pci_find_capability(ha->pdev, PCI_CAP_ID_PCIX);
-       if (pcix_cmd_reg) {
-               uint16_t pcix_cmd;
-
-               pcix_cmd_reg += PCI_X_CMD;
-               pci_read_config_word(ha->pdev, pcix_cmd_reg, &pcix_cmd);
-               pcix_cmd &= ~PCI_X_CMD_MAX_READ;
-               pcix_cmd |= 0x0008;
-               pci_write_config_word(ha->pdev, pcix_cmd_reg, pcix_cmd);
-       }
+       if (pci_find_capability(ha->pdev, PCI_CAP_ID_PCIX))
+               pcix_set_mmrbc(ha->pdev, 2048);
 
        /* PCIe -- adjust Maximum Read Request Size (2048). */
-       pcie_dctl_reg = pci_find_capability(ha->pdev, PCI_CAP_ID_EXP);
-       if (pcie_dctl_reg) {
-               uint16_t pcie_dctl;
-
-               pcie_dctl_reg += PCI_EXP_DEVCTL;
-               pci_read_config_word(ha->pdev, pcie_dctl_reg, &pcie_dctl);
-               pcie_dctl &= ~PCI_EXP_DEVCTL_READRQ;
-               pcie_dctl |= 0x4000;
-               pci_write_config_word(ha->pdev, pcie_dctl_reg, pcie_dctl);
-       }
+       if (pci_find_capability(ha->pdev, PCI_CAP_ID_EXP))
+               pcie_set_readrq(ha->pdev, 2048);
 
        /* Reset expansion ROM address decode enable */
        pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d);
@@ -306,6 +286,40 @@ qla24xx_pci_config(scsi_qla_host_t *ha)
        return QLA_SUCCESS;
 }
 
+/**
+ * qla25xx_pci_config() - Setup ISP25xx PCI configuration registers.
+ * @ha: HA context
+ *
+ * Returns 0 on success.
+ */
+int
+qla25xx_pci_config(scsi_qla_host_t *ha)
+{
+       uint16_t w;
+       uint32_t d;
+
+       pci_set_master(ha->pdev);
+       pci_try_set_mwi(ha->pdev);
+
+       pci_read_config_word(ha->pdev, PCI_COMMAND, &w);
+       w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
+       w &= ~PCI_COMMAND_INTX_DISABLE;
+       pci_write_config_word(ha->pdev, PCI_COMMAND, w);
+
+       /* PCIe -- adjust Maximum Read Request Size (2048). */
+       if (pci_find_capability(ha->pdev, PCI_CAP_ID_EXP))
+               pcie_set_readrq(ha->pdev, 2048);
+
+       /* Reset expansion ROM address decode enable */
+       pci_read_config_dword(ha->pdev, PCI_ROM_ADDRESS, &d);
+       d &= ~PCI_ROM_ADDRESS_ENABLE;
+       pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d);
+
+       ha->chip_revision = ha->pdev->revision;
+
+       return QLA_SUCCESS;
+}
+
 /**
  * qla2x00_isp_firmware() - Choose firmware image.
  * @ha: HA context
@@ -351,7 +365,7 @@ qla2x00_reset_chip(scsi_qla_host_t *ha)
        uint32_t        cnt;
        uint16_t        cmd;
 
-       ha->isp_ops.disable_intrs(ha);
+       ha->isp_ops->disable_intrs(ha);
 
        spin_lock_irqsave(&ha->hardware_lock, flags);
 
@@ -551,7 +565,7 @@ qla24xx_reset_risc(scsi_qla_host_t *ha)
 void
 qla24xx_reset_chip(scsi_qla_host_t *ha)
 {
-       ha->isp_ops.disable_intrs(ha);
+       ha->isp_ops->disable_intrs(ha);
 
        /* Perform RISC reset. */
        qla24xx_reset_risc(ha);
@@ -736,8 +750,10 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha)
                fixed_size = offsetof(struct qla2300_fw_dump, data_ram);
                mem_size = (ha->fw_memory_size - 0x11000 + 1) *
                    sizeof(uint16_t);
-       } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
-               fixed_size = offsetof(struct qla24xx_fw_dump, ext_mem);
+       } else if (IS_FWI2_CAPABLE(ha)) {
+               fixed_size = IS_QLA25XX(ha) ?
+                   offsetof(struct qla25xx_fw_dump, ext_mem):
+                   offsetof(struct qla24xx_fw_dump, ext_mem);
                mem_size = (ha->fw_memory_size - 0x100000 + 1) *
                    sizeof(uint32_t);
 
@@ -879,7 +895,7 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
        uint32_t srisc_address = 0;
 
        /* Load firmware sequences */
-       rval = ha->isp_ops.load_risc(ha, &srisc_address);
+       rval = ha->isp_ops->load_risc(ha, &srisc_address);
        if (rval == QLA_SUCCESS) {
                DEBUG(printk("scsi(%ld): Verifying Checksum of loaded RISC "
                    "code.\n", ha->host_no));
@@ -1130,12 +1146,12 @@ qla2x00_init_rings(scsi_qla_host_t *ha)
        /* Initialize response queue entries */
        qla2x00_init_response_q_entries(ha);
 
-       ha->isp_ops.config_rings(ha);
+       ha->isp_ops->config_rings(ha);
 
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
        /* Update any ISP specific firmware options before initialization. */
-       ha->isp_ops.update_fw_options(ha);
+       ha->isp_ops->update_fw_options(ha);
 
        DEBUG(printk("scsi(%ld): Issue init firmware.\n", ha->host_no));
 
@@ -1459,7 +1475,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
                        ha->nvram_base = 0x80;
 
        /* Get NVRAM data and calculate checksum. */
-       ha->isp_ops.read_nvram(ha, ptr, ha->nvram_base, ha->nvram_size);
+       ha->isp_ops->read_nvram(ha, ptr, ha->nvram_base, ha->nvram_size);
        for (cnt = 0, chksum = 0; cnt < ha->nvram_size; cnt++)
                chksum += *ptr++;
 
@@ -2119,7 +2135,7 @@ qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
        int rval;
        uint16_t port_speed, mb[6];
 
-       if (!IS_QLA24XX(ha))
+       if (!IS_IIDMA_CAPABLE(ha))
                return;
 
        switch (be16_to_cpu(fcport->fp_speed)) {
@@ -2267,7 +2283,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
        scsi_qla_host_t *pha = to_qla_parent(ha);
 
        /* If FL port exists, then SNS is present */
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
+       if (IS_FWI2_CAPABLE(ha))
                loop_id = NPH_F_PORT;
        else
                loop_id = SNS_FL_PORT;
@@ -2294,11 +2310,11 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
                        qla2x00_fdmi_register(ha);
 
                /* Ensure we are logged into the SNS. */
-               if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
+               if (IS_FWI2_CAPABLE(ha))
                        loop_id = NPH_SNS;
                else
                        loop_id = SIMPLE_NAME_SERVER;
-               ha->isp_ops.fabric_login(ha, loop_id, 0xff, 0xff,
+               ha->isp_ops->fabric_login(ha, loop_id, 0xff, 0xff,
                    0xfc, mb, BIT_1 | BIT_0);
                if (mb[0] != MBS_COMMAND_COMPLETE) {
                        DEBUG2(qla_printk(KERN_INFO, ha,
@@ -2355,7 +2371,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
                                    (fcport->flags & FCF_TAPE_PRESENT) == 0 &&
                                    fcport->port_type != FCT_INITIATOR &&
                                    fcport->port_type != FCT_BROADCAST) {
-                                       ha->isp_ops.fabric_logout(ha,
+                                       ha->isp_ops->fabric_logout(ha,
                                            fcport->loop_id,
                                            fcport->d_id.b.domain,
                                            fcport->d_id.b.area,
@@ -2664,7 +2680,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
                            (fcport->flags & FCF_TAPE_PRESENT) == 0 &&
                            fcport->port_type != FCT_INITIATOR &&
                            fcport->port_type != FCT_BROADCAST) {
-                               ha->isp_ops.fabric_logout(ha, fcport->loop_id,
+                               ha->isp_ops->fabric_logout(ha, fcport->loop_id,
                                    fcport->d_id.b.domain, fcport->d_id.b.area,
                                    fcport->d_id.b.al_pa);
                                fcport->loop_id = FC_NO_LOOP_ID;
@@ -2919,7 +2935,7 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *ha, fc_port_t *fcport,
                        opts |= BIT_1;
                rval = qla2x00_get_port_database(ha, fcport, opts);
                if (rval != QLA_SUCCESS) {
-                       ha->isp_ops.fabric_logout(ha, fcport->loop_id,
+                       ha->isp_ops->fabric_logout(ha, fcport->loop_id,
                            fcport->d_id.b.domain, fcport->d_id.b.area,
                            fcport->d_id.b.al_pa);
                        qla2x00_mark_device_lost(ha, fcport, 1, 0);
@@ -2964,7 +2980,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport,
                    fcport->d_id.b.area, fcport->d_id.b.al_pa));
 
                /* Login fcport on switch. */
-               ha->isp_ops.fabric_login(ha, fcport->loop_id,
+               ha->isp_ops->fabric_login(ha, fcport->loop_id,
                    fcport->d_id.b.domain, fcport->d_id.b.area,
                    fcport->d_id.b.al_pa, mb, BIT_0);
                if (mb[0] == MBS_PORT_ID_USED) {
@@ -3032,7 +3048,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport,
                         * dead.
                         */
                        *next_loopid = fcport->loop_id;
-                       ha->isp_ops.fabric_logout(ha, fcport->loop_id,
+                       ha->isp_ops->fabric_logout(ha, fcport->loop_id,
                            fcport->d_id.b.domain, fcport->d_id.b.area,
                            fcport->d_id.b.al_pa);
                        qla2x00_mark_device_lost(ha, fcport, 1, 0);
@@ -3050,7 +3066,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport,
                            fcport->d_id.b.al_pa, fcport->loop_id, jiffies));
 
                        *next_loopid = fcport->loop_id;
-                       ha->isp_ops.fabric_logout(ha, fcport->loop_id,
+                       ha->isp_ops->fabric_logout(ha, fcport->loop_id,
                            fcport->d_id.b.domain, fcport->d_id.b.area,
                            fcport->d_id.b.al_pa);
                        fcport->loop_id = FC_NO_LOOP_ID;
@@ -3206,7 +3222,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
 
                qla_printk(KERN_INFO, ha,
                    "Performing ISP error recovery - ha= %p.\n", ha);
-               ha->isp_ops.reset_chip(ha);
+               ha->isp_ops->reset_chip(ha);
 
                atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
                if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
@@ -3232,9 +3248,9 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
                }
                spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
-               ha->isp_ops.get_flash_version(ha, ha->request_ring);
+               ha->isp_ops->get_flash_version(ha, ha->request_ring);
 
-               ha->isp_ops.nvram_config(ha);
+               ha->isp_ops->nvram_config(ha);
 
                if (!qla2x00_restart_isp(ha)) {
                        clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
@@ -3249,7 +3265,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
 
                        ha->flags.online = 1;
 
-                       ha->isp_ops.enable_intrs(ha);
+                       ha->isp_ops->enable_intrs(ha);
 
                        ha->isp_abort_cnt = 0;
                        clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags);
@@ -3274,7 +3290,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
                                         * The next call disables the board
                                         * completely.
                                         */
-                                       ha->isp_ops.reset_adapter(ha);
+                                       ha->isp_ops->reset_adapter(ha);
                                        ha->flags.online = 0;
                                        clear_bit(ISP_ABORT_RETRY,
                                            &ha->dpc_flags);
@@ -3331,7 +3347,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha)
        /* If firmware needs to be loaded */
        if (qla2x00_isp_firmware(ha)) {
                ha->flags.online = 0;
-               if (!(status = ha->isp_ops.chip_diag(ha))) {
+               if (!(status = ha->isp_ops->chip_diag(ha))) {
                        if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
                                status = qla2x00_setup_chip(ha);
                                goto done;
@@ -3423,7 +3439,7 @@ qla2x00_reset_adapter(scsi_qla_host_t *ha)
        struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
        ha->flags.online = 0;
-       ha->isp_ops.disable_intrs(ha);
+       ha->isp_ops->disable_intrs(ha);
 
        spin_lock_irqsave(&ha->hardware_lock, flags);
        WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
@@ -3440,7 +3456,7 @@ qla24xx_reset_adapter(scsi_qla_host_t *ha)
        struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
 
        ha->flags.online = 0;
-       ha->isp_ops.disable_intrs(ha);
+       ha->isp_ops->disable_intrs(ha);
 
        spin_lock_irqsave(&ha->hardware_lock, flags);
        WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
@@ -3498,7 +3514,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
 
        /* Get NVRAM data and calculate checksum. */
        dptr = (uint32_t *)nv;
-       ha->isp_ops.read_nvram(ha, (uint8_t *)dptr, ha->nvram_base,
+       ha->isp_ops->read_nvram(ha, (uint8_t *)dptr, ha->nvram_base,
            ha->nvram_size);
        for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++)
                chksum += le32_to_cpu(*dptr++);
@@ -4012,7 +4028,7 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha)
 {
        int ret, retries;
 
-       if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
+       if (!IS_FWI2_CAPABLE(ha))
                return;
        if (!ha->fw_major_version)
                return;
index d3023338628ff844560baea4c84dd6f43faa8599..8e3b04464cff26903b69a87a164ec34f58176ac2 100644 (file)
@@ -104,7 +104,7 @@ static __inline__ void qla2x00_poll(scsi_qla_host_t *);
 static inline void
 qla2x00_poll(scsi_qla_host_t *ha)
 {
-       ha->isp_ops.intr_handler(0, ha);
+       ha->isp_ops->intr_handler(0, ha);
 }
 
 static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *);
@@ -163,7 +163,7 @@ static inline int qla2x00_is_reserved_id(scsi_qla_host_t *, uint16_t);
 static inline int
 qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id)
 {
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
+       if (IS_FWI2_CAPABLE(ha))
                return (loop_id > NPH_LAST_HANDLE);
 
        return ((loop_id > ha->last_loop_id && loop_id < SNS_FIRST_LOOP_ID) ||
index c71863ff5489e7db2ba9445fdc3d381f133fc7a6..3a5e78cb6b3f62c156ba0133a06fdbf00cb6ad35 100644 (file)
@@ -326,7 +326,7 @@ qla2x00_start_scsi(srb_t *sp)
        tot_dsds = nseg;
 
        /* Calculate the number of request entries needed. */
-       req_cnt = ha->isp_ops.calc_req_entries(tot_dsds);
+       req_cnt = ha->isp_ops->calc_req_entries(tot_dsds);
        if (ha->req_q_cnt < (req_cnt + 2)) {
                cnt = RD_REG_WORD_RELAXED(ISP_REQ_Q_OUT(ha, reg));
                if (ha->req_ring_index < cnt)
@@ -364,7 +364,7 @@ qla2x00_start_scsi(srb_t *sp)
        cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd));
 
        /* Build IOCB segments */
-       ha->isp_ops.build_iocbs(sp, cmd_pkt, tot_dsds);
+       ha->isp_ops->build_iocbs(sp, cmd_pkt, tot_dsds);
 
        /* Set total data segment count. */
        cmd_pkt->entry_count = (uint8_t)req_cnt;
@@ -432,7 +432,7 @@ __qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun,
        mrk->entry_type = MARKER_TYPE;
        mrk->modifier = type;
        if (type != MK_SYNC_ALL) {
-               if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+               if (IS_FWI2_CAPABLE(ha)) {
                        mrk24 = (struct mrk_entry_24xx *) mrk;
                        mrk24->nport_handle = cpu_to_le16(loop_id);
                        mrk24->lun[1] = LSB(lun);
@@ -487,7 +487,7 @@ qla2x00_req_pkt(scsi_qla_host_t *ha)
        for (timer = HZ; timer; timer--) {
                if ((req_cnt + 2) >= ha->req_q_cnt) {
                        /* Calculate number of free request entries. */
-                       if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
+                       if (IS_FWI2_CAPABLE(ha))
                                cnt = (uint16_t)RD_REG_DWORD(
                                    &reg->isp24.req_q_out);
                        else
@@ -561,7 +561,7 @@ qla2x00_isp_cmd(scsi_qla_host_t *ha)
                ha->request_ring_ptr++;
 
        /* Set chip new ring index. */
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (IS_FWI2_CAPABLE(ha)) {
                WRT_REG_DWORD(&reg->isp24.req_q_in, ha->req_ring_index);
                RD_REG_DWORD_RELAXED(&reg->isp24.req_q_in);
        } else {
index 0ba4c8d378790c759071cba64dbbb635809a6cd8..b8f226ae26334290eb9698bd3524eae2eba683a4 100644 (file)
@@ -143,7 +143,7 @@ qla2300_intr_handler(int irq, void *dev_id)
                        WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
                        RD_REG_WORD(&reg->hccr);
 
-                       ha->isp_ops.fw_dump(ha, 1);
+                       ha->isp_ops->fw_dump(ha, 1);
                        set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
                        break;
                } else if ((stat & HSR_RISC_INT) == 0)
@@ -247,7 +247,7 @@ void
 qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 {
 #define LS_UNKNOWN     2
-       static char     *link_speeds[5] = { "1", "2", "?", "4", "10" };
+       static char     *link_speeds[5] = { "1", "2", "?", "4", "8" };
        char            *link_speed;
        uint16_t        handle_cnt;
        uint16_t        cnt;
@@ -334,9 +334,9 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
                    "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n",
                    mb[1], mb[2], mb[3]);
 
-               ha->isp_ops.fw_dump(ha, 1);
+               ha->isp_ops->fw_dump(ha, 1);
 
-               if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+               if (IS_FWI2_CAPABLE(ha)) {
                        if (mb[1] == 0 && mb[2] == 0) {
                                qla_printk(KERN_ERR, ha,
                                    "Unrecoverable Hardware Error: adapter "
@@ -601,7 +601,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
                    "scsi(%ld): [R|Z]IO update completion.\n",
                    ha->host_no));
 
-               if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
+               if (IS_FWI2_CAPABLE(ha))
                        qla24xx_process_response_queue(ha);
                else
                        qla2x00_process_response_queue(ha);
@@ -823,7 +823,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
 
        sts = (sts_entry_t *) pkt;
        sts24 = (struct sts_entry_24xx *) pkt;
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (IS_FWI2_CAPABLE(ha)) {
                comp_status = le16_to_cpu(sts24->comp_status);
                scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
        } else {
@@ -872,7 +872,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
        fcport = sp->fcport;
 
        sense_len = rsp_info_len = resid_len = fw_resid_len = 0;
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (IS_FWI2_CAPABLE(ha)) {
                sense_len = le32_to_cpu(sts24->sense_len);
                rsp_info_len = le32_to_cpu(sts24->rsp_data_len);
                resid_len = le32_to_cpu(sts24->rsp_residual_count);
@@ -891,7 +891,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
        /* Check for any FCP transport errors. */
        if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) {
                /* Sense data lies beyond any FCP RESPONSE data. */
-               if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
+               if (IS_FWI2_CAPABLE(ha))
                        sense_data += rsp_info_len;
                if (rsp_info_len > 3 && rsp_info[3]) {
                        DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol "
@@ -990,7 +990,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
        case CS_DATA_UNDERRUN:
                resid = resid_len;
                /* Use F/W calculated residual length. */
-               if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
+               if (IS_FWI2_CAPABLE(ha))
                        resid = fw_resid_len;
 
                if (scsi_status & SS_RESIDUAL_UNDER) {
@@ -1062,6 +1062,25 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
                            cp->device->id, cp->device->lun, cp,
                            cp->serial_number));
 
+                       /*
+                        * In case of a Underrun condition, set both the lscsi
+                        * status and the completion status to appropriate
+                        * values.
+                        */
+                       if (resid &&
+                           ((unsigned)(cp->request_bufflen - resid) <
+                            cp->underflow)) {
+                               DEBUG2(qla_printk(KERN_INFO, ha,
+                                   "scsi(%ld:%d:%d:%d): Mid-layer underflow "
+                                   "detected (%x of %x bytes)...returning "
+                                   "error status.\n", ha->host_no,
+                                   cp->device->channel, cp->device->id,
+                                   cp->device->lun, resid,
+                                   cp->request_bufflen));
+
+                               cp->result = DID_ERROR << 16 | lscsi_status;
+                       }
+
                        if (sense_len)
                                DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
                                    CMD_ACTUAL_SNSLEN(cp)));
@@ -1166,7 +1185,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
        case CS_TIMEOUT:
                cp->result = DID_BUS_BUSY << 16;
 
-               if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+               if (IS_FWI2_CAPABLE(ha)) {
                        DEBUG2(printk(KERN_INFO
                            "scsi(%ld:%d:%d:%d): TIMEOUT status detected "
                            "0x%x-0x%x\n", ha->host_no, cp->device->channel,
@@ -1235,7 +1254,7 @@ qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt)
                }
 
                /* Move sense data. */
-               if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
+               if (IS_FWI2_CAPABLE(ha))
                        host_to_fcp_swap(pkt->data, sizeof(pkt->data));
                memcpy(sp->request_sense_ptr, pkt->data, sense_sz);
                DEBUG5(qla2x00_dump_buffer(sp->request_sense_ptr, sense_sz));
@@ -1483,7 +1502,7 @@ qla24xx_intr_handler(int irq, void *dev_id)
 
                        qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
                            "Dumping firmware!\n", hccr);
-                       ha->isp_ops.fw_dump(ha, 1);
+                       ha->isp_ops->fw_dump(ha, 1);
                        set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
                        break;
                } else if ((stat & HSRX_RISC_INT) == 0)
@@ -1617,7 +1636,7 @@ qla24xx_msix_default(int irq, void *dev_id)
 
                        qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
                            "Dumping firmware!\n", hccr);
-                       ha->isp_ops.fw_dump(ha, 1);
+                       ha->isp_ops->fw_dump(ha, 1);
                        set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
                        break;
                } else if ((stat & HSRX_RISC_INT) == 0)
@@ -1739,11 +1758,11 @@ qla2x00_request_irqs(scsi_qla_host_t *ha)
        int ret;
 
        /* If possible, enable MSI-X. */
-       if (!IS_QLA2432(ha))
+       if (!IS_QLA2432(ha) && !IS_QLA2532(ha))
                goto skip_msix;
 
-        if (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX ||
-           !QLA_MSIX_FW_MODE_1(ha->fw_attributes)) {
+        if (IS_QLA2432(ha) && (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX ||
+           !QLA_MSIX_FW_MODE_1(ha->fw_attributes))) {
                DEBUG2(qla_printk(KERN_WARNING, ha,
                    "MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n",
                    ha->chip_revision, ha->fw_attributes));
@@ -1762,7 +1781,7 @@ qla2x00_request_irqs(scsi_qla_host_t *ha)
            "MSI-X: Falling back-to INTa mode -- %d.\n", ret);
 skip_msix:
 
-       if (!IS_QLA24XX(ha))
+       if (!IS_QLA24XX(ha) && !IS_QLA2532(ha))
                goto skip_msi;
 
        ret = pci_enable_msi(ha->pdev);
@@ -1772,7 +1791,7 @@ skip_msix:
        }
 skip_msi:
 
-       ret = request_irq(ha->pdev->irq, ha->isp_ops.intr_handler,
+       ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
            IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, ha);
        if (!ret) {
                ha->flags.inta_enabled = 1;
index 2cd0cff25928453440d2889aee4f806d726eae6d..d3746ec80a857a3e1b9557378055382259b72dca 100644 (file)
@@ -90,7 +90,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *pvha, mbx_cmd_t *mcp)
        spin_lock_irqsave(&ha->hardware_lock, flags);
 
        /* Load mailbox registers. */
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
+       if (IS_FWI2_CAPABLE(ha))
                optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
        else
                optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
@@ -154,7 +154,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *pvha, mbx_cmd_t *mcp)
 
                set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
 
-               if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
+               if (IS_FWI2_CAPABLE(ha))
                        WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
                else
                        WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
@@ -175,7 +175,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *pvha, mbx_cmd_t *mcp)
                DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__,
                    ha->host_no, command));
 
-               if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
+               if (IS_FWI2_CAPABLE(ha))
                        WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
                else
                        WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
@@ -228,7 +228,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *pvha, mbx_cmd_t *mcp)
                uint16_t mb0;
                uint32_t ictrl;
 
-               if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+               if (IS_FWI2_CAPABLE(ha)) {
                        mb0 = RD_REG_WORD(&reg->isp24.mailbox0);
                        ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
                } else {
@@ -322,7 +322,7 @@ qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t risc_addr,
 
        DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
 
-       if (MSW(risc_addr) || IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {
                mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
                mcp->mb[8] = MSW(risc_addr);
                mcp->out_mb = MBX_8|MBX_0;
@@ -336,7 +336,7 @@ qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t risc_addr,
        mcp->mb[6] = MSW(MSD(req_dma));
        mcp->mb[7] = LSW(MSD(req_dma));
        mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (IS_FWI2_CAPABLE(ha)) {
                mcp->mb[4] = MSW(risc_code_size);
                mcp->mb[5] = LSW(risc_code_size);
                mcp->out_mb |= MBX_5|MBX_4;
@@ -387,7 +387,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr)
        mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
        mcp->out_mb = MBX_0;
        mcp->in_mb = MBX_0;
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (IS_FWI2_CAPABLE(ha)) {
                mcp->mb[1] = MSW(risc_addr);
                mcp->mb[2] = LSW(risc_addr);
                mcp->mb[3] = 0;
@@ -410,7 +410,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr)
                DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n", __func__,
                    ha->host_no, rval, mcp->mb[0]));
        } else {
-               if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+               if (IS_FWI2_CAPABLE(ha)) {
                        DEBUG11(printk("%s(%ld): done exchanges=%x.\n",
                            __func__, ha->host_no, mcp->mb[1]));
                } else {
@@ -551,7 +551,7 @@ qla2x00_set_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts)
        mcp->mb[3] = fwopts[3];
        mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
        mcp->in_mb = MBX_0;
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (IS_FWI2_CAPABLE(ha)) {
                mcp->in_mb |= MBX_1;
        } else {
                mcp->mb[10] = fwopts[10];
@@ -664,7 +664,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr)
        mcp->mb[0] = MBC_VERIFY_CHECKSUM;
        mcp->out_mb = MBX_0;
        mcp->in_mb = MBX_0;
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (IS_FWI2_CAPABLE(ha)) {
                mcp->mb[1] = MSW(risc_addr);
                mcp->mb[2] = LSW(risc_addr);
                mcp->out_mb |= MBX_2|MBX_1;
@@ -681,8 +681,8 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr)
 
        if (rval != QLA_SUCCESS) {
                DEBUG2_3_11(printk("%s(%ld): failed=%x chk sum=%x.\n", __func__,
-                   ha->host_no, rval, (IS_QLA24XX(ha) || IS_QLA54XX(ha) ?
-                   (mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1])));
+                   ha->host_no, rval, IS_FWI2_CAPABLE(ha) ?
+                   (mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1]));
        } else {
                DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
        }
@@ -739,7 +739,7 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void*  buffer, dma_addr_t phys_addr,
 
                /* Mask reserved bits. */
                sts_entry->entry_status &=
-                   IS_QLA24XX(ha) || IS_QLA54XX(ha) ? RF_MASK_24XX :RF_MASK;
+                   IS_FWI2_CAPABLE(ha) ? RF_MASK_24XX :RF_MASK;
        }
 
        return rval;
@@ -1085,7 +1085,7 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt)
        memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
 
        mcp->mb[0] = MBC_GET_PORT_DATABASE;
-       if (opt != 0 && !IS_QLA24XX(ha) && !IS_QLA54XX(ha))
+       if (opt != 0 && !IS_FWI2_CAPABLE(ha))
                mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
        mcp->mb[2] = MSW(pd_dma);
        mcp->mb[3] = LSW(pd_dma);
@@ -1094,7 +1094,7 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt)
        mcp->mb[9] = ha->vp_idx;
        mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
        mcp->in_mb = MBX_0;
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (IS_FWI2_CAPABLE(ha)) {
                mcp->mb[1] = fcport->loop_id;
                mcp->mb[10] = opt;
                mcp->out_mb |= MBX_10|MBX_1;
@@ -1107,15 +1107,15 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt)
                mcp->mb[1] = fcport->loop_id << 8 | opt;
                mcp->out_mb |= MBX_1;
        }
-       mcp->buf_size = (IS_QLA24XX(ha) || IS_QLA54XX(ha) ?
-           PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE);
+       mcp->buf_size = IS_FWI2_CAPABLE(ha) ?
+           PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;
        mcp->flags = MBX_DMA_IN;
        mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
        rval = qla2x00_mailbox_command(ha, mcp);
        if (rval != QLA_SUCCESS)
                goto gpd_error_out;
 
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (IS_FWI2_CAPABLE(ha)) {
                pd24 = (struct port_database_24xx *) pd;
 
                /* Check for logged in state. */
@@ -1333,7 +1333,7 @@ qla2x00_lip_reset(scsi_qla_host_t *ha)
 
        DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
 
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (IS_FWI2_CAPABLE(ha)) {
                mcp->mb[0] = MBC_LIP_FULL_LOGIN;
                mcp->mb[1] = BIT_6;
                mcp->mb[2] = 0;
@@ -1637,7 +1637,7 @@ qla2x00_login_local_device(scsi_qla_host_t *ha, fc_port_t *fcport,
        mbx_cmd_t mc;
        mbx_cmd_t *mcp = &mc;
 
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
+       if (IS_FWI2_CAPABLE(ha))
                return qla24xx_login_fabric(ha, fcport->loop_id,
                    fcport->d_id.b.domain, fcport->d_id.b.area,
                    fcport->d_id.b.al_pa, mb_ret, opt);
@@ -1821,7 +1821,7 @@ qla2x00_full_login_lip(scsi_qla_host_t *ha)
            ha->host_no));
 
        mcp->mb[0] = MBC_LIP_FULL_LOGIN;
-       mcp->mb[1] = IS_QLA24XX(ha) || IS_QLA54XX(ha) ? BIT_3: 0;
+       mcp->mb[1] = IS_FWI2_CAPABLE(ha) ? BIT_3: 0;
        mcp->mb[2] = 0;
        mcp->mb[3] = 0;
        mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
@@ -1871,7 +1871,7 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma,
 
        mcp->mb[0] = MBC_GET_ID_LIST;
        mcp->out_mb = MBX_0;
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (IS_FWI2_CAPABLE(ha)) {
                mcp->mb[2] = MSW(id_list_dma);
                mcp->mb[3] = LSW(id_list_dma);
                mcp->mb[6] = MSW(MSD(id_list_dma));
@@ -2063,7 +2063,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id,
        mcp->mb[7] = LSW(MSD(stat_buf_dma));
        mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
        mcp->in_mb = MBX_0;
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (IS_FWI2_CAPABLE(ha)) {
                mcp->mb[1] = loop_id;
                mcp->mb[4] = 0;
                mcp->mb[10] = 0;
@@ -2334,7 +2334,7 @@ qla2x00_system_error(scsi_qla_host_t *ha)
        mbx_cmd_t mc;
        mbx_cmd_t *mcp = &mc;
 
-       if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
+       if (!IS_FWI2_CAPABLE(ha))
                return QLA_FUNCTION_FAILED;
 
        DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
@@ -2444,7 +2444,7 @@ qla2x00_stop_firmware(scsi_qla_host_t *ha)
        mbx_cmd_t mc;
        mbx_cmd_t *mcp = &mc;
 
-       if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
+       if (!IS_FWI2_CAPABLE(ha))
                return QLA_FUNCTION_FAILED;
 
        DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
@@ -2474,7 +2474,7 @@ qla2x00_trace_control(scsi_qla_host_t *ha, uint16_t ctrl, dma_addr_t eft_dma,
        mbx_cmd_t mc;
        mbx_cmd_t *mcp = &mc;
 
-       if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
+       if (!IS_FWI2_CAPABLE(ha))
                return QLA_FUNCTION_FAILED;
 
        DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
@@ -2514,7 +2514,7 @@ qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr,
        mbx_cmd_t mc;
        mbx_cmd_t *mcp = &mc;
 
-       if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha))
+       if (!IS_FWI2_CAPABLE(ha))
                return QLA_FUNCTION_FAILED;
 
        DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
@@ -2552,7 +2552,7 @@ qla2x00_get_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id,
        mbx_cmd_t mc;
        mbx_cmd_t *mcp = &mc;
 
-       if (!IS_QLA24XX(ha))
+       if (!IS_IIDMA_CAPABLE(ha))
                return QLA_FUNCTION_FAILED;
 
        DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
@@ -2595,7 +2595,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id,
        mbx_cmd_t mc;
        mbx_cmd_t *mcp = &mc;
 
-       if (!IS_QLA24XX(ha))
+       if (!IS_IIDMA_CAPABLE(ha))
                return QLA_FUNCTION_FAILED;
 
        DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
index 92376f9dfdd50b057f5a9e70c15be322fa015dfe..c488996cb95873503ef544ba9b4328ee7ae60a17 100644 (file)
@@ -265,6 +265,8 @@ qla24xx_pci_info_str(struct scsi_qla_host *ha, char *str)
                strcpy(str, "PCIe (");
                if (lspeed == 1)
                        strcat(str, "2.5Gb/s ");
+               else if (lspeed == 2)
+                       strcat(str, "5.0Gb/s ");
                else
                        strcat(str, "<unknown> ");
                snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth);
@@ -343,6 +345,12 @@ qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str)
                strcat(str, "[IP] ");
        if (ha->fw_attributes & BIT_2)
                strcat(str, "[Multi-ID] ");
+       if (ha->fw_attributes & BIT_3)
+               strcat(str, "[SB-2] ");
+       if (ha->fw_attributes & BIT_4)
+               strcat(str, "[T10 CRC] ");
+       if (ha->fw_attributes & BIT_5)
+               strcat(str, "[VI] ");
        if (ha->fw_attributes & BIT_13)
                strcat(str, "[Experimental]");
        return str;
@@ -681,7 +689,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
                DEBUG3(qla2x00_print_scsi_cmd(cmd));
 
                spin_unlock_irqrestore(&pha->hardware_lock, flags);
-               if (ha->isp_ops.abort_command(ha, sp)) {
+               if (ha->isp_ops->abort_command(ha, sp)) {
                        DEBUG2(printk("%s(%ld): abort_command "
                            "mbx failed.\n", __func__, ha->host_no));
                } else {
@@ -813,7 +821,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
 #if defined(LOGOUT_AFTER_DEVICE_RESET)
                if (ret == SUCCESS) {
                        if (fcport->flags & FC_FABRIC_DEVICE) {
-                               ha->isp_ops.fabric_logout(ha, fcport->loop_id);
+                               ha->isp_ops->fabric_logout(ha, fcport->loop_id);
                                qla2x00_mark_device_lost(ha, fcport, 0, 0);
                        }
                }
@@ -1105,7 +1113,7 @@ static int
 qla2x00_device_reset(scsi_qla_host_t *ha, fc_port_t *reset_fcport)
 {
        /* Abort Target command will clear Reservation */
-       return ha->isp_ops.abort_target(reset_fcport);
+       return ha->isp_ops->abort_target(reset_fcport);
 }
 
 static int
@@ -1184,8 +1192,8 @@ qla2x00_config_dma_addressing(scsi_qla_host_t *ha)
                    !pci_set_consistent_dma_mask(ha->pdev, DMA_64BIT_MASK)) {
                        /* Ok, a 64bit DMA mask is applicable. */
                        ha->flags.enable_64bit_addressing = 1;
-                       ha->isp_ops.calc_req_entries = qla2x00_calc_iocbs_64;
-                       ha->isp_ops.build_iocbs = qla2x00_build_scsi_iocbs_64;
+                       ha->isp_ops->calc_req_entries = qla2x00_calc_iocbs_64;
+                       ha->isp_ops->build_iocbs = qla2x00_build_scsi_iocbs_64;
                        return;
                }
        }
@@ -1194,6 +1202,193 @@ qla2x00_config_dma_addressing(scsi_qla_host_t *ha)
        pci_set_consistent_dma_mask(ha->pdev, DMA_32BIT_MASK);
 }
 
+static void
+qla2x00_enable_intrs(scsi_qla_host_t *ha)
+{
+       unsigned long flags = 0;
+       struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       ha->interrupts_on = 1;
+       /* enable risc and host interrupts */
+       WRT_REG_WORD(&reg->ictrl, ICR_EN_INT | ICR_EN_RISC);
+       RD_REG_WORD(&reg->ictrl);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+}
+
+static void
+qla2x00_disable_intrs(scsi_qla_host_t *ha)
+{
+       unsigned long flags = 0;
+       struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       ha->interrupts_on = 0;
+       /* disable risc and host interrupts */
+       WRT_REG_WORD(&reg->ictrl, 0);
+       RD_REG_WORD(&reg->ictrl);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+static void
+qla24xx_enable_intrs(scsi_qla_host_t *ha)
+{
+       unsigned long flags = 0;
+       struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       ha->interrupts_on = 1;
+       WRT_REG_DWORD(&reg->ictrl, ICRX_EN_RISC_INT);
+       RD_REG_DWORD(&reg->ictrl);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+static void
+qla24xx_disable_intrs(scsi_qla_host_t *ha)
+{
+       unsigned long flags = 0;
+       struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       ha->interrupts_on = 0;
+       WRT_REG_DWORD(&reg->ictrl, 0);
+       RD_REG_DWORD(&reg->ictrl);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+static struct isp_operations qla2100_isp_ops = {
+       .pci_config             = qla2100_pci_config,
+       .reset_chip             = qla2x00_reset_chip,
+       .chip_diag              = qla2x00_chip_diag,
+       .config_rings           = qla2x00_config_rings,
+       .reset_adapter          = qla2x00_reset_adapter,
+       .nvram_config           = qla2x00_nvram_config,
+       .update_fw_options      = qla2x00_update_fw_options,
+       .load_risc              = qla2x00_load_risc,
+       .pci_info_str           = qla2x00_pci_info_str,
+       .fw_version_str         = qla2x00_fw_version_str,
+       .intr_handler           = qla2100_intr_handler,
+       .enable_intrs           = qla2x00_enable_intrs,
+       .disable_intrs          = qla2x00_disable_intrs,
+       .abort_command          = qla2x00_abort_command,
+       .abort_target           = qla2x00_abort_target,
+       .fabric_login           = qla2x00_login_fabric,
+       .fabric_logout          = qla2x00_fabric_logout,
+       .calc_req_entries       = qla2x00_calc_iocbs_32,
+       .build_iocbs            = qla2x00_build_scsi_iocbs_32,
+       .prep_ms_iocb           = qla2x00_prep_ms_iocb,
+       .prep_ms_fdmi_iocb      = qla2x00_prep_ms_fdmi_iocb,
+       .read_nvram             = qla2x00_read_nvram_data,
+       .write_nvram            = qla2x00_write_nvram_data,
+       .fw_dump                = qla2100_fw_dump,
+       .beacon_on              = NULL,
+       .beacon_off             = NULL,
+       .beacon_blink           = NULL,
+       .read_optrom            = qla2x00_read_optrom_data,
+       .write_optrom           = qla2x00_write_optrom_data,
+       .get_flash_version      = qla2x00_get_flash_version,
+};
+
+static struct isp_operations qla2300_isp_ops = {
+       .pci_config             = qla2300_pci_config,
+       .reset_chip             = qla2x00_reset_chip,
+       .chip_diag              = qla2x00_chip_diag,
+       .config_rings           = qla2x00_config_rings,
+       .reset_adapter          = qla2x00_reset_adapter,
+       .nvram_config           = qla2x00_nvram_config,
+       .update_fw_options      = qla2x00_update_fw_options,
+       .load_risc              = qla2x00_load_risc,
+       .pci_info_str           = qla2x00_pci_info_str,
+       .fw_version_str         = qla2x00_fw_version_str,
+       .intr_handler           = qla2300_intr_handler,
+       .enable_intrs           = qla2x00_enable_intrs,
+       .disable_intrs          = qla2x00_disable_intrs,
+       .abort_command          = qla2x00_abort_command,
+       .abort_target           = qla2x00_abort_target,
+       .fabric_login           = qla2x00_login_fabric,
+       .fabric_logout          = qla2x00_fabric_logout,
+       .calc_req_entries       = qla2x00_calc_iocbs_32,
+       .build_iocbs            = qla2x00_build_scsi_iocbs_32,
+       .prep_ms_iocb           = qla2x00_prep_ms_iocb,
+       .prep_ms_fdmi_iocb      = qla2x00_prep_ms_fdmi_iocb,
+       .read_nvram             = qla2x00_read_nvram_data,
+       .write_nvram            = qla2x00_write_nvram_data,
+       .fw_dump                = qla2300_fw_dump,
+       .beacon_on              = qla2x00_beacon_on,
+       .beacon_off             = qla2x00_beacon_off,
+       .beacon_blink           = qla2x00_beacon_blink,
+       .read_optrom            = qla2x00_read_optrom_data,
+       .write_optrom           = qla2x00_write_optrom_data,
+       .get_flash_version      = qla2x00_get_flash_version,
+};
+
+static struct isp_operations qla24xx_isp_ops = {
+       .pci_config             = qla24xx_pci_config,
+       .reset_chip             = qla24xx_reset_chip,
+       .chip_diag              = qla24xx_chip_diag,
+       .config_rings           = qla24xx_config_rings,
+       .reset_adapter          = qla24xx_reset_adapter,
+       .nvram_config           = qla24xx_nvram_config,
+       .update_fw_options      = qla24xx_update_fw_options,
+       .load_risc              = qla24xx_load_risc,
+       .pci_info_str           = qla24xx_pci_info_str,
+       .fw_version_str         = qla24xx_fw_version_str,
+       .intr_handler           = qla24xx_intr_handler,
+       .enable_intrs           = qla24xx_enable_intrs,
+       .disable_intrs          = qla24xx_disable_intrs,
+       .abort_command          = qla24xx_abort_command,
+       .abort_target           = qla24xx_abort_target,
+       .fabric_login           = qla24xx_login_fabric,
+       .fabric_logout          = qla24xx_fabric_logout,
+       .calc_req_entries       = NULL,
+       .build_iocbs            = NULL,
+       .prep_ms_iocb           = qla24xx_prep_ms_iocb,
+       .prep_ms_fdmi_iocb      = qla24xx_prep_ms_fdmi_iocb,
+       .read_nvram             = qla24xx_read_nvram_data,
+       .write_nvram            = qla24xx_write_nvram_data,
+       .fw_dump                = qla24xx_fw_dump,
+       .beacon_on              = qla24xx_beacon_on,
+       .beacon_off             = qla24xx_beacon_off,
+       .beacon_blink           = qla24xx_beacon_blink,
+       .read_optrom            = qla24xx_read_optrom_data,
+       .write_optrom           = qla24xx_write_optrom_data,
+       .get_flash_version      = qla24xx_get_flash_version,
+};
+
+static struct isp_operations qla25xx_isp_ops = {
+       .pci_config             = qla25xx_pci_config,
+       .reset_chip             = qla24xx_reset_chip,
+       .chip_diag              = qla24xx_chip_diag,
+       .config_rings           = qla24xx_config_rings,
+       .reset_adapter          = qla24xx_reset_adapter,
+       .nvram_config           = qla24xx_nvram_config,
+       .update_fw_options      = qla24xx_update_fw_options,
+       .load_risc              = qla24xx_load_risc,
+       .pci_info_str           = qla24xx_pci_info_str,
+       .fw_version_str         = qla24xx_fw_version_str,
+       .intr_handler           = qla24xx_intr_handler,
+       .enable_intrs           = qla24xx_enable_intrs,
+       .disable_intrs          = qla24xx_disable_intrs,
+       .abort_command          = qla24xx_abort_command,
+       .abort_target           = qla24xx_abort_target,
+       .fabric_login           = qla24xx_login_fabric,
+       .fabric_logout          = qla24xx_fabric_logout,
+       .calc_req_entries       = NULL,
+       .build_iocbs            = NULL,
+       .prep_ms_iocb           = qla24xx_prep_ms_iocb,
+       .prep_ms_fdmi_iocb      = qla24xx_prep_ms_fdmi_iocb,
+       .read_nvram             = qla25xx_read_nvram_data,
+       .write_nvram            = qla25xx_write_nvram_data,
+       .fw_dump                = qla25xx_fw_dump,
+       .beacon_on              = qla24xx_beacon_on,
+       .beacon_off             = qla24xx_beacon_off,
+       .beacon_blink           = qla24xx_beacon_blink,
+       .read_optrom            = qla24xx_read_optrom_data,
+       .write_optrom           = qla24xx_write_optrom_data,
+       .get_flash_version      = qla24xx_get_flash_version,
+};
+
 static inline void
 qla2x00_set_isp_flags(scsi_qla_host_t *ha)
 {
@@ -1238,19 +1433,32 @@ qla2x00_set_isp_flags(scsi_qla_host_t *ha)
        case PCI_DEVICE_ID_QLOGIC_ISP2422:
                ha->device_type |= DT_ISP2422;
                ha->device_type |= DT_ZIO_SUPPORTED;
+               ha->device_type |= DT_FWI2;
+               ha->device_type |= DT_IIDMA;
                ha->fw_srisc_address = RISC_START_ADDRESS_2400;
                break;
        case PCI_DEVICE_ID_QLOGIC_ISP2432:
                ha->device_type |= DT_ISP2432;
                ha->device_type |= DT_ZIO_SUPPORTED;
+               ha->device_type |= DT_FWI2;
+               ha->device_type |= DT_IIDMA;
                ha->fw_srisc_address = RISC_START_ADDRESS_2400;
                break;
        case PCI_DEVICE_ID_QLOGIC_ISP5422:
                ha->device_type |= DT_ISP5422;
+               ha->device_type |= DT_FWI2;
                ha->fw_srisc_address = RISC_START_ADDRESS_2400;
                break;
        case PCI_DEVICE_ID_QLOGIC_ISP5432:
                ha->device_type |= DT_ISP5432;
+               ha->device_type |= DT_FWI2;
+               ha->fw_srisc_address = RISC_START_ADDRESS_2400;
+               break;
+       case PCI_DEVICE_ID_QLOGIC_ISP2532:
+               ha->device_type |= DT_ISP2532;
+               ha->device_type |= DT_ZIO_SUPPORTED;
+               ha->device_type |= DT_FWI2;
+               ha->device_type |= DT_IIDMA;
                ha->fw_srisc_address = RISC_START_ADDRESS_2400;
                break;
        }
@@ -1322,61 +1530,6 @@ iospace_error_exit:
        return (-ENOMEM);
 }
 
-static void
-qla2x00_enable_intrs(scsi_qla_host_t *ha)
-{
-       unsigned long flags = 0;
-       struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
-
-       spin_lock_irqsave(&ha->hardware_lock, flags);
-       ha->interrupts_on = 1;
-       /* enable risc and host interrupts */
-       WRT_REG_WORD(&reg->ictrl, ICR_EN_INT | ICR_EN_RISC);
-       RD_REG_WORD(&reg->ictrl);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
-
-}
-
-static void
-qla2x00_disable_intrs(scsi_qla_host_t *ha)
-{
-       unsigned long flags = 0;
-       struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
-
-       spin_lock_irqsave(&ha->hardware_lock, flags);
-       ha->interrupts_on = 0;
-       /* disable risc and host interrupts */
-       WRT_REG_WORD(&reg->ictrl, 0);
-       RD_REG_WORD(&reg->ictrl);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
-}
-
-static void
-qla24xx_enable_intrs(scsi_qla_host_t *ha)
-{
-       unsigned long flags = 0;
-       struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
-
-       spin_lock_irqsave(&ha->hardware_lock, flags);
-       ha->interrupts_on = 1;
-       WRT_REG_DWORD(&reg->ictrl, ICRX_EN_RISC_INT);
-       RD_REG_DWORD(&reg->ictrl);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
-}
-
-static void
-qla24xx_disable_intrs(scsi_qla_host_t *ha)
-{
-       unsigned long flags = 0;
-       struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
-
-       spin_lock_irqsave(&ha->hardware_lock, flags);
-       ha->interrupts_on = 0;
-       WRT_REG_DWORD(&reg->ictrl, 0);
-       RD_REG_DWORD(&reg->ictrl);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
-}
-
 static void
 qla2xxx_scan_start(struct Scsi_Host *shost)
 {
@@ -1422,7 +1575,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
            pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 ||
            pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 ||
-           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432)
+           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 ||
+           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532)
                sht = &qla24xx_driver_template;
        host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t));
        if (host == NULL) {
@@ -1466,33 +1620,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
                ha->max_q_depth = ql2xmaxqdepth;
 
        /* Assign ISP specific operations. */
-       ha->isp_ops.pci_config          = qla2100_pci_config;
-       ha->isp_ops.reset_chip          = qla2x00_reset_chip;
-       ha->isp_ops.chip_diag           = qla2x00_chip_diag;
-       ha->isp_ops.config_rings        = qla2x00_config_rings;
-       ha->isp_ops.reset_adapter       = qla2x00_reset_adapter;
-       ha->isp_ops.nvram_config        = qla2x00_nvram_config;
-       ha->isp_ops.update_fw_options   = qla2x00_update_fw_options;
-       ha->isp_ops.load_risc           = qla2x00_load_risc;
-       ha->isp_ops.pci_info_str        = qla2x00_pci_info_str;
-       ha->isp_ops.fw_version_str      = qla2x00_fw_version_str;
-       ha->isp_ops.intr_handler        = qla2100_intr_handler;
-       ha->isp_ops.enable_intrs        = qla2x00_enable_intrs;
-       ha->isp_ops.disable_intrs       = qla2x00_disable_intrs;
-       ha->isp_ops.abort_command       = qla2x00_abort_command;
-       ha->isp_ops.abort_target        = qla2x00_abort_target;
-       ha->isp_ops.fabric_login        = qla2x00_login_fabric;
-       ha->isp_ops.fabric_logout       = qla2x00_fabric_logout;
-       ha->isp_ops.calc_req_entries    = qla2x00_calc_iocbs_32;
-       ha->isp_ops.build_iocbs         = qla2x00_build_scsi_iocbs_32;
-       ha->isp_ops.prep_ms_iocb        = qla2x00_prep_ms_iocb;
-       ha->isp_ops.prep_ms_fdmi_iocb   = qla2x00_prep_ms_fdmi_iocb;
-       ha->isp_ops.read_nvram          = qla2x00_read_nvram_data;
-       ha->isp_ops.write_nvram         = qla2x00_write_nvram_data;
-       ha->isp_ops.fw_dump             = qla2100_fw_dump;
-       ha->isp_ops.read_optrom         = qla2x00_read_optrom_data;
-       ha->isp_ops.write_optrom        = qla2x00_write_optrom_data;
-       ha->isp_ops.get_flash_version   = qla2x00_get_flash_version;
        if (IS_QLA2100(ha)) {
                host->max_id = MAX_TARGETS_2100;
                ha->mbx_count = MAILBOX_REGISTER_COUNT_2100;
@@ -1501,6 +1628,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
                ha->last_loop_id = SNS_LAST_LOOP_ID_2100;
                host->sg_tablesize = 32;
                ha->gid_list_info_size = 4;
+               ha->isp_ops = &qla2100_isp_ops;
        } else if (IS_QLA2200(ha)) {
                host->max_id = MAX_TARGETS_2200;
                ha->mbx_count = MAILBOX_REGISTER_COUNT;
@@ -1508,21 +1636,17 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
                ha->response_q_length = RESPONSE_ENTRY_CNT_2100;
                ha->last_loop_id = SNS_LAST_LOOP_ID_2100;
                ha->gid_list_info_size = 4;
+               ha->isp_ops = &qla2100_isp_ops;
        } else if (IS_QLA23XX(ha)) {
                host->max_id = MAX_TARGETS_2200;
                ha->mbx_count = MAILBOX_REGISTER_COUNT;
                ha->request_q_length = REQUEST_ENTRY_CNT_2200;
                ha->response_q_length = RESPONSE_ENTRY_CNT_2300;
                ha->last_loop_id = SNS_LAST_LOOP_ID_2300;
-               ha->isp_ops.pci_config = qla2300_pci_config;
-               ha->isp_ops.intr_handler = qla2300_intr_handler;
-               ha->isp_ops.fw_dump = qla2300_fw_dump;
-               ha->isp_ops.beacon_on = qla2x00_beacon_on;
-               ha->isp_ops.beacon_off = qla2x00_beacon_off;
-               ha->isp_ops.beacon_blink = qla2x00_beacon_blink;
                ha->gid_list_info_size = 6;
                if (IS_QLA2322(ha) || IS_QLA6322(ha))
                        ha->optrom_size = OPTROM_SIZE_2322;
+               ha->isp_ops = &qla2300_isp_ops;
        } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
                host->max_id = MAX_TARGETS_2200;
                ha->mbx_count = MAILBOX_REGISTER_COUNT;
@@ -1531,36 +1655,20 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
                ha->last_loop_id = SNS_LAST_LOOP_ID_2300;
                ha->init_cb_size = sizeof(struct mid_init_cb_24xx);
                ha->mgmt_svr_loop_id = 10 + ha->vp_idx;
-               ha->isp_ops.pci_config = qla24xx_pci_config;
-               ha->isp_ops.reset_chip = qla24xx_reset_chip;
-               ha->isp_ops.chip_diag = qla24xx_chip_diag;
-               ha->isp_ops.config_rings = qla24xx_config_rings;
-               ha->isp_ops.reset_adapter = qla24xx_reset_adapter;
-               ha->isp_ops.nvram_config = qla24xx_nvram_config;
-               ha->isp_ops.update_fw_options = qla24xx_update_fw_options;
-               ha->isp_ops.load_risc = qla24xx_load_risc;
-               ha->isp_ops.pci_info_str = qla24xx_pci_info_str;
-               ha->isp_ops.fw_version_str = qla24xx_fw_version_str;
-               ha->isp_ops.intr_handler = qla24xx_intr_handler;
-               ha->isp_ops.enable_intrs = qla24xx_enable_intrs;
-               ha->isp_ops.disable_intrs = qla24xx_disable_intrs;
-               ha->isp_ops.abort_command = qla24xx_abort_command;
-               ha->isp_ops.abort_target = qla24xx_abort_target;
-               ha->isp_ops.fabric_login = qla24xx_login_fabric;
-               ha->isp_ops.fabric_logout = qla24xx_fabric_logout;
-               ha->isp_ops.prep_ms_iocb = qla24xx_prep_ms_iocb;
-               ha->isp_ops.prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb;
-               ha->isp_ops.read_nvram = qla24xx_read_nvram_data;
-               ha->isp_ops.write_nvram = qla24xx_write_nvram_data;
-               ha->isp_ops.fw_dump = qla24xx_fw_dump;
-               ha->isp_ops.read_optrom = qla24xx_read_optrom_data;
-               ha->isp_ops.write_optrom = qla24xx_write_optrom_data;
-               ha->isp_ops.beacon_on = qla24xx_beacon_on;
-               ha->isp_ops.beacon_off = qla24xx_beacon_off;
-               ha->isp_ops.beacon_blink = qla24xx_beacon_blink;
-               ha->isp_ops.get_flash_version = qla24xx_get_flash_version;
                ha->gid_list_info_size = 8;
                ha->optrom_size = OPTROM_SIZE_24XX;
+               ha->isp_ops = &qla24xx_isp_ops;
+       } else if (IS_QLA25XX(ha)) {
+               host->max_id = MAX_TARGETS_2200;
+               ha->mbx_count = MAILBOX_REGISTER_COUNT;
+               ha->request_q_length = REQUEST_ENTRY_CNT_24XX;
+               ha->response_q_length = RESPONSE_ENTRY_CNT_2300;
+               ha->last_loop_id = SNS_LAST_LOOP_ID_2300;
+               ha->init_cb_size = sizeof(struct mid_init_cb_24xx);
+               ha->mgmt_svr_loop_id = 10 + ha->vp_idx;
+               ha->gid_list_info_size = 8;
+               ha->optrom_size = OPTROM_SIZE_25XX;
+               ha->isp_ops = &qla25xx_isp_ops;
        }
        host->can_queue = ha->request_q_length + 128;
 
@@ -1628,11 +1736,11 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n",
            ha->host_no, ha));
 
-       ha->isp_ops.disable_intrs(ha);
+       ha->isp_ops->disable_intrs(ha);
 
        spin_lock_irqsave(&ha->hardware_lock, flags);
        reg = ha->iobase;
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (IS_FWI2_CAPABLE(ha)) {
                WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_HOST_INT);
                WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_RISC_INT);
        } else {
@@ -1654,7 +1762,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        }
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
-       ha->isp_ops.enable_intrs(ha);
+       ha->isp_ops->enable_intrs(ha);
 
        pci_set_drvdata(pdev, ha);
 
@@ -1679,9 +1787,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
            "  ISP%04X: %s @ %s hdma%c, host#=%ld, fw=%s\n",
            qla2x00_version_str, ha->model_number,
            ha->model_desc ? ha->model_desc: "", pdev->device,
-           ha->isp_ops.pci_info_str(ha, pci_info), pci_name(pdev),
+           ha->isp_ops->pci_info_str(ha, pci_info), pci_name(pdev),
            ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no,
-           ha->isp_ops.fw_version_str(ha, fw_str));
+           ha->isp_ops->fw_version_str(ha, fw_str));
 
        return 0;
 
@@ -1747,7 +1855,7 @@ qla2x00_free_device(scsi_qla_host_t *ha)
 
        /* turn-off interrupts on the card */
        if (ha->interrupts_on)
-               ha->isp_ops.disable_intrs(ha);
+               ha->isp_ops->disable_intrs(ha);
 
        qla2x00_mem_free(ha);
 
@@ -2025,7 +2133,7 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha)
                        }
                        memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt));
 
-                       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+                       if (IS_FWI2_CAPABLE(ha)) {
                                /*
                                 * Get consistent memory allocated for SFP
                                 * block.
@@ -2305,7 +2413,7 @@ qla2x00_do_dpc(void *data)
                                        if (fcport->flags & FCF_FABRIC_DEVICE) {
                                                if (fcport->flags &
                                                    FCF_TAPE_PRESENT)
-                                                       ha->isp_ops.fabric_logout(
+                                                       ha->isp_ops->fabric_logout(
                                                            ha, fcport->loop_id,
                                                            fcport->d_id.b.domain,
                                                            fcport->d_id.b.area,
@@ -2385,10 +2493,10 @@ qla2x00_do_dpc(void *data)
                }
 
                if (!ha->interrupts_on)
-                       ha->isp_ops.enable_intrs(ha);
+                       ha->isp_ops->enable_intrs(ha);
 
                if (test_and_clear_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags))
-                       ha->isp_ops.beacon_blink(ha);
+                       ha->isp_ops->beacon_blink(ha);
 
                qla2x00_do_dpc_all_vps(ha);
 
@@ -2617,18 +2725,20 @@ qla2x00_down_timeout(struct semaphore *sema, unsigned long timeout)
 
 /* Firmware interface routines. */
 
-#define FW_BLOBS       5
+#define FW_BLOBS       6
 #define FW_ISP21XX     0
 #define FW_ISP22XX     1
 #define FW_ISP2300     2
 #define FW_ISP2322     3
 #define FW_ISP24XX     4
+#define FW_ISP25XX     5
 
 #define FW_FILE_ISP21XX        "ql2100_fw.bin"
 #define FW_FILE_ISP22XX        "ql2200_fw.bin"
 #define FW_FILE_ISP2300        "ql2300_fw.bin"
 #define FW_FILE_ISP2322        "ql2322_fw.bin"
 #define FW_FILE_ISP24XX        "ql2400_fw.bin"
+#define FW_FILE_ISP25XX        "ql2500_fw.bin"
 
 static DECLARE_MUTEX(qla_fw_lock);
 
@@ -2638,6 +2748,7 @@ static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
        { .name = FW_FILE_ISP2300, .segs = { 0x800, 0 }, },
        { .name = FW_FILE_ISP2322, .segs = { 0x800, 0x1c000, 0x1e000, 0 }, },
        { .name = FW_FILE_ISP24XX, },
+       { .name = FW_FILE_ISP25XX, },
 };
 
 struct fw_blob *
@@ -2656,6 +2767,8 @@ qla2x00_request_firmware(scsi_qla_host_t *ha)
                blob = &qla_fw_blobs[FW_ISP2322];
        } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
                blob = &qla_fw_blobs[FW_ISP24XX];
+       } else if (IS_QLA25XX(ha)) {
+               blob = &qla_fw_blobs[FW_ISP25XX];
        }
 
        down(&qla_fw_lock);
@@ -2699,6 +2812,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) },
        { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) },
        { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) },
+       { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) },
        { 0 },
 };
 MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
index 206bda093da23a22440831c03870af11b6101fda..a925a3f179f959e196b7e12bf5bff46c82e06743 100644 (file)
@@ -766,6 +766,29 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
        return ret;
 }
 
+uint8_t *
+qla25xx_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
+    uint32_t bytes)
+{
+       uint32_t i;
+       uint32_t *dwptr;
+
+       /* Dword reads to flash. */
+       dwptr = (uint32_t *)buf;
+       for (i = 0; i < bytes >> 2; i++, naddr++)
+               dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
+                   flash_data_to_access_addr(FA_VPD_NVRAM_ADDR | naddr)));
+
+       return buf;
+}
+
+int
+qla25xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
+    uint32_t bytes)
+{
+       return qla24xx_write_flash_data(ha, (uint32_t *)buf,
+           FA_VPD_NVRAM_ADDR | naddr, bytes >> 2);
+}
 
 static inline void
 qla2x00_flip_colors(scsi_qla_host_t *ha, uint16_t *pflags)
@@ -919,7 +942,7 @@ qla2x00_beacon_off(struct scsi_qla_host *ha)
        else
                ha->beacon_color_state = QLA_LED_GRN_ON;
 
-       ha->isp_ops.beacon_blink(ha);   /* This turns green LED off */
+       ha->isp_ops->beacon_blink(ha);  /* This turns green LED off */
 
        ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING;
        ha->fw_options[1] &= ~FO1_DISABLE_GPIO6_7;
@@ -1031,7 +1054,7 @@ qla24xx_beacon_off(struct scsi_qla_host *ha)
        ha->beacon_blink_led = 0;
        ha->beacon_color_state = QLA_LED_ALL_ON;
 
-       ha->isp_ops.beacon_blink(ha);   /* Will flip to all off. */
+       ha->isp_ops->beacon_blink(ha);  /* Will flip to all off. */
 
        /* Give control back to firmware. */
        spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -1419,7 +1442,7 @@ qla2x00_suspend_hba(struct scsi_qla_host *ha)
 
        /* Suspend HBA. */
        scsi_block_requests(ha->host);
-       ha->isp_ops.disable_intrs(ha);
+       ha->isp_ops->disable_intrs(ha);
        set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
 
        /* Pause RISC. */
@@ -1705,7 +1728,7 @@ qla24xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf,
 {
        /* Suspend HBA. */
        scsi_block_requests(ha->host);
-       ha->isp_ops.disable_intrs(ha);
+       ha->isp_ops->disable_intrs(ha);
        set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
 
        /* Go with read. */
@@ -1713,7 +1736,7 @@ qla24xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf,
 
        /* Resume HBA. */
        clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
-       ha->isp_ops.enable_intrs(ha);
+       ha->isp_ops->enable_intrs(ha);
        scsi_unblock_requests(ha->host);
 
        return buf;
@@ -1727,7 +1750,7 @@ qla24xx_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf,
 
        /* Suspend HBA. */
        scsi_block_requests(ha->host);
-       ha->isp_ops.disable_intrs(ha);
+       ha->isp_ops->disable_intrs(ha);
        set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
 
        /* Go with write. */
index fd2f10a253486bc34ad3e96250c6cf1a25eb0208..dd1f8ceb79c464b96a8514bf52d1a456e0c8c92d 100644 (file)
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.02.00-k1"
+#define QLA2XXX_VERSION      "8.02.00-k2"
 
 #define QLA_DRIVER_MAJOR_VER   8
 #define QLA_DRIVER_MINOR_VER   2
index 4cd9c58efef12007f208dd0bf07710cd87313cce..4947dfe625a6f694546b3862c9f4d92b9b332f7f 100644 (file)
@@ -2875,7 +2875,7 @@ static int __init scsi_debug_init(void)
 
        init_all_queued();
 
-       sdebug_driver_template.proc_name = (char *)sdebug_proc_name;
+       sdebug_driver_template.proc_name = sdebug_proc_name;
 
        host_to_add = scsi_debug_add_host;
         scsi_debug_add_host = 0;
index 6cfaaa2d0c819a1478f4b31a80503a24db71f652..63a30f566f3a538c15894e2adf6805d6503308a1 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/sysctl.h>
 
 #include "scsi_logging.h"
+#include "scsi_priv.h"
 
 
 static ctl_table scsi_table[] = {
index ed720863ab97fe52cdc0947d19b594e40b954b11..34cdce6738a6c3fe4fab28a739b7ea926788babd 100644 (file)
@@ -16,6 +16,7 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi_transport.h>
+#include <scsi/scsi_driver.h>
 
 #include "scsi_priv.h"
 #include "scsi_logging.h"
@@ -714,6 +715,7 @@ static int attr_add(struct device *dev, struct device_attribute *attr)
 int scsi_sysfs_add_sdev(struct scsi_device *sdev)
 {
        int error, i;
+       struct request_queue *rq = sdev->request_queue;
 
        if ((error = scsi_device_set_state(sdev, SDEV_RUNNING)) != 0)
                return error;
@@ -733,6 +735,17 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
        /* take a reference for the sdev_classdev; this is
         * released by the sdev_class .release */
        get_device(&sdev->sdev_gendev);
+
+       error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL);
+
+       if (error)
+               sdev_printk(KERN_INFO, sdev,
+                           "Failed to register bsg queue, errno=%d\n", error);
+
+       /* we're treating error on bsg register as non-fatal, so pretend
+        * nothing went wrong */
+       error = 0;
+
        if (sdev->host->hostt->sdev_attrs) {
                for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) {
                        error = attr_add(&sdev->sdev_gendev,
@@ -779,6 +792,7 @@ void __scsi_remove_device(struct scsi_device *sdev)
        if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0)
                return;
 
+       bsg_unregister_queue(sdev->request_queue);
        class_device_unregister(&sdev->sdev_classdev);
        transport_remove_device(dev);
        device_del(dev);
@@ -803,7 +817,7 @@ void scsi_remove_device(struct scsi_device *sdev)
 }
 EXPORT_SYMBOL(scsi_remove_device);
 
-void __scsi_remove_target(struct scsi_target *starget)
+static void __scsi_remove_target(struct scsi_target *starget)
 {
        struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
        unsigned long flags;
index e8825709797eee5b8a972cd40d7a080772705180..47057254850dae0cf3d7f4b86811474c953455bd 100644 (file)
@@ -2358,7 +2358,7 @@ fc_rport_final_delete(struct work_struct *work)
  * Notes:
  *     This routine assumes no locks are held on entry.
  **/
-struct fc_rport *
+static struct fc_rport *
 fc_rport_create(struct Scsi_Host *shost, int channel,
        struct fc_rport_identifiers  *ids)
 {
index b2ef71a86292c6477dacc38ee7e4f37c960be9f2..3120f4b3a11a806254a3eb3dcbf3f71cc4c6e40b 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/blkdev.h>
+#include <linux/bsg.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
@@ -40,6 +42,7 @@
 struct sas_host_attrs {
        struct list_head rphy_list;
        struct mutex lock;
+       struct request_queue *q;
        u32 next_target_id;
        u32 next_expander_id;
        int next_port_id;
@@ -152,6 +155,106 @@ static struct {
 sas_bitfield_name_search(linkspeed, sas_linkspeed_names)
 sas_bitfield_name_set(linkspeed, sas_linkspeed_names)
 
+static void sas_smp_request(struct request_queue *q, struct Scsi_Host *shost,
+                           struct sas_rphy *rphy)
+{
+       struct request *req;
+       int ret;
+       int (*handler)(struct Scsi_Host *, struct sas_rphy *, struct request *);
+
+       while (!blk_queue_plugged(q)) {
+               req = elv_next_request(q);
+               if (!req)
+                       break;
+
+               blkdev_dequeue_request(req);
+
+               spin_unlock_irq(q->queue_lock);
+
+               handler = to_sas_internal(shost->transportt)->f->smp_handler;
+               ret = handler(shost, rphy, req);
+
+               spin_lock_irq(q->queue_lock);
+
+               req->end_io(req, ret);
+       }
+}
+
+static void sas_host_smp_request(struct request_queue *q)
+{
+       sas_smp_request(q, (struct Scsi_Host *)q->queuedata, NULL);
+}
+
+static void sas_non_host_smp_request(struct request_queue *q)
+{
+       struct sas_rphy *rphy = q->queuedata;
+       sas_smp_request(q, rphy_to_shost(rphy), rphy);
+}
+
+static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy)
+{
+       struct request_queue *q;
+       int error;
+       struct device *dev;
+       char namebuf[BUS_ID_SIZE];
+       const char *name;
+
+       if (!to_sas_internal(shost->transportt)->f->smp_handler) {
+               printk("%s can't handle SMP requests\n", shost->hostt->name);
+               return 0;
+       }
+
+       if (rphy) {
+               q = blk_init_queue(sas_non_host_smp_request, NULL);
+               dev = &rphy->dev;
+               name = dev->bus_id;
+       } else {
+               q = blk_init_queue(sas_host_smp_request, NULL);
+               dev = &shost->shost_gendev;
+               snprintf(namebuf, sizeof(namebuf),
+                        "sas_host%d", shost->host_no);
+               name = namebuf;
+       }
+       if (!q)
+               return -ENOMEM;
+
+       error = bsg_register_queue(q, dev, name);
+       if (error) {
+               blk_cleanup_queue(q);
+               return -ENOMEM;
+       }
+
+       if (rphy)
+               rphy->q = q;
+       else
+               to_sas_host_attrs(shost)->q = q;
+
+       if (rphy)
+               q->queuedata = rphy;
+       else
+               q->queuedata = shost;
+
+       set_bit(QUEUE_FLAG_BIDI, &q->queue_flags);
+
+       return 0;
+}
+
+static void sas_bsg_remove(struct Scsi_Host *shost, struct sas_rphy *rphy)
+{
+       struct request_queue *q;
+
+       if (rphy)
+               q = rphy->q;
+       else
+               q = to_sas_host_attrs(shost)->q;
+
+       if (!q)
+               return;
+
+       bsg_unregister_queue(q);
+       blk_cleanup_queue(q);
+}
+
 /*
  * SAS host attributes
  */
@@ -167,11 +270,26 @@ static int sas_host_setup(struct transport_container *tc, struct device *dev,
        sas_host->next_target_id = 0;
        sas_host->next_expander_id = 0;
        sas_host->next_port_id = 0;
+
+       if (sas_bsg_initialize(shost, NULL))
+               dev_printk(KERN_ERR, dev, "fail to a bsg device %d\n",
+                          shost->host_no);
+
+       return 0;
+}
+
+static int sas_host_remove(struct transport_container *tc, struct device *dev,
+                          struct class_device *cdev)
+{
+       struct Scsi_Host *shost = dev_to_shost(dev);
+
+       sas_bsg_remove(shost, NULL);
+
        return 0;
 }
 
 static DECLARE_TRANSPORT_CLASS(sas_host_class,
-               "sas_host", sas_host_setup, NULL, NULL);
+               "sas_host", sas_host_setup, sas_host_remove, NULL);
 
 static int sas_host_match(struct attribute_container *cont,
                            struct device *dev)
@@ -1287,6 +1405,9 @@ int sas_rphy_add(struct sas_rphy *rphy)
                return error;
        transport_add_device(&rphy->dev);
        transport_configure_device(&rphy->dev);
+       if (sas_bsg_initialize(shost, rphy))
+               printk("fail to a bsg device %s\n", rphy->dev.bus_id);
+
 
        mutex_lock(&sas_host->lock);
        list_add_tail(&rphy->list, &sas_host->rphy_list);
@@ -1329,6 +1450,8 @@ void sas_rphy_free(struct sas_rphy *rphy)
        list_del(&rphy->list);
        mutex_unlock(&sas_host->lock);
 
+       sas_bsg_remove(shost, rphy);
+
        transport_destroy_device(dev);
 
        put_device(dev);
index ff62e9708e1c706078b8352d5f3e8ee698c1fcd8..ce80fa9ad815906d6a234fad52f9d2ae44443c53 100644 (file)
@@ -420,7 +420,7 @@ static inline void borken_wait (void)
 #define ULOOP( i ) for (clock = i*8;;)
 #define TIMEOUT (!(clock--))
 
-int __init seagate_st0x_detect (struct scsi_host_template * tpnt)
+static int __init seagate_st0x_detect (struct scsi_host_template * tpnt)
 {
        struct Scsi_Host *instance;
        int i, j;
index 710f19de3d4008d5ec4be5cd4e80ba6d9e9a7e2e..d63d229e23233149aa221ebcaec0f99a72141484 100644 (file)
@@ -138,6 +138,7 @@ sim710_probe_common(struct device *dev, unsigned long base_addr,
                goto out_put_host;
        }
 
+       dev_set_drvdata(dev, host);
        scsi_scan_host(host);
 
        return 0;
@@ -155,7 +156,7 @@ sim710_probe_common(struct device *dev, unsigned long base_addr,
 static __devexit int
 sim710_device_remove(struct device *dev)
 {
-       struct Scsi_Host *host = dev_to_shost(dev);
+       struct Scsi_Host *host = dev_get_drvdata(dev);
        struct NCR_700_Host_Parameters *hostdata =
                (struct NCR_700_Host_Parameters *)host->hostdata[0];
 
index 5143c899084523f3b9f47e67577757b6ce97a5ad..e7b6a7fde1cb051fdfc7ae4002740177a55d3ca9 100644 (file)
@@ -175,7 +175,7 @@ static void scsi_cd_put(struct scsi_cd *cd)
  * an inode for that to work, and we do not always have one.
  */
 
-int sr_media_change(struct cdrom_device_info *cdi, int slot)
+static int sr_media_change(struct cdrom_device_info *cdi, int slot)
 {
        struct scsi_cd *cd = cdi->handle;
        int retval;
index fa4e08e508ad68b35c7c2d490e0639c64f7c4384..b92ff047af381c223333aca9b6ac9a4449ccabd8 100644 (file)
@@ -89,6 +89,8 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 
+#include <asm/irq.h>
+
 #include "wd33c93.h"
 
 #define optimum_sx_per(hostdata) (hostdata)->sx_table[1].period_ns
@@ -1762,7 +1764,7 @@ static char setup_buffer[SETUP_BUFFER_SIZE];
 static char setup_used[MAX_SETUP_ARGS];
 static int done_setup = 0;
 
-int
+static int
 wd33c93_setup(char *str)
 {
        int i;
index 50703877a5858daad99fceabcb6c0454c152a7d1..c822debc2668ef687368443907c9ad2d1bca87f7 100644 (file)
@@ -130,6 +130,7 @@ static int __devinit zorro7xx_init_one(struct zorro_dev *z,
                goto out_put_host;
        }
 
+       zorro_set_drvdata(z, host);
        scsi_scan_host(host);
 
        return 0;
@@ -148,7 +149,7 @@ static int __devinit zorro7xx_init_one(struct zorro_dev *z,
 
 static __devexit void zorro7xx_remove_one(struct zorro_dev *z)
 {
-       struct Scsi_Host *host = dev_to_shost(&z->dev);
+       struct Scsi_Host *host = zorro_get_drvdata(z);
        struct NCR_700_Host_Parameters *hostdata = shost_priv(host);
 
        scsi_remove_host(host);
index e42faa4e42829f9f06387ea5e8035f838b5bbd19..dc1967176fe228811b77a27fb2fcb82c41c8274c 100644 (file)
@@ -1114,8 +1114,8 @@ static int __init imx_serial_init(void)
 
 static void __exit imx_serial_exit(void)
 {
-       uart_unregister_driver(&imx_reg);
        platform_driver_unregister(&serial_imx_driver);
+       uart_unregister_driver(&imx_reg);
 }
 
 module_init(imx_serial_init);
index 10bc0209cd661a7b68f7bb7853b0aa10f20751ef..3f26c4b2f322a0e4140a8987c4b21c42894c84b3 100644 (file)
@@ -78,7 +78,7 @@
 
 #include <asm/hardware.h>
 
-#include <asm/arch/regs-serial.h>
+#include <asm/plat-s3c/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 
 /* structures */
index 018884d7a5fac3e8c69d2cb0b062e3d79a865de8..b05de30b5d9bbf4af1991ca8bc514b12acc8290d 100644 (file)
@@ -303,8 +303,7 @@ spi_register_board_info(struct spi_board_info const *info, unsigned n)
  * creates board info from kernel command lines
  */
 
-static void __init_or_module
-scan_boardinfo(struct spi_master *master)
+static void scan_boardinfo(struct spi_master *master)
 {
        struct boardinfo        *bi;
        struct device           *dev = master->cdev.dev;
index b09c83568c1a8b455520feb3cd58df8250fe3aef..1cb56f2d5c8421df8036cf09bc00d9405fb97c32 100644 (file)
@@ -138,7 +138,7 @@ exit:
 
 static int appledisplay_bl_update_status(struct backlight_device *bd)
 {
-       struct appledisplay *pdata = class_get_devdata(&bd->class_dev);
+       struct appledisplay *pdata = bl_get_data(bd);
        int retval;
 
        pdata->msgdata[0] = 0x10;
@@ -159,7 +159,7 @@ static int appledisplay_bl_update_status(struct backlight_device *bd)
 
 static int appledisplay_bl_get_brightness(struct backlight_device *bd)
 {
-       struct appledisplay *pdata = class_get_devdata(&bd->class_dev);
+       struct appledisplay *pdata = bl_get_data(bd);
        int retval;
 
        retval = usb_control_msg(
index 0c5644bb59af9397aab96a0828c9d53014a979b8..564cc9b5182243ddf4f24c3ddb131231ff913ed1 100644 (file)
@@ -12,6 +12,13 @@ config VGASTATE
        tristate
        default n
 
+config VIDEO_OUTPUT_CONTROL
+       tristate "Lowlevel video output switch controls"
+       default m
+       help
+         This framework adds support for low-level control of the video 
+         output switch.
+
 config FB
        tristate "Support for frame buffer devices"
        ---help---
@@ -849,6 +856,16 @@ config FB_INTSRAM
          Say Y if you want to map Frame Buffer in internal SRAM. Say N if you want
          to let frame buffer in external SDRAM.
 
+config FB_ATMEL_STN
+       bool "Use a STN display with AT91/AT32 LCD Controller"
+       depends on FB_ATMEL && MACH_AT91SAM9261EK
+       default n
+       help
+         Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD
+         Controller. Say N if you want to connect a TFT.
+
+         If unsure, say N.
+
 config FB_NVIDIA
        tristate "nVidia Framebuffer Support"
        depends on FB && PCI
@@ -1796,13 +1813,14 @@ config FB_PS3
        select FB_SYS_COPYAREA
        select FB_SYS_IMAGEBLIT
        select FB_SYS_FOPS
+       select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
        ---help---
          Include support for the virtual frame buffer in the PS3 platform.
 
 config FB_PS3_DEFAULT_SIZE_M
        int "PS3 default frame buffer size (in MiB)"
        depends on FB_PS3
-       default 18
+       default 9
        ---help---
          This is the default size (in MiB) of the virtual frame buffer in
          the PS3.
index a562f9d69d2c2285bc7e633e59ec6c5ec4d884d9..518933d4905f4f97098dac3608d13ccb81503ec4 100644 (file)
@@ -123,3 +123,6 @@ obj-$(CONFIG_FB_OF)               += offb.o
 
 # the test framebuffer is last
 obj-$(CONFIG_FB_VIRTUAL)          += vfb.o
+
+#video output switch sysfs driver
+obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o
index e1d5bd0c98c4a2b0b6bf31f4cabf76c3d1ad023c..235b618b41178053670879cb5e9961a164871730 100644 (file)
@@ -79,6 +79,29 @@ static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = {
        .accel          = FB_ACCEL_NONE,
 };
 
+static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2)
+{
+       unsigned long value;
+
+       if (!(cpu_is_at91sam9261() || cpu_is_at32ap7000()))
+               return xres;
+
+       value = xres;
+       if ((lcdcon2 & ATMEL_LCDC_DISTYPE) != ATMEL_LCDC_DISTYPE_TFT) {
+               /* STN display */
+               if ((lcdcon2 & ATMEL_LCDC_DISTYPE) == ATMEL_LCDC_DISTYPE_STNCOLOR) {
+                       value *= 3;
+               }
+               if ( (lcdcon2 & ATMEL_LCDC_IFWIDTH) == ATMEL_LCDC_IFWIDTH_4
+                  || ( (lcdcon2 & ATMEL_LCDC_IFWIDTH) == ATMEL_LCDC_IFWIDTH_8
+                     && (lcdcon2 & ATMEL_LCDC_SCANMOD) == ATMEL_LCDC_SCANMOD_DUAL ))
+                       value = DIV_ROUND_UP(value, 4);
+               else
+                       value = DIV_ROUND_UP(value, 8);
+       }
+
+       return value;
+}
 
 static void atmel_lcdfb_update_dma(struct fb_info *info,
                               struct fb_var_screeninfo *var)
@@ -181,6 +204,7 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
        var->xoffset = var->yoffset = 0;
 
        switch (var->bits_per_pixel) {
+       case 1:
        case 2:
        case 4:
        case 8:
@@ -195,8 +219,11 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
                var->blue.offset = 10;
                var->red.length = var->green.length = var->blue.length = 5;
                break;
-       case 24:
        case 32:
+               var->transp.offset = 24;
+               var->transp.length = 8;
+               /* fall through */
+       case 24:
                var->red.offset = 0;
                var->green.offset = 8;
                var->blue.offset = 16;
@@ -228,8 +255,10 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
 static int atmel_lcdfb_set_par(struct fb_info *info)
 {
        struct atmel_lcdfb_info *sinfo = info->par;
+       unsigned long hozval_linesz;
        unsigned long value;
        unsigned long clk_value_khz;
+       unsigned long bits_per_line;
 
        dev_dbg(info->device, "%s:\n", __func__);
        dev_dbg(info->device, "  * resolution: %ux%u (%ux%u virtual)\n",
@@ -241,12 +270,15 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
 
        lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
 
-       if (info->var.bits_per_pixel <= 8)
+       if (info->var.bits_per_pixel == 1)
+               info->fix.visual = FB_VISUAL_MONO01;
+       else if (info->var.bits_per_pixel <= 8)
                info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
        else
                info->fix.visual = FB_VISUAL_TRUECOLOR;
 
-       info->fix.line_length = info->var.xres_virtual * (info->var.bits_per_pixel / 8);
+       bits_per_line = info->var.xres_virtual * info->var.bits_per_pixel;
+       info->fix.line_length = DIV_ROUND_UP(bits_per_line, 8);
 
        /* Re-initialize the DMA engine... */
        dev_dbg(info->device, "  * update DMA engine\n");
@@ -262,18 +294,21 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
        /* Set pixel clock */
        clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000;
 
-       value = clk_value_khz / PICOS2KHZ(info->var.pixclock);
-
-       if (clk_value_khz % PICOS2KHZ(info->var.pixclock))
-               value++;
+       value = DIV_ROUND_UP(clk_value_khz, PICOS2KHZ(info->var.pixclock));
 
        value = (value / 2) - 1;
+       dev_dbg(info->device, "  * programming CLKVAL = 0x%08lx\n", value);
 
        if (value <= 0) {
                dev_notice(info->device, "Bypassing pixel clock divider\n");
                lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, ATMEL_LCDC_BYPASS);
-       } else
+       } else {
                lcdc_writel(sinfo, ATMEL_LCDC_LCDCON1, value << ATMEL_LCDC_CLKVAL_OFFSET);
+               info->var.pixclock = KHZ2PICOS(clk_value_khz / (2 * (value + 1)));
+               dev_dbg(info->device, "  updated pixclk:     %lu KHz\n",
+                                       PICOS2KHZ(info->var.pixclock));
+       }
+
 
        /* Initialize control register 2 */
        value = sinfo->default_lcdcon2;
@@ -311,9 +346,14 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
        dev_dbg(info->device, "  * LCDTIM2 = %08lx\n", value);
        lcdc_writel(sinfo, ATMEL_LCDC_TIM2, value);
 
+       /* Horizontal value (aka line size) */
+       hozval_linesz = compute_hozval(info->var.xres,
+                                       lcdc_readl(sinfo, ATMEL_LCDC_LCDCON2));
+
        /* Display size */
-       value = (info->var.xres - 1) << ATMEL_LCDC_HOZVAL_OFFSET;
+       value = (hozval_linesz - 1) << ATMEL_LCDC_HOZVAL_OFFSET;
        value |= info->var.yres - 1;
+       dev_dbg(info->device, "  * LCDFRMCFG = %08lx\n", value);
        lcdc_writel(sinfo, ATMEL_LCDC_LCDFRMCFG, value);
 
        /* FIFO Threshold: Use formula from data sheet */
@@ -421,6 +461,15 @@ static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red,
                        ret = 0;
                }
                break;
+
+       case FB_VISUAL_MONO01:
+               if (regno < 2) {
+                       val = (regno == 0) ? 0x00 : 0x1F;
+                       lcdc_writel(sinfo, ATMEL_LCDC_LUT(regno), val);
+                       ret = 0;
+               }
+               break;
+
        }
 
        return ret;
index 7fea4d8ae8e2a59719c6db6d918c9f77d79531a8..cfcbe37d2d703478742a95f847c33878721edce4 100644 (file)
@@ -1733,7 +1733,7 @@ static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
 
 static int aty128_bl_update_status(struct backlight_device *bd)
 {
-       struct aty128fb_par *par = class_get_devdata(&bd->class_dev);
+       struct aty128fb_par *par = bl_get_data(bd);
        unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);
        int level;
 
index 13990697b5c12a76e41cd31fdc37873bebcbc2d5..bc6f0096aa04424c333a28d8dc7f89def808c132 100644 (file)
@@ -2141,7 +2141,7 @@ static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
 
 static int aty_bl_update_status(struct backlight_device *bd)
 {
-       struct atyfb_par *par = class_get_devdata(&bd->class_dev);
+       struct atyfb_par *par = bl_get_data(bd);
        unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par);
        int level;
 
index 0be25fa5540c8a938507bbdb7f3046e40c5973ff..1a056adb61c836784fce99d1c0314e710f4948e8 100644 (file)
@@ -47,7 +47,7 @@ static int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata,
 
 static int radeon_bl_update_status(struct backlight_device *bd)
 {
-       struct radeon_bl_privdata *pdata = class_get_devdata(&bd->class_dev);
+       struct radeon_bl_privdata *pdata = bl_get_data(bd);
        struct radeonfb_info *rinfo = pdata->rinfo;
        u32 lvds_gen_cntl, tmpPixclksCntl;
        int level;
@@ -206,7 +206,7 @@ void radeonfb_bl_exit(struct radeonfb_info *rinfo)
        if (bd) {
                struct radeon_bl_privdata *pdata;
 
-               pdata = class_get_devdata(&bd->class_dev);
+               pdata = bl_get_data(bd);
                backlight_device_unregister(bd);
                kfree(pdata);
                rinfo->info->bl_dev = NULL;
index fbef663fc0571988001fa848a11b460020035972..2580f5fa2486e4caefbed82b3bbd357901926151 100644 (file)
@@ -8,26 +8,32 @@ menuconfig BACKLIGHT_LCD_SUPPORT
          Enable this to be able to choose the drivers for controlling the
          backlight and the LCD panel on some platforms, for example on PDAs.
 
-config BACKLIGHT_CLASS_DEVICE
-        tristate "Lowlevel Backlight controls"
+#
+# LCD
+#
+config LCD_CLASS_DEVICE
+        tristate "Lowlevel LCD controls"
        depends on BACKLIGHT_LCD_SUPPORT
        default m
        help
-         This framework adds support for low-level control of the LCD
-          backlight. This includes support for brightness and power.
+         This framework adds support for low-level control of LCD.
+         Some framebuffer devices connect to platform-specific LCD modules
+         in order to have a platform-specific way to control the flat panel
+         (contrast and applying power to the LCD (not to the backlight!)).
 
          To have support for your specific LCD panel you will have to
          select the proper drivers which depend on this option.
 
-config LCD_CLASS_DEVICE
-        tristate "Lowlevel LCD controls"
+#
+# Backlight
+#
+config BACKLIGHT_CLASS_DEVICE
+        tristate "Lowlevel Backlight controls"
        depends on BACKLIGHT_LCD_SUPPORT
        default m
        help
-         This framework adds support for low-level control of LCD.
-         Some framebuffer devices connect to platform-specific LCD modules
-         in order to have a platform-specific way to control the flat panel
-         (contrast and applying power to the LCD (not to the backlight!)).
+         This framework adds support for low-level control of the LCD
+          backlight. This includes support for brightness and power.
 
          To have support for your specific LCD panel you will have to
          select the proper drivers which depend on this option.
index 7e06223bca9494178632f444b989a554f3e5180f..b26de8cf311270ef4eff4a1478f48dbf7120d8b8 100644 (file)
@@ -69,18 +69,20 @@ static inline void backlight_unregister_fb(struct backlight_device *bd)
 }
 #endif /* CONFIG_FB */
 
-static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
+static ssize_t backlight_show_power(struct device *dev,
+               struct device_attribute *attr,char *buf)
 {
-       struct backlight_device *bd = to_backlight_device(cdev);
+       struct backlight_device *bd = to_backlight_device(dev);
 
        return sprintf(buf, "%d\n", bd->props.power);
 }
 
-static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count)
+static ssize_t backlight_store_power(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t count)
 {
        int rc = -ENXIO;
        char *endp;
-       struct backlight_device *bd = to_backlight_device(cdev);
+       struct backlight_device *bd = to_backlight_device(dev);
        int power = simple_strtoul(buf, &endp, 0);
        size_t size = endp - buf;
 
@@ -101,18 +103,20 @@ static ssize_t backlight_store_power(struct class_device *cdev, const char *buf,
        return rc;
 }
 
-static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf)
+static ssize_t backlight_show_brightness(struct device *dev,
+               struct device_attribute *attr, char *buf)
 {
-       struct backlight_device *bd = to_backlight_device(cdev);
+       struct backlight_device *bd = to_backlight_device(dev);
 
        return sprintf(buf, "%d\n", bd->props.brightness);
 }
 
-static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count)
+static ssize_t backlight_store_brightness(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t count)
 {
        int rc = -ENXIO;
        char *endp;
-       struct backlight_device *bd = to_backlight_device(cdev);
+       struct backlight_device *bd = to_backlight_device(dev);
        int brightness = simple_strtoul(buf, &endp, 0);
        size_t size = endp - buf;
 
@@ -138,18 +142,19 @@ static ssize_t backlight_store_brightness(struct class_device *cdev, const char
        return rc;
 }
 
-static ssize_t backlight_show_max_brightness(struct class_device *cdev, char *buf)
+static ssize_t backlight_show_max_brightness(struct device *dev,
+               struct device_attribute *attr, char *buf)
 {
-       struct backlight_device *bd = to_backlight_device(cdev);
+       struct backlight_device *bd = to_backlight_device(dev);
 
        return sprintf(buf, "%d\n", bd->props.max_brightness);
 }
 
-static ssize_t backlight_show_actual_brightness(struct class_device *cdev,
-                                               char *buf)
+static ssize_t backlight_show_actual_brightness(struct device *dev,
+               struct device_attribute *attr, char *buf)
 {
        int rc = -ENXIO;
-       struct backlight_device *bd = to_backlight_device(cdev);
+       struct backlight_device *bd = to_backlight_device(dev);
 
        mutex_lock(&bd->ops_lock);
        if (bd->ops && bd->ops->get_brightness)
@@ -159,31 +164,22 @@ static ssize_t backlight_show_actual_brightness(struct class_device *cdev,
        return rc;
 }
 
-static void backlight_class_release(struct class_device *dev)
+struct class *backlight_class;
+
+static void bl_device_release(struct device *dev)
 {
        struct backlight_device *bd = to_backlight_device(dev);
        kfree(bd);
 }
 
-static struct class backlight_class = {
-       .name = "backlight",
-       .release = backlight_class_release,
-};
-
-#define DECLARE_ATTR(_name,_mode,_show,_store)                 \
-{                                                              \
-       .attr   = { .name = __stringify(_name), .mode = _mode }, \
-       .show   = _show,                                        \
-       .store  = _store,                                       \
-}
-
-static const struct class_device_attribute bl_class_device_attributes[] = {
-       DECLARE_ATTR(power, 0644, backlight_show_power, backlight_store_power),
-       DECLARE_ATTR(brightness, 0644, backlight_show_brightness,
+static struct device_attribute bl_device_attributes[] = {
+       __ATTR(bl_power, 0644, backlight_show_power, backlight_store_power),
+       __ATTR(brightness, 0644, backlight_show_brightness,
                     backlight_store_brightness),
-       DECLARE_ATTR(actual_brightness, 0444, backlight_show_actual_brightness,
+       __ATTR(actual_brightness, 0444, backlight_show_actual_brightness,
                     NULL),
-       DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
+       __ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
+       __ATTR_NULL,
 };
 
 /**
@@ -191,22 +187,20 @@ static const struct class_device_attribute bl_class_device_attributes[] = {
  *   backlight_device class.
  * @name: the name of the new object(must be the same as the name of the
  *   respective framebuffer device).
- * @devdata: an optional pointer to be stored in the class_device. The
- *   methods may retrieve it by using class_get_devdata(&bd->class_dev).
+ * @devdata: an optional pointer to be stored for private driver use. The
+ *   methods may retrieve it by using bl_get_data(bd).
  * @ops: the backlight operations structure.
  *
- * Creates and registers new backlight class_device. Returns either an
+ * Creates and registers new backlight device. Returns either an
  * ERR_PTR() or a pointer to the newly allocated device.
  */
 struct backlight_device *backlight_device_register(const char *name,
-       struct device *dev,
-       void *devdata,
-       struct backlight_ops *ops)
+               struct device *parent, void *devdata, struct backlight_ops *ops)
 {
-       int i, rc;
        struct backlight_device *new_bd;
+       int rc;
 
-       pr_debug("backlight_device_alloc: name=%s\n", name);
+       pr_debug("backlight_device_register: name=%s\n", name);
 
        new_bd = kzalloc(sizeof(struct backlight_device), GFP_KERNEL);
        if (!new_bd)
@@ -214,13 +208,14 @@ struct backlight_device *backlight_device_register(const char *name,
 
        mutex_init(&new_bd->update_lock);
        mutex_init(&new_bd->ops_lock);
-       new_bd->ops = ops;
-       new_bd->class_dev.class = &backlight_class;
-       new_bd->class_dev.dev = dev;
-       strlcpy(new_bd->class_dev.class_id, name, KOBJ_NAME_LEN);
-       class_set_devdata(&new_bd->class_dev, devdata);
 
-       rc = class_device_register(&new_bd->class_dev);
+       new_bd->dev.class = backlight_class;
+       new_bd->dev.parent = parent;
+       new_bd->dev.release = bl_device_release;
+       strlcpy(new_bd->dev.bus_id, name, BUS_ID_SIZE);
+       dev_set_drvdata(&new_bd->dev, devdata);
+
+       rc = device_register(&new_bd->dev);
        if (rc) {
                kfree(new_bd);
                return ERR_PTR(rc);
@@ -228,23 +223,11 @@ struct backlight_device *backlight_device_register(const char *name,
 
        rc = backlight_register_fb(new_bd);
        if (rc) {
-               class_device_unregister(&new_bd->class_dev);
+               device_unregister(&new_bd->dev);
                return ERR_PTR(rc);
        }
 
-
-       for (i = 0; i < ARRAY_SIZE(bl_class_device_attributes); i++) {
-               rc = class_device_create_file(&new_bd->class_dev,
-                                             &bl_class_device_attributes[i]);
-               if (rc) {
-                       while (--i >= 0)
-                               class_device_remove_file(&new_bd->class_dev,
-                                                        &bl_class_device_attributes[i]);
-                       class_device_unregister(&new_bd->class_dev);
-                       /* No need to kfree(new_bd) since release() method was called */
-                       return ERR_PTR(rc);
-               }
-       }
+       new_bd->ops = ops;
 
 #ifdef CONFIG_PMAC_BACKLIGHT
        mutex_lock(&pmac_backlight_mutex);
@@ -265,42 +248,40 @@ EXPORT_SYMBOL(backlight_device_register);
  */
 void backlight_device_unregister(struct backlight_device *bd)
 {
-       int i;
-
        if (!bd)
                return;
 
-       pr_debug("backlight_device_unregister: name=%s\n", bd->class_dev.class_id);
-
 #ifdef CONFIG_PMAC_BACKLIGHT
        mutex_lock(&pmac_backlight_mutex);
        if (pmac_backlight == bd)
                pmac_backlight = NULL;
        mutex_unlock(&pmac_backlight_mutex);
 #endif
-
-       for (i = 0; i < ARRAY_SIZE(bl_class_device_attributes); i++)
-               class_device_remove_file(&bd->class_dev,
-                                        &bl_class_device_attributes[i]);
-
        mutex_lock(&bd->ops_lock);
        bd->ops = NULL;
        mutex_unlock(&bd->ops_lock);
 
        backlight_unregister_fb(bd);
-
-       class_device_unregister(&bd->class_dev);
+       device_unregister(&bd->dev);
 }
 EXPORT_SYMBOL(backlight_device_unregister);
 
 static void __exit backlight_class_exit(void)
 {
-       class_unregister(&backlight_class);
+       class_destroy(backlight_class);
 }
 
 static int __init backlight_class_init(void)
 {
-       return class_register(&backlight_class);
+       backlight_class = class_create(THIS_MODULE, "backlight");
+       if (IS_ERR(backlight_class)) {
+               printk(KERN_WARNING "Unable to create backlight class; errno = %ld\n",
+                               PTR_ERR(backlight_class));
+               return PTR_ERR(backlight_class);
+       }
+
+       backlight_class->dev_attrs = bl_device_attributes;
+       return 0;
 }
 
 /*
index 1b3f6586bc9f433295ccee5bf5c32d5868e6d461..b7904da51b231158d4f74d0a4ff5da448f3b8821 100644 (file)
@@ -202,7 +202,7 @@ static int cr_backlight_probe(struct platform_device *pdev)
        }
 
        crp->cr_lcd_device = lcd_device_register("cr-lcd",
-                                                       &pdev->dev,
+                                                       &pdev->dev, NULL,
                                                        &cr_lcd_ops);
 
        if (IS_ERR(crp->cr_lcd_device)) {
index 648b53c1fdea7f7f2687f8f5d6b60c179f61007a..6f652c65fae130ab59bbcd89a29d5da0a0be551f 100644 (file)
@@ -61,10 +61,11 @@ static inline void lcd_unregister_fb(struct lcd_device *ld)
 }
 #endif /* CONFIG_FB */
 
-static ssize_t lcd_show_power(struct class_device *cdev, char *buf)
+static ssize_t lcd_show_power(struct device *dev, struct device_attribute *attr,
+               char *buf)
 {
        int rc;
-       struct lcd_device *ld = to_lcd_device(cdev);
+       struct lcd_device *ld = to_lcd_device(dev);
 
        mutex_lock(&ld->ops_lock);
        if (ld->ops && ld->ops->get_power)
@@ -76,11 +77,12 @@ static ssize_t lcd_show_power(struct class_device *cdev, char *buf)
        return rc;
 }
 
-static ssize_t lcd_store_power(struct class_device *cdev, const char *buf, size_t count)
+static ssize_t lcd_store_power(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t count)
 {
        int rc = -ENXIO;
        char *endp;
-       struct lcd_device *ld = to_lcd_device(cdev);
+       struct lcd_device *ld = to_lcd_device(dev);
        int power = simple_strtoul(buf, &endp, 0);
        size_t size = endp - buf;
 
@@ -100,10 +102,11 @@ static ssize_t lcd_store_power(struct class_device *cdev, const char *buf, size_
        return rc;
 }
 
-static ssize_t lcd_show_contrast(struct class_device *cdev, char *buf)
+static ssize_t lcd_show_contrast(struct device *dev,
+               struct device_attribute *attr, char *buf)
 {
        int rc = -ENXIO;
-       struct lcd_device *ld = to_lcd_device(cdev);
+       struct lcd_device *ld = to_lcd_device(dev);
 
        mutex_lock(&ld->ops_lock);
        if (ld->ops && ld->ops->get_contrast)
@@ -113,11 +116,12 @@ static ssize_t lcd_show_contrast(struct class_device *cdev, char *buf)
        return rc;
 }
 
-static ssize_t lcd_store_contrast(struct class_device *cdev, const char *buf, size_t count)
+static ssize_t lcd_store_contrast(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t count)
 {
        int rc = -ENXIO;
        char *endp;
-       struct lcd_device *ld = to_lcd_device(cdev);
+       struct lcd_device *ld = to_lcd_device(dev);
        int contrast = simple_strtoul(buf, &endp, 0);
        size_t size = endp - buf;
 
@@ -137,53 +141,45 @@ static ssize_t lcd_store_contrast(struct class_device *cdev, const char *buf, si
        return rc;
 }
 
-static ssize_t lcd_show_max_contrast(struct class_device *cdev, char *buf)
+static ssize_t lcd_show_max_contrast(struct device *dev,
+               struct device_attribute *attr, char *buf)
 {
-       struct lcd_device *ld = to_lcd_device(cdev);
+       struct lcd_device *ld = to_lcd_device(dev);
 
        return sprintf(buf, "%d\n", ld->props.max_contrast);
 }
 
-static void lcd_class_release(struct class_device *dev)
+struct class *lcd_class;
+
+static void lcd_device_release(struct device *dev)
 {
        struct lcd_device *ld = to_lcd_device(dev);
        kfree(ld);
 }
 
-static struct class lcd_class = {
-       .name = "lcd",
-       .release = lcd_class_release,
-};
-
-#define DECLARE_ATTR(_name,_mode,_show,_store)                 \
-{                                                              \
-       .attr   = { .name = __stringify(_name), .mode = _mode }, \
-       .show   = _show,                                        \
-       .store  = _store,                                       \
-}
-
-static const struct class_device_attribute lcd_class_device_attributes[] = {
-       DECLARE_ATTR(power, 0644, lcd_show_power, lcd_store_power),
-       DECLARE_ATTR(contrast, 0644, lcd_show_contrast, lcd_store_contrast),
-       DECLARE_ATTR(max_contrast, 0444, lcd_show_max_contrast, NULL),
+static struct device_attribute lcd_device_attributes[] = {
+       __ATTR(lcd_power, 0644, lcd_show_power, lcd_store_power),
+       __ATTR(contrast, 0644, lcd_show_contrast, lcd_store_contrast),
+       __ATTR(max_contrast, 0444, lcd_show_max_contrast, NULL),
+       __ATTR_NULL,
 };
 
 /**
  * lcd_device_register - register a new object of lcd_device class.
  * @name: the name of the new object(must be the same as the name of the
  *   respective framebuffer device).
- * @devdata: an optional pointer to be stored in the class_device. The
- *   methods may retrieve it by using class_get_devdata(ld->class_dev).
+ * @devdata: an optional pointer to be stored in the device. The
+ *   methods may retrieve it by using lcd_get_data(ld).
  * @ops: the lcd operations structure.
  *
- * Creates and registers a new lcd class_device. Returns either an ERR_PTR()
+ * Creates and registers a new lcd device. Returns either an ERR_PTR()
  * or a pointer to the newly allocated device.
  */
-struct lcd_device *lcd_device_register(const char *name, void *devdata,
-                                      struct lcd_ops *ops)
+struct lcd_device *lcd_device_register(const char *name, struct device *parent,
+               void *devdata, struct lcd_ops *ops)
 {
-       int i, rc;
        struct lcd_device *new_ld;
+       int rc;
 
        pr_debug("lcd_device_register: name=%s\n", name);
 
@@ -193,12 +189,14 @@ struct lcd_device *lcd_device_register(const char *name, void *devdata,
 
        mutex_init(&new_ld->ops_lock);
        mutex_init(&new_ld->update_lock);
-       new_ld->ops = ops;
-       new_ld->class_dev.class = &lcd_class;
-       strlcpy(new_ld->class_dev.class_id, name, KOBJ_NAME_LEN);
-       class_set_devdata(&new_ld->class_dev, devdata);
 
-       rc = class_device_register(&new_ld->class_dev);
+       new_ld->dev.class = lcd_class;
+       new_ld->dev.parent = parent;
+       new_ld->dev.release = lcd_device_release;
+       strlcpy(new_ld->dev.bus_id, name, BUS_ID_SIZE);
+       dev_set_drvdata(&new_ld->dev, devdata);
+
+       rc = device_register(&new_ld->dev);
        if (rc) {
                kfree(new_ld);
                return ERR_PTR(rc);
@@ -206,22 +204,11 @@ struct lcd_device *lcd_device_register(const char *name, void *devdata,
 
        rc = lcd_register_fb(new_ld);
        if (rc) {
-               class_device_unregister(&new_ld->class_dev);
+               device_unregister(&new_ld->dev);
                return ERR_PTR(rc);
        }
 
-       for (i = 0; i < ARRAY_SIZE(lcd_class_device_attributes); i++) {
-               rc = class_device_create_file(&new_ld->class_dev,
-                                             &lcd_class_device_attributes[i]);
-               if (rc) {
-                       while (--i >= 0)
-                               class_device_remove_file(&new_ld->class_dev,
-                                                        &lcd_class_device_attributes[i]);
-                       class_device_unregister(&new_ld->class_dev);
-                       /* No need to kfree(new_ld) since release() method was called */
-                       return ERR_PTR(rc);
-               }
-       }
+       new_ld->ops = ops;
 
        return new_ld;
 }
@@ -235,33 +222,34 @@ EXPORT_SYMBOL(lcd_device_register);
  */
 void lcd_device_unregister(struct lcd_device *ld)
 {
-       int i;
-
        if (!ld)
                return;
 
-       pr_debug("lcd_device_unregister: name=%s\n", ld->class_dev.class_id);
-
-       for (i = 0; i < ARRAY_SIZE(lcd_class_device_attributes); i++)
-               class_device_remove_file(&ld->class_dev,
-                                        &lcd_class_device_attributes[i]);
-
        mutex_lock(&ld->ops_lock);
        ld->ops = NULL;
        mutex_unlock(&ld->ops_lock);
        lcd_unregister_fb(ld);
-       class_device_unregister(&ld->class_dev);
+
+       device_unregister(&ld->dev);
 }
 EXPORT_SYMBOL(lcd_device_unregister);
 
 static void __exit lcd_class_exit(void)
 {
-       class_unregister(&lcd_class);
+       class_destroy(lcd_class);
 }
 
 static int __init lcd_class_init(void)
 {
-       return class_register(&lcd_class);
+       lcd_class = class_create(THIS_MODULE, "lcd");
+       if (IS_ERR(lcd_class)) {
+               printk(KERN_WARNING "Unable to create backlight class; errno = %ld\n",
+                               PTR_ERR(lcd_class));
+               return PTR_ERR(lcd_class);
+       }
+
+       lcd_class->dev_attrs = lcd_device_attributes;
+       return 0;
 }
 
 /*
index f46fe95f69fbf13504fbc740799d1d64005d7631..d18b73aafa0d16af70fdf41886ee3e2fbcf00b09 100644 (file)
@@ -187,7 +187,11 @@ static void vgacon_scrollback_init(int pitch)
        }
 }
 
-static void vgacon_scrollback_startup(void)
+/*
+ * Called only duing init so call of alloc_bootmen is ok.
+ * Marked __init_refok to silence modpost.
+ */
+static void __init_refok vgacon_scrollback_startup(void)
 {
        vgacon_scrollback = alloc_bootmem(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE
                                          * 1024);
index 43f62d8ee41d8e3f0417c75757ffd1864e881bfb..443e3c85a9a0a677c12c2840899b55c209b261be 100644 (file)
@@ -50,7 +50,7 @@ static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
 
 static int nvidia_bl_update_status(struct backlight_device *bd)
 {
-       struct nvidia_par *par = class_get_devdata(&bd->class_dev);
+       struct nvidia_par *par = bl_get_data(bd);
        u32 tmp_pcrt, tmp_pmc, fpcontrol;
        int level;
 
index 3972aa8cf859051760c8f8be7b473217613c796d..646ec823c16844b50832152a8fc35c3665dcd636 100644 (file)
@@ -1067,7 +1067,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
        info->fix.smem_len = ps3fb_videomemory.size - offset;
        info->pseudo_palette = info->par;
        info->par = NULL;
-       info->flags = FBINFO_FLAG_DEFAULT;
+       info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST;
 
        retval = fb_alloc_cmap(&info->cmap, 256, 0);
        if (retval < 0)
index 0fe547842c643efceef03f9582e4940b7a3e2fd0..5c47968e7f2152bd3004cd8f0dd9c8a93ff18880 100644 (file)
@@ -307,7 +307,7 @@ static int riva_bl_get_level_brightness(struct riva_par *par,
 
 static int riva_bl_update_status(struct backlight_device *bd)
 {
-       struct riva_par *par = class_get_devdata(&bd->class_dev);
+       struct riva_par *par = bl_get_data(bd);
        U032 tmp_pcrt, tmp_pmc;
        int level;
 
@@ -2146,7 +2146,7 @@ static void __devexit rivafb_remove(struct pci_dev *pd)
  * ------------------------------------------------------------------------- */
 
 #ifndef MODULE
-static int __init rivafb_setup(char *options)
+static int __devinit rivafb_setup(char *options)
 {
        char *this_opt;
 
index ba24cb2ff6ceb83859f782677372ded1c69b20c2..4482a0673b1591869c63358a1db6a21582848252 100644 (file)
@@ -45,7 +45,7 @@
 
 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
 static int load_elf_library(struct file *);
-static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int, unsigned long);
+static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
 
 /*
  * If we don't support core dumping, then supply a NULL so we
@@ -80,7 +80,7 @@ static struct linux_binfmt elf_format = {
                .hasvdso        = 1
 };
 
-#define BAD_ADDR(x) IS_ERR_VALUE(x)
+#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE)
 
 static int set_brk(unsigned long start, unsigned long end)
 {
@@ -295,70 +295,33 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
 #ifndef elf_map
 
 static unsigned long elf_map(struct file *filep, unsigned long addr,
-               struct elf_phdr *eppnt, int prot, int type,
-               unsigned long total_size)
+               struct elf_phdr *eppnt, int prot, int type)
 {
        unsigned long map_addr;
-       unsigned long size = eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr);
-       unsigned long off = eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr);
-       addr = ELF_PAGESTART(addr);
-       size = ELF_PAGEALIGN(size);
+       unsigned long pageoffset = ELF_PAGEOFFSET(eppnt->p_vaddr);
 
+       down_write(&current->mm->mmap_sem);
        /* mmap() will return -EINVAL if given a zero size, but a
         * segment with zero filesize is perfectly valid */
-       if (!size)
-               return addr;
-
-       down_write(&current->mm->mmap_sem);
-       /*
-       * total_size is the size of the ELF (interpreter) image.
-       * The _first_ mmap needs to know the full size, otherwise
-       * randomization might put this image into an overlapping
-       * position with the ELF binary image. (since size < total_size)
-       * So we first map the 'big' image - and unmap the remainder at
-       * the end. (which unmap is needed for ELF images with holes.)
-       */
-       if (total_size) {
-               total_size = ELF_PAGEALIGN(total_size);
-               map_addr = do_mmap(filep, addr, total_size, prot, type, off);
-               if (!BAD_ADDR(map_addr))
-                       do_munmap(current->mm, map_addr+size, total_size-size);
-       } else
-               map_addr = do_mmap(filep, addr, size, prot, type, off);
-
+       if (eppnt->p_filesz + pageoffset)
+               map_addr = do_mmap(filep, ELF_PAGESTART(addr),
+                                  eppnt->p_filesz + pageoffset, prot, type,
+                                  eppnt->p_offset - pageoffset);
+       else
+               map_addr = ELF_PAGESTART(addr);
        up_write(&current->mm->mmap_sem);
        return(map_addr);
 }
 
 #endif /* !elf_map */
 
-static unsigned long total_mapping_size(struct elf_phdr *cmds, int nr)
-{
-       int i, first_idx = -1, last_idx = -1;
-
-       for (i = 0; i < nr; i++) {
-               if (cmds[i].p_type == PT_LOAD) {
-                       last_idx = i;
-                       if (first_idx == -1)
-                               first_idx = i;
-               }
-       }
-       if (first_idx == -1)
-               return 0;
-
-       return cmds[last_idx].p_vaddr + cmds[last_idx].p_memsz -
-                               ELF_PAGESTART(cmds[first_idx].p_vaddr);
-}
-
-
 /* This is much more generalized than the library routine read function,
    so we keep this separate.  Technically the library read function
    is only provided so that we can read a.out libraries that have
    an ELF header */
 
 static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
-               struct file *interpreter, unsigned long *interp_map_addr,
-               unsigned long no_base)
+               struct file *interpreter, unsigned long *interp_load_addr)
 {
        struct elf_phdr *elf_phdata;
        struct elf_phdr *eppnt;
@@ -366,7 +329,6 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
        int load_addr_set = 0;
        unsigned long last_bss = 0, elf_bss = 0;
        unsigned long error = ~0UL;
-       unsigned long total_size;
        int retval, i, size;
 
        /* First of all, some simple consistency checks */
@@ -405,12 +367,6 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
                goto out_close;
        }
 
-       total_size = total_mapping_size(elf_phdata, interp_elf_ex->e_phnum);
-       if (!total_size) {
-               error = -EINVAL;
-               goto out_close;
-       }
-
        eppnt = elf_phdata;
        for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
                if (eppnt->p_type == PT_LOAD) {
@@ -428,14 +384,9 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
                        vaddr = eppnt->p_vaddr;
                        if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
                                elf_type |= MAP_FIXED;
-                       else if (no_base && interp_elf_ex->e_type == ET_DYN)
-                               load_addr = -vaddr;
 
                        map_addr = elf_map(interpreter, load_addr + vaddr,
-                                          eppnt, elf_prot, elf_type, total_size);
-                       total_size = 0;
-                       if (!*interp_map_addr)
-                               *interp_map_addr = map_addr;
+                                          eppnt, elf_prot, elf_type);
                        error = map_addr;
                        if (BAD_ADDR(map_addr))
                                goto out_close;
@@ -501,7 +452,8 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
                        goto out_close;
        }
 
-       error = load_addr;
+       *interp_load_addr = load_addr;
+       error = ((unsigned long)interp_elf_ex->e_entry) + load_addr;
 
 out_close:
        kfree(elf_phdata);
@@ -598,8 +550,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
        int elf_exec_fileno;
        int retval, i;
        unsigned int size;
-       unsigned long elf_entry;
-       unsigned long interp_load_addr = 0;
+       unsigned long elf_entry, interp_load_addr = 0;
        unsigned long start_code, end_code, start_data, end_data;
        unsigned long reloc_func_desc = 0;
        char passed_fileno[6];
@@ -863,7 +814,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
        current->mm->start_stack = bprm->p;
 
        /* Now we do a little grungy work by mmaping the ELF image into
-          the correct location in memory. */
+          the correct location in memory.  At this point, we assume that
+          the image should be loaded at fixed address, not at a variable
+          address. */
        for(i = 0, elf_ppnt = elf_phdata;
            i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {
                int elf_prot = 0, elf_flags;
@@ -917,15 +870,11 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
                         * default mmap base, as well as whatever program they
                         * might try to exec.  This is because the brk will
                         * follow the loader, and is not movable.  */
-#ifdef CONFIG_X86
-                       load_bias = 0;
-#else
                        load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
-#endif
                }
 
                error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
-                               elf_prot, elf_flags,0);
+                               elf_prot, elf_flags);
                if (BAD_ADDR(error)) {
                        send_sig(SIGKILL, current, 0);
                        retval = IS_ERR((void *)error) ?
@@ -1001,25 +950,13 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
        }
 
        if (elf_interpreter) {
-               if (interpreter_type == INTERPRETER_AOUT) {
+               if (interpreter_type == INTERPRETER_AOUT)
                        elf_entry = load_aout_interp(&loc->interp_ex,
                                                     interpreter);
-               } else {
-                       unsigned long uninitialized_var(interp_map_addr);
-
+               else
                        elf_entry = load_elf_interp(&loc->interp_elf_ex,
                                                    interpreter,
-                                                   &interp_map_addr,
-                                                   load_bias);
-                       if (!BAD_ADDR(elf_entry)) {
-                               /*
-                                * load_elf_interp() returns relocation
-                                * adjustment
-                                */
-                               interp_load_addr = elf_entry;
-                               elf_entry += loc->interp_elf_ex.e_entry;
-                       }
-               }
+                                                   &interp_load_addr);
                if (BAD_ADDR(elf_entry)) {
                        force_sig(SIGSEGV, current);
                        retval = IS_ERR((void *)elf_entry) ?
index 8e61236abf4a7e2eb650480628aa2ab9fa1cc46c..f89ff083079ba5b8fd1595f233c3c9b949d472de 100644 (file)
@@ -86,7 +86,6 @@ const struct file_operations coda_dir_operations = {
        .read           = generic_read_dir,
        .readdir        = coda_readdir,
        .open           = coda_open,
-       .flush          = coda_flush,
        .release        = coda_release,
        .fsync          = coda_fsync,
 };
index 7594962604c21051bc1d48a154f701678f191144..29137ff3ca67c155ac2da3d9328258700369195e 100644 (file)
 
 #include "coda_int.h"
 
-/* if CODA_STORE fails with EOPNOTSUPP, venus clearly doesn't support
- * CODA_STORE/CODA_RELEASE and we fall back on using the CODA_CLOSE upcall */
-static int use_coda_close;
-
 static ssize_t
 coda_file_read(struct file *coda_file, char __user *buf, size_t count, loff_t *ppos)
 {
@@ -163,47 +159,6 @@ int coda_open(struct inode *coda_inode, struct file *coda_file)
        return 0;
 }
 
-int coda_flush(struct file *coda_file, fl_owner_t id)
-{
-       unsigned short flags = coda_file->f_flags & ~O_EXCL;
-       unsigned short coda_flags = coda_flags_to_cflags(flags);
-       struct coda_file_info *cfi;
-       struct inode *coda_inode;
-       int err = 0, fcnt;
-
-       lock_kernel();
-
-       /* last close semantics */
-       fcnt = file_count(coda_file);
-       if (fcnt > 1)
-               goto out;
-
-       /* No need to make an upcall when we have not made any modifications
-        * to the file */
-       if ((coda_file->f_flags & O_ACCMODE) == O_RDONLY)
-               goto out;
-
-       if (use_coda_close)
-               goto out;
-
-       cfi = CODA_FTOC(coda_file);
-       BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
-
-       coda_inode = coda_file->f_path.dentry->d_inode;
-
-       err = venus_store(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags,
-                         coda_file->f_uid);
-
-       if (err == -EOPNOTSUPP) {
-               use_coda_close = 1;
-               err = 0;
-       }
-
-out:
-       unlock_kernel();
-       return err;
-}
-
 int coda_release(struct inode *coda_inode, struct file *coda_file)
 {
        unsigned short flags = (coda_file->f_flags) & (~O_EXCL);
@@ -215,21 +170,11 @@ int coda_release(struct inode *coda_inode, struct file *coda_file)
 
        lock_kernel();
 
-       if (!use_coda_close) {
-               err = venus_release(coda_inode->i_sb, coda_i2f(coda_inode),
-                                   coda_flags);
-               if (err == -EOPNOTSUPP) {
-                       use_coda_close = 1;
-                       err = 0;
-               }
-       }
-
        cfi = CODA_FTOC(coda_file);
        BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
 
-       if (use_coda_close)
-               err = venus_close(coda_inode->i_sb, coda_i2f(coda_inode),
-                                 coda_flags, coda_file->f_uid);
+       err = venus_close(coda_inode->i_sb, coda_i2f(coda_inode),
+                         coda_flags, coda_file->f_uid);
 
        host_inode = cfi->cfi_container->f_path.dentry->d_inode;
        cii = ITOC(coda_inode);
@@ -246,7 +191,10 @@ int coda_release(struct inode *coda_inode, struct file *coda_file)
        coda_file->private_data = NULL;
 
        unlock_kernel();
-       return err;
+
+       /* VFS fput ignores the return value from file_operations->release, so
+        * there is no use returning an error here */
+       return 0;
 }
 
 int coda_fsync(struct file *coda_file, struct dentry *coda_dentry, int datasync)
@@ -288,7 +236,6 @@ const struct file_operations coda_file_operations = {
        .write          = coda_file_write,
        .mmap           = coda_file_mmap,
        .open           = coda_open,
-       .flush          = coda_flush,
        .release        = coda_release,
        .fsync          = coda_fsync,
        .splice_read    = coda_file_splice_read,
index cd561d2e90b05723dfd611ae6604ca2a895695cf..cdb4c07a78700a93e34739a4aadddda96bfce8cc 100644 (file)
@@ -160,55 +160,8 @@ int venus_lookup(struct super_block *sb, struct CodaFid *fid,
        return error;
 }
 
-int venus_store(struct super_block *sb, struct CodaFid *fid, int flags,
-                vuid_t uid)
-{
-        union inputArgs *inp;
-        union outputArgs *outp;
-        int insize, outsize, error;
-#ifdef CONFIG_CODA_FS_OLD_API
-       struct coda_cred cred = { 0, };
-       cred.cr_fsuid = uid;
-#endif
-       
-       insize = SIZE(store);
-       UPARG(CODA_STORE);
-       
-#ifdef CONFIG_CODA_FS_OLD_API
-       memcpy(&(inp->ih.cred), &cred, sizeof(cred));
-#else
-       inp->ih.uid = uid;
-#endif
-       
-        inp->coda_store.VFid = *fid;
-        inp->coda_store.flags = flags;
-
-       error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
-
-       CODA_FREE(inp, insize);
-        return error;
-}
-
-int venus_release(struct super_block *sb, struct CodaFid *fid, int flags)
-{
-        union inputArgs *inp;
-        union outputArgs *outp;
-        int insize, outsize, error;
-       
-       insize = SIZE(release);
-       UPARG(CODA_RELEASE);
-       
-       inp->coda_release.VFid = *fid;
-       inp->coda_release.flags = flags;
-
-       error = coda_upcall(coda_vcp(sb), insize, &outsize, inp);
-
-       CODA_FREE(inp, insize);
-       return error;
-}
-
 int venus_close(struct super_block *sb, struct CodaFid *fid, int flags,
-                vuid_t uid)
+               vuid_t uid)
 {
        union inputArgs *inp;
        union outputArgs *outp;
index b34b7a711d5b6e3e7f8280b71ee26940523f0eaf..b2a851c1b8cb0230a59a2dfef0a2dd77f9c9593d 100644 (file)
@@ -732,7 +732,7 @@ static int nfs_parse_mount_options(char *raw,
                                return 0;
                        if (option < 0 || option > 65535)
                                return 0;
-                       mnt->nfs_server.address.sin_port = htonl(option);
+                       mnt->nfs_server.address.sin_port = htons(option);
                        break;
                case Opt_rsize:
                        if (match_int(args, &mnt->rsize))
index 6ab8de40904ce97c4c41f8c7a5b1a671fe85ce19..2d295dda4c1d63c774970f7baa76403658ccae4f 100644 (file)
@@ -1503,9 +1503,9 @@ static void exp_flags(struct seq_file *m, int flag, int fsid,
        if (flag & NFSEXP_FSID)
                seq_printf(m, ",fsid=%d", fsid);
        if (anonu != (uid_t)-2 && anonu != (0x10000-2))
-               seq_printf(m, ",sanonuid=%d", anonu);
+               seq_printf(m, ",anonuid=%u", anonu);
        if (anong != (gid_t)-2 && anong != (0x10000-2))
-               seq_printf(m, ",sanongid=%d", anong);
+               seq_printf(m, ",anongid=%u", anong);
        if (fsloc && fsloc->locations_count > 0) {
                char *loctype = (fsloc->migrated) ? "refer" : "replicas";
                int i;
index f133afebed7aca1c7ece0a2ddebc234fb1fcff2d..bee251cb87c8c42c3d051ec2ea53df209e422c52 100644 (file)
@@ -507,7 +507,8 @@ static int show_stat(struct seq_file *p, void *v)
        }
        seq_printf(p, "intr %llu", (unsigned long long)sum);
 
-#if !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
+#ifndef CONFIG_SMP
+       /* Touches too many cache lines on SMP setups */
        for (i = 0; i < NR_IRQS; i++)
                seq_printf(p, " %u", per_irq_sum[i]);
 #endif
index ef48d094dd2b0bcd8427613594d1fd9d38f4495e..276f7207a5642369ba2d56dabad2b683f9444388 100644 (file)
@@ -70,9 +70,9 @@ static inline int find_next_one_bit(void *addr, int size, int offset)
        if (!size)
                return result;
        tmp = leBPL_to_cpup(p);
-      found_first:
+found_first:
        tmp &= ~0UL >> (BITS_PER_LONG - size);
-      found_middle:
+found_middle:
        return result + ffz(~tmp);
 }
 
@@ -110,11 +110,11 @@ static int __load_block_bitmap(struct super_block *sb,
                          nr_groups);
        }
 
-       if (bitmap->s_block_bitmap[block_group])
+       if (bitmap->s_block_bitmap[block_group]) {
                return block_group;
-       else {
-               retval =
-                   read_block_bitmap(sb, bitmap, block_group, block_group);
+       else {
+               retval = read_block_bitmap(sb, bitmap, block_group,
+                                          block_group);
                if (retval < 0)
                        return retval;
                return block_group;
@@ -155,22 +155,16 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
 
        mutex_lock(&sbi->s_alloc_mutex);
        if (bloc.logicalBlockNum < 0 ||
-           (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb,
-                                                           bloc.
-                                                           partitionReferenceNum))
-       {
-               udf_debug("%d < %d || %d + %d > %d\n", bloc.logicalBlockNum, 0,
-                         bloc.logicalBlockNum, count, UDF_SB_PARTLEN(sb,
-                                                                     bloc.
-                                                                     partitionReferenceNum));
+           (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
+               udf_debug("%d < %d || %d + %d > %d\n",
+                         bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
+                         UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum));
                goto error_return;
        }
 
-       block =
-           bloc.logicalBlockNum + offset +
-           (sizeof(struct spaceBitmapDesc) << 3);
+       block = bloc.logicalBlockNum + offset + (sizeof(struct spaceBitmapDesc) << 3);
 
-      do_more:
+do_more:
        overflow = 0;
        block_group = block >> (sb->s_blocksize_bits + 3);
        bit = block % (sb->s_blocksize << 3);
@@ -190,18 +184,13 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
        for (i = 0; i < count; i++) {
                if (udf_set_bit(bit + i, bh->b_data)) {
                        udf_debug("bit %ld already set\n", bit + i);
-                       udf_debug("byte=%2x\n",
-                                 ((char *)bh->b_data)[(bit + i) >> 3]);
+                       udf_debug("byte=%2x\n", ((char *)bh->b_data)[(bit + i) >> 3]);
                } else {
                        if (inode)
                                DQUOT_FREE_BLOCK(inode, 1);
                        if (UDF_SB_LVIDBH(sb)) {
-                               UDF_SB_LVID(sb)->
-                                   freeSpaceTable[UDF_SB_PARTITION(sb)] =
-                                   cpu_to_le32(le32_to_cpu
-                                               (UDF_SB_LVID(sb)->
-                                                freeSpaceTable[UDF_SB_PARTITION
-                                                               (sb)]) + 1);
+                               UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
+                                       cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]) + 1);
                        }
                }
        }
@@ -211,7 +200,7 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
                count = overflow;
                goto do_more;
        }
-      error_return:
+error_return:
        sb->s_dirt = 1;
        if (UDF_SB_LVIDBH(sb))
                mark_buffer_dirty(UDF_SB_LVIDBH(sb));
@@ -238,7 +227,7 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb,
        if (first_block + block_count > UDF_SB_PARTLEN(sb, partition))
                block_count = UDF_SB_PARTLEN(sb, partition) - first_block;
 
-      repeat:
+repeat:
        nr_groups = (UDF_SB_PARTLEN(sb, partition) +
                     (sizeof(struct spaceBitmapDesc) << 3) +
                     (sb->s_blocksize * 8) - 1) / (sb->s_blocksize * 8);
@@ -254,11 +243,11 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb,
        bit = block % (sb->s_blocksize << 3);
 
        while (bit < (sb->s_blocksize << 3) && block_count > 0) {
-               if (!udf_test_bit(bit, bh->b_data))
+               if (!udf_test_bit(bit, bh->b_data)) {
                        goto out;
-               else if (DQUOT_PREALLOC_BLOCK(inode, 1))
+               } else if (DQUOT_PREALLOC_BLOCK(inode, 1)) {
                        goto out;
-               else if (!udf_clear_bit(bit, bh->b_data)) {
+               else if (!udf_clear_bit(bit, bh->b_data)) {
                        udf_debug("bit already cleared for block %d\n", bit);
                        DQUOT_FREE_BLOCK(inode, 1);
                        goto out;
@@ -271,12 +260,10 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb,
        mark_buffer_dirty(bh);
        if (block_count > 0)
                goto repeat;
-      out:
+out:
        if (UDF_SB_LVIDBH(sb)) {
                UDF_SB_LVID(sb)->freeSpaceTable[partition] =
-                   cpu_to_le32(le32_to_cpu
-                               (UDF_SB_LVID(sb)->freeSpaceTable[partition]) -
-                               alloc_count);
+                       cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition]) - alloc_count);
                mark_buffer_dirty(UDF_SB_LVIDBH(sb));
        }
        sb->s_dirt = 1;
@@ -299,7 +286,7 @@ static int udf_bitmap_new_block(struct super_block *sb,
        *err = -ENOSPC;
        mutex_lock(&sbi->s_alloc_mutex);
 
-      repeat:
+repeat:
        if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
                goal = 0;
 
@@ -312,31 +299,27 @@ static int udf_bitmap_new_block(struct super_block *sb,
        if (bitmap_nr < 0)
                goto error_return;
        bh = bitmap->s_block_bitmap[bitmap_nr];
-       ptr =
-           memscan((char *)bh->b_data + group_start, 0xFF,
-                   sb->s_blocksize - group_start);
+       ptr = memscan((char *)bh->b_data + group_start, 0xFF,
+                     sb->s_blocksize - group_start);
 
        if ((ptr - ((char *)bh->b_data)) < sb->s_blocksize) {
                bit = block % (sb->s_blocksize << 3);
-
-               if (udf_test_bit(bit, bh->b_data)) {
+               if (udf_test_bit(bit, bh->b_data))
                        goto got_block;
-               }
+
                end_goal = (bit + 63) & ~63;
                bit = udf_find_next_one_bit(bh->b_data, end_goal, bit);
                if (bit < end_goal)
                        goto got_block;
-               ptr =
-                   memscan((char *)bh->b_data + (bit >> 3), 0xFF,
-                           sb->s_blocksize - ((bit + 7) >> 3));
+
+               ptr = memscan((char *)bh->b_data + (bit >> 3), 0xFF, sb->s_blocksize - ((bit + 7) >> 3));
                newbit = (ptr - ((char *)bh->b_data)) << 3;
                if (newbit < sb->s_blocksize << 3) {
                        bit = newbit;
                        goto search_back;
                }
-               newbit =
-                   udf_find_next_one_bit(bh->b_data, sb->s_blocksize << 3,
-                                         bit);
+
+               newbit = udf_find_next_one_bit(bh->b_data, sb->s_blocksize << 3, bit);
                if (newbit < sb->s_blocksize << 3) {
                        bit = newbit;
                        goto got_block;
@@ -354,18 +337,16 @@ static int udf_bitmap_new_block(struct super_block *sb,
                        goto error_return;
                bh = bitmap->s_block_bitmap[bitmap_nr];
                if (i < nr_groups) {
-                       ptr =
-                           memscan((char *)bh->b_data + group_start, 0xFF,
-                                   sb->s_blocksize - group_start);
+                       ptr = memscan((char *)bh->b_data + group_start, 0xFF,
+                                     sb->s_blocksize - group_start);
                        if ((ptr - ((char *)bh->b_data)) < sb->s_blocksize) {
                                bit = (ptr - ((char *)bh->b_data)) << 3;
                                break;
                        }
                } else {
-                       bit =
-                           udf_find_next_one_bit((char *)bh->b_data,
-                                                 sb->s_blocksize << 3,
-                                                 group_start << 3);
+                       bit = udf_find_next_one_bit((char *)bh->b_data,
+                                                   sb->s_blocksize << 3,
+                                                   group_start << 3);
                        if (bit < sb->s_blocksize << 3)
                                break;
                }
@@ -377,20 +358,17 @@ static int udf_bitmap_new_block(struct super_block *sb,
        if (bit < sb->s_blocksize << 3)
                goto search_back;
        else
-               bit =
-                   udf_find_next_one_bit(bh->b_data, sb->s_blocksize << 3,
-                                         group_start << 3);
+               bit = udf_find_next_one_bit(bh->b_data, sb->s_blocksize << 3, group_start << 3);
        if (bit >= sb->s_blocksize << 3) {
                mutex_unlock(&sbi->s_alloc_mutex);
                return 0;
        }
 
-      search_back:
-       for (i = 0;
-            i < 7 && bit > (group_start << 3)
-            && udf_test_bit(bit - 1, bh->b_data); i++, bit--) ;
+search_back:
+       for (i = 0; i < 7 && bit > (group_start << 3) && udf_test_bit(bit - 1, bh->b_data); i++, bit--)
+               ; /* empty loop */
 
-      got_block:
+got_block:
 
        /*
         * Check quota for allocation of this block.
@@ -402,7 +380,7 @@ static int udf_bitmap_new_block(struct super_block *sb,
        }
 
        newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) -
-           (sizeof(struct spaceBitmapDesc) << 3);
+               (sizeof(struct spaceBitmapDesc) << 3);
 
        if (!udf_clear_bit(bit, bh->b_data)) {
                udf_debug("bit already cleared for block %d\n", bit);
@@ -413,9 +391,7 @@ static int udf_bitmap_new_block(struct super_block *sb,
 
        if (UDF_SB_LVIDBH(sb)) {
                UDF_SB_LVID(sb)->freeSpaceTable[partition] =
-                   cpu_to_le32(le32_to_cpu
-                               (UDF_SB_LVID(sb)->freeSpaceTable[partition]) -
-                               1);
+                       cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition]) - 1);
                mark_buffer_dirty(UDF_SB_LVIDBH(sb));
        }
        sb->s_dirt = 1;
@@ -423,7 +399,7 @@ static int udf_bitmap_new_block(struct super_block *sb,
        *err = 0;
        return newblock;
 
-      error_return:
+error_return:
        *err = -EIO;
        mutex_unlock(&sbi->s_alloc_mutex);
        return 0;
@@ -445,14 +421,10 @@ static void udf_table_free_blocks(struct super_block *sb,
 
        mutex_lock(&sbi->s_alloc_mutex);
        if (bloc.logicalBlockNum < 0 ||
-           (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb,
-                                                           bloc.
-                                                           partitionReferenceNum))
-       {
-               udf_debug("%d < %d || %d + %d > %d\n", bloc.logicalBlockNum, 0,
-                         bloc.logicalBlockNum, count, UDF_SB_PARTLEN(sb,
-                                                                     bloc.
-                                                                     partitionReferenceNum));
+           (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
+               udf_debug("%d < %d || %d + %d > %d\n",
+                         bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
+                         UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum));
                goto error_return;
        }
 
@@ -462,9 +434,7 @@ static void udf_table_free_blocks(struct super_block *sb,
                DQUOT_FREE_BLOCK(inode, count);
        if (UDF_SB_LVIDBH(sb)) {
                UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)] =
-                   cpu_to_le32(le32_to_cpu
-                               (UDF_SB_LVID(sb)->
-                                freeSpaceTable[UDF_SB_PARTITION(sb)]) + count);
+                       cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]) + count);
                mark_buffer_dirty(UDF_SB_LVIDBH(sb));
        }
 
@@ -476,47 +446,28 @@ static void udf_table_free_blocks(struct super_block *sb,
        epos.block = oepos.block = UDF_I_LOCATION(table);
        epos.bh = oepos.bh = NULL;
 
-       while (count && (etype =
-                        udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) {
-               if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) ==
-                    start)) {
-                       if ((0x3FFFFFFF - elen) <
-                           (count << sb->s_blocksize_bits)) {
-                               count -=
-                                   ((0x3FFFFFFF -
-                                     elen) >> sb->s_blocksize_bits);
-                               start +=
-                                   ((0x3FFFFFFF -
-                                     elen) >> sb->s_blocksize_bits);
-                               elen =
-                                   (etype << 30) | (0x40000000 -
-                                                    sb->s_blocksize);
+       while (count &&
+              (etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) {
+               if (((eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits)) == start)) {
+                       if ((0x3FFFFFFF - elen) < (count << sb->s_blocksize_bits)) {
+                               count -= ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
+                               start += ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
+                               elen = (etype << 30) | (0x40000000 - sb->s_blocksize);
                        } else {
-                               elen = (etype << 30) |
-                                   (elen + (count << sb->s_blocksize_bits));
+                               elen = (etype << 30) | (elen + (count << sb->s_blocksize_bits));
                                start += count;
                                count = 0;
                        }
                        udf_write_aext(table, &oepos, eloc, elen, 1);
                } else if (eloc.logicalBlockNum == (end + 1)) {
-                       if ((0x3FFFFFFF - elen) <
-                           (count << sb->s_blocksize_bits)) {
-                               count -=
-                                   ((0x3FFFFFFF -
-                                     elen) >> sb->s_blocksize_bits);
-                               end -=
-                                   ((0x3FFFFFFF -
-                                     elen) >> sb->s_blocksize_bits);
-                               eloc.logicalBlockNum -=
-                                   ((0x3FFFFFFF -
-                                     elen) >> sb->s_blocksize_bits);
-                               elen =
-                                   (etype << 30) | (0x40000000 -
-                                                    sb->s_blocksize);
+                       if ((0x3FFFFFFF - elen) < (count << sb->s_blocksize_bits)) {
+                               count -= ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
+                               end -= ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
+                               eloc.logicalBlockNum -= ((0x3FFFFFFF - elen) >> sb->s_blocksize_bits);
+                               elen = (etype << 30) | (0x40000000 - sb->s_blocksize);
                        } else {
                                eloc.logicalBlockNum = start;
-                               elen = (etype << 30) |
-                                   (elen + (count << sb->s_blocksize_bits));
+                               elen = (etype << 30) | (elen + (count << sb->s_blocksize_bits));
                                end -= count;
                                count = 0;
                        }
@@ -530,21 +481,23 @@ static void udf_table_free_blocks(struct super_block *sb,
                        get_bh(epos.bh);
                        oepos.bh = epos.bh;
                        oepos.offset = 0;
-               } else
+               } else {
                        oepos.offset = epos.offset;
+               }
        }
 
        if (count) {
-               /* NOTE: we CANNOT use udf_add_aext here, as it can try to allocate
-                  a new block, and since we hold the super block lock already
-                  very bad things would happen :)
-
-                  We copy the behavior of udf_add_aext, but instead of
-                  trying to allocate a new block close to the existing one,
-                  we just steal a block from the extent we are trying to add.
-
-                  It would be nice if the blocks were close together, but it
-                  isn't required.
+               /*
+                * NOTE: we CANNOT use udf_add_aext here, as it can try to allocate
+                * a new block, and since we hold the super block lock already
+                * very bad things would happen :)
+                *
+                * We copy the behavior of udf_add_aext, but instead of
+                * trying to allocate a new block close to the existing one,
+                * we just steal a block from the extent we are trying to add.
+                *
+                * It would be nice if the blocks were close together, but it
+                * isn't required.
                 */
 
                int adsize;
@@ -553,13 +506,14 @@ static void udf_table_free_blocks(struct super_block *sb,
                struct allocExtDesc *aed;
 
                eloc.logicalBlockNum = start;
-               elen = EXT_RECORDED_ALLOCATED | (count << sb->s_blocksize_bits);
+               elen = EXT_RECORDED_ALLOCATED |
+                       (count << sb->s_blocksize_bits);
 
-               if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
+               if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT) {
                        adsize = sizeof(short_ad);
-               else if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_LONG)
+               } else if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_LONG) {
                        adsize = sizeof(long_ad);
-               else {
+               else {
                        brelse(oepos.bh);
                        brelse(epos.bh);
                        goto error_return;
@@ -577,28 +531,21 @@ static void udf_table_free_blocks(struct super_block *sb,
                        eloc.logicalBlockNum++;
                        elen -= sb->s_blocksize;
 
-                       if (!(epos.bh = udf_tread(sb,
-                                                 udf_get_lb_pblock(sb,
-                                                                   epos.block,
-                                                                   0)))) {
+                       if (!(epos.bh = udf_tread(sb, udf_get_lb_pblock(sb, epos.block, 0)))) {
                                brelse(oepos.bh);
                                goto error_return;
                        }
                        aed = (struct allocExtDesc *)(epos.bh->b_data);
-                       aed->previousAllocExtLocation =
-                           cpu_to_le32(oepos.block.logicalBlockNum);
+                       aed->previousAllocExtLocation = cpu_to_le32(oepos.block.logicalBlockNum);
                        if (epos.offset + adsize > sb->s_blocksize) {
                                loffset = epos.offset;
                                aed->lengthAllocDescs = cpu_to_le32(adsize);
                                sptr = UDF_I_DATA(inode) + epos.offset -
-                                   udf_file_entry_alloc_offset(inode) +
-                                   UDF_I_LENEATTR(inode) - adsize;
-                               dptr =
-                                   epos.bh->b_data +
-                                   sizeof(struct allocExtDesc);
+                                       udf_file_entry_alloc_offset(inode) +
+                                       UDF_I_LENEATTR(inode) - adsize;
+                               dptr = epos.bh->b_data + sizeof(struct allocExtDesc);
                                memcpy(dptr, sptr, adsize);
-                               epos.offset =
-                                   sizeof(struct allocExtDesc) + adsize;
+                               epos.offset = sizeof(struct allocExtDesc) + adsize;
                        } else {
                                loffset = epos.offset + adsize;
                                aed->lengthAllocDescs = cpu_to_le32(0);
@@ -606,60 +553,46 @@ static void udf_table_free_blocks(struct super_block *sb,
                                epos.offset = sizeof(struct allocExtDesc);
 
                                if (oepos.bh) {
-                                       aed =
-                                           (struct allocExtDesc *)oepos.bh->
-                                           b_data;
+                                       aed = (struct allocExtDesc *)oepos.bh->b_data;
                                        aed->lengthAllocDescs =
-                                           cpu_to_le32(le32_to_cpu
-                                                       (aed->
-                                                        lengthAllocDescs) +
-                                                       adsize);
+                                               cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
                                } else {
                                        UDF_I_LENALLOC(table) += adsize;
                                        mark_inode_dirty(table);
                                }
                        }
                        if (UDF_SB_UDFREV(sb) >= 0x0200)
-                               udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 3,
-                                           1, epos.block.logicalBlockNum,
-                                           sizeof(tag));
+                               udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 3, 1,
+                                           epos.block.logicalBlockNum, sizeof(tag));
                        else
-                               udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 2,
-                                           1, epos.block.logicalBlockNum,
-                                           sizeof(tag));
+                               udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 2, 1,
+                                           epos.block.logicalBlockNum, sizeof(tag));
+
                        switch (UDF_I_ALLOCTYPE(table)) {
-                       case ICBTAG_FLAG_AD_SHORT:
-                               {
-                                       sad = (short_ad *) sptr;
-                                       sad->extLength =
-                                           cpu_to_le32
-                                           (EXT_NEXT_EXTENT_ALLOCDECS | sb->
-                                            s_blocksize);
-                                       sad->extPosition =
-                                           cpu_to_le32(epos.block.
-                                                       logicalBlockNum);
+                               case ICBTAG_FLAG_AD_SHORT:
+                                       sad = (short_ad *)sptr;
+                                       sad->extLength = cpu_to_le32(
+                                               EXT_NEXT_EXTENT_ALLOCDECS |
+                                               sb->s_blocksize);
+                                       sad->extPosition = cpu_to_le32(epos.block.logicalBlockNum);
                                        break;
-                               }
-                       case ICBTAG_FLAG_AD_LONG:
-                               {
-                                       lad = (long_ad *) sptr;
-                                       lad->extLength =
-                                           cpu_to_le32
-                                           (EXT_NEXT_EXTENT_ALLOCDECS | sb->
-                                            s_blocksize);
-                                       lad->extLocation =
-                                           cpu_to_lelb(epos.block);
+                               case ICBTAG_FLAG_AD_LONG:
+                                       lad = (long_ad *)sptr;
+                                       lad->extLength = cpu_to_le32(
+                                               EXT_NEXT_EXTENT_ALLOCDECS |
+                                               sb->s_blocksize);
+                                       lad->extLocation = cpu_to_lelb(epos.block);
                                        break;
-                               }
                        }
                        if (oepos.bh) {
                                udf_update_tag(oepos.bh->b_data, loffset);
                                mark_buffer_dirty(oepos.bh);
-                       } else
+                       } else {
                                mark_inode_dirty(table);
+                       }
                }
 
-               if (elen) {     /* It's possible that stealing the block emptied the extent */
+               if (elen) { /* It's possible that stealing the block emptied the extent */
                        udf_write_aext(table, &epos, eloc, elen, 1);
 
                        if (!epos.bh) {
@@ -668,9 +601,7 @@ static void udf_table_free_blocks(struct super_block *sb,
                        } else {
                                aed = (struct allocExtDesc *)epos.bh->b_data;
                                aed->lengthAllocDescs =
-                                   cpu_to_le32(le32_to_cpu
-                                               (aed->lengthAllocDescs) +
-                                               adsize);
+                                       cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
                                udf_update_tag(epos.bh->b_data, epos.offset);
                                mark_buffer_dirty(epos.bh);
                        }
@@ -680,7 +611,7 @@ static void udf_table_free_blocks(struct super_block *sb,
        brelse(epos.bh);
        brelse(oepos.bh);
 
-      error_return:
+error_return:
        sb->s_dirt = 1;
        mutex_unlock(&sbi->s_alloc_mutex);
        return;
@@ -714,47 +645,36 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
        epos.bh = NULL;
        eloc.logicalBlockNum = 0xFFFFFFFF;
 
-       while (first_block != eloc.logicalBlockNum && (etype =
-                                                      udf_next_aext(table,
-                                                                    &epos,
-                                                                    &eloc,
-                                                                    &elen,
-                                                                    1)) !=
-              -1) {
+       while (first_block != eloc.logicalBlockNum &&
+              (etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) {
                udf_debug("eloc=%d, elen=%d, first_block=%d\n",
                          eloc.logicalBlockNum, elen, first_block);
-               ;               /* empty loop body */
+               ; /* empty loop body */
        }
 
        if (first_block == eloc.logicalBlockNum) {
                epos.offset -= adsize;
 
                alloc_count = (elen >> sb->s_blocksize_bits);
-               if (inode
-                   && DQUOT_PREALLOC_BLOCK(inode,
-                                           alloc_count >
-                                           block_count ? block_count :
-                                           alloc_count))
+               if (inode && DQUOT_PREALLOC_BLOCK(inode, alloc_count > block_count ? block_count : alloc_count)) {
                        alloc_count = 0;
-               else if (alloc_count > block_count) {
+               else if (alloc_count > block_count) {
                        alloc_count = block_count;
                        eloc.logicalBlockNum += alloc_count;
                        elen -= (alloc_count << sb->s_blocksize_bits);
-                       udf_write_aext(table, &epos, eloc, (etype << 30) | elen,
-                                      1);
-               } else
-                       udf_delete_aext(table, epos, eloc,
-                                       (etype << 30) | elen);
-       } else
+                       udf_write_aext(table, &epos, eloc, (etype << 30) | elen, 1);
+               } else {
+                       udf_delete_aext(table, epos, eloc, (etype << 30) | elen);
+               }
+       } else {
                alloc_count = 0;
+       }
 
        brelse(epos.bh);
 
        if (alloc_count && UDF_SB_LVIDBH(sb)) {
                UDF_SB_LVID(sb)->freeSpaceTable[partition] =
-                   cpu_to_le32(le32_to_cpu
-                               (UDF_SB_LVID(sb)->freeSpaceTable[partition]) -
-                               alloc_count);
+                       cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition]) - alloc_count);
                mark_buffer_dirty(UDF_SB_LVIDBH(sb));
                sb->s_dirt = 1;
        }
@@ -797,18 +717,17 @@ static int udf_table_new_block(struct super_block *sb,
        epos.block = UDF_I_LOCATION(table);
        epos.bh = goal_epos.bh = NULL;
 
-       while (spread && (etype =
-                         udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) {
+       while (spread &&
+              (etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) {
                if (goal >= eloc.logicalBlockNum) {
-                       if (goal <
-                           eloc.logicalBlockNum +
-                           (elen >> sb->s_blocksize_bits))
+                       if (goal < eloc.logicalBlockNum + (elen >> sb->s_blocksize_bits))
                                nspread = 0;
                        else
                                nspread = goal - eloc.logicalBlockNum -
-                                   (elen >> sb->s_blocksize_bits);
-               } else
+                                       (elen >> sb->s_blocksize_bits);
+               } else {
                        nspread = eloc.logicalBlockNum - goal;
+               }
 
                if (nspread < spread) {
                        spread = nspread;
@@ -856,9 +775,7 @@ static int udf_table_new_block(struct super_block *sb,
 
        if (UDF_SB_LVIDBH(sb)) {
                UDF_SB_LVID(sb)->freeSpaceTable[partition] =
-                   cpu_to_le32(le32_to_cpu
-                               (UDF_SB_LVID(sb)->freeSpaceTable[partition]) -
-                               1);
+                       cpu_to_le32(le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[partition]) - 1);
                mark_buffer_dirty(UDF_SB_LVIDBH(sb));
        }
 
@@ -877,27 +794,23 @@ inline void udf_free_blocks(struct super_block *sb,
 
        if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP) {
                return udf_bitmap_free_blocks(sb, inode,
-                                             UDF_SB_PARTMAPS(sb)[partition].
-                                             s_uspace.s_bitmap, bloc, offset,
-                                             count);
-       } else if (UDF_SB_PARTFLAGS(sb, partition) &
-                  UDF_PART_FLAG_UNALLOC_TABLE) {
+                                             UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
+                                             bloc, offset, count);
+       } else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE) {
                return udf_table_free_blocks(sb, inode,
-                                            UDF_SB_PARTMAPS(sb)[partition].
-                                            s_uspace.s_table, bloc, offset,
-                                            count);
+                                            UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
+                                            bloc, offset, count);
        } else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP) {
                return udf_bitmap_free_blocks(sb, inode,
-                                             UDF_SB_PARTMAPS(sb)[partition].
-                                             s_fspace.s_bitmap, bloc, offset,
-                                             count);
+                                             UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
+                                             bloc, offset, count);
        } else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE) {
                return udf_table_free_blocks(sb, inode,
-                                            UDF_SB_PARTMAPS(sb)[partition].
-                                            s_fspace.s_table, bloc, offset,
-                                            count);
-       } else
+                                            UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
+                                            bloc, offset, count);
+       } else {
                return;
+       }
 }
 
 inline int udf_prealloc_blocks(struct super_block *sb,
@@ -907,29 +820,23 @@ inline int udf_prealloc_blocks(struct super_block *sb,
 {
        if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP) {
                return udf_bitmap_prealloc_blocks(sb, inode,
-                                                 UDF_SB_PARTMAPS(sb)
-                                                 [partition].s_uspace.s_bitmap,
-                                                 partition, first_block,
-                                                 block_count);
-       } else if (UDF_SB_PARTFLAGS(sb, partition) &
-                  UDF_PART_FLAG_UNALLOC_TABLE) {
+                                                 UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
+                                                 partition, first_block, block_count);
+       } else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE) {
                return udf_table_prealloc_blocks(sb, inode,
-                                                UDF_SB_PARTMAPS(sb)[partition].
-                                                s_uspace.s_table, partition,
-                                                first_block, block_count);
+                                                UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
+                                                partition, first_block, block_count);
        } else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP) {
                return udf_bitmap_prealloc_blocks(sb, inode,
-                                                 UDF_SB_PARTMAPS(sb)
-                                                 [partition].s_fspace.s_bitmap,
-                                                 partition, first_block,
-                                                 block_count);
+                                                 UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
+                                                 partition, first_block, block_count);
        } else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE) {
                return udf_table_prealloc_blocks(sb, inode,
-                                                UDF_SB_PARTMAPS(sb)[partition].
-                                                s_fspace.s_table, partition,
-                                                first_block, block_count);
-       } else
+                                                UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
+                                                partition, first_block, block_count);
+       } else {
                return 0;
+       }
 }
 
 inline int udf_new_block(struct super_block *sb,
@@ -940,26 +847,21 @@ inline int udf_new_block(struct super_block *sb,
 
        if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_BITMAP) {
                ret = udf_bitmap_new_block(sb, inode,
-                                          UDF_SB_PARTMAPS(sb)[partition].
-                                          s_uspace.s_bitmap, partition, goal,
-                                          err);
+                                          UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_bitmap,
+                                          partition, goal, err);
                return ret;
-       } else if (UDF_SB_PARTFLAGS(sb, partition) &
-                  UDF_PART_FLAG_UNALLOC_TABLE) {
+       } else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_UNALLOC_TABLE) {
                return udf_table_new_block(sb, inode,
-                                          UDF_SB_PARTMAPS(sb)[partition].
-                                          s_uspace.s_table, partition, goal,
-                                          err);
+                                          UDF_SB_PARTMAPS(sb)[partition].s_uspace.s_table,
+                                          partition, goal, err);
        } else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_BITMAP) {
                return udf_bitmap_new_block(sb, inode,
-                                           UDF_SB_PARTMAPS(sb)[partition].
-                                           s_fspace.s_bitmap, partition, goal,
-                                           err);
+                                           UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_bitmap,
+                                           partition, goal, err);
        } else if (UDF_SB_PARTFLAGS(sb, partition) & UDF_PART_FLAG_FREED_TABLE) {
                return udf_table_new_block(sb, inode,
-                                          UDF_SB_PARTMAPS(sb)[partition].
-                                          s_fspace.s_table, partition, goal,
-                                          err);
+                                          UDF_SB_PARTMAPS(sb)[partition].s_fspace.s_table,
+                                          partition, goal, err);
        } else {
                *err = -EIO;
                return 0;
index ae3d49790941aa78df7163ec50a9e009c5551e3b..85aaee5fab261ec42621e594e7710e80abc7b789 100644 (file)
@@ -111,7 +111,7 @@ int main(void)
        return 0;
 }
 
-#endif                         /* defined(TEST) */
+#endif /* defined(TEST) */
 
 /****************************************************************************/
 #if defined(GENERATE)
@@ -169,4 +169,4 @@ int main(int argc, char **argv)
        return 0;
 }
 
-#endif                         /* defined(GENERATE) */
+#endif /* defined(GENERATE) */
index 79bab9fe120c44309b321c1ab0b0f6b4daeeb8f7..9e3b9f97ddbc31bdc7715b51da85fb70ccb3b459 100644 (file)
@@ -43,10 +43,10 @@ static int do_udf_readdir(struct inode *, struct file *, filldir_t, void *);
 /* readdir and lookup functions */
 
 const struct file_operations udf_dir_operations = {
-       .read = generic_read_dir,
-       .readdir = udf_readdir,
-       .ioctl = udf_ioctl,
-       .fsync = udf_fsync_file,
+       .read                   = generic_read_dir,
+       .readdir                = udf_readdir,
+       .ioctl                  = udf_ioctl,
+       .fsync                  = udf_fsync_file,
 };
 
 /*
@@ -83,8 +83,7 @@ int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)
        lock_kernel();
 
        if (filp->f_pos == 0) {
-               if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) <
-                   0) {
+               if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0) {
                        unlock_kernel();
                        return 0;
                }
@@ -93,7 +92,7 @@ int udf_readdir(struct file *filp, void *dirent, filldir_t filldir)
 
        result = do_udf_readdir(dir, filp, filldir, dirent);
        unlock_kernel();
-       return result;
+       return result;
 }
 
 static int
@@ -125,21 +124,20 @@ do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir,
        if (nf_pos == 0)
                nf_pos = (udf_ext0_offset(dir) >> 2);
 
-       fibh.soffset = fibh.eoffset =
-           (nf_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
-       if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
+       fibh.soffset = fibh.eoffset = (nf_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
+       if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
                fibh.sbh = fibh.ebh = NULL;
-       else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2),
-                           &epos, &eloc, &elen,
-                           &offset) == (EXT_RECORDED_ALLOCATED >> 30)) {
+       } else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2),
+                             &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) {
                block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
                if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
                        if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
                                epos.offset -= sizeof(short_ad);
                        else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
                                epos.offset -= sizeof(long_ad);
-               } else
+               } else {
                        offset = 0;
+               }
 
                if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) {
                        brelse(epos.bh);
@@ -149,15 +147,11 @@ do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir,
                if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9)) - 1))) {
                        i = 16 >> (dir->i_sb->s_blocksize_bits - 9);
                        if (i + offset > (elen >> dir->i_sb->s_blocksize_bits))
-                               i = (elen >> dir->i_sb->s_blocksize_bits) -
-                                   offset;
+                               i = (elen >> dir->i_sb->s_blocksize_bits) - offset;
                        for (num = 0; i > 0; i--) {
-                               block =
-                                   udf_get_lb_pblock(dir->i_sb, eloc,
-                                                     offset + i);
+                               block = udf_get_lb_pblock(dir->i_sb, eloc, offset + i);
                                tmp = udf_tgetblk(dir->i_sb, block);
-                               if (tmp && !buffer_uptodate(tmp)
-                                   && !buffer_locked(tmp))
+                               if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
                                        bha[num++] = tmp;
                                else
                                        brelse(tmp);
@@ -178,7 +172,6 @@ do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir,
 
                fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc,
                                        &elen, &offset);
-
                if (!fi) {
                        if (fibh.sbh != fibh.ebh)
                                brelse(fibh.ebh);
@@ -190,19 +183,16 @@ do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir,
                liu = le16_to_cpu(cfi.lengthOfImpUse);
                lfi = cfi.lengthFileIdent;
 
-               if (fibh.sbh == fibh.ebh)
+               if (fibh.sbh == fibh.ebh) {
                        nameptr = fi->fileIdent + liu;
-               else {
+               else {
                        int poffset;    /* Unpaded ending offset */
 
-                       poffset =
-                           fibh.soffset + sizeof(struct fileIdentDesc) + liu +
-                           lfi;
+                       poffset = fibh.soffset + sizeof(struct fileIdentDesc) + liu + lfi;
 
-                       if (poffset >= lfi)
-                               nameptr =
-                                   (char *)(fibh.ebh->b_data + poffset - lfi);
-                       else {
+                       if (poffset >= lfi) {
+                               nameptr = (char *)(fibh.ebh->b_data + poffset - lfi);
+                       } else {
                                nameptr = fname;
                                memcpy(nameptr, fi->fileIdent + liu,
                                       lfi - poffset);
@@ -235,17 +225,15 @@ do_udf_readdir(struct inode *dir, struct file *filp, filldir_t filldir,
                }
 
                if (flen) {
-                       if (filldir
-                           (dirent, fname, flen, filp->f_pos, iblock,
-                            dt_type) < 0) {
+                       if (filldir(dirent, fname, flen, filp->f_pos, iblock, dt_type) < 0) {
                                if (fibh.sbh != fibh.ebh)
                                        brelse(fibh.ebh);
                                brelse(fibh.sbh);
                                brelse(epos.bh);
-                               return 0;
+                               return 0;
                        }
                }
-       }                       /* end while */
+       } /* end while */
 
        filp->f_pos = nf_pos + 1;
 
index 8adc77c1d579943b7d2b6d7e7c9f8e7875549d58..ff8c08fd7bf533ff53d6e659f284edb9c23e5a1d 100644 (file)
@@ -31,7 +31,7 @@ static uint8_t *udf_filead_read(struct inode *dir, uint8_t * tmpad,
 
        *error = 0;
 
-       ad = (uint8_t *) (*bh)->b_data + *offset;
+       ad = (uint8_t *)(*bh)->b_data + *offset;
        *offset += ad_size;
 
        if (!ad) {
@@ -51,7 +51,7 @@ static uint8_t *udf_filead_read(struct inode *dir, uint8_t * tmpad,
                ad = tmpad;
 
                remainder = dir->i_sb->s_blocksize - loffset;
-               memcpy((uint8_t *) ad, (*bh)->b_data + loffset, remainder);
+               memcpy((uint8_t *)ad, (*bh)->b_data + loffset, remainder);
 
                brelse(*bh);
                block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
@@ -60,10 +60,10 @@ static uint8_t *udf_filead_read(struct inode *dir, uint8_t * tmpad,
                if (!((*bh) = udf_tread(dir->i_sb, block)))
                        return NULL;
 
-               memcpy((uint8_t *) ad + remainder, (*bh)->b_data,
-                      ad_size - remainder);
+               memcpy((uint8_t *)ad + remainder, (*bh)->b_data, ad_size - remainder);
                *offset = ad_size - remainder;
        }
+
        return ad;
 }
 #endif
@@ -86,15 +86,13 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t * nf_pos,
                                       (UDF_I_EFE(dir) ?
                                        sizeof(struct extendedFileEntry) :
                                        sizeof(struct fileEntry)),
-                                      dir->i_sb->s_blocksize,
-                                      &(fibh->eoffset));
-
+                                      dir->i_sb->s_blocksize, &(fibh->eoffset));
                if (!fi)
                        return NULL;
 
                *nf_pos += ((fibh->eoffset - fibh->soffset) >> 2);
 
-               memcpy((uint8_t *) cfi, (uint8_t *) fi,
+               memcpy((uint8_t *)cfi, (uint8_t *)fi,
                       sizeof(struct fileIdentDesc));
 
                return fi;
@@ -121,21 +119,14 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t * nf_pos,
                        return NULL;
                fibh->soffset = fibh->eoffset = 0;
 
-               if (!
-                   (*offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9)) - 1)))
-               {
+               if (!(*offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9)) - 1))) {
                        i = 16 >> (dir->i_sb->s_blocksize_bits - 9);
-                       if (i + *offset >
-                           (*elen >> dir->i_sb->s_blocksize_bits))
-                               i = (*elen >> dir->i_sb->s_blocksize_bits) -
-                                   *offset;
+                       if (i + *offset > (*elen >> dir->i_sb->s_blocksize_bits))
+                               i = (*elen >> dir->i_sb->s_blocksize_bits)-*offset;
                        for (num = 0; i > 0; i--) {
-                               block =
-                                   udf_get_lb_pblock(dir->i_sb, *eloc,
-                                                     *offset + i);
+                               block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset + i);
                                tmp = udf_tgetblk(dir->i_sb, block);
-                               if (tmp && !buffer_uptodate(tmp)
-                                   && !buffer_locked(tmp))
+                               if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
                                        bha[num++] = tmp;
                                else
                                        brelse(tmp);
@@ -160,7 +151,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t * nf_pos,
        *nf_pos += ((fibh->eoffset - fibh->soffset) >> 2);
 
        if (fibh->eoffset <= dir->i_sb->s_blocksize) {
-               memcpy((uint8_t *) cfi, (uint8_t *) fi,
+               memcpy((uint8_t *)cfi, (uint8_t *)fi,
                       sizeof(struct fileIdentDesc));
        } else if (fibh->eoffset > dir->i_sb->s_blocksize) {
                int lextoffset = epos->offset;
@@ -187,21 +178,17 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t * nf_pos,
                if (sizeof(struct fileIdentDesc) > -fibh->soffset) {
                        int fi_len;
 
-                       memcpy((uint8_t *) cfi, (uint8_t *) fi, -fibh->soffset);
-                       memcpy((uint8_t *) cfi - fibh->soffset,
-                              fibh->ebh->b_data,
+                       memcpy((uint8_t *)cfi, (uint8_t *)fi, -fibh->soffset);
+                       memcpy((uint8_t *)cfi - fibh->soffset, fibh->ebh->b_data,
                               sizeof(struct fileIdentDesc) + fibh->soffset);
 
-                       fi_len =
-                           (sizeof(struct fileIdentDesc) +
-                            cfi->lengthFileIdent +
-                            le16_to_cpu(cfi->lengthOfImpUse) + 3) & ~3;
+                       fi_len = (sizeof(struct fileIdentDesc) + cfi->lengthFileIdent +
+                                 le16_to_cpu(cfi->lengthOfImpUse) + 3) & ~3;
 
-                       *nf_pos +=
-                           ((fi_len - (fibh->eoffset - fibh->soffset)) >> 2);
+                       *nf_pos += ((fi_len - (fibh->eoffset - fibh->soffset)) >> 2);
                        fibh->eoffset = fibh->soffset + fi_len;
                } else {
-                       memcpy((uint8_t *) cfi, (uint8_t *) fi,
+                       memcpy((uint8_t *)cfi, (uint8_t *)fi,
                               sizeof(struct fileIdentDesc));
                }
        }
@@ -237,9 +224,10 @@ struct fileIdentDesc *udf_get_fileident(void *buffer, int bufsize, int *offset)
        }
        if ((*offset + sizeof(struct fileIdentDesc)) > bufsize) {
                lengthThisIdent = sizeof(struct fileIdentDesc);
-       } else
+       } else {
                lengthThisIdent = sizeof(struct fileIdentDesc) +
-                   fi->lengthFileIdent + le16_to_cpu(fi->lengthOfImpUse);
+                       fi->lengthFileIdent + le16_to_cpu(fi->lengthOfImpUse);
+       }
 
        /* we need to figure padding, too! */
        padlen = lengthThisIdent % UDF_NAME_PAD;
@@ -270,22 +258,20 @@ static extent_ad *udf_get_fileextent(void *buffer, int bufsize, int *offset)
                return NULL;
        }
 
-       ptr =
-           (uint8_t *) (fe->extendedAttr) +
-           le32_to_cpu(fe->lengthExtendedAttr);
+       ptr = (uint8_t *)(fe->extendedAttr) + le32_to_cpu(fe->lengthExtendedAttr);
 
        if ((*offset > 0) && (*offset < le32_to_cpu(fe->lengthAllocDescs))) {
                ptr += *offset;
        }
 
-       ext = (extent_ad *) ptr;
+       ext = (extent_ad *)ptr;
 
        *offset = *offset + sizeof(extent_ad);
        return ext;
 }
 #endif
 
-short_ad *udf_get_fileshortad(uint8_t * ptr, int maxoffset, int *offset,
+short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, int *offset,
                              int inc)
 {
        short_ad *sa;
@@ -297,7 +283,7 @@ short_ad *udf_get_fileshortad(uint8_t * ptr, int maxoffset, int *offset,
 
        if ((*offset < 0) || ((*offset + sizeof(short_ad)) > maxoffset))
                return NULL;
-       else if ((sa = (short_ad *) ptr)->extLength == 0)
+       else if ((sa = (short_ad *)ptr)->extLength == 0)
                return NULL;
 
        if (inc)
@@ -305,7 +291,7 @@ short_ad *udf_get_fileshortad(uint8_t * ptr, int maxoffset, int *offset,
        return sa;
 }
 
-long_ad *udf_get_filelongad(uint8_t * ptr, int maxoffset, int *offset, int inc)
+long_ad *udf_get_filelongad(uint8_t *ptr, int maxoffset, int *offset, int inc)
 {
        long_ad *la;
 
@@ -316,7 +302,7 @@ long_ad *udf_get_filelongad(uint8_t * ptr, int maxoffset, int *offset, int inc)
 
        if ((*offset < 0) || ((*offset + sizeof(long_ad)) > maxoffset))
                return NULL;
-       else if ((la = (long_ad *) ptr)->extLength == 0)
+       else if ((la = (long_ad *)ptr)->extLength == 0)
                return NULL;
 
        if (inc)
index 294ce2daa03a741bad355a024130b08fd3f2351f..56387711589b0aaf2ad30ad5a9150480e6e1f522 100644 (file)
@@ -39,8 +39,8 @@
 
 /* Character set specification (ECMA 167r3 1/7.2.1) */
 typedef struct {
-       uint8_t charSetType;
-       uint8_t charSetInfo[63];
+       uint8_t         charSetType;
+       uint8_t         charSetInfo[63];
 } __attribute__ ((packed)) charspec;
 
 /* Character Set Type (ECMA 167r3 1/7.2.1.1) */
@@ -54,33 +54,33 @@ typedef struct {
 #define CHARSPEC_TYPE_CS7              0x07    /* (1/7.2.9) */
 #define CHARSPEC_TYPE_CS8              0x08    /* (1/7.2.10) */
 
-typedef uint8_t dstring;
+typedef uint8_t                dstring;
 
 /* Timestamp (ECMA 167r3 1/7.3) */
 typedef struct {
-       __le16 typeAndTimezone;
-       __le16 year;
-       uint8_t month;
-       uint8_t day;
-       uint8_t hour;
-       uint8_t minute;
-       uint8_t second;
-       uint8_t centiseconds;
-       uint8_t hundredsOfMicroseconds;
-       uint8_t microseconds;
+       __le16          typeAndTimezone;
+       __le16          year;
+       uint8_t         month;
+       uint8_t         day;
+       uint8_t         hour;
+       uint8_t         minute;
+       uint8_t         second;
+       uint8_t         centiseconds;
+       uint8_t         hundredsOfMicroseconds;
+       uint8_t         microseconds;
 } __attribute__ ((packed)) timestamp;
 
 typedef struct {
-       uint16_t typeAndTimezone;
-       int16_t year;
-       uint8_t month;
-       uint8_t day;
-       uint8_t hour;
-       uint8_t minute;
-       uint8_t second;
-       uint8_t centiseconds;
-       uint8_t hundredsOfMicroseconds;
-       uint8_t microseconds;
+       uint16_t        typeAndTimezone;
+       int16_t         year;
+       uint8_t         month;
+       uint8_t         day;
+       uint8_t         hour;
+       uint8_t         minute;
+       uint8_t         second;
+       uint8_t         centiseconds;
+       uint8_t         hundredsOfMicroseconds;
+       uint8_t         microseconds;
 } __attribute__ ((packed)) kernel_timestamp;
 
 /* Type and Time Zone (ECMA 167r3 1/7.3.1) */
@@ -92,9 +92,9 @@ typedef struct {
 
 /* Entity identifier (ECMA 167r3 1/7.4) */
 typedef struct {
-       uint8_t flags;
-       uint8_t ident[23];
-       uint8_t identSuffix[8];
+       uint8_t         flags;
+       uint8_t         ident[23];
+       uint8_t         identSuffix[8];
 } __attribute__ ((packed)) regid;
 
 /* Flags (ECMA 167r3 1/7.4.1) */
@@ -104,10 +104,10 @@ typedef struct {
 /* Volume Structure Descriptor (ECMA 167r3 2/9.1) */
 #define VSD_STD_ID_LEN                 5
 struct volStructDesc {
-       uint8_t structType;
-       uint8_t stdIdent[VSD_STD_ID_LEN];
-       uint8_t structVersion;
-       uint8_t structData[2041];
+       uint8_t         structType;
+       uint8_t         stdIdent[VSD_STD_ID_LEN];
+       uint8_t         structVersion;
+       uint8_t         structData[2041];
 } __attribute__ ((packed));
 
 /* Standard Identifier (EMCA 167r2 2/9.1.2) */
@@ -123,36 +123,36 @@ struct volStructDesc {
 
 /* Beginning Extended Area Descriptor (ECMA 167r3 2/9.2) */
 struct beginningExtendedAreaDesc {
-       uint8_t structType;
-       uint8_t stdIdent[VSD_STD_ID_LEN];
-       uint8_t structVersion;
-       uint8_t structData[2041];
+       uint8_t         structType;
+       uint8_t         stdIdent[VSD_STD_ID_LEN];
+       uint8_t         structVersion;
+       uint8_t         structData[2041];
 } __attribute__ ((packed));
 
 /* Terminating Extended Area Descriptor (ECMA 167r3 2/9.3) */
 struct terminatingExtendedAreaDesc {
-       uint8_t structType;
-       uint8_t stdIdent[VSD_STD_ID_LEN];
-       uint8_t structVersion;
-       uint8_t structData[2041];
+       uint8_t         structType;
+       uint8_t         stdIdent[VSD_STD_ID_LEN];
+       uint8_t         structVersion;
+       uint8_t         structData[2041];
 } __attribute__ ((packed));
 
 /* Boot Descriptor (ECMA 167r3 2/9.4) */
 struct bootDesc {
-       uint8_t structType;
-       uint8_t stdIdent[VSD_STD_ID_LEN];
-       uint8_t structVersion;
-       uint8_t reserved1;
-       regid archType;
-       regid bootIdent;
-       __le32 bootExtLocation;
-       __le32 bootExtLength;
-       __le64 loadAddress;
-       __le64 startAddress;
-       timestamp descCreationDateAndTime;
-       __le16 flags;
-       uint8_t reserved2[32];
-       uint8_t bootUse[1906];
+       uint8_t         structType;
+       uint8_t         stdIdent[VSD_STD_ID_LEN];
+       uint8_t         structVersion;
+       uint8_t         reserved1;
+       regid           archType;
+       regid           bootIdent;
+       __le32          bootExtLocation;
+       __le32          bootExtLength;
+       __le64          loadAddress;
+       __le64          startAddress;
+       timestamp       descCreationDateAndTime;
+       __le16          flags;
+       uint8_t         reserved2[32];
+       uint8_t         bootUse[1906];
 } __attribute__ ((packed));
 
 /* Flags (ECMA 167r3 2/9.4.12) */
@@ -160,25 +160,25 @@ struct bootDesc {
 
 /* Extent Descriptor (ECMA 167r3 3/7.1) */
 typedef struct {
-       __le32 extLength;
-       __le32 extLocation;
+       __le32          extLength;
+       __le32          extLocation;
 } __attribute__ ((packed)) extent_ad;
 
 typedef struct {
-       uint32_t extLength;
-       uint32_t extLocation;
+       uint32_t        extLength;
+       uint32_t        extLocation;
 } kernel_extent_ad;
 
 /* Descriptor Tag (ECMA 167r3 3/7.2) */
 typedef struct {
-       __le16 tagIdent;
-       __le16 descVersion;
-       uint8_t tagChecksum;
-       uint8_t reserved;
-       __le16 tagSerialNum;
-       __le16 descCRC;
-       __le16 descCRCLength;
-       __le32 tagLocation;
+       __le16          tagIdent;
+       __le16          descVersion;
+       uint8_t         tagChecksum;
+       uint8_t         reserved;
+       __le16          tagSerialNum;
+       __le16          descCRC;
+       __le16          descCRCLength;
+       __le32          tagLocation;
 } __attribute__ ((packed)) tag;
 
 /* Tag Identifier (ECMA 167r3 3/7.2.1) */
@@ -194,37 +194,37 @@ typedef struct {
 
 /* NSR Descriptor (ECMA 167r3 3/9.1) */
 struct NSRDesc {
-       uint8_t structType;
-       uint8_t stdIdent[VSD_STD_ID_LEN];
-       uint8_t structVersion;
-       uint8_t reserved;
-       uint8_t structData[2040];
+       uint8_t         structType;
+       uint8_t         stdIdent[VSD_STD_ID_LEN];
+       uint8_t         structVersion;
+       uint8_t         reserved;
+       uint8_t         structData[2040];
 } __attribute__ ((packed));
 
 /* Primary Volume Descriptor (ECMA 167r3 3/10.1) */
 struct primaryVolDesc {
-       tag descTag;
-       __le32 volDescSeqNum;
-       __le32 primaryVolDescNum;
-       dstring volIdent[32];
-       __le16 volSeqNum;
-       __le16 maxVolSeqNum;
-       __le16 interchangeLvl;
-       __le16 maxInterchangeLvl;
-       __le32 charSetList;
-       __le32 maxCharSetList;
-       dstring volSetIdent[128];
-       charspec descCharSet;
-       charspec explanatoryCharSet;
-       extent_ad volAbstract;
-       extent_ad volCopyright;
-       regid appIdent;
-       timestamp recordingDateAndTime;
-       regid impIdent;
-       uint8_t impUse[64];
-       __le32 predecessorVolDescSeqLocation;
-       __le16 flags;
-       uint8_t reserved[22];
+       tag             descTag;
+       __le32          volDescSeqNum;
+       __le32          primaryVolDescNum;
+       dstring         volIdent[32];
+       __le16          volSeqNum;
+       __le16          maxVolSeqNum;
+       __le16          interchangeLvl;
+       __le16          maxInterchangeLvl;
+       __le32          charSetList;
+       __le32          maxCharSetList;
+       dstring         volSetIdent[128];
+       charspec        descCharSet;
+       charspec        explanatoryCharSet;
+       extent_ad       volAbstract;
+       extent_ad       volCopyright;
+       regid           appIdent;
+       timestamp       recordingDateAndTime;
+       regid           impIdent;
+       uint8_t         impUse[64];
+       __le32          predecessorVolDescSeqLocation;
+       __le16          flags;
+       uint8_t         reserved[22];
 } __attribute__ ((packed));
 
 /* Flags (ECMA 167r3 3/10.1.21) */
@@ -232,26 +232,26 @@ struct primaryVolDesc {
 
 /* Anchor Volume Descriptor Pointer (ECMA 167r3 3/10.2) */
 struct anchorVolDescPtr {
-       tag descTag;
-       extent_ad mainVolDescSeqExt;
-       extent_ad reserveVolDescSeqExt;
-       uint8_t reserved[480];
+       tag             descTag;
+       extent_ad       mainVolDescSeqExt;
+       extent_ad       reserveVolDescSeqExt;
+       uint8_t         reserved[480];
 } __attribute__ ((packed));
 
 /* Volume Descriptor Pointer (ECMA 167r3 3/10.3) */
 struct volDescPtr {
-       tag descTag;
-       __le32 volDescSeqNum;
-       extent_ad nextVolDescSeqExt;
-       uint8_t reserved[484];
+       tag             descTag;
+       __le32          volDescSeqNum;
+       extent_ad       nextVolDescSeqExt;
+       uint8_t         reserved[484];
 } __attribute__ ((packed));
 
 /* Implementation Use Volume Descriptor (ECMA 167r3 3/10.4) */
 struct impUseVolDesc {
-       tag descTag;
-       __le32 volDescSeqNum;
-       regid impIdent;
-       uint8_t impUse[460];
+       tag             descTag;
+       __le32          volDescSeqNum;
+       regid           impIdent;
+       uint8_t         impUse[460];
 } __attribute__ ((packed));
 
 /* Partition Descriptor (ECMA 167r3 3/10.5) */
@@ -291,26 +291,26 @@ struct partitionDesc {
 
 /* Logical Volume Descriptor (ECMA 167r3 3/10.6) */
 struct logicalVolDesc {
-       tag descTag;
-       __le32 volDescSeqNum;
-       charspec descCharSet;
-       dstring logicalVolIdent[128];
-       __le32 logicalBlockSize;
-       regid domainIdent;
-       uint8_t logicalVolContentsUse[16];
-       __le32 mapTableLength;
-       __le32 numPartitionMaps;
-       regid impIdent;
-       uint8_t impUse[128];
-       extent_ad integritySeqExt;
-       uint8_t partitionMaps[0];
+       tag             descTag;
+       __le32          volDescSeqNum;
+       charspec        descCharSet;
+       dstring         logicalVolIdent[128];
+       __le32          logicalBlockSize;
+       regid           domainIdent;
+       uint8_t         logicalVolContentsUse[16];
+       __le32          mapTableLength;
+       __le32          numPartitionMaps;
+       regid           impIdent;
+       uint8_t         impUse[128];
+       extent_ad       integritySeqExt;
+       uint8_t         partitionMaps[0];
 } __attribute__ ((packed));
 
 /* Generic Partition Map (ECMA 167r3 3/10.7.1) */
 struct genericPartitionMap {
-       uint8_t partitionMapType;
-       uint8_t partitionMapLength;
-       uint8_t partitionMapping[0];
+       uint8_t         partitionMapType;
+       uint8_t         partitionMapLength;
+       uint8_t         partitionMapping[0];
 } __attribute__ ((packed));
 
 /* Partition Map Type (ECMA 167r3 3/10.7.1.1) */
@@ -320,45 +320,45 @@ struct genericPartitionMap {
 
 /* Type 1 Partition Map (ECMA 167r3 3/10.7.2) */
 struct genericPartitionMap1 {
-       uint8_t partitionMapType;
-       uint8_t partitionMapLength;
-       __le16 volSeqNum;
-       __le16 partitionNum;
+       uint8_t         partitionMapType;
+       uint8_t         partitionMapLength;
+       __le16          volSeqNum;
+       __le16          partitionNum;
 } __attribute__ ((packed));
 
 /* Type 2 Partition Map (ECMA 167r3 3/10.7.3) */
 struct genericPartitionMap2 {
-       uint8_t partitionMapType;
-       uint8_t partitionMapLength;
-       uint8_t partitionIdent[62];
+       uint8_t         partitionMapType;
+       uint8_t         partitionMapLength;
+       uint8_t         partitionIdent[62];
 } __attribute__ ((packed));
 
 /* Unallocated Space Descriptor (ECMA 167r3 3/10.8) */
 struct unallocSpaceDesc {
-       tag descTag;
-       __le32 volDescSeqNum;
-       __le32 numAllocDescs;
-       extent_ad allocDescs[0];
+       tag             descTag;
+       __le32          volDescSeqNum;
+       __le32          numAllocDescs;
+       extent_ad       allocDescs[0];
 } __attribute__ ((packed));
 
 /* Terminating Descriptor (ECMA 167r3 3/10.9) */
 struct terminatingDesc {
-       tag descTag;
-       uint8_t reserved[496];
+       tag             descTag;
+       uint8_t         reserved[496];
 } __attribute__ ((packed));
 
 /* Logical Volume Integrity Descriptor (ECMA 167r3 3/10.10) */
 struct logicalVolIntegrityDesc {
-       tag descTag;
-       timestamp recordingDateAndTime;
-       __le32 integrityType;
-       extent_ad nextIntegrityExt;
-       uint8_t logicalVolContentsUse[32];
-       __le32 numOfPartitions;
-       __le32 lengthOfImpUse;
-       __le32 freeSpaceTable[0];
-       __le32 sizeTable[0];
-       uint8_t impUse[0];
+       tag             descTag;
+       timestamp       recordingDateAndTime;
+       __le32          integrityType;
+       extent_ad       nextIntegrityExt;
+       uint8_t         logicalVolContentsUse[32];
+       __le32          numOfPartitions;
+       __le32          lengthOfImpUse;
+       __le32          freeSpaceTable[0];
+       __le32          sizeTable[0];
+       uint8_t         impUse[0];
 } __attribute__ ((packed));
 
 /* Integrity Type (ECMA 167r3 3/10.10.3) */
@@ -367,48 +367,48 @@ struct logicalVolIntegrityDesc {
 
 /* Recorded Address (ECMA 167r3 4/7.1) */
 typedef struct {
-       __le32 logicalBlockNum;
-       __le16 partitionReferenceNum;
+       __le32          logicalBlockNum;
+       __le16          partitionReferenceNum;
 } __attribute__ ((packed)) lb_addr;
 
 /* ... and its in-core analog */
 typedef struct {
-       uint32_t logicalBlockNum;
-       uint16_t partitionReferenceNum;
+       uint32_t                logicalBlockNum;
+       uint16_t                partitionReferenceNum;
 } kernel_lb_addr;
 
 /* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */
 typedef struct {
-       __le32 extLength;
-       __le32 extPosition;
+        __le32         extLength;
+        __le32         extPosition;
 } __attribute__ ((packed)) short_ad;
 
 /* Long Allocation Descriptor (ECMA 167r3 4/14.14.2) */
 typedef struct {
-       __le32 extLength;
-       lb_addr extLocation;
-       uint8_t impUse[6];
+       __le32          extLength;
+       lb_addr         extLocation;
+       uint8_t         impUse[6];
 } __attribute__ ((packed)) long_ad;
 
 typedef struct {
-       uint32_t extLength;
-       kernel_lb_addr extLocation;
-       uint8_t impUse[6];
+       uint32_t        extLength;
+       kernel_lb_addr  extLocation;
+       uint8_t         impUse[6];
 } kernel_long_ad;
 
 /* Extended Allocation Descriptor (ECMA 167r3 4/14.14.3) */
 typedef struct {
-       __le32 extLength;
-       __le32 recordedLength;
-       __le32 informationLength;
-       lb_addr extLocation;
+       __le32          extLength;
+       __le32          recordedLength;
+       __le32          informationLength;
+       lb_addr         extLocation;
 } __attribute__ ((packed)) ext_ad;
 
 typedef struct {
-       uint32_t extLength;
-       uint32_t recordedLength;
-       uint32_t informationLength;
-       kernel_lb_addr extLocation;
+       uint32_t        extLength;
+       uint32_t        recordedLength;
+       uint32_t        informationLength;
+       kernel_lb_addr  extLocation;
 } kernel_ext_ad;
 
 /* Descriptor Tag (ECMA 167r3 4/7.2 - See 3/7.2) */
@@ -428,48 +428,48 @@ typedef struct {
 
 /* File Set Descriptor (ECMA 167r3 4/14.1) */
 struct fileSetDesc {
-       tag descTag;
-       timestamp recordingDateAndTime;
-       __le16 interchangeLvl;
-       __le16 maxInterchangeLvl;
-       __le32 charSetList;
-       __le32 maxCharSetList;
-       __le32 fileSetNum;
-       __le32 fileSetDescNum;
-       charspec logicalVolIdentCharSet;
-       dstring logicalVolIdent[128];
-       charspec fileSetCharSet;
-       dstring fileSetIdent[32];
-       dstring copyrightFileIdent[32];
-       dstring abstractFileIdent[32];
-       long_ad rootDirectoryICB;
-       regid domainIdent;
-       long_ad nextExt;
-       long_ad streamDirectoryICB;
-       uint8_t reserved[32];
+       tag             descTag;
+       timestamp       recordingDateAndTime;
+       __le16          interchangeLvl;
+       __le16          maxInterchangeLvl;
+       __le32          charSetList;
+       __le32          maxCharSetList;
+       __le32          fileSetNum;
+       __le32          fileSetDescNum;
+       charspec        logicalVolIdentCharSet;
+       dstring         logicalVolIdent[128];
+       charspec        fileSetCharSet;
+       dstring         fileSetIdent[32];
+       dstring         copyrightFileIdent[32];
+       dstring         abstractFileIdent[32];
+       long_ad         rootDirectoryICB;
+       regid           domainIdent;
+       long_ad         nextExt;
+       long_ad         streamDirectoryICB;
+       uint8_t         reserved[32];
 } __attribute__ ((packed));
 
 /* Partition Header Descriptor (ECMA 167r3 4/14.3) */
 struct partitionHeaderDesc {
-       short_ad unallocSpaceTable;
-       short_ad unallocSpaceBitmap;
-       short_ad partitionIntegrityTable;
-       short_ad freedSpaceTable;
-       short_ad freedSpaceBitmap;
-       uint8_t reserved[88];
+       short_ad        unallocSpaceTable;
+       short_ad        unallocSpaceBitmap;
+       short_ad        partitionIntegrityTable;
+       short_ad        freedSpaceTable;
+       short_ad        freedSpaceBitmap;
+       uint8_t         reserved[88];
 } __attribute__ ((packed));
 
 /* File Identifier Descriptor (ECMA 167r3 4/14.4) */
 struct fileIdentDesc {
-       tag descTag;
-       __le16 fileVersionNum;
-       uint8_t fileCharacteristics;
-       uint8_t lengthFileIdent;
-       long_ad icb;
-       __le16 lengthOfImpUse;
-       uint8_t impUse[0];
-       uint8_t fileIdent[0];
-       uint8_t padding[0];
+       tag             descTag;
+       __le16          fileVersionNum;
+       uint8_t         fileCharacteristics;
+       uint8_t         lengthFileIdent;
+       long_ad         icb;
+       __le16          lengthOfImpUse;
+       uint8_t         impUse[0];
+       uint8_t         fileIdent[0];
+       uint8_t         padding[0];
 } __attribute__ ((packed));
 
 /* File Characteristics (ECMA 167r3 4/14.4.3) */
@@ -481,21 +481,21 @@ struct fileIdentDesc {
 
 /* Allocation Ext Descriptor (ECMA 167r3 4/14.5) */
 struct allocExtDesc {
-       tag descTag;
-       __le32 previousAllocExtLocation;
-       __le32 lengthAllocDescs;
+       tag             descTag;
+       __le32          previousAllocExtLocation;
+       __le32          lengthAllocDescs;
 } __attribute__ ((packed));
 
 /* ICB Tag (ECMA 167r3 4/14.6) */
 typedef struct {
-       __le32 priorRecordedNumDirectEntries;
-       __le16 strategyType;
-       __le16 strategyParameter;
-       __le16 numEntries;
-       uint8_t reserved;
-       uint8_t fileType;
-       lb_addr parentICBLocation;
-       __le16 flags;
+       __le32          priorRecordedNumDirectEntries;
+       __le16          strategyType;
+       __le16          strategyParameter;
+       __le16          numEntries;
+       uint8_t         reserved;
+       uint8_t         fileType;
+       lb_addr         parentICBLocation;
+       __le16          flags;
 } __attribute__ ((packed)) icbtag;
 
 /* Strategy Type (ECMA 167r3 4/14.6.2) */
@@ -541,41 +541,41 @@ typedef struct {
 
 /* Indirect Entry (ECMA 167r3 4/14.7) */
 struct indirectEntry {
-       tag descTag;
-       icbtag icbTag;
-       long_ad indirectICB;
+       tag             descTag;
+       icbtag          icbTag;
+       long_ad         indirectICB;
 } __attribute__ ((packed));
 
 /* Terminal Entry (ECMA 167r3 4/14.8) */
 struct terminalEntry {
-       tag descTag;
-       icbtag icbTag;
+       tag             descTag;
+       icbtag          icbTag;
 } __attribute__ ((packed));
 
 /* File Entry (ECMA 167r3 4/14.9) */
 struct fileEntry {
-       tag descTag;
-       icbtag icbTag;
-       __le32 uid;
-       __le32 gid;
-       __le32 permissions;
-       __le16 fileLinkCount;
-       uint8_t recordFormat;
-       uint8_t recordDisplayAttr;
-       __le32 recordLength;
-       __le64 informationLength;
-       __le64 logicalBlocksRecorded;
-       timestamp accessTime;
-       timestamp modificationTime;
-       timestamp attrTime;
-       __le32 checkpoint;
-       long_ad extendedAttrICB;
-       regid impIdent;
-       __le64 uniqueID;
-       __le32 lengthExtendedAttr;
-       __le32 lengthAllocDescs;
-       uint8_t extendedAttr[0];
-       uint8_t allocDescs[0];
+       tag             descTag;
+       icbtag          icbTag;
+       __le32          uid;
+       __le32          gid;
+       __le32          permissions;
+       __le16          fileLinkCount;
+       uint8_t         recordFormat;
+       uint8_t         recordDisplayAttr;
+       __le32          recordLength;
+       __le64          informationLength;
+       __le64          logicalBlocksRecorded;
+       timestamp       accessTime;
+       timestamp       modificationTime;
+       timestamp       attrTime;
+       __le32          checkpoint;
+       long_ad         extendedAttrICB;
+       regid           impIdent;
+       __le64          uniqueID;
+       __le32          lengthExtendedAttr;
+       __le32          lengthAllocDescs;
+       uint8_t         extendedAttr[0];
+       uint8_t         allocDescs[0];
 } __attribute__ ((packed));
 
 /* Permissions (ECMA 167r3 4/14.9.5) */
@@ -617,51 +617,51 @@ struct fileEntry {
 
 /* Extended Attribute Header Descriptor (ECMA 167r3 4/14.10.1) */
 struct extendedAttrHeaderDesc {
-       tag descTag;
-       __le32 impAttrLocation;
-       __le32 appAttrLocation;
+       tag             descTag;
+       __le32          impAttrLocation;
+       __le32          appAttrLocation;
 } __attribute__ ((packed));
 
 /* Generic Format (ECMA 167r3 4/14.10.2) */
 struct genericFormat {
-       __le32 attrType;
-       uint8_t attrSubtype;
-       uint8_t reserved[3];
-       __le32 attrLength;
-       uint8_t attrData[0];
+       __le32          attrType;
+       uint8_t         attrSubtype;
+       uint8_t         reserved[3];
+       __le32          attrLength;
+       uint8_t         attrData[0];
 } __attribute__ ((packed));
 
 /* Character Set Information (ECMA 167r3 4/14.10.3) */
 struct charSetInfo {
-       __le32 attrType;
-       uint8_t attrSubtype;
-       uint8_t reserved[3];
-       __le32 attrLength;
-       __le32 escapeSeqLength;
-       uint8_t charSetType;
-       uint8_t escapeSeq[0];
+       __le32          attrType;
+       uint8_t         attrSubtype;
+       uint8_t         reserved[3];
+       __le32          attrLength;
+       __le32          escapeSeqLength;
+       uint8_t         charSetType;
+       uint8_t         escapeSeq[0];
 } __attribute__ ((packed));
 
 /* Alternate Permissions (ECMA 167r3 4/14.10.4) */
 struct altPerms {
-       __le32 attrType;
-       uint8_t attrSubtype;
-       uint8_t reserved[3];
-       __le32 attrLength;
-       __le16 ownerIdent;
-       __le16 groupIdent;
-       __le16 permission;
+       __le32          attrType;
+       uint8_t         attrSubtype;
+       uint8_t         reserved[3];
+       __le32          attrLength;
+       __le16          ownerIdent;
+       __le16          groupIdent;
+       __le16          permission;
 } __attribute__ ((packed));
 
 /* File Times Extended Attribute (ECMA 167r3 4/14.10.5) */
 struct fileTimesExtAttr {
-       __le32 attrType;
-       uint8_t attrSubtype;
-       uint8_t reserved[3];
-       __le32 attrLength;
-       __le32 dataLength;
-       __le32 fileTimeExistence;
-       uint8_t fileTimes;
+       __le32          attrType;
+       uint8_t         attrSubtype;
+       uint8_t         reserved[3];
+       __le32          attrLength;
+       __le32          dataLength;
+       __le32          fileTimeExistence;
+       uint8_t         fileTimes;
 } __attribute__ ((packed));
 
 /* FileTimeExistence (ECMA 167r3 4/14.10.5.6) */
@@ -672,47 +672,47 @@ struct fileTimesExtAttr {
 
 /* Information Times Extended Attribute (ECMA 167r3 4/14.10.6) */
 struct infoTimesExtAttr {
-       __le32 attrType;
-       uint8_t attrSubtype;
-       uint8_t reserved[3];
-       __le32 attrLength;
-       __le32 dataLength;
-       __le32 infoTimeExistence;
-       uint8_t infoTimes[0];
+       __le32          attrType;
+       uint8_t         attrSubtype;
+       uint8_t         reserved[3];
+       __le32          attrLength;
+       __le32          dataLength;
+       __le32          infoTimeExistence;
+       uint8_t         infoTimes[0];
 } __attribute__ ((packed));
 
 /* Device Specification (ECMA 167r3 4/14.10.7) */
 struct deviceSpec {
-       __le32 attrType;
-       uint8_t attrSubtype;
-       uint8_t reserved[3];
-       __le32 attrLength;
-       __le32 impUseLength;
-       __le32 majorDeviceIdent;
-       __le32 minorDeviceIdent;
-       uint8_t impUse[0];
+       __le32          attrType;
+       uint8_t         attrSubtype;
+       uint8_t         reserved[3];
+       __le32          attrLength;
+       __le32          impUseLength;
+       __le32          majorDeviceIdent;
+       __le32          minorDeviceIdent;
+       uint8_t         impUse[0];
 } __attribute__ ((packed));
 
 /* Implementation Use Extended Attr (ECMA 167r3 4/14.10.8) */
 struct impUseExtAttr {
-       __le32 attrType;
-       uint8_t attrSubtype;
-       uint8_t reserved[3];
-       __le32 attrLength;
-       __le32 impUseLength;
-       regid impIdent;
-       uint8_t impUse[0];
+       __le32          attrType;
+       uint8_t         attrSubtype;
+       uint8_t         reserved[3];
+       __le32          attrLength;
+       __le32          impUseLength;
+       regid           impIdent;
+       uint8_t         impUse[0];
 } __attribute__ ((packed));
 
 /* Application Use Extended Attribute (ECMA 167r3 4/14.10.9) */
 struct appUseExtAttr {
-       __le32 attrType;
-       uint8_t attrSubtype;
-       uint8_t reserved[3];
-       __le32 attrLength;
-       __le32 appUseLength;
-       regid appIdent;
-       uint8_t appUse[0];
+       __le32          attrType;
+       uint8_t         attrSubtype;
+       uint8_t         reserved[3];
+       __le32          attrLength;
+       __le32          appUseLength;
+       regid           appIdent;
+       uint8_t         appUse[0];
 } __attribute__ ((packed));
 
 #define EXTATTR_CHAR_SET               1
@@ -725,29 +725,29 @@ struct appUseExtAttr {
 
 /* Unallocated Space Entry (ECMA 167r3 4/14.11) */
 struct unallocSpaceEntry {
-       tag descTag;
-       icbtag icbTag;
-       __le32 lengthAllocDescs;
-       uint8_t allocDescs[0];
+       tag             descTag;
+       icbtag          icbTag;
+       __le32          lengthAllocDescs;
+       uint8_t         allocDescs[0];
 } __attribute__ ((packed));
 
 /* Space Bitmap Descriptor (ECMA 167r3 4/14.12) */
 struct spaceBitmapDesc {
-       tag descTag;
-       __le32 numOfBits;
-       __le32 numOfBytes;
-       uint8_t bitmap[0];
+       tag             descTag;
+       __le32          numOfBits;
+       __le32          numOfBytes;
+       uint8_t         bitmap[0];
 } __attribute__ ((packed));
 
 /* Partition Integrity Entry (ECMA 167r3 4/14.13) */
 struct partitionIntegrityEntry {
-       tag descTag;
-       icbtag icbTag;
-       timestamp recordingDateAndTime;
-       uint8_t integrityType;
-       uint8_t reserved[175];
-       regid impIdent;
-       uint8_t impUse[256];
+       tag             descTag;
+       icbtag          icbTag;
+       timestamp       recordingDateAndTime;
+       uint8_t         integrityType;
+       uint8_t         reserved[175];
+       regid           impIdent;
+       uint8_t         impUse[256];
 } __attribute__ ((packed));
 
 /* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */
@@ -764,46 +764,46 @@ struct partitionIntegrityEntry {
 
 /* Logical Volume Header Descriptor (ECMA 167r3 4/14.15) */
 struct logicalVolHeaderDesc {
-       __le64 uniqueID;
-       uint8_t reserved[24];
+       __le64          uniqueID;
+       uint8_t         reserved[24];
 } __attribute__ ((packed));
 
 /* Path Component (ECMA 167r3 4/14.16.1) */
 struct pathComponent {
-       uint8_t componentType;
-       uint8_t lengthComponentIdent;
-       __le16 componentFileVersionNum;
-       dstring componentIdent[0];
+       uint8_t         componentType;
+       uint8_t         lengthComponentIdent;
+       __le16          componentFileVersionNum;
+       dstring         componentIdent[0];
 } __attribute__ ((packed));
 
 /* File Entry (ECMA 167r3 4/14.17) */
 struct extendedFileEntry {
-       tag descTag;
-       icbtag icbTag;
-       __le32 uid;
-       __le32 gid;
-       __le32 permissions;
-       __le16 fileLinkCount;
-       uint8_t recordFormat;
-       uint8_t recordDisplayAttr;
-       __le32 recordLength;
-       __le64 informationLength;
-       __le64 objectSize;
-       __le64 logicalBlocksRecorded;
-       timestamp accessTime;
-       timestamp modificationTime;
-       timestamp createTime;
-       timestamp attrTime;
-       __le32 checkpoint;
-       __le32 reserved;
-       long_ad extendedAttrICB;
-       long_ad streamDirectoryICB;
-       regid impIdent;
-       __le64 uniqueID;
-       __le32 lengthExtendedAttr;
-       __le32 lengthAllocDescs;
-       uint8_t extendedAttr[0];
-       uint8_t allocDescs[0];
-} __attribute__ ((packed));
-
-#endif                         /* _ECMA_167_H */
+       tag             descTag;
+       icbtag          icbTag;
+       __le32          uid;
+       __le32          gid;
+       __le32          permissions;
+       __le16          fileLinkCount;
+       uint8_t         recordFormat;
+       uint8_t         recordDisplayAttr;
+       __le32          recordLength;
+       __le64          informationLength;
+       __le64          objectSize;
+       __le64          logicalBlocksRecorded;
+       timestamp       accessTime;
+       timestamp       modificationTime;
+       timestamp       createTime;
+       timestamp       attrTime;
+       __le32          checkpoint;
+       __le32          reserved;
+       long_ad         extendedAttrICB;
+       long_ad         streamDirectoryICB;
+       regid           impIdent;
+       __le64          uniqueID;
+       __le32          lengthExtendedAttr;
+       __le32          lengthAllocDescs;
+       uint8_t         extendedAttr[0];
+       uint8_t         allocDescs[0];
+} __attribute__ ((packed));
+
+#endif /* _ECMA_167_H */
index 67bf36bd3e6ed88c00af94892c5facef893c9729..5d7a4ea27753b4afb8ebc012aa7542b0aa0f3981 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/udf_fs.h>
 #include <asm/uaccess.h>
 #include <linux/kernel.h>
-#include <linux/string.h>      /* memset */
+#include <linux/string.h> /* memset */
 #include <linux/capability.h>
 #include <linux/errno.h>
 #include <linux/smp_lock.h>
@@ -55,11 +55,11 @@ static int udf_adinicb_readpage(struct file *file, struct page *page)
        SetPageUptodate(page);
        kunmap(page);
        unlock_page(page);
+
        return 0;
 }
 
-static int udf_adinicb_writepage(struct page *page,
-                                struct writeback_control *wbc)
+static int udf_adinicb_writepage(struct page *page, struct writeback_control *wbc)
 {
        struct inode *inode = page->mapping->host;
        char *kaddr;
@@ -72,6 +72,7 @@ static int udf_adinicb_writepage(struct page *page,
        SetPageUptodate(page);
        kunmap(page);
        unlock_page(page);
+
        return 0;
 }
 
@@ -100,11 +101,11 @@ static int udf_adinicb_commit_write(struct file *file, struct page *page,
 }
 
 const struct address_space_operations udf_adinicb_aops = {
-       .readpage = udf_adinicb_readpage,
-       .writepage = udf_adinicb_writepage,
-       .sync_page = block_sync_page,
-       .prepare_write = udf_adinicb_prepare_write,
-       .commit_write = udf_adinicb_commit_write,
+       .readpage       = udf_adinicb_readpage,
+       .writepage      = udf_adinicb_writepage,
+       .sync_page      = block_sync_page,
+       .prepare_write  = udf_adinicb_prepare_write,
+       .commit_write   = udf_adinicb_commit_write,
 };
 
 static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
@@ -122,8 +123,8 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
                else
                        pos = ppos;
 
-               if (inode->i_sb->s_blocksize <
-                   (udf_file_entry_alloc_offset(inode) + pos + count)) {
+               if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
+                                               pos + count)) {
                        udf_expand_file_adinicb(inode, pos + count, &err);
                        if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) {
                                udf_debug("udf_expand_adinicb: err=%d\n", err);
@@ -138,9 +139,9 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
        }
 
        retval = generic_file_aio_write(iocb, iov, nr_segs, ppos);
-
        if (retval > 0)
                mark_inode_dirty(inode);
+
        return retval;
 }
 
@@ -181,10 +182,12 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
              unsigned long arg)
 {
+       long old_block, new_block;
        int result = -EINVAL;
 
        if (file_permission(filp, MAY_READ) != 0) {
-               udf_debug("no permission to access inode %lu\n", inode->i_ino);
+               udf_debug("no permission to access inode %lu\n",
+                         inode->i_ino);
                return -EPERM;
        }
 
@@ -196,26 +199,19 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
        switch (cmd) {
        case UDF_GETVOLIDENT:
                return copy_to_user((char __user *)arg,
-                                   UDF_SB_VOLIDENT(inode->i_sb),
-                                   32) ? -EFAULT : 0;
+                                   UDF_SB_VOLIDENT(inode->i_sb), 32) ? -EFAULT : 0;
        case UDF_RELOCATE_BLOCKS:
-               {
-                       long old, new;
-
-                       if (!capable(CAP_SYS_ADMIN))
-                               return -EACCES;
-                       if (get_user(old, (long __user *)arg))
-                               return -EFAULT;
-                       if ((result = udf_relocate_blocks(inode->i_sb,
-                                                         old, &new)) == 0)
-                               result = put_user(new, (long __user *)arg);
-
-                       return result;
-               }
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EACCES;
+               if (get_user(old_block, (long __user *)arg))
+                       return -EFAULT;
+               if ((result = udf_relocate_blocks(inode->i_sb,
+                                                 old_block, &new_block)) == 0)
+                       result = put_user(new_block, (long __user *)arg);
+               return result;
        case UDF_GETEASIZE:
                result = put_user(UDF_I_LENEATTR(inode), (int __user *)arg);
                break;
-
        case UDF_GETEABLOCK:
                result = copy_to_user((char __user *)arg, UDF_I_DATA(inode),
                                      UDF_I_LENEATTR(inode)) ? -EFAULT : 0;
@@ -248,16 +244,16 @@ static int udf_release_file(struct inode *inode, struct file *filp)
 }
 
 const struct file_operations udf_file_operations = {
-       .read = do_sync_read,
-       .aio_read = generic_file_aio_read,
-       .ioctl = udf_ioctl,
-       .open = generic_file_open,
-       .mmap = generic_file_mmap,
-       .write = do_sync_write,
-       .aio_write = udf_file_aio_write,
-       .release = udf_release_file,
-       .fsync = udf_fsync_file,
-       .splice_read = generic_file_splice_read,
+       .read                   = do_sync_read,
+       .aio_read               = generic_file_aio_read,
+       .ioctl                  = udf_ioctl,
+       .open                   = generic_file_open,
+       .mmap                   = generic_file_mmap,
+       .write                  = do_sync_write,
+       .aio_write              = udf_file_aio_write,
+       .release                = udf_release_file,
+       .fsync                  = udf_fsync_file,
+       .splice_read            = generic_file_splice_read,
 };
 
 const struct inode_operations udf_file_inode_operations = {
index 7f0901c4f1f19a96edff585be6aba152af838ab6..b2c472b733b8a75cb83456fff70808da11dfbca6 100644 (file)
@@ -32,6 +32,7 @@ static int udf_fsync_inode(struct inode *, int);
 int udf_fsync_file(struct file *file, struct dentry *dentry, int datasync)
 {
        struct inode *inode = dentry->d_inode;
+
        return udf_fsync_inode(inode, datasync);
 }
 
@@ -46,5 +47,6 @@ static int udf_fsync_inode(struct inode *inode, int datasync)
                return err;
 
        err |= udf_sync_inode(inode);
+
        return err ? -EIO : 0;
 }
index 2eb503806bce12528a517277ce4fa4020bb0967d..636d8f613929a01dd854ae8773e87abdb325ba1b 100644 (file)
@@ -46,12 +46,10 @@ void udf_free_inode(struct inode *inode)
        if (sbi->s_lvidbh) {
                if (S_ISDIR(inode->i_mode))
                        UDF_SB_LVIDIU(sb)->numDirs =
-                           cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs)
-                                       - 1);
+                               cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) - 1);
                else
                        UDF_SB_LVIDIU(sb)->numFiles =
-                           cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles)
-                                       - 1);
+                               cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) - 1);
 
                mark_buffer_dirty(sbi->s_lvidbh);
        }
@@ -82,10 +80,8 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
        UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
        UDF_I_STRAT4096(inode) = 0;
 
-       block =
-           udf_new_block(dir->i_sb, NULL,
-                         UDF_I_LOCATION(dir).partitionReferenceNum, start,
-                         err);
+       block = udf_new_block(dir->i_sb, NULL, UDF_I_LOCATION(dir).partitionReferenceNum,
+                             start, err);
        if (*err) {
                iput(inode);
                return NULL;
@@ -95,17 +91,13 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
        if (UDF_SB_LVIDBH(sb)) {
                struct logicalVolHeaderDesc *lvhd;
                uint64_t uniqueID;
-               lvhd =
-                   (struct logicalVolHeaderDesc *)(UDF_SB_LVID(sb)->
-                                                   logicalVolContentsUse);
+               lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(sb)->logicalVolContentsUse);
                if (S_ISDIR(mode))
                        UDF_SB_LVIDIU(sb)->numDirs =
-                           cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs)
-                                       + 1);
+                               cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) + 1);
                else
                        UDF_SB_LVIDIU(sb)->numFiles =
-                           cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles)
-                                       + 1);
+                               cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) + 1);
                UDF_I_UNIQUE(inode) = uniqueID = le64_to_cpu(lvhd->uniqueID);
                if (!(++uniqueID & 0x00000000FFFFFFFFUL))
                        uniqueID += 16;
@@ -118,12 +110,12 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
                inode->i_gid = dir->i_gid;
                if (S_ISDIR(mode))
                        mode |= S_ISGID;
-       } else
+       } else {
                inode->i_gid = current->fsgid;
+       }
 
        UDF_I_LOCATION(inode).logicalBlockNum = block;
-       UDF_I_LOCATION(inode).partitionReferenceNum =
-           UDF_I_LOCATION(dir).partitionReferenceNum;
+       UDF_I_LOCATION(inode).partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum;
        inode->i_ino = udf_get_lb_pblock(sb, UDF_I_LOCATION(inode), 0);
        inode->i_blocks = 0;
        UDF_I_LENEATTR(inode) = 0;
@@ -132,14 +124,10 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
        if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE)) {
                UDF_I_EFE(inode) = 1;
                UDF_UPDATE_UDFREV(inode->i_sb, UDF_VERS_USE_EXTENDED_FE);
-               UDF_I_DATA(inode) =
-                   kzalloc(inode->i_sb->s_blocksize -
-                           sizeof(struct extendedFileEntry), GFP_KERNEL);
+               UDF_I_DATA(inode) = kzalloc(inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry), GFP_KERNEL);
        } else {
                UDF_I_EFE(inode) = 0;
-               UDF_I_DATA(inode) =
-                   kzalloc(inode->i_sb->s_blocksize - sizeof(struct fileEntry),
-                           GFP_KERNEL);
+               UDF_I_DATA(inode) = kzalloc(inode->i_sb->s_blocksize - sizeof(struct fileEntry), GFP_KERNEL);
        }
        if (!UDF_I_DATA(inode)) {
                iput(inode);
@@ -154,7 +142,7 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
        else
                UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
        inode->i_mtime = inode->i_atime = inode->i_ctime =
-           UDF_I_CRTIME(inode) = current_fs_time(inode->i_sb);
+               UDF_I_CRTIME(inode) = current_fs_time(inode->i_sb);
        insert_inode_hash(inode);
        mark_inode_dirty(inode);
        mutex_unlock(&sbi->s_alloc_mutex);
index be6326f449a1a5a8db77d8bb4a30109f42da25d3..0d2c41666cd28d877ce10f72e8782ecf0cbeaf81 100644 (file)
@@ -97,7 +97,8 @@ void udf_delete_inode(struct inode *inode)
 
        unlock_kernel();
        return;
-      no_delete:
+
+no_delete:
        clear_inode(inode);
 }
 
@@ -144,12 +145,12 @@ static sector_t udf_bmap(struct address_space *mapping, sector_t block)
 }
 
 const struct address_space_operations udf_aops = {
-       .readpage = udf_readpage,
-       .writepage = udf_writepage,
-       .sync_page = block_sync_page,
-       .prepare_write = udf_prepare_write,
-       .commit_write = generic_commit_write,
-       .bmap = udf_bmap,
+       .readpage       = udf_readpage,
+       .writepage      = udf_writepage,
+       .sync_page      = block_sync_page,
+       .prepare_write  = udf_prepare_write,
+       .commit_write   = generic_commit_write,
+       .bmap           = udf_bmap,
 };
 
 void udf_expand_file_adinicb(struct inode *inode, int newsize, int *err)
@@ -230,12 +231,10 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block,
        *block = udf_new_block(inode->i_sb, inode,
                               UDF_I_LOCATION(inode).partitionReferenceNum,
                               UDF_I_LOCATION(inode).logicalBlockNum, err);
-
        if (!(*block))
                return NULL;
        newblock = udf_get_pblock(inode->i_sb, *block,
-                                 UDF_I_LOCATION(inode).partitionReferenceNum,
-                                 0);
+                                 UDF_I_LOCATION(inode).partitionReferenceNum, 0);
        if (!newblock)
                return NULL;
        dbh = udf_tgetblk(inode->i_sb, newblock);
@@ -247,16 +246,13 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block,
        unlock_buffer(dbh);
        mark_buffer_dirty_inode(dbh, inode);
 
-       sfibh.soffset = sfibh.eoffset =
-           (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2;
+       sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2;
        sfibh.sbh = sfibh.ebh = NULL;
        dfibh.soffset = dfibh.eoffset = 0;
        dfibh.sbh = dfibh.ebh = dbh;
        while ((f_pos < size)) {
                UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
-               sfi =
-                   udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL,
-                                      NULL, NULL);
+               sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL);
                if (!sfi) {
                        brelse(dbh);
                        return NULL;
@@ -267,8 +263,7 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block,
                dfibh.eoffset += (sfibh.eoffset - sfibh.soffset);
                dfi = (struct fileIdentDesc *)(dbh->b_data + dfibh.soffset);
                if (udf_write_fi(inode, sfi, dfi, &dfibh, sfi->impUse,
-                                sfi->fileIdent +
-                                le16_to_cpu(sfi->lengthOfImpUse))) {
+                                sfi->fileIdent + le16_to_cpu(sfi->lengthOfImpUse))) {
                        UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
                        brelse(dbh);
                        return NULL;
@@ -276,12 +271,10 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block,
        }
        mark_buffer_dirty_inode(dbh, inode);
 
-       memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0,
-              UDF_I_LENALLOC(inode));
+       memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0, UDF_I_LENALLOC(inode));
        UDF_I_LENALLOC(inode) = 0;
        eloc.logicalBlockNum = *block;
-       eloc.partitionReferenceNum =
-           UDF_I_LOCATION(inode).partitionReferenceNum;
+       eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
        elen = inode->i_size;
        UDF_I_LENEXTENTS(inode) = elen;
        epos.bh = NULL;
@@ -334,11 +327,12 @@ static int udf_get_block(struct inode *inode, sector_t block,
        if (new)
                set_buffer_new(bh_result);
        map_bh(bh_result, inode->i_sb, phys);
-      abort:
+
+abort:
        unlock_kernel();
        return err;
 
-      abort_negative:
+abort_negative:
        udf_warning(inode->i_sb, "udf_get_block", "block < 0");
        goto abort;
 }
@@ -346,13 +340,13 @@ static int udf_get_block(struct inode *inode, sector_t block,
 static struct buffer_head *udf_getblk(struct inode *inode, long block,
                                      int create, int *err)
 {
+       struct buffer_head *bh;
        struct buffer_head dummy;
 
        dummy.b_state = 0;
        dummy.b_blocknr = -1000;
        *err = udf_get_block(inode, block, &dummy, create);
        if (!*err && buffer_mapped(&dummy)) {
-               struct buffer_head *bh;
                bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
                if (buffer_new(&dummy)) {
                        lock_buffer(bh);
@@ -363,6 +357,7 @@ static struct buffer_head *udf_getblk(struct inode *inode, long block,
                }
                return bh;
        }
+
        return NULL;
 }
 
@@ -373,42 +368,41 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
        sector_t add;
        int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
        struct super_block *sb = inode->i_sb;
-       kernel_lb_addr prealloc_loc = { 0, 0 };
+       kernel_lb_addr prealloc_loc = {};
        int prealloc_len = 0;
 
        /* The previous extent is fake and we should not extend by anything
         * - there's nothing to do... */
        if (!blocks && fake)
                return 0;
+
        /* Round the last extent up to a multiple of block size */
        if (last_ext->extLength & (sb->s_blocksize - 1)) {
                last_ext->extLength =
-                   (last_ext->extLength & UDF_EXTENT_FLAG_MASK) |
-                   (((last_ext->extLength & UDF_EXTENT_LENGTH_MASK) +
-                     sb->s_blocksize - 1) & ~(sb->s_blocksize - 1));
+                       (last_ext->extLength & UDF_EXTENT_FLAG_MASK) |
+                       (((last_ext->extLength & UDF_EXTENT_LENGTH_MASK) +
+                         sb->s_blocksize - 1) & ~(sb->s_blocksize - 1));
                UDF_I_LENEXTENTS(inode) =
-                   (UDF_I_LENEXTENTS(inode) + sb->s_blocksize - 1) &
-                   ~(sb->s_blocksize - 1);
+                       (UDF_I_LENEXTENTS(inode) + sb->s_blocksize - 1) &
+                       ~(sb->s_blocksize - 1);
        }
+
        /* Last extent are just preallocated blocks? */
-       if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
-           EXT_NOT_RECORDED_ALLOCATED) {
+       if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_ALLOCATED) {
                /* Save the extent so that we can reattach it to the end */
                prealloc_loc = last_ext->extLocation;
                prealloc_len = last_ext->extLength;
                /* Mark the extent as a hole */
                last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
-                   (last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
+                       (last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
                last_ext->extLocation.logicalBlockNum = 0;
-               last_ext->extLocation.partitionReferenceNum = 0;
+                       last_ext->extLocation.partitionReferenceNum = 0;
        }
+
        /* Can we merge with the previous extent? */
-       if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
-           EXT_NOT_RECORDED_NOT_ALLOCATED) {
-               add =
-                   ((1 << 30) - sb->s_blocksize -
-                    (last_ext->extLength & UDF_EXTENT_LENGTH_MASK)) >> sb->
-                   s_blocksize_bits;
+       if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_NOT_ALLOCATED) {
+               add = ((1 << 30) - sb->s_blocksize - (last_ext->extLength &
+                                                     UDF_EXTENT_LENGTH_MASK)) >> sb->s_blocksize_bits;
                if (add > blocks)
                        add = blocks;
                blocks -= add;
@@ -419,19 +413,20 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
                udf_add_aext(inode, last_pos, last_ext->extLocation,
                             last_ext->extLength, 1);
                count++;
-       } else
-               udf_write_aext(inode, last_pos, last_ext->extLocation,
-                              last_ext->extLength, 1);
+       } else {
+               udf_write_aext(inode, last_pos, last_ext->extLocation, last_ext->extLength, 1);
+       }
+
        /* Managed to do everything necessary? */
        if (!blocks)
                goto out;
 
        /* All further extents will be NOT_RECORDED_NOT_ALLOCATED */
        last_ext->extLocation.logicalBlockNum = 0;
-       last_ext->extLocation.partitionReferenceNum = 0;
-       add = (1 << (30 - sb->s_blocksize_bits)) - 1;
-       last_ext->extLength =
-           EXT_NOT_RECORDED_NOT_ALLOCATED | (add << sb->s_blocksize_bits);
+               last_ext->extLocation.partitionReferenceNum = 0;
+       add = (1 << (30-sb->s_blocksize_bits)) - 1;
+       last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | (add << sb->s_blocksize_bits);
+
        /* Create enough extents to cover the whole hole */
        while (blocks > add) {
                blocks -= add;
@@ -442,22 +437,23 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
        }
        if (blocks) {
                last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
-                   (blocks << sb->s_blocksize_bits);
+                       (blocks << sb->s_blocksize_bits);
                if (udf_add_aext(inode, last_pos, last_ext->extLocation,
                                 last_ext->extLength, 1) == -1)
                        return -1;
                count++;
        }
-      out:
+
+out:
        /* Do we have some preallocated blocks saved? */
        if (prealloc_len) {
-               if (udf_add_aext(inode, last_pos, prealloc_loc, prealloc_len, 1)
-                   == -1)
+               if (udf_add_aext(inode, last_pos, prealloc_loc, prealloc_len, 1) == -1)
                        return -1;
                last_ext->extLocation = prealloc_loc;
                last_ext->extLength = prealloc_len;
                count++;
        }
+
        /* last_pos should point to the last written extent... */
        if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
                last_pos->offset -= sizeof(short_ad);
@@ -465,6 +461,7 @@ int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
                last_pos->offset -= sizeof(long_ad);
        else
                return -1;
+
        return count;
 }
 
@@ -490,7 +487,7 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
        prev_epos.block = UDF_I_LOCATION(inode);
        prev_epos.bh = NULL;
        cur_epos = next_epos = prev_epos;
-       b_off = (loff_t) block << inode->i_sb->s_blocksize_bits;
+       b_off = (loff_t)block << inode->i_sb->s_blocksize_bits;
 
        /* find the extent which contains the block we are looking for.
           alternate between laarr[0] and laarr[1] for locations of the
@@ -515,8 +512,7 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
                prev_epos.offset = cur_epos.offset;
                cur_epos.offset = next_epos.offset;
 
-               if ((etype =
-                    udf_next_aext(inode, &next_epos, &eloc, &elen, 1)) == -1)
+               if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 1)) == -1)
                        break;
 
                c = !c;
@@ -526,8 +522,8 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
 
                if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
                        pgoal = eloc.logicalBlockNum +
-                           ((elen + inode->i_sb->s_blocksize - 1) >>
-                            inode->i_sb->s_blocksize_bits);
+                               ((elen + inode->i_sb->s_blocksize - 1) >>
+                                inode->i_sb->s_blocksize_bits);
 
                count++;
        } while (lbcount + elen <= b_off);
@@ -547,8 +543,8 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
        if (etype == (EXT_RECORDED_ALLOCATED >> 30)) {
                if (elen & (inode->i_sb->s_blocksize - 1)) {
                        elen = EXT_RECORDED_ALLOCATED |
-                           ((elen + inode->i_sb->s_blocksize - 1) &
-                            ~(inode->i_sb->s_blocksize - 1));
+                               ((elen + inode->i_sb->s_blocksize - 1) &
+                                ~(inode->i_sb->s_blocksize - 1));
                        etype = udf_write_aext(inode, &cur_epos, eloc, elen, 1);
                }
                brelse(prev_epos.bh);
@@ -570,8 +566,7 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
                        startnum = 1;
                } else {
                        /* Create a fake extent when there's not one */
-                       memset(&laarr[0].extLocation, 0x00,
-                              sizeof(kernel_lb_addr));
+                       memset(&laarr[0].extLocation, 0x00, sizeof(kernel_lb_addr));
                        laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED;
                        /* Will udf_extend_file() create real extent from a fake one? */
                        startnum = (offset > 0);
@@ -591,16 +586,14 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
                offset = 0;
                count += ret;
                /* We are not covered by a preallocated extent? */
-               if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) !=
-                   EXT_NOT_RECORDED_ALLOCATED) {
+               if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) != EXT_NOT_RECORDED_ALLOCATED) {
                        /* Is there any real extent? - otherwise we overwrite
                         * the fake one... */
                        if (count)
                                c = !c;
                        laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
-                           inode->i_sb->s_blocksize;
-                       memset(&laarr[c].extLocation, 0x00,
-                              sizeof(kernel_lb_addr));
+                               inode->i_sb->s_blocksize;
+                       memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr));
                        count++;
                        endnum++;
                }
@@ -618,8 +611,7 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
                }
 
                /* if the current block is located in an extent, read the next extent */
-               if ((etype =
-                    udf_next_aext(inode, &next_epos, &eloc, &elen, 0)) != -1) {
+               if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 0)) != -1) {
                        laarr[c + 1].extLength = (etype << 30) | elen;
                        laarr[c + 1].extLocation = eloc;
                        count++;
@@ -631,24 +623,21 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
        }
 
        /* if the current extent is not recorded but allocated, get the
-          block in the extent corresponding to the requested block */
-       if ((laarr[c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
+        * block in the extent corresponding to the requested block */
+       if ((laarr[c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
                newblocknum = laarr[c].extLocation.logicalBlockNum + offset;
-       else {                  /* otherwise, allocate a new block */
-
+       } else { /* otherwise, allocate a new block */
                if (UDF_I_NEXT_ALLOC_BLOCK(inode) == block)
                        goal = UDF_I_NEXT_ALLOC_GOAL(inode);
 
                if (!goal) {
                        if (!(goal = pgoal))
-                               goal =
-                                   UDF_I_LOCATION(inode).logicalBlockNum + 1;
+                               goal = UDF_I_LOCATION(inode).logicalBlockNum + 1;
                }
 
                if (!(newblocknum = udf_new_block(inode->i_sb, inode,
-                                                 UDF_I_LOCATION(inode).
-                                                 partitionReferenceNum, goal,
-                                                 err))) {
+                                                 UDF_I_LOCATION(inode).partitionReferenceNum,
+                                                 goal, err))) {
                        brelse(prev_epos.bh);
                        *err = -ENOSPC;
                        return NULL;
@@ -657,8 +646,8 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
        }
 
        /* if the extent the requsted block is located in contains multiple blocks,
-          split the extent into at most three extents. blocks prior to requested
-          block, requested block, and blocks after requested block */
+        * split the extent into at most three extents. blocks prior to requested
+        * block, requested block, and blocks after requested block */
        udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum);
 
 #ifdef UDF_PREALLOCATE
@@ -670,15 +659,14 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
        udf_merge_extents(inode, laarr, &endnum);
 
        /* write back the new extents, inserting new extents if the new number
-          of extents is greater than the old number, and deleting extents if
-          the new number of extents is less than the old number */
+        * of extents is greater than the old number, and deleting extents if
+        * the new number of extents is less than the old number */
        udf_update_extents(inode, laarr, startnum, endnum, &prev_epos);
 
        brelse(prev_epos.bh);
 
        if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum,
-                                       UDF_I_LOCATION(inode).
-                                       partitionReferenceNum, 0))) {
+                                       UDF_I_LOCATION(inode).partitionReferenceNum, 0))) {
                return NULL;
        }
        *phys = newblock;
@@ -692,6 +680,7 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
                udf_sync_inode(inode);
        else
                mark_inode_dirty(inode);
+
        return result;
 }
 
@@ -701,16 +690,15 @@ static void udf_split_extents(struct inode *inode, int *c, int offset,
                              int *endnum)
 {
        if ((laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30) ||
-           (laarr[*c].extLength >> 30) ==
-           (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) {
+           (laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) {
                int curr = *c;
                int blen = ((laarr[curr].extLength & UDF_EXTENT_LENGTH_MASK) +
-                           inode->i_sb->s_blocksize -
-                           1) >> inode->i_sb->s_blocksize_bits;
+                           inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
                int8_t etype = (laarr[curr].extLength >> 30);
 
-               if (blen == 1) ;
-               else if (!offset || blen == offset + 1) {
+               if (blen == 1) {
+                       ;
+               } else if (!offset || blen == offset + 1) {
                        laarr[curr + 2] = laarr[curr + 1];
                        laarr[curr + 1] = laarr[curr];
                } else {
@@ -720,20 +708,15 @@ static void udf_split_extents(struct inode *inode, int *c, int offset,
 
                if (offset) {
                        if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
-                               udf_free_blocks(inode->i_sb, inode,
-                                               laarr[curr].extLocation, 0,
-                                               offset);
-                               laarr[curr].extLength =
-                                   EXT_NOT_RECORDED_NOT_ALLOCATED | (offset <<
-                                                                     inode->
-                                                                     i_sb->
-                                                                     s_blocksize_bits);
+                               udf_free_blocks(inode->i_sb, inode, laarr[curr].extLocation, 0, offset);
+                               laarr[curr].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
+                                       (offset << inode->i_sb->s_blocksize_bits);
                                laarr[curr].extLocation.logicalBlockNum = 0;
-                               laarr[curr].extLocation.partitionReferenceNum =
-                                   0;
-                       } else
+                               laarr[curr].extLocation.partitionReferenceNum = 0;
+                       } else {
                                laarr[curr].extLength = (etype << 30) |
-                                   (offset << inode->i_sb->s_blocksize_bits);
+                                       (offset << inode->i_sb->s_blocksize_bits);
+                       }
                        curr++;
                        (*c)++;
                        (*endnum)++;
@@ -742,18 +725,16 @@ static void udf_split_extents(struct inode *inode, int *c, int offset,
                laarr[curr].extLocation.logicalBlockNum = newblocknum;
                if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
                        laarr[curr].extLocation.partitionReferenceNum =
-                           UDF_I_LOCATION(inode).partitionReferenceNum;
+                               UDF_I_LOCATION(inode).partitionReferenceNum;
                laarr[curr].extLength = EXT_RECORDED_ALLOCATED |
-                   inode->i_sb->s_blocksize;
+                       inode->i_sb->s_blocksize;
                curr++;
 
                if (blen != offset + 1) {
                        if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
-                               laarr[curr].extLocation.logicalBlockNum +=
-                                   (offset + 1);
-                       laarr[curr].extLength =
-                           (etype << 30) | ((blen - (offset + 1)) << inode->
-                                            i_sb->s_blocksize_bits);
+                               laarr[curr].extLocation.logicalBlockNum += (offset + 1);
+                       laarr[curr].extLength = (etype << 30) |
+                               ((blen - (offset + 1)) << inode->i_sb->s_blocksize_bits);
                        curr++;
                        (*endnum)++;
                }
@@ -772,90 +753,69 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
                else
                        start = c;
        } else {
-               if ((laarr[c + 1].extLength >> 30) ==
-                   (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
+               if ((laarr[c + 1].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
                        start = c + 1;
-                       length = currlength =
-                           (((laarr[c + 1].
-                              extLength & UDF_EXTENT_LENGTH_MASK) +
-                             inode->i_sb->s_blocksize -
-                             1) >> inode->i_sb->s_blocksize_bits);
-               } else
+                       length = currlength = (((laarr[c + 1].extLength & UDF_EXTENT_LENGTH_MASK) +
+                                               inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
+               } else {
                        start = c;
+               }
        }
 
        for (i = start + 1; i <= *endnum; i++) {
                if (i == *endnum) {
                        if (lastblock)
                                length += UDF_DEFAULT_PREALLOC_BLOCKS;
-               } else if ((laarr[i].extLength >> 30) ==
-                          (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
-                       length +=
-                           (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
-                             inode->i_sb->s_blocksize -
-                             1) >> inode->i_sb->s_blocksize_bits);
-               else
+               } else if ((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) {
+                       length += (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
+                                   inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
+               } else {
                        break;
+               }
        }
 
        if (length) {
                int next = laarr[start].extLocation.logicalBlockNum +
-                   (((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) +
-                     inode->i_sb->s_blocksize -
-                     1) >> inode->i_sb->s_blocksize_bits);
+                       (((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) +
+                         inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
                int numalloc = udf_prealloc_blocks(inode->i_sb, inode,
-                                                  laarr[start].extLocation.
-                                                  partitionReferenceNum,
-                                                  next,
-                                                  (UDF_DEFAULT_PREALLOC_BLOCKS
-                                                   >
-                                                   length ? length :
-                                                   UDF_DEFAULT_PREALLOC_BLOCKS)
-                                                  - currlength);
-
-               if (numalloc) {
-                       if (start == (c + 1))
+                                                  laarr[start].extLocation.partitionReferenceNum,
+                                                  next, (UDF_DEFAULT_PREALLOC_BLOCKS > length ? length :
+                                                         UDF_DEFAULT_PREALLOC_BLOCKS) - currlength);
+               if (numalloc)   {
+                       if (start == (c + 1)) {
                                laarr[start].extLength +=
-                                   (numalloc << inode->i_sb->s_blocksize_bits);
-                       else {
+                                       (numalloc << inode->i_sb->s_blocksize_bits);
+                       else {
                                memmove(&laarr[c + 2], &laarr[c + 1],
                                        sizeof(long_ad) * (*endnum - (c + 1)));
                                (*endnum)++;
                                laarr[c + 1].extLocation.logicalBlockNum = next;
                                laarr[c + 1].extLocation.partitionReferenceNum =
-                                   laarr[c].extLocation.partitionReferenceNum;
-                               laarr[c + 1].extLength =
-                                   EXT_NOT_RECORDED_ALLOCATED | (numalloc <<
-                                                                 inode->i_sb->
-                                                                 s_blocksize_bits);
+                                       laarr[c].extLocation.partitionReferenceNum;
+                               laarr[c + 1].extLength = EXT_NOT_RECORDED_ALLOCATED |
+                                       (numalloc << inode->i_sb->s_blocksize_bits);
                                start = c + 1;
                        }
 
                        for (i = start + 1; numalloc && i < *endnum; i++) {
-                               int elen =
-                                   ((laarr[i].
-                                     extLength & UDF_EXTENT_LENGTH_MASK) +
-                                    inode->i_sb->s_blocksize -
-                                    1) >> inode->i_sb->s_blocksize_bits;
+                               int elen = ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
+                                           inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
 
                                if (elen > numalloc) {
                                        laarr[i].extLength -=
-                                           (numalloc << inode->i_sb->
-                                            s_blocksize_bits);
+                                               (numalloc << inode->i_sb->s_blocksize_bits);
                                        numalloc = 0;
                                } else {
                                        numalloc -= elen;
                                        if (*endnum > (i + 1))
-                                               memmove(&laarr[i],
-                                                       &laarr[i + 1],
-                                                       sizeof(long_ad) *
-                                                       (*endnum - (i + 1)));
+                                               memmove(&laarr[i], &laarr[i + 1],
+                                                       sizeof(long_ad) * (*endnum - (i + 1)));
                                        i--;
                                        (*endnum)--;
                                }
                        }
-                       UDF_I_LENEXTENTS(inode) +=
-                           numalloc << inode->i_sb->s_blocksize_bits;
+                       UDF_I_LENEXTENTS(inode) += numalloc << inode->i_sb->s_blocksize_bits;
                }
        }
 }
@@ -867,119 +827,68 @@ static void udf_merge_extents(struct inode *inode,
        int i;
 
        for (i = 0; i < (*endnum - 1); i++) {
-               if ((laarr[i].extLength >> 30) ==
-                   (laarr[i + 1].extLength >> 30)) {
-                       if (((laarr[i].extLength >> 30) ==
-                            (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
-                           ||
-                           ((laarr[i + 1].extLocation.logicalBlockNum -
-                             laarr[i].extLocation.logicalBlockNum) ==
+               if ((laarr[i].extLength >> 30) == (laarr[i + 1].extLength >> 30)) {
+                       if (((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) ||
+                           ((laarr[i + 1].extLocation.logicalBlockNum - laarr[i].extLocation.logicalBlockNum) ==
                             (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
-                              inode->i_sb->s_blocksize -
-                              1) >> inode->i_sb->s_blocksize_bits))) {
-                               if (((laarr[i].
-                                     extLength & UDF_EXTENT_LENGTH_MASK) +
-                                    (laarr[i + 1].
-                                     extLength & UDF_EXTENT_LENGTH_MASK) +
-                                    inode->i_sb->s_blocksize -
-                                    1) & ~UDF_EXTENT_LENGTH_MASK) {
-                                       laarr[i + 1].extLength =
-                                           (laarr[i + 1].extLength -
-                                            (laarr[i].
-                                             extLength &
-                                             UDF_EXTENT_LENGTH_MASK) +
-                                            UDF_EXTENT_LENGTH_MASK) & ~(inode->
-                                                                        i_sb->
-                                                                        s_blocksize
-                                                                        - 1);
-                                       laarr[i].extLength =
-                                           (laarr[i].
-                                            extLength & UDF_EXTENT_FLAG_MASK) +
-                                           (UDF_EXTENT_LENGTH_MASK + 1) -
-                                           inode->i_sb->s_blocksize;
-                                       laarr[i +
-                                             1].extLocation.logicalBlockNum =
-                                           laarr[i].extLocation.
-                                           logicalBlockNum +
-                                           ((laarr[i].
-                                             extLength &
-                                             UDF_EXTENT_LENGTH_MASK) >> inode->
-                                            i_sb->s_blocksize_bits);
+                              inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits))) {
+                               if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
+                                    (laarr[i + 1].extLength & UDF_EXTENT_LENGTH_MASK) +
+                                    inode->i_sb->s_blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) {
+                                       laarr[i + 1].extLength = (laarr[i + 1].extLength -
+                                                                 (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
+                                                                 UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize - 1);
+                                       laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_FLAG_MASK) +
+                                               (UDF_EXTENT_LENGTH_MASK + 1) - inode->i_sb->s_blocksize;
+                                       laarr[i + 1].extLocation.logicalBlockNum =
+                                               laarr[i].extLocation.logicalBlockNum +
+                                               ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) >>
+                                                inode->i_sb->s_blocksize_bits);
                                } else {
-                                       laarr[i].extLength =
-                                           laarr[i + 1].extLength +
-                                           (((laarr[i].
-                                              extLength &
-                                              UDF_EXTENT_LENGTH_MASK) +
-                                             inode->i_sb->s_blocksize -
-                                             1) & ~(inode->i_sb->s_blocksize -
-                                                    1));
+                                       laarr[i].extLength = laarr[i + 1].extLength +
+                                               (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
+                                                 inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize - 1));
                                        if (*endnum > (i + 2))
-                                               memmove(&laarr[i + 1],
-                                                       &laarr[i + 2],
-                                                       sizeof(long_ad) *
-                                                       (*endnum - (i + 2)));
+                                               memmove(&laarr[i + 1], &laarr[i + 2],
+                                                       sizeof(long_ad) * (*endnum - (i + 2)));
                                        i--;
                                        (*endnum)--;
                                }
                        }
-               } else
-                   if (((laarr[i].extLength >> 30) ==
-                        (EXT_NOT_RECORDED_ALLOCATED >> 30))
-                       && ((laarr[i + 1].extLength >> 30) ==
-                           (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))) {
-                       udf_free_blocks(inode->i_sb, inode,
-                                       laarr[i].extLocation, 0,
-                                       ((laarr[i].
-                                         extLength & UDF_EXTENT_LENGTH_MASK) +
-                                        inode->i_sb->s_blocksize -
-                                        1) >> inode->i_sb->s_blocksize_bits);
+               } else if (((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) &&
+                          ((laarr[i + 1].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))) {
+                       udf_free_blocks(inode->i_sb, inode, laarr[i].extLocation, 0,
+                                       ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
+                                        inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
                        laarr[i].extLocation.logicalBlockNum = 0;
                        laarr[i].extLocation.partitionReferenceNum = 0;
 
                        if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
                             (laarr[i + 1].extLength & UDF_EXTENT_LENGTH_MASK) +
-                            inode->i_sb->s_blocksize -
-                            1) & ~UDF_EXTENT_LENGTH_MASK) {
-                               laarr[i + 1].extLength =
-                                   (laarr[i + 1].extLength -
-                                    (laarr[i].
-                                     extLength & UDF_EXTENT_LENGTH_MASK) +
-                                    UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->
-                                                                s_blocksize -
-                                                                1);
-                               laarr[i].extLength =
-                                   (laarr[i].
-                                    extLength & UDF_EXTENT_FLAG_MASK) +
-                                   (UDF_EXTENT_LENGTH_MASK + 1) -
-                                   inode->i_sb->s_blocksize;
+                            inode->i_sb->s_blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) {
+                               laarr[i + 1].extLength = (laarr[i + 1].extLength -
+                                                         (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
+                                                         UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize - 1);
+                               laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_FLAG_MASK) +
+                                       (UDF_EXTENT_LENGTH_MASK + 1) - inode->i_sb->s_blocksize;
                        } else {
                                laarr[i].extLength = laarr[i + 1].extLength +
-                                   (((laarr[i].
-                                      extLength & UDF_EXTENT_LENGTH_MASK) +
-                                     inode->i_sb->s_blocksize -
-                                     1) & ~(inode->i_sb->s_blocksize - 1));
+                                       (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
+                                         inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize - 1));
                                if (*endnum > (i + 2))
                                        memmove(&laarr[i + 1], &laarr[i + 2],
-                                               sizeof(long_ad) * (*endnum -
-                                                                  (i + 2)));
+                                               sizeof(long_ad) * (*endnum - (i + 2)));
                                i--;
                                (*endnum)--;
                        }
-               } else if ((laarr[i].extLength >> 30) ==
-                          (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
-                       udf_free_blocks(inode->i_sb, inode,
-                                       laarr[i].extLocation, 0,
-                                       ((laarr[i].
-                                         extLength & UDF_EXTENT_LENGTH_MASK) +
-                                        inode->i_sb->s_blocksize -
-                                        1) >> inode->i_sb->s_blocksize_bits);
+               } else if ((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
+                       udf_free_blocks(inode->i_sb, inode, laarr[i].extLocation, 0,
+                                       ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
+                                        inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
                        laarr[i].extLocation.logicalBlockNum = 0;
                        laarr[i].extLocation.partitionReferenceNum = 0;
-                       laarr[i].extLength =
-                           (laarr[i].
-                            extLength & UDF_EXTENT_LENGTH_MASK) |
-                           EXT_NOT_RECORDED_NOT_ALLOCATED;
+                       laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) |
+                               EXT_NOT_RECORDED_NOT_ALLOCATED;
                }
        }
 }
@@ -1025,10 +934,13 @@ struct buffer_head *udf_bread(struct inode *inode, int block,
 
        if (buffer_uptodate(bh))
                return bh;
+
        ll_rw_block(READ, 1, &bh);
+
        wait_on_buffer(bh);
        if (buffer_uptodate(bh))
                return bh;
+
        brelse(bh);
        *err = -EIO;
        return NULL;
@@ -1047,26 +959,24 @@ void udf_truncate(struct inode *inode)
 
        lock_kernel();
        if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) {
-               if (inode->i_sb->s_blocksize <
-                   (udf_file_entry_alloc_offset(inode) + inode->i_size)) {
+               if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
+                                               inode->i_size)) {
                        udf_expand_file_adinicb(inode, inode->i_size, &err);
                        if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) {
                                inode->i_size = UDF_I_LENALLOC(inode);
                                unlock_kernel();
                                return;
-                       } else
+                       } else {
                                udf_truncate_extents(inode);
+                       }
                } else {
                        offset = inode->i_size & (inode->i_sb->s_blocksize - 1);
-                       memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) +
-                              offset, 0x00,
-                              inode->i_sb->s_blocksize - offset -
-                              udf_file_entry_alloc_offset(inode));
+                       memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) + offset, 0x00,
+                              inode->i_sb->s_blocksize - offset - udf_file_entry_alloc_offset(inode));
                        UDF_I_LENALLOC(inode) = inode->i_size;
                }
        } else {
-               block_truncate_page(inode->i_mapping, inode->i_size,
-                                   udf_get_block);
+               block_truncate_page(inode->i_mapping, inode->i_size, udf_get_block);
                udf_truncate_extents(inode);
        }
 
@@ -1097,7 +1007,6 @@ static void __udf_read_inode(struct inode *inode)
         *      i_op = NULL;
         */
        bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident);
-
        if (!bh) {
                printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed !bh\n",
                       inode->i_ino);
@@ -1107,8 +1016,7 @@ static void __udf_read_inode(struct inode *inode)
 
        if (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE &&
            ident != TAG_IDENT_USE) {
-               printk(KERN_ERR
-                      "udf: udf_read_inode(ino %ld) failed ident=%d\n",
+               printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n",
                       inode->i_ino, ident);
                brelse(bh);
                make_bad_inode(inode);
@@ -1121,9 +1029,7 @@ static void __udf_read_inode(struct inode *inode)
                struct buffer_head *ibh = NULL, *nbh = NULL;
                struct indirectEntry *ie;
 
-               ibh =
-                   udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 1,
-                                    &ident);
+               ibh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 1, &ident);
                if (ident == TAG_IDENT_IE) {
                        if (ibh) {
                                kernel_lb_addr loc;
@@ -1132,13 +1038,10 @@ static void __udf_read_inode(struct inode *inode)
                                loc = lelb_to_cpu(ie->indirectICB.extLocation);
 
                                if (ie->indirectICB.extLength &&
-                                   (nbh =
-                                    udf_read_ptagged(inode->i_sb, loc, 0,
-                                                     &ident))) {
-                                       if (ident == TAG_IDENT_FE
-                                           || ident == TAG_IDENT_EFE) {
-                                               memcpy(&UDF_I_LOCATION(inode),
-                                                      &loc,
+                                   (nbh = udf_read_ptagged(inode->i_sb, loc, 0, &ident))) {
+                                       if (ident == TAG_IDENT_FE ||
+                                           ident == TAG_IDENT_EFE) {
+                                               memcpy(&UDF_I_LOCATION(inode), &loc,
                                                       sizeof(kernel_lb_addr));
                                                brelse(bh);
                                                brelse(ibh);
@@ -1149,11 +1052,13 @@ static void __udf_read_inode(struct inode *inode)
                                                brelse(nbh);
                                                brelse(ibh);
                                        }
-                               } else
+                               } else {
                                        brelse(ibh);
+                               }
                        }
-               } else
+               } else {
                        brelse(ibh);
+               }
        } else if (le16_to_cpu(fe->icbTag.strategyType) != 4) {
                printk(KERN_ERR "udf: unsupported strategy type: %d\n",
                       le16_to_cpu(fe->icbTag.strategyType));
@@ -1179,11 +1084,10 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
 
        if (le16_to_cpu(fe->icbTag.strategyType) == 4)
                UDF_I_STRAT4096(inode) = 0;
-       else                    /* if (le16_to_cpu(fe->icbTag.strategyType) == 4096) */
+       else /* if (le16_to_cpu(fe->icbTag.strategyType) == 4096) */
                UDF_I_STRAT4096(inode) = 1;
 
-       UDF_I_ALLOCTYPE(inode) =
-           le16_to_cpu(fe->icbTag.flags) & ICBTAG_FLAG_AD_MASK;
+       UDF_I_ALLOCTYPE(inode) = le16_to_cpu(fe->icbTag.flags) & ICBTAG_FLAG_AD_MASK;
        UDF_I_UNIQUE(inode) = 0;
        UDF_I_LENEATTR(inode) = 0;
        UDF_I_LENEXTENTS(inode) = 0;
@@ -1193,23 +1097,16 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
        if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_EFE) {
                UDF_I_EFE(inode) = 1;
                UDF_I_USE(inode) = 0;
-               if (udf_alloc_i_data
-                   (inode,
-                    inode->i_sb->s_blocksize -
-                    sizeof(struct extendedFileEntry))) {
+               if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry))) {
                        make_bad_inode(inode);
                        return;
                }
-               memcpy(UDF_I_DATA(inode),
-                      bh->b_data + sizeof(struct extendedFileEntry),
-                      inode->i_sb->s_blocksize -
-                      sizeof(struct extendedFileEntry));
+               memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct extendedFileEntry),
+                      inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry));
        } else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_FE) {
                UDF_I_EFE(inode) = 0;
                UDF_I_USE(inode) = 0;
-               if (udf_alloc_i_data
-                   (inode,
-                    inode->i_sb->s_blocksize - sizeof(struct fileEntry))) {
+               if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize - sizeof(struct fileEntry))) {
                        make_bad_inode(inode);
                        return;
                }
@@ -1219,19 +1116,13 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
                UDF_I_EFE(inode) = 0;
                UDF_I_USE(inode) = 1;
                UDF_I_LENALLOC(inode) =
-                   le32_to_cpu(((struct unallocSpaceEntry *)bh->b_data)->
-                               lengthAllocDescs);
-               if (udf_alloc_i_data
-                   (inode,
-                    inode->i_sb->s_blocksize -
-                    sizeof(struct unallocSpaceEntry))) {
+                   le32_to_cpu(((struct unallocSpaceEntry *)bh->b_data)->lengthAllocDescs);
+               if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry))) {
                        make_bad_inode(inode);
                        return;
                }
-               memcpy(UDF_I_DATA(inode),
-                      bh->b_data + sizeof(struct unallocSpaceEntry),
-                      inode->i_sb->s_blocksize -
-                      sizeof(struct unallocSpaceEntry));
+               memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct unallocSpaceEntry),
+                      inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry));
                return;
        }
 
@@ -1257,7 +1148,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
 
        if (UDF_I_EFE(inode) == 0) {
                inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
-                   (inode->i_sb->s_blocksize_bits - 9);
+                       (inode->i_sb->s_blocksize_bits - 9);
 
                if (udf_stamp_to_time(&convtime, &convtime_usec,
                                      lets_to_cpu(fe->accessTime))) {
@@ -1326,78 +1217,56 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
                UDF_I_UNIQUE(inode) = le64_to_cpu(efe->uniqueID);
                UDF_I_LENEATTR(inode) = le32_to_cpu(efe->lengthExtendedAttr);
                UDF_I_LENALLOC(inode) = le32_to_cpu(efe->lengthAllocDescs);
-               offset =
-                   sizeof(struct extendedFileEntry) + UDF_I_LENEATTR(inode);
+               offset = sizeof(struct extendedFileEntry) + UDF_I_LENEATTR(inode);
        }
 
        switch (fe->icbTag.fileType) {
        case ICBTAG_FILE_TYPE_DIRECTORY:
-               {
-                       inode->i_op = &udf_dir_inode_operations;
-                       inode->i_fop = &udf_dir_operations;
-                       inode->i_mode |= S_IFDIR;
-                       inc_nlink(inode);
-                       break;
-               }
+               inode->i_op = &udf_dir_inode_operations;
+               inode->i_fop = &udf_dir_operations;
+               inode->i_mode |= S_IFDIR;
+               inc_nlink(inode);
+               break;
        case ICBTAG_FILE_TYPE_REALTIME:
        case ICBTAG_FILE_TYPE_REGULAR:
        case ICBTAG_FILE_TYPE_UNDEF:
-               {
-                       if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
-                               inode->i_data.a_ops = &udf_adinicb_aops;
-                       else
-                               inode->i_data.a_ops = &udf_aops;
-                       inode->i_op = &udf_file_inode_operations;
-                       inode->i_fop = &udf_file_operations;
-                       inode->i_mode |= S_IFREG;
-                       break;
-               }
+               if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
+                       inode->i_data.a_ops = &udf_adinicb_aops;
+               else
+                       inode->i_data.a_ops = &udf_aops;
+               inode->i_op = &udf_file_inode_operations;
+               inode->i_fop = &udf_file_operations;
+               inode->i_mode |= S_IFREG;
+               break;
        case ICBTAG_FILE_TYPE_BLOCK:
-               {
-                       inode->i_mode |= S_IFBLK;
-                       break;
-               }
+               inode->i_mode |= S_IFBLK;
+               break;
        case ICBTAG_FILE_TYPE_CHAR:
-               {
-                       inode->i_mode |= S_IFCHR;
-                       break;
-               }
+               inode->i_mode |= S_IFCHR;
+               break;
        case ICBTAG_FILE_TYPE_FIFO:
-               {
-                       init_special_inode(inode, inode->i_mode | S_IFIFO, 0);
-                       break;
-               }
+               init_special_inode(inode, inode->i_mode | S_IFIFO, 0);
+               break;
        case ICBTAG_FILE_TYPE_SOCKET:
-               {
-                       init_special_inode(inode, inode->i_mode | S_IFSOCK, 0);
-                       break;
-               }
+               init_special_inode(inode, inode->i_mode | S_IFSOCK, 0);
+               break;
        case ICBTAG_FILE_TYPE_SYMLINK:
-               {
-                       inode->i_data.a_ops = &udf_symlink_aops;
-                       inode->i_op = &page_symlink_inode_operations;
-                       inode->i_mode = S_IFLNK | S_IRWXUGO;
-                       break;
-               }
+               inode->i_data.a_ops = &udf_symlink_aops;
+               inode->i_op = &page_symlink_inode_operations;
+               inode->i_mode = S_IFLNK | S_IRWXUGO;
+               break;
        default:
-               {
-                       printk(KERN_ERR
-                              "udf: udf_fill_inode(ino %ld) failed unknown file type=%d\n",
-                              inode->i_ino, fe->icbTag.fileType);
-                       make_bad_inode(inode);
-                       return;
-               }
+               printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown file type=%d\n",
+                      inode->i_ino, fe->icbTag.fileType);
+               make_bad_inode(inode);
+               return;
        }
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
-               struct deviceSpec *dsea = (struct deviceSpec *)
-                   udf_get_extendedattr(inode, 12, 1);
-
+               struct deviceSpec *dsea = (struct deviceSpec *)udf_get_extendedattr(inode, 12, 1);
                if (dsea) {
                        init_special_inode(inode, inode->i_mode,
-                                          MKDEV(le32_to_cpu
-                                                (dsea->majorDeviceIdent),
-                                                le32_to_cpu(dsea->
-                                                            minorDeviceIdent)));
+                                          MKDEV(le32_to_cpu(dsea->majorDeviceIdent),
+                                                le32_to_cpu(dsea->minorDeviceIdent)));
                        /* Developer ID ??? */
                } else {
                        make_bad_inode(inode);
@@ -1410,8 +1279,7 @@ static int udf_alloc_i_data(struct inode *inode, size_t size)
        UDF_I_DATA(inode) = kmalloc(size, GFP_KERNEL);
 
        if (!UDF_I_DATA(inode)) {
-               printk(KERN_ERR
-                      "udf:udf_alloc_i_data (ino %ld) no free memory\n",
+               printk(KERN_ERR "udf:udf_alloc_i_data (ino %ld) no free memory\n",
                       inode->i_ino);
                return -ENOMEM;
        }
@@ -1428,12 +1296,12 @@ static mode_t udf_convert_permissions(struct fileEntry *fe)
        permissions = le32_to_cpu(fe->permissions);
        flags = le16_to_cpu(fe->icbTag.flags);
 
-       mode = ((permissions) & S_IRWXO) |
-           ((permissions >> 2) & S_IRWXG) |
-           ((permissions >> 4) & S_IRWXU) |
-           ((flags & ICBTAG_FLAG_SETUID) ? S_ISUID : 0) |
-           ((flags & ICBTAG_FLAG_SETGID) ? S_ISGID : 0) |
-           ((flags & ICBTAG_FLAG_STICKY) ? S_ISVTX : 0);
+       mode =  (( permissions      ) & S_IRWXO) |
+               (( permissions >> 2 ) & S_IRWXG) |
+               (( permissions >> 4 ) & S_IRWXU) |
+               (( flags & ICBTAG_FLAG_SETUID) ? S_ISUID : 0) |
+               (( flags & ICBTAG_FLAG_SETGID) ? S_ISGID : 0) |
+               (( flags & ICBTAG_FLAG_STICKY) ? S_ISVTX : 0);
 
        return mode;
 }
@@ -1456,9 +1324,11 @@ static mode_t udf_convert_permissions(struct fileEntry *fe)
 int udf_write_inode(struct inode *inode, int sync)
 {
        int ret;
+
        lock_kernel();
        ret = udf_update_inode(inode, sync);
        unlock_kernel();
+
        return ret;
 }
 
@@ -1479,10 +1349,7 @@ static int udf_update_inode(struct inode *inode, int do_sync)
        kernel_timestamp cpu_time;
        int err = 0;
 
-       bh = udf_tread(inode->i_sb,
-                      udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode),
-                                        0));
-
+       bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0));
        if (!bh) {
                udf_debug("bread failure\n");
                return -EIO;
@@ -1495,27 +1362,21 @@ static int udf_update_inode(struct inode *inode, int do_sync)
 
        if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE) {
                struct unallocSpaceEntry *use =
-                   (struct unallocSpaceEntry *)bh->b_data;
+                       (struct unallocSpaceEntry *)bh->b_data;
 
                use->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
-               memcpy(bh->b_data + sizeof(struct unallocSpaceEntry),
-                      UDF_I_DATA(inode),
-                      inode->i_sb->s_blocksize -
-                      sizeof(struct unallocSpaceEntry));
-               crclen =
-                   sizeof(struct unallocSpaceEntry) + UDF_I_LENALLOC(inode) -
-                   sizeof(tag);
-               use->descTag.tagLocation =
-                   cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
+               memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), UDF_I_DATA(inode),
+                      inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry));
+               crclen = sizeof(struct unallocSpaceEntry) + UDF_I_LENALLOC(inode) - sizeof(tag);
+               use->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
                use->descTag.descCRCLength = cpu_to_le16(crclen);
-               use->descTag.descCRC =
-                   cpu_to_le16(udf_crc((char *)use + sizeof(tag), crclen, 0));
+               use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use + sizeof(tag), crclen, 0));
 
                use->descTag.tagChecksum = 0;
-               for (i = 0; i < 16; i++)
+               for (i = 0; i < 16; i++) {
                        if (i != 4)
-                               use->descTag.tagChecksum +=
-                                   ((uint8_t *) & (use->descTag))[i];
+                               use->descTag.tagChecksum += ((uint8_t *)&(use->descTag))[i];
+               }
 
                mark_buffer_dirty(bh);
                brelse(bh);
@@ -1532,13 +1393,14 @@ static int udf_update_inode(struct inode *inode, int do_sync)
        else
                fe->gid = cpu_to_le32(inode->i_gid);
 
-       udfperms = ((inode->i_mode & S_IRWXO)) |
-           ((inode->i_mode & S_IRWXG) << 2) | ((inode->i_mode & S_IRWXU) << 4);
+       udfperms =      ((inode->i_mode & S_IRWXO)     ) |
+                       ((inode->i_mode & S_IRWXG) << 2) |
+                       ((inode->i_mode & S_IRWXU) << 4);
 
-       udfperms |= (le32_to_cpu(fe->permissions) &
-                    (FE_PERM_O_DELETE | FE_PERM_O_CHATTR |
-                     FE_PERM_G_DELETE | FE_PERM_G_CHATTR |
-                     FE_PERM_U_DELETE | FE_PERM_U_CHATTR));
+       udfperms |=     (le32_to_cpu(fe->permissions) &
+                       (FE_PERM_O_DELETE | FE_PERM_O_CHATTR |
+                        FE_PERM_G_DELETE | FE_PERM_G_CHATTR |
+                        FE_PERM_U_DELETE | FE_PERM_U_CHATTR));
        fe->permissions = cpu_to_le32(udfperms);
 
        if (S_ISDIR(inode->i_mode))
@@ -1550,22 +1412,20 @@ static int udf_update_inode(struct inode *inode, int do_sync)
 
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
                regid *eid;
-               struct deviceSpec *dsea = (struct deviceSpec *)
-                   udf_get_extendedattr(inode, 12, 1);
-
+               struct deviceSpec *dsea =
+                       (struct deviceSpec *)udf_get_extendedattr(inode, 12, 1);
                if (!dsea) {
                        dsea = (struct deviceSpec *)
-                           udf_add_extendedattr(inode,
-                                                sizeof(struct deviceSpec) +
-                                                sizeof(regid), 12, 0x3);
+                               udf_add_extendedattr(inode,
+                                                    sizeof(struct deviceSpec) +
+                                                    sizeof(regid), 12, 0x3);
                        dsea->attrType = cpu_to_le32(12);
                        dsea->attrSubtype = 1;
-                       dsea->attrLength =
-                           cpu_to_le32(sizeof(struct deviceSpec) +
-                                       sizeof(regid));
+                       dsea->attrLength = cpu_to_le32(sizeof(struct deviceSpec) +
+                                                      sizeof(regid));
                        dsea->impUseLength = cpu_to_le32(sizeof(regid));
                }
-               eid = (regid *) dsea->impUse;
+               eid = (regid *)dsea->impUse;
                memset(eid, 0, sizeof(regid));
                strcpy(eid->ident, UDF_ID_DEVELOPER);
                eid->identSuffix[0] = UDF_OS_CLASS_UNIX;
@@ -1577,10 +1437,9 @@ static int udf_update_inode(struct inode *inode, int do_sync)
        if (UDF_I_EFE(inode) == 0) {
                memcpy(bh->b_data + sizeof(struct fileEntry), UDF_I_DATA(inode),
                       inode->i_sb->s_blocksize - sizeof(struct fileEntry));
-               fe->logicalBlocksRecorded =
-                   cpu_to_le64((inode->i_blocks +
-                                (1 << (inode->i_sb->s_blocksize_bits - 9)) -
-                                1) >> (inode->i_sb->s_blocksize_bits - 9));
+               fe->logicalBlocksRecorded = cpu_to_le64(
+                       (inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >>
+                       (inode->i_sb->s_blocksize_bits - 9));
 
                if (udf_time_to_stamp(&cpu_time, inode->i_atime))
                        fe->accessTime = cpu_to_lets(cpu_time);
@@ -1598,19 +1457,12 @@ static int udf_update_inode(struct inode *inode, int do_sync)
                fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE);
                crclen = sizeof(struct fileEntry);
        } else {
-               memcpy(bh->b_data + sizeof(struct extendedFileEntry),
-                      UDF_I_DATA(inode),
-                      inode->i_sb->s_blocksize -
-                      sizeof(struct extendedFileEntry));
+               memcpy(bh->b_data + sizeof(struct extendedFileEntry), UDF_I_DATA(inode),
+                      inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry));
                efe->objectSize = cpu_to_le64(inode->i_size);
-               efe->logicalBlocksRecorded = cpu_to_le64((inode->i_blocks +
-                                                         (1 <<
-                                                          (inode->i_sb->
-                                                           s_blocksize_bits -
-                                                           9)) -
-                                                         1) >> (inode->i_sb->
-                                                                s_blocksize_bits
-                                                                - 9));
+               efe->logicalBlocksRecorded = cpu_to_le64(
+                       (inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >>
+                       (inode->i_sb->s_blocksize_bits - 9));
 
                if (UDF_I_CRTIME(inode).tv_sec > inode->i_atime.tv_sec ||
                    (UDF_I_CRTIME(inode).tv_sec == inode->i_atime.tv_sec &&
@@ -1671,13 +1523,13 @@ static int udf_update_inode(struct inode *inode, int do_sync)
        else if (S_ISSOCK(inode->i_mode))
                fe->icbTag.fileType = ICBTAG_FILE_TYPE_SOCKET;
 
-       icbflags = UDF_I_ALLOCTYPE(inode) |
-           ((inode->i_mode & S_ISUID) ? ICBTAG_FLAG_SETUID : 0) |
-           ((inode->i_mode & S_ISGID) ? ICBTAG_FLAG_SETGID : 0) |
-           ((inode->i_mode & S_ISVTX) ? ICBTAG_FLAG_STICKY : 0) |
-           (le16_to_cpu(fe->icbTag.flags) &
-            ~(ICBTAG_FLAG_AD_MASK | ICBTAG_FLAG_SETUID |
-              ICBTAG_FLAG_SETGID | ICBTAG_FLAG_STICKY));
+       icbflags =      UDF_I_ALLOCTYPE(inode) |
+                       ((inode->i_mode & S_ISUID) ? ICBTAG_FLAG_SETUID : 0) |
+                       ((inode->i_mode & S_ISGID) ? ICBTAG_FLAG_SETGID : 0) |
+                       ((inode->i_mode & S_ISVTX) ? ICBTAG_FLAG_STICKY : 0) |
+                       (le16_to_cpu(fe->icbTag.flags) &
+                               ~(ICBTAG_FLAG_AD_MASK | ICBTAG_FLAG_SETUID |
+                               ICBTAG_FLAG_SETGID | ICBTAG_FLAG_STICKY));
 
        fe->icbTag.flags = cpu_to_le16(icbflags);
        if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
@@ -1685,18 +1537,16 @@ static int udf_update_inode(struct inode *inode, int do_sync)
        else
                fe->descTag.descVersion = cpu_to_le16(2);
        fe->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb));
-       fe->descTag.tagLocation =
-           cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
+       fe->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
        crclen += UDF_I_LENEATTR(inode) + UDF_I_LENALLOC(inode) - sizeof(tag);
        fe->descTag.descCRCLength = cpu_to_le16(crclen);
-       fe->descTag.descCRC =
-           cpu_to_le16(udf_crc((char *)fe + sizeof(tag), crclen, 0));
+       fe->descTag.descCRC = cpu_to_le16(udf_crc((char *)fe + sizeof(tag), crclen, 0));
 
        fe->descTag.tagChecksum = 0;
-       for (i = 0; i < 16; i++)
+       for (i = 0; i < 16; i++) {
                if (i != 4)
-                       fe->descTag.tagChecksum +=
-                           ((uint8_t *) & (fe->descTag))[i];
+                       fe->descTag.tagChecksum += ((uint8_t *)&(fe->descTag))[i];
+       }
 
        /* write the data blocks */
        mark_buffer_dirty(bh);
@@ -1709,6 +1559,7 @@ static int udf_update_inode(struct inode *inode, int do_sync)
                }
        }
        brelse(bh);
+
        return err;
 }
 
@@ -1729,8 +1580,7 @@ struct inode *udf_iget(struct super_block *sb, kernel_lb_addr ino)
        if (is_bad_inode(inode))
                goto out_iput;
 
-       if (ino.logicalBlockNum >=
-           UDF_SB_PARTLEN(sb, ino.partitionReferenceNum)) {
+       if (ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum)) {
                udf_debug("block=%d, partition=%d out of range\n",
                          ino.logicalBlockNum, ino.partitionReferenceNum);
                make_bad_inode(inode);
@@ -1739,7 +1589,7 @@ struct inode *udf_iget(struct super_block *sb, kernel_lb_addr ino)
 
        return inode;
 
     out_iput:
+ out_iput:
        iput(inode);
        return NULL;
 }
@@ -1755,9 +1605,7 @@ int8_t udf_add_aext(struct inode * inode, struct extent_position * epos,
        uint8_t *ptr;
 
        if (!epos->bh)
-               ptr =
-                   UDF_I_DATA(inode) + epos->offset -
-                   udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
+               ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
        else
                ptr = epos->bh->b_data + epos->offset;
 
@@ -1774,18 +1622,13 @@ int8_t udf_add_aext(struct inode * inode, struct extent_position * epos,
                int err, loffset;
                kernel_lb_addr obloc = epos->block;
 
-               if (!
-                   (epos->block.logicalBlockNum =
-                    udf_new_block(inode->i_sb, NULL,
-                                  obloc.partitionReferenceNum,
-                                  obloc.logicalBlockNum, &err))) {
+               if (!(epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL,
+                                                                 obloc.partitionReferenceNum,
+                                                                 obloc.logicalBlockNum, &err))) {
                        return -1;
                }
-               if (!
-                   (nbh =
-                    udf_tgetblk(inode->i_sb,
-                                udf_get_lb_pblock(inode->i_sb, epos->block,
-                                                  0)))) {
+               if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb,
+                                                                      epos->block, 0)))) {
                        return -1;
                }
                lock_buffer(nbh);
@@ -1796,8 +1639,7 @@ int8_t udf_add_aext(struct inode * inode, struct extent_position * epos,
 
                aed = (struct allocExtDesc *)(nbh->b_data);
                if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
-                       aed->previousAllocExtLocation =
-                           cpu_to_le32(obloc.logicalBlockNum);
+                       aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);
                if (epos->offset + adsize > inode->i_sb->s_blocksize) {
                        loffset = epos->offset;
                        aed->lengthAllocDescs = cpu_to_le32(adsize);
@@ -1814,9 +1656,7 @@ int8_t udf_add_aext(struct inode * inode, struct extent_position * epos,
                        if (epos->bh) {
                                aed = (struct allocExtDesc *)epos->bh->b_data;
                                aed->lengthAllocDescs =
-                                   cpu_to_le32(le32_to_cpu
-                                               (aed->lengthAllocDescs) +
-                                               adsize);
+                                       cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
                        } else {
                                UDF_I_LENALLOC(inode) += adsize;
                                mark_inode_dirty(inode);
@@ -1830,37 +1670,30 @@ int8_t udf_add_aext(struct inode * inode, struct extent_position * epos,
                                    epos->block.logicalBlockNum, sizeof(tag));
                switch (UDF_I_ALLOCTYPE(inode)) {
                case ICBTAG_FLAG_AD_SHORT:
-                       {
-                               sad = (short_ad *) sptr;
-                               sad->extLength =
-                                   cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
-                                               inode->i_sb->s_blocksize);
-                               sad->extPosition =
-                                   cpu_to_le32(epos->block.logicalBlockNum);
-                               break;
-                       }
+                       sad = (short_ad *)sptr;
+                       sad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
+                                                    inode->i_sb->s_blocksize);
+                       sad->extPosition = cpu_to_le32(epos->block.logicalBlockNum);
+                       break;
                case ICBTAG_FLAG_AD_LONG:
-                       {
-                               lad = (long_ad *) sptr;
-                               lad->extLength =
-                                   cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
-                                               inode->i_sb->s_blocksize);
-                               lad->extLocation = cpu_to_lelb(epos->block);
-                               memset(lad->impUse, 0x00, sizeof(lad->impUse));
-                               break;
-                       }
+                       lad = (long_ad *)sptr;
+                       lad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
+                                                    inode->i_sb->s_blocksize);
+                       lad->extLocation = cpu_to_lelb(epos->block);
+                       memset(lad->impUse, 0x00, sizeof(lad->impUse));
+                       break;
                }
                if (epos->bh) {
-                       if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)
-                           || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
+                       if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
+                           UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
                                udf_update_tag(epos->bh->b_data, loffset);
                        else
-                               udf_update_tag(epos->bh->b_data,
-                                              sizeof(struct allocExtDesc));
+                               udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc));
                        mark_buffer_dirty_inode(epos->bh, inode);
                        brelse(epos->bh);
-               } else
+               } else {
                        mark_inode_dirty(inode);
+               }
                epos->bh = nbh;
        }
 
@@ -1872,14 +1705,11 @@ int8_t udf_add_aext(struct inode * inode, struct extent_position * epos,
        } else {
                aed = (struct allocExtDesc *)epos->bh->b_data;
                aed->lengthAllocDescs =
-                   cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
-               if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)
-                   || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
-                       udf_update_tag(epos->bh->b_data,
-                                      epos->offset + (inc ? 0 : adsize));
+                       cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
+               if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
+                       udf_update_tag(epos->bh->b_data, epos->offset + (inc ? 0 : adsize));
                else
-                       udf_update_tag(epos->bh->b_data,
-                                      sizeof(struct allocExtDesc));
+                       udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc));
                mark_buffer_dirty_inode(epos->bh, inode);
        }
 
@@ -1891,51 +1721,47 @@ int8_t udf_write_aext(struct inode * inode, struct extent_position * epos,
 {
        int adsize;
        uint8_t *ptr;
+       short_ad *sad;
+       long_ad *lad;
 
        if (!epos->bh)
-               ptr =
-                   UDF_I_DATA(inode) + epos->offset -
-                   udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
+               ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
        else
                ptr = epos->bh->b_data + epos->offset;
 
        switch (UDF_I_ALLOCTYPE(inode)) {
        case ICBTAG_FLAG_AD_SHORT:
-               {
-                       short_ad *sad = (short_ad *) ptr;
-                       sad->extLength = cpu_to_le32(elen);
-                       sad->extPosition = cpu_to_le32(eloc.logicalBlockNum);
-                       adsize = sizeof(short_ad);
-                       break;
-               }
+               sad = (short_ad *)ptr;
+               sad->extLength = cpu_to_le32(elen);
+               sad->extPosition = cpu_to_le32(eloc.logicalBlockNum);
+               adsize = sizeof(short_ad);
+               break;
        case ICBTAG_FLAG_AD_LONG:
-               {
-                       long_ad *lad = (long_ad *) ptr;
-                       lad->extLength = cpu_to_le32(elen);
-                       lad->extLocation = cpu_to_lelb(eloc);
-                       memset(lad->impUse, 0x00, sizeof(lad->impUse));
-                       adsize = sizeof(long_ad);
-                       break;
-               }
+               lad = (long_ad *)ptr;
+               lad->extLength = cpu_to_le32(elen);
+               lad->extLocation = cpu_to_lelb(eloc);
+               memset(lad->impUse, 0x00, sizeof(lad->impUse));
+               adsize = sizeof(long_ad);
+               break;
        default:
                return -1;
        }
 
        if (epos->bh) {
-               if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)
-                   || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) {
-                       struct allocExtDesc *aed =
-                           (struct allocExtDesc *)epos->bh->b_data;
+               if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
+                   UDF_SB_UDFREV(inode->i_sb) >= 0x0201) {
+                       struct allocExtDesc *aed = (struct allocExtDesc *)epos->bh->b_data;
                        udf_update_tag(epos->bh->b_data,
-                                      le32_to_cpu(aed->lengthAllocDescs) +
-                                      sizeof(struct allocExtDesc));
+                                      le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc));
                }
                mark_buffer_dirty_inode(epos->bh, inode);
-       } else
+       } else {
                mark_inode_dirty(inode);
+       }
 
        if (inc)
                epos->offset += adsize;
+
        return (elen >> 30);
 }
 
@@ -1949,14 +1775,9 @@ int8_t udf_next_aext(struct inode * inode, struct extent_position * epos,
                epos->block = *eloc;
                epos->offset = sizeof(struct allocExtDesc);
                brelse(epos->bh);
-               if (!
-                   (epos->bh =
-                    udf_tread(inode->i_sb,
-                              udf_get_lb_pblock(inode->i_sb, epos->block,
-                                                0)))) {
+               if (!(epos->bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, epos->block, 0)))) {
                        udf_debug("reading block %d failed!\n",
-                                 udf_get_lb_pblock(inode->i_sb, epos->block,
-                                                   0));
+                                 udf_get_lb_pblock(inode->i_sb, epos->block, 0));
                        return -1;
                }
        }
@@ -1970,75 +1791,49 @@ int8_t udf_current_aext(struct inode * inode, struct extent_position * epos,
        int alen;
        int8_t etype;
        uint8_t *ptr;
+       short_ad *sad;
+       long_ad *lad;
+
 
        if (!epos->bh) {
                if (!epos->offset)
                        epos->offset = udf_file_entry_alloc_offset(inode);
-               ptr =
-                   UDF_I_DATA(inode) + epos->offset -
-                   udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
-               alen =
-                   udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode);
+               ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
+               alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode);
        } else {
                if (!epos->offset)
                        epos->offset = sizeof(struct allocExtDesc);
                ptr = epos->bh->b_data + epos->offset;
-               alen =
-                   sizeof(struct allocExtDesc) +
-                   le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)->
-                               lengthAllocDescs);
+               alen = sizeof(struct allocExtDesc) +
+                       le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)->lengthAllocDescs);
        }
 
        switch (UDF_I_ALLOCTYPE(inode)) {
        case ICBTAG_FLAG_AD_SHORT:
-               {
-                       short_ad *sad;
-
-                       if (!
-                           (sad =
-                            udf_get_fileshortad(ptr, alen, &epos->offset,
-                                                inc)))
-                               return -1;
-
-                       etype = le32_to_cpu(sad->extLength) >> 30;
-                       eloc->logicalBlockNum = le32_to_cpu(sad->extPosition);
-                       eloc->partitionReferenceNum =
-                           UDF_I_LOCATION(inode).partitionReferenceNum;
-                       *elen =
-                           le32_to_cpu(sad->
-                                       extLength) & UDF_EXTENT_LENGTH_MASK;
-                       break;
-               }
+               if (!(sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc)))
+                       return -1;
+               etype = le32_to_cpu(sad->extLength) >> 30;
+               eloc->logicalBlockNum = le32_to_cpu(sad->extPosition);
+               eloc->partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
+               *elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK;
+               break;
        case ICBTAG_FLAG_AD_LONG:
-               {
-                       long_ad *lad;
-
-                       if (!
-                           (lad =
-                            udf_get_filelongad(ptr, alen, &epos->offset, inc)))
-                               return -1;
-
-                       etype = le32_to_cpu(lad->extLength) >> 30;
-                       *eloc = lelb_to_cpu(lad->extLocation);
-                       *elen =
-                           le32_to_cpu(lad->
-                                       extLength) & UDF_EXTENT_LENGTH_MASK;
-                       break;
-               }
-       default:
-               {
-                       udf_debug("alloc_type = %d unsupported\n",
-                                 UDF_I_ALLOCTYPE(inode));
+               if (!(lad = udf_get_filelongad(ptr, alen, &epos->offset, inc)))
                        return -1;
-               }
+               etype = le32_to_cpu(lad->extLength) >> 30;
+               *eloc = lelb_to_cpu(lad->extLocation);
+               *elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK;
+               break;
+       default:
+               udf_debug("alloc_type = %d unsupported\n", UDF_I_ALLOCTYPE(inode));
+               return -1;
        }
 
        return etype;
 }
 
-static int8_t
-udf_insert_aext(struct inode *inode, struct extent_position epos,
-               kernel_lb_addr neloc, uint32_t nelen)
+static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos,
+                             kernel_lb_addr neloc, uint32_t nelen)
 {
        kernel_lb_addr oeloc;
        uint32_t oelen;
@@ -2049,12 +1844,12 @@ udf_insert_aext(struct inode *inode, struct extent_position epos,
 
        while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1) {
                udf_write_aext(inode, &epos, neloc, nelen, 1);
-
                neloc = oeloc;
                nelen = (etype << 30) | oelen;
        }
        udf_add_aext(inode, &epos, neloc, nelen, 1);
        brelse(epos.bh);
+
        return (nelen >> 30);
 }
 
@@ -2105,15 +1900,12 @@ int8_t udf_delete_aext(struct inode * inode, struct extent_position epos,
                } else {
                        aed = (struct allocExtDesc *)oepos.bh->b_data;
                        aed->lengthAllocDescs =
-                           cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) -
-                                       (2 * adsize));
-                       if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)
-                           || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
-                               udf_update_tag(oepos.bh->b_data,
-                                              oepos.offset - (2 * adsize));
+                               cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2 * adsize));
+                       if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
+                           UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
+                               udf_update_tag(oepos.bh->b_data, oepos.offset - (2 * adsize));
                        else
-                               udf_update_tag(oepos.bh->b_data,
-                                              sizeof(struct allocExtDesc));
+                               udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc));
                        mark_buffer_dirty_inode(oepos.bh, inode);
                }
        } else {
@@ -2124,21 +1916,19 @@ int8_t udf_delete_aext(struct inode * inode, struct extent_position epos,
                } else {
                        aed = (struct allocExtDesc *)oepos.bh->b_data;
                        aed->lengthAllocDescs =
-                           cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) -
-                                       adsize);
-                       if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)
-                           || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
-                               udf_update_tag(oepos.bh->b_data,
-                                              epos.offset - adsize);
+                               cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize);
+                       if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
+                           UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
+                               udf_update_tag(oepos.bh->b_data, epos.offset - adsize);
                        else
-                               udf_update_tag(oepos.bh->b_data,
-                                              sizeof(struct allocExtDesc));
+                               udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc));
                        mark_buffer_dirty_inode(oepos.bh, inode);
                }
        }
 
        brelse(epos.bh);
        brelse(oepos.bh);
+
        return (elen >> 30);
 }
 
@@ -2162,8 +1952,7 @@ int8_t inode_bmap(struct inode * inode, sector_t block,
 
        do {
                if ((etype = udf_next_aext(inode, pos, eloc, elen, 1)) == -1) {
-                       *offset =
-                           (bcount - lbcount) >> inode->i_sb->s_blocksize_bits;
+                       *offset = (bcount - lbcount) >> inode->i_sb->s_blocksize_bits;
                        UDF_I_LENEXTENTS(inode) = lbcount;
                        return -1;
                }
@@ -2180,13 +1969,12 @@ long udf_block_map(struct inode *inode, sector_t block)
        kernel_lb_addr eloc;
        uint32_t elen;
        sector_t offset;
-       struct extent_position epos = { NULL, 0, {0, 0} };
+       struct extent_position epos = {};
        int ret;
 
        lock_kernel();
 
-       if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) ==
-           (EXT_RECORDED_ALLOCATED >> 30))
+       if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
                ret = udf_get_lb_pblock(inode->i_sb, eloc, offset);
        else
                ret = 0;
index 4826c3616eef2ed03089332af6817e56198f6abd..579bae71e67efe7dc62d69d3998b184da2f14f93 100644 (file)
@@ -43,7 +43,7 @@ unsigned int udf_get_last_session(struct super_block *sb)
                udf_debug("XA disk: %s, vol_desc_start=%d\n",
                          (ms_info.xa_flag ? "yes" : "no"), ms_info.addr.lba);
 #if WE_OBEY_THE_WRITTEN_STANDARDS
-               if (ms_info.xa_flag)    /* necessary for a valid ms_info.addr */
+               if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */
 #endif
                        vol_desc_start = ms_info.addr.lba;
        } else {
@@ -57,7 +57,7 @@ unsigned long udf_get_last_block(struct super_block *sb)
        struct block_device *bdev = sb->s_bdev;
        unsigned long lblock = 0;
 
-       if (ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long)&lblock))
+       if (ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock))
                lblock = bdev->bd_inode->i_size >> sb->s_blocksize_bits;
 
        if (lblock)
index a7f57277a96e840fdb3e71a5554c46463c4b4c9f..15297deb5051022fbc31c877aa2b6f7d525bd348 100644 (file)
@@ -54,15 +54,15 @@ struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size,
        int i;
 
        ea = UDF_I_DATA(inode);
-       if (UDF_I_LENEATTR(inode))
+       if (UDF_I_LENEATTR(inode)) {
                ad = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
-       else {
+       else {
                ad = ea;
                size += sizeof(struct extendedAttrHeaderDesc);
        }
 
        offset = inode->i_sb->s_blocksize - udf_file_entry_alloc_offset(inode) -
-           UDF_I_LENALLOC(inode);
+               UDF_I_LENALLOC(inode);
 
        /* TODO - Check for FreeEASpace */
 
@@ -76,56 +76,45 @@ struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size,
 
                if (UDF_I_LENEATTR(inode)) {
                        /* check checksum/crc */
-                       if (le16_to_cpu(eahd->descTag.tagIdent) !=
-                           TAG_IDENT_EAHD
-                           || le32_to_cpu(eahd->descTag.tagLocation) !=
-                           UDF_I_LOCATION(inode).logicalBlockNum) {
+                       if (le16_to_cpu(eahd->descTag.tagIdent) != TAG_IDENT_EAHD ||
+                           le32_to_cpu(eahd->descTag.tagLocation) != UDF_I_LOCATION(inode).logicalBlockNum) {
                                return NULL;
                        }
                } else {
                        size -= sizeof(struct extendedAttrHeaderDesc);
-                       UDF_I_LENEATTR(inode) +=
-                           sizeof(struct extendedAttrHeaderDesc);
+                       UDF_I_LENEATTR(inode) += sizeof(struct extendedAttrHeaderDesc);
                        eahd->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EAHD);
                        if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
                                eahd->descTag.descVersion = cpu_to_le16(3);
                        else
                                eahd->descTag.descVersion = cpu_to_le16(2);
-                       eahd->descTag.tagSerialNum =
-                           cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb));
-                       eahd->descTag.tagLocation =
-                           cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
+                       eahd->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb));
+                       eahd->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
                        eahd->impAttrLocation = cpu_to_le32(0xFFFFFFFF);
                        eahd->appAttrLocation = cpu_to_le32(0xFFFFFFFF);
                }
 
                offset = UDF_I_LENEATTR(inode);
                if (type < 2048) {
-                       if (le32_to_cpu(eahd->appAttrLocation) <
-                           UDF_I_LENEATTR(inode)) {
-                               uint32_t aal =
-                                   le32_to_cpu(eahd->appAttrLocation);
-                               memmove(&ea[offset - aal + size], &ea[aal],
-                                       offset - aal);
+                       if (le32_to_cpu(eahd->appAttrLocation) < UDF_I_LENEATTR(inode)) {
+                               uint32_t aal = le32_to_cpu(eahd->appAttrLocation);
+                               memmove(&ea[offset - aal + size],
+                                       &ea[aal], offset - aal);
                                offset -= aal;
                                eahd->appAttrLocation = cpu_to_le32(aal + size);
                        }
-                       if (le32_to_cpu(eahd->impAttrLocation) <
-                           UDF_I_LENEATTR(inode)) {
-                               uint32_t ial =
-                                   le32_to_cpu(eahd->impAttrLocation);
-                               memmove(&ea[offset - ial + size], &ea[ial],
-                                       offset - ial);
+                       if (le32_to_cpu(eahd->impAttrLocation) < UDF_I_LENEATTR(inode)) {
+                               uint32_t ial = le32_to_cpu(eahd->impAttrLocation);
+                               memmove(&ea[offset - ial + size],
+                                       &ea[ial], offset - ial);
                                offset -= ial;
                                eahd->impAttrLocation = cpu_to_le32(ial + size);
                        }
                } else if (type < 65536) {
-                       if (le32_to_cpu(eahd->appAttrLocation) <
-                           UDF_I_LENEATTR(inode)) {
-                               uint32_t aal =
-                                   le32_to_cpu(eahd->appAttrLocation);
-                               memmove(&ea[offset - aal + size], &ea[aal],
-                                       offset - aal);
+                       if (le32_to_cpu(eahd->appAttrLocation) < UDF_I_LENEATTR(inode)) {
+                               uint32_t aal = le32_to_cpu(eahd->appAttrLocation);
+                               memmove(&ea[offset - aal + size],
+                                       &ea[aal], offset - aal);
                                offset -= aal;
                                eahd->appAttrLocation = cpu_to_le32(aal + size);
                        }
@@ -133,18 +122,18 @@ struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size,
                /* rewrite CRC + checksum of eahd */
                crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(tag);
                eahd->descTag.descCRCLength = cpu_to_le16(crclen);
-               eahd->descTag.descCRC =
-                   cpu_to_le16(udf_crc((char *)eahd + sizeof(tag), crclen, 0));
+               eahd->descTag.descCRC = cpu_to_le16(udf_crc((char *)eahd +
+                                                           sizeof(tag), crclen, 0));
                eahd->descTag.tagChecksum = 0;
                for (i = 0; i < 16; i++)
                        if (i != 4)
-                               eahd->descTag.tagChecksum +=
-                                   ((uint8_t *) & (eahd->descTag))[i];
+                               eahd->descTag.tagChecksum += ((uint8_t *)&(eahd->descTag))[i];
                UDF_I_LENEATTR(inode) += size;
                return (struct genericFormat *)&ea[offset];
        }
        if (loc & 0x02) {
        }
+
        return NULL;
 }
 
@@ -163,8 +152,7 @@ struct genericFormat *udf_get_extendedattr(struct inode *inode, uint32_t type,
 
                /* check checksum/crc */
                if (le16_to_cpu(eahd->descTag.tagIdent) != TAG_IDENT_EAHD ||
-                   le32_to_cpu(eahd->descTag.tagLocation) !=
-                   UDF_I_LOCATION(inode).logicalBlockNum) {
+                   le32_to_cpu(eahd->descTag.tagLocation) != UDF_I_LOCATION(inode).logicalBlockNum) {
                        return NULL;
                }
 
@@ -177,13 +165,13 @@ struct genericFormat *udf_get_extendedattr(struct inode *inode, uint32_t type,
 
                while (offset < UDF_I_LENEATTR(inode)) {
                        gaf = (struct genericFormat *)&ea[offset];
-                       if (le32_to_cpu(gaf->attrType) == type
-                           && gaf->attrSubtype == subtype)
+                       if (le32_to_cpu(gaf->attrType) == type && gaf->attrSubtype == subtype)
                                return gaf;
                        else
                                offset += le32_to_cpu(gaf->attrLength);
                }
        }
+
        return NULL;
 }
 
@@ -216,23 +204,22 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block,
                return NULL;
        }
 
-       tag_p = (tag *) (bh->b_data);
+       tag_p = (tag *)(bh->b_data);
 
        *ident = le16_to_cpu(tag_p->tagIdent);
 
        if (location != le32_to_cpu(tag_p->tagLocation)) {
                udf_debug("location mismatch block %u, tag %u != %u\n",
-                         block + UDF_SB_SESSION(sb),
-                         le32_to_cpu(tag_p->tagLocation), location);
+                         block + UDF_SB_SESSION(sb), le32_to_cpu(tag_p->tagLocation), location);
                goto error_out;
        }
 
        /* Verify the tag checksum */
        checksum = 0U;
        for (i = 0; i < 4; i++)
-               checksum += (uint8_t) (bh->b_data[i]);
+               checksum += (uint8_t)(bh->b_data[i]);
        for (i = 5; i < 16; i++)
-               checksum += (uint8_t) (bh->b_data[i]);
+               checksum += (uint8_t)(bh->b_data[i]);
        if (checksum != tag_p->tagChecksum) {
                printk(KERN_ERR "udf: tag checksum failed block %d\n", block);
                goto error_out;
@@ -249,16 +236,14 @@ struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block,
        /* Verify the descriptor CRC */
        if (le16_to_cpu(tag_p->descCRCLength) + sizeof(tag) > sb->s_blocksize ||
            le16_to_cpu(tag_p->descCRC) == udf_crc(bh->b_data + sizeof(tag),
-                                                  le16_to_cpu(tag_p->
-                                                              descCRCLength),
-                                                  0)) {
+                                                  le16_to_cpu(tag_p->descCRCLength), 0)) {
                return bh;
        }
        udf_debug("Crc failure block %d: crc = %d, crclen = %d\n",
                  block + UDF_SB_SESSION(sb), le16_to_cpu(tag_p->descCRC),
                  le16_to_cpu(tag_p->descCRCLength));
 
-      error_out:
+error_out:
        brelse(bh);
        return NULL;
 }
@@ -272,7 +257,7 @@ struct buffer_head *udf_read_ptagged(struct super_block *sb, kernel_lb_addr loc,
 
 void udf_update_tag(char *data, int length)
 {
-       tag *tptr = (tag *) data;
+       tag *tptr = (tag *)data;
        int i;
 
        length -= sizeof(tag);
@@ -283,13 +268,13 @@ void udf_update_tag(char *data, int length)
 
        for (i = 0; i < 16; i++)
                if (i != 4)
-                       tptr->tagChecksum += (uint8_t) (data[i]);
+                       tptr->tagChecksum += (uint8_t)(data[i]);
 }
 
 void udf_new_tag(char *data, uint16_t ident, uint16_t version, uint16_t snum,
                 uint32_t loc, int length)
 {
-       tag *tptr = (tag *) data;
+       tag *tptr = (tag *)data;
        tptr->tagIdent = cpu_to_le16(ident);
        tptr->descVersion = cpu_to_le16(version);
        tptr->tagSerialNum = cpu_to_le16(snum);
index 334d363a0903c764cf79daa479a27fe894d86569..bec96a6b3343c8586fa30823673fb8f8db32cbe7 100644 (file)
@@ -37,6 +37,7 @@ static inline int udf_match(int len1, const char *name1, int len2,
 {
        if (len1 != len2)
                return 0;
+
        return !memcmp(name1, name2, len1);
 }
 
@@ -52,7 +53,7 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi,
        uint16_t liu = le16_to_cpu(cfi->lengthOfImpUse);
        uint8_t lfi = cfi->lengthFileIdent;
        int padlen = fibh->eoffset - fibh->soffset - liu - lfi -
-           sizeof(struct fileIdentDesc);
+               sizeof(struct fileIdentDesc);
        int adinicb = 0;
 
        if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
@@ -61,85 +62,75 @@ int udf_write_fi(struct inode *inode, struct fileIdentDesc *cfi,
        offset = fibh->soffset + sizeof(struct fileIdentDesc);
 
        if (impuse) {
-               if (adinicb || (offset + liu < 0))
-                       memcpy((uint8_t *) sfi->impUse, impuse, liu);
-               else if (offset >= 0)
+               if (adinicb || (offset + liu < 0)) {
+                       memcpy((uint8_t *)sfi->impUse, impuse, liu);
+               } else if (offset >= 0) {
                        memcpy(fibh->ebh->b_data + offset, impuse, liu);
-               else {
-                       memcpy((uint8_t *) sfi->impUse, impuse, -offset);
-                       memcpy(fibh->ebh->b_data, impuse - offset,
-                              liu + offset);
+               } else {
+                       memcpy((uint8_t *)sfi->impUse, impuse, -offset);
+                       memcpy(fibh->ebh->b_data, impuse - offset, liu + offset);
                }
        }
 
        offset += liu;
 
        if (fileident) {
-               if (adinicb || (offset + lfi < 0))
-                       memcpy((uint8_t *) sfi->fileIdent + liu, fileident,
-                              lfi);
-               else if (offset >= 0)
+               if (adinicb || (offset + lfi < 0)) {
+                       memcpy((uint8_t *)sfi->fileIdent + liu, fileident, lfi);
+               } else if (offset >= 0) {
                        memcpy(fibh->ebh->b_data + offset, fileident, lfi);
-               else {
-                       memcpy((uint8_t *) sfi->fileIdent + liu, fileident,
-                              -offset);
-                       memcpy(fibh->ebh->b_data, fileident - offset,
-                              lfi + offset);
+               } else {
+                       memcpy((uint8_t *)sfi->fileIdent + liu, fileident, -offset);
+                       memcpy(fibh->ebh->b_data, fileident - offset, lfi + offset);
                }
        }
 
        offset += lfi;
 
-       if (adinicb || (offset + padlen < 0))
-               memset((uint8_t *) sfi->padding + liu + lfi, 0x00, padlen);
-       else if (offset >= 0)
+       if (adinicb || (offset + padlen < 0)) {
+               memset((uint8_t *)sfi->padding + liu + lfi, 0x00, padlen);
+       } else if (offset >= 0) {
                memset(fibh->ebh->b_data + offset, 0x00, padlen);
-       else {
-               memset((uint8_t *) sfi->padding + liu + lfi, 0x00, -offset);
+       else {
+               memset((uint8_t *)sfi->padding + liu + lfi, 0x00, -offset);
                memset(fibh->ebh->b_data, 0x00, padlen + offset);
        }
 
-       crc =
-           udf_crc((uint8_t *) cfi + sizeof(tag),
-                   sizeof(struct fileIdentDesc) - sizeof(tag), 0);
-
-       if (fibh->sbh == fibh->ebh)
-               crc = udf_crc((uint8_t *) sfi->impUse,
-                             crclen + sizeof(tag) -
-                             sizeof(struct fileIdentDesc), crc);
-       else if (sizeof(struct fileIdentDesc) >= -fibh->soffset)
-               crc =
-                   udf_crc(fibh->ebh->b_data + sizeof(struct fileIdentDesc) +
-                           fibh->soffset,
-                           crclen + sizeof(tag) - sizeof(struct fileIdentDesc),
-                           crc);
-       else {
-               crc = udf_crc((uint8_t *) sfi->impUse,
-                             -fibh->soffset - sizeof(struct fileIdentDesc),
-                             crc);
+       crc = udf_crc((uint8_t *)cfi + sizeof(tag),
+                     sizeof(struct fileIdentDesc) - sizeof(tag), 0);
+
+       if (fibh->sbh == fibh->ebh) {
+               crc = udf_crc((uint8_t *)sfi->impUse,
+                             crclen + sizeof(tag) - sizeof(struct fileIdentDesc), crc);
+       } else if (sizeof(struct fileIdentDesc) >= -fibh->soffset) {
+               crc = udf_crc(fibh->ebh->b_data + sizeof(struct fileIdentDesc) + fibh->soffset,
+                             crclen + sizeof(tag) - sizeof(struct fileIdentDesc), crc);
+       } else {
+               crc = udf_crc((uint8_t *)sfi->impUse,
+                             -fibh->soffset - sizeof(struct fileIdentDesc), crc);
                crc = udf_crc(fibh->ebh->b_data, fibh->eoffset, crc);
        }
 
        cfi->descTag.descCRC = cpu_to_le16(crc);
        cfi->descTag.descCRCLength = cpu_to_le16(crclen);
 
-       for (i = 0; i < 16; i++)
+       for (i = 0; i < 16; i++) {
                if (i != 4)
-                       checksum += ((uint8_t *) & cfi->descTag)[i];
+                       checksum += ((uint8_t *)&cfi->descTag)[i];
+       }
 
        cfi->descTag.tagChecksum = checksum;
-       if (adinicb || (sizeof(struct fileIdentDesc) <= -fibh->soffset))
-               memcpy((uint8_t *) sfi, (uint8_t *) cfi,
-                      sizeof(struct fileIdentDesc));
-       else {
-               memcpy((uint8_t *) sfi, (uint8_t *) cfi, -fibh->soffset);
-               memcpy(fibh->ebh->b_data, (uint8_t *) cfi - fibh->soffset,
+       if (adinicb || (sizeof(struct fileIdentDesc) <= -fibh->soffset)) {
+               memcpy((uint8_t *)sfi, (uint8_t *)cfi, sizeof(struct fileIdentDesc));
+       } else {
+               memcpy((uint8_t *)sfi, (uint8_t *)cfi, -fibh->soffset);
+               memcpy(fibh->ebh->b_data, (uint8_t *)cfi - fibh->soffset,
                       sizeof(struct fileIdentDesc) + fibh->soffset);
        }
 
-       if (adinicb)
+       if (adinicb) {
                mark_inode_dirty(inode);
-       else {
+       else {
                if (fibh->sbh != fibh->ebh)
                        mark_buffer_dirty_inode(fibh->ebh, inode);
                mark_buffer_dirty_inode(fibh->sbh, inode);
@@ -163,26 +154,25 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
        kernel_lb_addr eloc;
        uint32_t elen;
        sector_t offset;
-       struct extent_position epos = { NULL, 0, {0, 0} };
+       struct extent_position epos = {};
 
        size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
        f_pos = (udf_ext0_offset(dir) >> 2);
 
-       fibh->soffset = fibh->eoffset =
-           (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
-       if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
+       fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
+       if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
                fibh->sbh = fibh->ebh = NULL;
-       else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
-                           &epos, &eloc, &elen,
-                           &offset) == (EXT_RECORDED_ALLOCATED >> 30)) {
+       } else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
+                             &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) {
                block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
                if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
                        if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
                                epos.offset -= sizeof(short_ad);
                        else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
                                epos.offset -= sizeof(long_ad);
-               } else
+               } else {
                        offset = 0;
+               }
 
                if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) {
                        brelse(epos.bh);
@@ -196,7 +186,6 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
        while ((f_pos < size)) {
                fi = udf_fileident_read(dir, &f_pos, fibh, cfi, &epos, &eloc,
                                        &elen, &offset);
-
                if (!fi) {
                        if (fibh->sbh != fibh->ebh)
                                brelse(fibh->ebh);
@@ -213,20 +202,14 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
                } else {
                        int poffset;    /* Unpaded ending offset */
 
-                       poffset =
-                           fibh->soffset + sizeof(struct fileIdentDesc) + liu +
-                           lfi;
+                       poffset = fibh->soffset + sizeof(struct fileIdentDesc) + liu + lfi;
 
-                       if (poffset >= lfi)
-                               nameptr =
-                                   (uint8_t *) (fibh->ebh->b_data + poffset -
-                                                lfi);
-                       else {
+                       if (poffset >= lfi) {
+                               nameptr = (uint8_t *)(fibh->ebh->b_data + poffset - lfi);
+                       } else {
                                nameptr = fname;
-                               memcpy(nameptr, fi->fileIdent + liu,
-                                      lfi - poffset);
-                               memcpy(nameptr + lfi - poffset,
-                                      fibh->ebh->b_data, poffset);
+                               memcpy(nameptr, fi->fileIdent + liu, lfi - poffset);
+                               memcpy(nameptr + lfi - poffset, fibh->ebh->b_data, poffset);
                        }
                }
 
@@ -244,18 +227,18 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
                        continue;
 
                if ((flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi))) {
-                       if (udf_match
-                           (flen, fname, dentry->d_name.len,
-                            dentry->d_name.name)) {
+                       if (udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name)) {
                                brelse(epos.bh);
                                return fi;
                        }
                }
        }
+
        if (fibh->sbh != fibh->ebh)
                brelse(fibh->ebh);
        brelse(fibh->sbh);
        brelse(epos.bh);
+
        return NULL;
 }
 
@@ -306,15 +289,19 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
 #ifdef UDF_RECOVERY
        /* temporary shorthand for specifying files by inode number */
        if (!strncmp(dentry->d_name.name, ".B=", 3)) {
-               kernel_lb_addr lb =
-                   { 0, simple_strtoul(dentry->d_name.name + 3, NULL, 0) };
+               kernel_lb_addr lb = {
+                       .logicalBlockNum = 0,
+                       .partitionReferenceNum = simple_strtoul(dentry->d_name.name + 3,
+                                                               NULL, 0),
+               };
                inode = udf_iget(dir->i_sb, lb);
                if (!inode) {
                        unlock_kernel();
                        return ERR_PTR(-EACCES);
                }
-       } else
-#endif                         /* UDF_RECOVERY */
+       }
+       else
+#endif /* UDF_RECOVERY */
 
        if (udf_find_entry(dir, dentry, &fibh, &cfi)) {
                if (fibh.sbh != fibh.ebh)
@@ -329,6 +316,7 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
        }
        unlock_kernel();
        d_add(dentry, inode);
+
        return NULL;
 }
 
@@ -352,7 +340,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
        kernel_lb_addr eloc;
        uint32_t elen;
        sector_t offset;
-       struct extent_position epos = { NULL, 0, {0, 0} };
+       struct extent_position epos = {};
 
        sb = dir->i_sb;
 
@@ -361,36 +349,33 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
                        *err = -EINVAL;
                        return NULL;
                }
-
-               if (!
-                   (namelen =
-                    udf_put_filename(sb, dentry->d_name.name, name,
-                                     dentry->d_name.len))) {
+               if (!(namelen = udf_put_filename(sb, dentry->d_name.name, name,
+                                                dentry->d_name.len))) {
                        *err = -ENAMETOOLONG;
                        return NULL;
                }
-       } else
+       } else {
                namelen = 0;
+       }
 
        nfidlen = (sizeof(struct fileIdentDesc) + namelen + 3) & ~3;
 
        f_pos = (udf_ext0_offset(dir) >> 2);
 
-       fibh->soffset = fibh->eoffset =
-           (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
-       if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
+       fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
+       if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
                fibh->sbh = fibh->ebh = NULL;
-       else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
-                           &epos, &eloc, &elen,
-                           &offset) == (EXT_RECORDED_ALLOCATED >> 30)) {
+       } else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
+                             &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) {
                block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
                if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
                        if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
                                epos.offset -= sizeof(short_ad);
                        else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
                                epos.offset -= sizeof(long_ad);
-               } else
+               } else {
                        offset = 0;
+               }
 
                if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block))) {
                        brelse(epos.bh);
@@ -423,40 +408,33 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
                liu = le16_to_cpu(cfi->lengthOfImpUse);
                lfi = cfi->lengthFileIdent;
 
-               if (fibh->sbh == fibh->ebh)
+               if (fibh->sbh == fibh->ebh) {
                        nameptr = fi->fileIdent + liu;
-               else {
+               else {
                        int poffset;    /* Unpaded ending offset */
 
-                       poffset =
-                           fibh->soffset + sizeof(struct fileIdentDesc) + liu +
-                           lfi;
+                       poffset = fibh->soffset + sizeof(struct fileIdentDesc) + liu + lfi;
 
-                       if (poffset >= lfi)
-                               nameptr =
-                                   (char *)(fibh->ebh->b_data + poffset - lfi);
-                       else {
+                       if (poffset >= lfi) {
+                               nameptr = (char *)(fibh->ebh->b_data + poffset - lfi);
+                       } else {
                                nameptr = fname;
-                               memcpy(nameptr, fi->fileIdent + liu,
-                                      lfi - poffset);
-                               memcpy(nameptr + lfi - poffset,
-                                      fibh->ebh->b_data, poffset);
+                               memcpy(nameptr, fi->fileIdent + liu, lfi - poffset);
+                               memcpy(nameptr + lfi - poffset, fibh->ebh->b_data, poffset);
                        }
                }
 
                if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) {
-                       if (((sizeof(struct fileIdentDesc) + liu + lfi +
-                             3) & ~3) == nfidlen) {
+                       if (((sizeof(struct fileIdentDesc) + liu + lfi + 3) & ~3) == nfidlen) {
                                brelse(epos.bh);
                                cfi->descTag.tagSerialNum = cpu_to_le16(1);
                                cfi->fileVersionNum = cpu_to_le16(1);
                                cfi->fileCharacteristics = 0;
                                cfi->lengthFileIdent = namelen;
                                cfi->lengthOfImpUse = cpu_to_le16(0);
-                               if (!udf_write_fi
-                                   (dir, cfi, fi, fibh, NULL, name))
+                               if (!udf_write_fi(dir, cfi, fi, fibh, NULL, name)) {
                                        return fi;
-                               else {
+                               else {
                                        *err = -EIO;
                                        return NULL;
                                }
@@ -467,8 +445,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
                        continue;
 
                if ((flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi)) &&
-                   udf_match(flen, fname, dentry->d_name.len,
-                             dentry->d_name.name)) {
+                   udf_match(flen, fname, dentry->d_name.len, dentry->d_name.name)) {
                        if (fibh->sbh != fibh->ebh)
                                brelse(fibh->ebh);
                        brelse(fibh->sbh);
@@ -478,7 +455,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
                }
        }
 
-      add:
+add:
        f_pos += nfidlen;
 
        if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB &&
@@ -491,14 +468,11 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
                if (fibh->sbh != fibh->ebh)
                        brelse(fibh->ebh);
                brelse(fibh->sbh);
-               if (!
-                   (fibh->sbh = fibh->ebh =
-                    udf_expand_dir_adinicb(dir, &block, err)))
+               if (!(fibh->sbh = fibh->ebh = udf_expand_dir_adinicb(dir, &block, err)))
                        return NULL;
                epos.block = UDF_I_LOCATION(dir);
                eloc.logicalBlockNum = block;
-               eloc.partitionReferenceNum =
-                   UDF_I_LOCATION(dir).partitionReferenceNum;
+               eloc.partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum;
                elen = dir->i_sb->s_blocksize;
                epos.offset = udf_file_entry_alloc_offset(dir);
                if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
@@ -517,16 +491,13 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
 
                if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
                        block = UDF_I_LOCATION(dir).logicalBlockNum;
-                       fi = (struct fileIdentDesc *)(UDF_I_DATA(dir) +
-                                                     fibh->soffset -
+                       fi = (struct fileIdentDesc *)(UDF_I_DATA(dir) + fibh->soffset -
                                                      udf_ext0_offset(dir) +
                                                      UDF_I_LENEATTR(dir));
                } else {
                        block = eloc.logicalBlockNum + ((elen - 1) >>
-                                                       dir->i_sb->
-                                                       s_blocksize_bits);
-                       fi = (struct fileIdentDesc *)(fibh->sbh->b_data +
-                                                     fibh->soffset);
+                                                       dir->i_sb->s_blocksize_bits);
+                       fi = (struct fileIdentDesc *)(fibh->sbh->b_data + fibh->soffset);
                }
        } else {
                fibh->soffset = fibh->eoffset - sb->s_blocksize;
@@ -538,42 +509,36 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
 
                block = eloc.logicalBlockNum + ((elen - 1) >>
                                                dir->i_sb->s_blocksize_bits);
-
-               if (!
-                   (fibh->ebh =
-                    udf_bread(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
-                              1, err))) {
+               fibh->ebh = udf_bread(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2), 1, err);
+               if (!fibh->ebh) {
                        brelse(epos.bh);
                        brelse(fibh->sbh);
                        return NULL;
                }
 
-               if (!(fibh->soffset)) {
+               if (!fibh->soffset) {
                        if (udf_next_aext(dir, &epos, &eloc, &elen, 1) ==
                            (EXT_RECORDED_ALLOCATED >> 30)) {
                                block = eloc.logicalBlockNum + ((elen - 1) >>
-                                                               dir->i_sb->
-                                                               s_blocksize_bits);
-                       } else
+                                       dir->i_sb->s_blocksize_bits);
+                       } else {
                                block++;
+                       }
 
                        brelse(fibh->sbh);
                        fibh->sbh = fibh->ebh;
                        fi = (struct fileIdentDesc *)(fibh->sbh->b_data);
                } else {
                        fi = (struct fileIdentDesc *)
-                           (fibh->sbh->b_data + sb->s_blocksize +
-                            fibh->soffset);
+                               (fibh->sbh->b_data + sb->s_blocksize + fibh->soffset);
                }
        }
 
        memset(cfi, 0, sizeof(struct fileIdentDesc));
        if (UDF_SB_UDFREV(sb) >= 0x0200)
-               udf_new_tag((char *)cfi, TAG_IDENT_FID, 3, 1, block,
-                           sizeof(tag));
+               udf_new_tag((char *)cfi, TAG_IDENT_FID, 3, 1, block, sizeof(tag));
        else
-               udf_new_tag((char *)cfi, TAG_IDENT_FID, 2, 1, block,
-                           sizeof(tag));
+               udf_new_tag((char *)cfi, TAG_IDENT_FID, 2, 1, block, sizeof(tag));
        cfi->fileVersionNum = cpu_to_le16(1);
        cfi->lengthFileIdent = namelen;
        cfi->lengthOfImpUse = cpu_to_le16(0);
@@ -599,8 +564,10 @@ static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi,
                            struct fileIdentDesc *cfi)
 {
        cfi->fileCharacteristics |= FID_FILE_CHAR_DELETED;
+
        if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
                memset(&(cfi->icb), 0x00, sizeof(long_ad));
+
        return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL);
 }
 
@@ -637,8 +604,8 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode,
        }
        cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
        cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
-       *(__le32 *) ((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
-           cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
+       *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
+               cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
        udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
        if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
                mark_inode_dirty(dir);
@@ -648,6 +615,7 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode,
        brelse(fibh.sbh);
        unlock_kernel();
        d_instantiate(dentry, inode);
+
        return 0;
 }
 
@@ -679,8 +647,8 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode,
        }
        cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
        cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
-       *(__le32 *) ((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
-           cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
+       *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
+               cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
        udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
        if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
                mark_inode_dirty(dir);
@@ -692,7 +660,8 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode,
        brelse(fibh.sbh);
        d_instantiate(dentry, inode);
        err = 0;
-      out:
+
+out:
        unlock_kernel();
        return err;
 }
@@ -725,10 +694,9 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        inode->i_nlink = 2;
        cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
        cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(dir));
-       *(__le32 *) ((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
-           cpu_to_le32(UDF_I_UNIQUE(dir) & 0x00000000FFFFFFFFUL);
-       cfi.fileCharacteristics =
-           FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT;
+       *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
+               cpu_to_le32(UDF_I_UNIQUE(dir) & 0x00000000FFFFFFFFUL);
+       cfi.fileCharacteristics = FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT;
        udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL);
        brelse(fibh.sbh);
        inode->i_mode = S_IFDIR | mode;
@@ -744,8 +712,8 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        }
        cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
        cfi.icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(inode));
-       *(__le32 *) ((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
-           cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
+       *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
+               cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL);
        cfi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY;
        udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
        inc_nlink(dir);
@@ -755,7 +723,8 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode)
                brelse(fibh.ebh);
        brelse(fibh.sbh);
        err = 0;
-      out:
+
+out:
        unlock_kernel();
        return err;
 }
@@ -770,26 +739,25 @@ static int empty_dir(struct inode *dir)
        kernel_lb_addr eloc;
        uint32_t elen;
        sector_t offset;
-       struct extent_position epos = { NULL, 0, {0, 0} };
+       struct extent_position epos = {};
 
        f_pos = (udf_ext0_offset(dir) >> 2);
 
-       fibh.soffset = fibh.eoffset =
-           (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
+       fibh.soffset = fibh.eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
 
-       if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
+       if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
                fibh.sbh = fibh.ebh = NULL;
-       else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
-                           &epos, &eloc, &elen,
-                           &offset) == (EXT_RECORDED_ALLOCATED >> 30)) {
+       } else if (inode_bmap(dir, f_pos >> (dir->i_sb->s_blocksize_bits - 2),
+                             &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30)) {
                block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
                if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
                        if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
                                epos.offset -= sizeof(short_ad);
                        else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
                                epos.offset -= sizeof(long_ad);
-               } else
+               } else {
                        offset = 0;
+               }
 
                if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) {
                        brelse(epos.bh);
@@ -803,7 +771,6 @@ static int empty_dir(struct inode *dir)
        while ((f_pos < size)) {
                fi = udf_fileident_read(dir, &f_pos, &fibh, &cfi, &epos, &eloc,
                                        &elen, &offset);
-
                if (!fi) {
                        if (fibh.sbh != fibh.ebh)
                                brelse(fibh.ebh);
@@ -812,8 +779,8 @@ static int empty_dir(struct inode *dir)
                        return 0;
                }
 
-               if (cfi.lengthFileIdent
-                   && (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0) {
+               if (cfi.lengthFileIdent &&
+                   (cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) == 0) {
                        if (fibh.sbh != fibh.ebh)
                                brelse(fibh.ebh);
                        brelse(fibh.sbh);
@@ -821,10 +788,12 @@ static int empty_dir(struct inode *dir)
                        return 0;
                }
        }
+
        if (fibh.sbh != fibh.ebh)
                brelse(fibh.ebh);
        brelse(fibh.sbh);
        brelse(epos.bh);
+
        return 1;
 }
 
@@ -859,15 +828,15 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry)
        clear_nlink(inode);
        inode->i_size = 0;
        inode_dec_link_count(dir);
-       inode->i_ctime = dir->i_ctime = dir->i_mtime =
-           current_fs_time(dir->i_sb);
+       inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
        mark_inode_dirty(dir);
 
-      end_rmdir:
+end_rmdir:
        if (fibh.sbh != fibh.ebh)
                brelse(fibh.ebh);
        brelse(fibh.sbh);
-      out:
+
+out:
        unlock_kernel();
        return retval;
 }
@@ -906,11 +875,12 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry)
        inode->i_ctime = dir->i_ctime;
        retval = 0;
 
-      end_unlink:
+end_unlink:
        if (fibh.sbh != fibh.ebh)
                brelse(fibh.ebh);
        brelse(fibh.sbh);
-      out:
+
+out:
        unlock_kernel();
        return retval;
 }
@@ -922,7 +892,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
        struct pathComponent *pc;
        char *compstart;
        struct udf_fileident_bh fibh;
-       struct extent_position epos = { NULL, 0, {0, 0} };
+       struct extent_position epos = {};
        int eoffset, elen = 0;
        struct fileIdentDesc *fi;
        struct fileIdentDesc cfi;
@@ -945,26 +915,22 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
                uint32_t elen;
 
                block = udf_new_block(inode->i_sb, inode,
-                                     UDF_I_LOCATION(inode).
-                                     partitionReferenceNum,
-                                     UDF_I_LOCATION(inode).logicalBlockNum,
-                                     &err);
+                                     UDF_I_LOCATION(inode).partitionReferenceNum,
+                                     UDF_I_LOCATION(inode).logicalBlockNum, &err);
                if (!block)
                        goto out_no_entry;
                epos.block = UDF_I_LOCATION(inode);
                epos.offset = udf_file_entry_alloc_offset(inode);
                epos.bh = NULL;
                eloc.logicalBlockNum = block;
-               eloc.partitionReferenceNum =
-                   UDF_I_LOCATION(inode).partitionReferenceNum;
+               eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
                elen = inode->i_sb->s_blocksize;
                UDF_I_LENEXTENTS(inode) = elen;
                udf_add_aext(inode, &epos, eloc, elen, 0);
                brelse(epos.bh);
 
                block = udf_get_pblock(inode->i_sb, block,
-                                      UDF_I_LOCATION(inode).
-                                      partitionReferenceNum, 0);
+                                      UDF_I_LOCATION(inode).partitionReferenceNum, 0);
                epos.bh = udf_tread(inode->i_sb, block);
                lock_buffer(epos.bh);
                memset(epos.bh->b_data, 0x00, inode->i_sb->s_blocksize);
@@ -972,8 +938,9 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
                unlock_buffer(epos.bh);
                mark_buffer_dirty_inode(epos.bh, inode);
                ea = epos.bh->b_data + udf_ext0_offset(inode);
-       } else
+       } else {
                ea = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
+       }
 
        eoffset = inode->i_sb->s_blocksize - udf_ext0_offset(inode);
        pc = (struct pathComponent *)ea;
@@ -1010,20 +977,17 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
                if (compstart[0] == '.') {
                        if ((symname - compstart) == 1)
                                pc->componentType = 4;
-                       else if ((symname - compstart) == 2
-                                && compstart[1] == '.')
+                       else if ((symname - compstart) == 2 && compstart[1] == '.')
                                pc->componentType = 3;
                }
 
                if (pc->componentType == 5) {
-                       if (!
-                           (namelen =
-                            udf_put_filename(inode->i_sb, compstart, name,
-                                             symname - compstart)))
+                       namelen = udf_put_filename(inode->i_sb, compstart, name,
+                                                  symname - compstart);
+                       if (!namelen)
                                goto out_no_entry;
 
-                       if (elen + sizeof(struct pathComponent) + namelen >
-                           eoffset)
+                       if (elen + sizeof(struct pathComponent) + namelen > eoffset)
                                goto out_no_entry;
                        else
                                pc->lengthComponentIdent = namelen;
@@ -1053,12 +1017,10 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
        if (UDF_SB_LVIDBH(inode->i_sb)) {
                struct logicalVolHeaderDesc *lvhd;
                uint64_t uniqueID;
-               lvhd =
-                   (struct logicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->
-                                                   logicalVolContentsUse);
+               lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->logicalVolContentsUse);
                uniqueID = le64_to_cpu(lvhd->uniqueID);
-               *(__le32 *) ((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
-                   cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
+               *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
+                       cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
                if (!(++uniqueID & 0x00000000FFFFFFFFUL))
                        uniqueID += 16;
                lvhd->uniqueID = cpu_to_le64(uniqueID);
@@ -1074,11 +1036,11 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
        d_instantiate(dentry, inode);
        err = 0;
 
-      out:
+out:
        unlock_kernel();
        return err;
 
-      out_no_entry:
+out_no_entry:
        inode_dec_link_count(inode);
        iput(inode);
        goto out;
@@ -1107,12 +1069,10 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir,
        if (UDF_SB_LVIDBH(inode->i_sb)) {
                struct logicalVolHeaderDesc *lvhd;
                uint64_t uniqueID;
-               lvhd =
-                   (struct logicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->
-                                                   logicalVolContentsUse);
+               lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(inode->i_sb)->logicalVolContentsUse);
                uniqueID = le64_to_cpu(lvhd->uniqueID);
-               *(__le32 *) ((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
-                   cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
+               *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
+                       cpu_to_le32(uniqueID & 0x00000000FFFFFFFFUL);
                if (!(++uniqueID & 0x00000000FFFFFFFFUL))
                        uniqueID += 16;
                lvhd->uniqueID = cpu_to_le64(uniqueID);
@@ -1122,6 +1082,7 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir,
        if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB) {
                mark_inode_dirty(dir);
        }
+
        if (fibh.sbh != fibh.ebh)
                brelse(fibh.ebh);
        brelse(fibh.sbh);
@@ -1131,6 +1092,7 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir,
        atomic_inc(&inode->i_count);
        d_instantiate(dentry, inode);
        unlock_kernel();
+
        return 0;
 }
 
@@ -1143,8 +1105,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
        struct inode *old_inode = old_dentry->d_inode;
        struct inode *new_inode = new_dentry->d_inode;
        struct udf_fileident_bh ofibh, nfibh;
-       struct fileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi =
-           NULL, ocfi, ncfi;
+       struct fileIdentDesc *ofi = NULL, *nfi = NULL, *dir_fi = NULL, ocfi, ncfi;
        struct buffer_head *dir_bh = NULL;
        int retval = -ENOENT;
        kernel_lb_addr tloc;
@@ -1181,36 +1142,27 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
                if (UDF_I_ALLOCTYPE(old_inode) == ICBTAG_FLAG_AD_IN_ICB) {
                        dir_fi = udf_get_fileident(UDF_I_DATA(old_inode) -
                                                   (UDF_I_EFE(old_inode) ?
-                                                   sizeof(struct
-                                                          extendedFileEntry) :
+                                                   sizeof(struct extendedFileEntry) :
                                                    sizeof(struct fileEntry)),
-                                                  old_inode->i_sb->s_blocksize,
-                                                  &offset);
+                                                  old_inode->i_sb->s_blocksize, &offset);
                } else {
                        dir_bh = udf_bread(old_inode, 0, 0, &retval);
                        if (!dir_bh)
                                goto end_rename;
-                       dir_fi =
-                           udf_get_fileident(dir_bh->b_data,
-                                             old_inode->i_sb->s_blocksize,
-                                             &offset);
+                       dir_fi = udf_get_fileident(dir_bh->b_data, old_inode->i_sb->s_blocksize, &offset);
                }
                if (!dir_fi)
                        goto end_rename;
                tloc = lelb_to_cpu(dir_fi->icb.extLocation);
-               if (udf_get_lb_pblock(old_inode->i_sb, tloc, 0)
-                   != old_dir->i_ino)
+               if (udf_get_lb_pblock(old_inode->i_sb, tloc, 0) != old_dir->i_ino)
                        goto end_rename;
 
                retval = -EMLINK;
-               if (!new_inode
-                   && new_dir->i_nlink >=
-                   (256 << sizeof(new_dir->i_nlink)) - 1)
+               if (!new_inode && new_dir->i_nlink >= (256 << sizeof(new_dir->i_nlink)) - 1)
                        goto end_rename;
        }
        if (!nfi) {
-               nfi =
-                   udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi, &retval);
+               nfi = udf_add_entry(new_dir, new_dentry, &nfibh, &ncfi, &retval);
                if (!nfi)
                        goto end_rename;
        }
@@ -1244,13 +1196,12 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
        if (dir_fi) {
                dir_fi->icb.extLocation = cpu_to_lelb(UDF_I_LOCATION(new_dir));
                udf_update_tag((char *)dir_fi, (sizeof(struct fileIdentDesc) +
-                                               le16_to_cpu(dir_fi->
-                                                           lengthOfImpUse) +
-                                               3) & ~3);
+                                               le16_to_cpu(dir_fi->lengthOfImpUse) + 3) & ~3);
                if (UDF_I_ALLOCTYPE(old_inode) == ICBTAG_FLAG_AD_IN_ICB) {
                        mark_inode_dirty(old_inode);
-               } else
+               } else {
                        mark_buffer_dirty_inode(dir_bh, old_inode);
+               }
                inode_dec_link_count(old_dir);
                if (new_inode) {
                        inode_dec_link_count(new_inode);
@@ -1268,7 +1219,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
 
        retval = 0;
 
-      end_rename:
+end_rename:
        brelse(dir_bh);
        if (nfi) {
                if (nfibh.sbh != nfibh.ebh)
@@ -1276,17 +1227,18 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
                brelse(nfibh.sbh);
        }
        unlock_kernel();
+
        return retval;
 }
 
 const struct inode_operations udf_dir_inode_operations = {
-       .lookup = udf_lookup,
-       .create = udf_create,
-       .link = udf_link,
-       .unlink = udf_unlink,
-       .symlink = udf_symlink,
-       .mkdir = udf_mkdir,
-       .rmdir = udf_rmdir,
-       .mknod = udf_mknod,
-       .rename = udf_rename,
+       .lookup                         = udf_lookup,
+       .create                         = udf_create,
+       .link                           = udf_link,
+       .unlink                         = udf_unlink,
+       .symlink                        = udf_symlink,
+       .mkdir                          = udf_mkdir,
+       .rmdir                          = udf_rmdir,
+       .mknod                          = udf_mknod,
+       .rename                         = udf_rename,
 };
index bec5d340d8c5acfb26258b964399811ead46fed4..65ff47902bd25784940b9ac3bc7744fc9da0e04f 100644 (file)
 #define IS_DF_SOFT_WRITE_PROTECT       0x02
 
 struct UDFIdentSuffix {
-       __le16 UDFRevision;
-       uint8_t OSClass;
-       uint8_t OSIdentifier;
-       uint8_t reserved[4];
+       __le16          UDFRevision;
+       uint8_t         OSClass;
+       uint8_t         OSIdentifier;
+       uint8_t         reserved[4];
 } __attribute__ ((packed));
 
 struct impIdentSuffix {
-       uint8_t OSClass;
-       uint8_t OSIdentifier;
-       uint8_t reserved[6];
+       uint8_t         OSClass;
+       uint8_t         OSIdentifier;
+       uint8_t         reserved[6];
 } __attribute__ ((packed));
 
 struct appIdentSuffix {
-       uint8_t impUse[8];
+       uint8_t         impUse[8];
 } __attribute__ ((packed));
 
 /* Logical Volume Integrity Descriptor (UDF 2.50 2.2.6) */
 /* Implementation Use (UDF 2.50 2.2.6.4) */
 struct logicalVolIntegrityDescImpUse {
-       regid impIdent;
-       __le32 numFiles;
-       __le32 numDirs;
-       __le16 minUDFReadRev;
-       __le16 minUDFWriteRev;
-       __le16 maxUDFWriteRev;
-       uint8_t impUse[0];
+       regid           impIdent;
+       __le32          numFiles;
+       __le32          numDirs;
+       __le16          minUDFReadRev;
+       __le16          minUDFWriteRev;
+       __le16          maxUDFWriteRev;
+       uint8_t         impUse[0];
 } __attribute__ ((packed));
 
 /* Implementation Use Volume Descriptor (UDF 2.50 2.2.7) */
 /* Implementation Use (UDF 2.50 2.2.7.2) */
 struct impUseVolDescImpUse {
-       charspec LVICharset;
-       dstring logicalVolIdent[128];
-       dstring LVInfo1[36];
-       dstring LVInfo2[36];
-       dstring LVInfo3[36];
-       regid impIdent;
-       uint8_t impUse[128];
+       charspec        LVICharset;
+       dstring         logicalVolIdent[128];
+       dstring         LVInfo1[36];
+       dstring         LVInfo2[36];
+       dstring         LVInfo3[36];
+       regid           impIdent;
+       uint8_t         impUse[128];
 } __attribute__ ((packed));
 
 struct udfPartitionMap2 {
-       uint8_t partitionMapType;
-       uint8_t partitionMapLength;
-       uint8_t reserved1[2];
-       regid partIdent;
-       __le16 volSeqNum;
-       __le16 partitionNum;
+       uint8_t         partitionMapType;
+       uint8_t         partitionMapLength;
+       uint8_t         reserved1[2];
+       regid           partIdent;
+       __le16          volSeqNum;
+       __le16          partitionNum;
 } __attribute__ ((packed));
 
 /* Virtual Partition Map (UDF 2.50 2.2.8) */
 struct virtualPartitionMap {
-       uint8_t partitionMapType;
-       uint8_t partitionMapLength;
-       uint8_t reserved1[2];
-       regid partIdent;
-       __le16 volSeqNum;
-       __le16 partitionNum;
-       uint8_t reserved2[24];
+       uint8_t         partitionMapType;
+       uint8_t         partitionMapLength;
+       uint8_t         reserved1[2];
+       regid           partIdent;
+       __le16          volSeqNum;
+       __le16          partitionNum;
+       uint8_t         reserved2[24];
 } __attribute__ ((packed));
 
 /* Sparable Partition Map (UDF 2.50 2.2.9) */
@@ -143,62 +143,62 @@ struct sparablePartitionMap {
 
 /* Metadata Partition Map (UDF 2.4.0 2.2.10) */
 struct metadataPartitionMap {
-       uint8_t partitionMapType;
-       uint8_t partitionMapLength;
-       uint8_t reserved1[2];
-       regid partIdent;
-       __le16 volSeqNum;
-       __le16 partitionNum;
-       __le32 metadataFileLoc;
-       __le32 metadataMirrorFileLoc;
-       __le32 metadataBitmapFileLoc;
-       __le32 allocUnitSize;
-       __le16 alignUnitSize;
-       uint8_t flags;
-       uint8_t reserved2[5];
+       uint8_t         partitionMapType;
+       uint8_t         partitionMapLength;
+       uint8_t         reserved1[2];
+       regid           partIdent;
+       __le16          volSeqNum;
+       __le16          partitionNum;
+       __le32          metadataFileLoc;
+       __le32          metadataMirrorFileLoc;
+       __le32          metadataBitmapFileLoc;
+       __le32          allocUnitSize;
+       __le16          alignUnitSize;
+       uint8_t         flags;
+       uint8_t         reserved2[5];
 } __attribute__ ((packed));
 
 /* Virtual Allocation Table (UDF 1.5 2.2.10) */
 struct virtualAllocationTable15 {
-       __le32 VirtualSector[0];
-       regid vatIdent;
-       __le32 previousVATICBLoc;
+       __le32          VirtualSector[0];
+       regid           vatIdent;
+       __le32          previousVATICBLoc;
 } __attribute__ ((packed));
 
 #define ICBTAG_FILE_TYPE_VAT15         0x00U
 
 /* Virtual Allocation Table (UDF 2.50 2.2.11) */
 struct virtualAllocationTable20 {
-       __le16 lengthHeader;
-       __le16 lengthImpUse;
-       dstring logicalVolIdent[128];
-       __le32 previousVATICBLoc;
-       __le32 numFiles;
-       __le32 numDirs;
-       __le16 minReadRevision;
-       __le16 minWriteRevision;
-       __le16 maxWriteRevision;
-       __le16 reserved;
-       uint8_t impUse[0];
-       __le32 vatEntry[0];
+       __le16          lengthHeader;
+       __le16          lengthImpUse;
+       dstring         logicalVolIdent[128];
+       __le32          previousVATICBLoc;
+       __le32          numFiles;
+       __le32          numDirs;
+       __le16          minReadRevision;
+       __le16          minWriteRevision;
+       __le16          maxWriteRevision;
+       __le16          reserved;
+       uint8_t         impUse[0];
+       __le32          vatEntry[0];
 } __attribute__ ((packed));
 
 #define ICBTAG_FILE_TYPE_VAT20         0xF8U
 
 /* Sparing Table (UDF 2.50 2.2.12) */
 struct sparingEntry {
-       __le32 origLocation;
-       __le32 mappedLocation;
+       __le32          origLocation;
+       __le32          mappedLocation;
 } __attribute__ ((packed));
 
 struct sparingTable {
-       tag descTag;
-       regid sparingIdent;
-       __le16 reallocationTableLen;
-       __le16 reserved;
-       __le32 sequenceNum;
+       tag             descTag;
+       regid           sparingIdent;
+       __le16          reallocationTableLen;
+       __le16          reserved;
+       __le32          sequenceNum;
        struct sparingEntry
-        mapEntry[0];
+                       mapEntry[0];
 } __attribute__ ((packed));
 
 /* Metadata File (and Metadata Mirror File) (UDF 2.50 2.2.13.1) */
@@ -208,8 +208,8 @@ struct sparingTable {
 
 /* struct long_ad ICB - ADImpUse (UDF 2.50 2.2.4.3) */
 struct allocDescImpUse {
-       __le16 flags;
-       uint8_t impUse[4];
+       __le16          flags;
+       uint8_t         impUse[4];
 } __attribute__ ((packed));
 
 #define AD_IU_EXT_ERASED               0x0001
@@ -220,23 +220,23 @@ struct allocDescImpUse {
 /* Implementation Use Extended Attribute (UDF 2.50 3.3.4.5) */
 /* FreeEASpace (UDF 2.50 3.3.4.5.1.1) */
 struct freeEaSpace {
-       __le16 headerChecksum;
-       uint8_t freeEASpace[0];
+       __le16          headerChecksum;
+       uint8_t         freeEASpace[0];
 } __attribute__ ((packed));
 
 /* DVD Copyright Management Information (UDF 2.50 3.3.4.5.1.2) */
 struct DVDCopyrightImpUse {
-       __le16 headerChecksum;
-       uint8_t CGMSInfo;
-       uint8_t dataType;
-       uint8_t protectionSystemInfo[4];
+       __le16          headerChecksum;
+       uint8_t         CGMSInfo;
+       uint8_t         dataType;
+       uint8_t         protectionSystemInfo[4];
 } __attribute__ ((packed));
 
 /* Application Use Extended Attribute (UDF 2.50 3.3.4.6) */
 /* FreeAppEASpace (UDF 2.50 3.3.4.6.1) */
 struct freeAppEASpace {
-       __le16 headerChecksum;
-       uint8_t freeEASpace[0];
+       __le16          headerChecksum;
+       uint8_t         freeEASpace[0];
 } __attribute__ ((packed));
 
 /* UDF Defined System Stream (UDF 2.50 3.3.7) */
@@ -276,4 +276,4 @@ struct freeAppEASpace {
 #define UDF_OS_ID_BEOS                 0x00U
 #define UDF_OS_ID_WINCE                        0x00U
 
-#endif                         /* _OSTA_UDF_H */
+#endif /* _OSTA_UDF_H */
index a95d830a674d12e076d85ae7e0fc980d8cdadfd2..aaab24c8c498d33ee3e9bb8774cf4fca47cee0bb 100644 (file)
@@ -14,7 +14,7 @@
  *
  * HISTORY
  *
- * 12/06/98 blf  Created file. 
+ * 12/06/98 blf  Created file.
  *
  */
 
@@ -32,19 +32,17 @@ inline uint32_t udf_get_pblock(struct super_block *sb, uint32_t block,
                               uint16_t partition, uint32_t offset)
 {
        if (partition >= UDF_SB_NUMPARTS(sb)) {
-               udf_debug
-                   ("block=%d, partition=%d, offset=%d: invalid partition\n",
-                    block, partition, offset);
+               udf_debug("block=%d, partition=%d, offset=%d: invalid partition\n",
+                         block, partition, offset);
                return 0xFFFFFFFF;
        }
        if (UDF_SB_PARTFUNC(sb, partition))
-               return UDF_SB_PARTFUNC(sb, partition) (sb, block, partition,
-                                                      offset);
+               return UDF_SB_PARTFUNC(sb, partition)(sb, block, partition, offset);
        else
                return UDF_SB_PARTROOT(sb, partition) + block + offset;
 }
 
-uint32_t udf_get_pblock_virt15(struct super_block * sb, uint32_t block,
+uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block,
                               uint16_t partition, uint32_t offset)
 {
        struct buffer_head *bh = NULL;
@@ -52,14 +50,11 @@ uint32_t udf_get_pblock_virt15(struct super_block * sb, uint32_t block,
        uint32_t index;
        uint32_t loc;
 
-       index =
-           (sb->s_blocksize -
-            UDF_SB_TYPEVIRT(sb, partition).s_start_offset) / sizeof(uint32_t);
+       index = (sb->s_blocksize - UDF_SB_TYPEVIRT(sb,partition).s_start_offset) / sizeof(uint32_t);
 
-       if (block > UDF_SB_TYPEVIRT(sb, partition).s_num_entries) {
-               udf_debug
-                   ("Trying to access block beyond end of VAT (%d max %d)\n",
-                    block, UDF_SB_TYPEVIRT(sb, partition).s_num_entries);
+       if (block > UDF_SB_TYPEVIRT(sb,partition).s_num_entries) {
+               udf_debug("Trying to access block beyond end of VAT (%d max %d)\n",
+                         block, UDF_SB_TYPEVIRT(sb,partition).s_num_entries);
                return 0xFFFFFFFF;
        }
 
@@ -69,10 +64,7 @@ uint32_t udf_get_pblock_virt15(struct super_block * sb, uint32_t block,
                index = block % (sb->s_blocksize / sizeof(uint32_t));
        } else {
                newblock = 0;
-               index =
-                   UDF_SB_TYPEVIRT(sb,
-                                   partition).s_start_offset /
-                   sizeof(uint32_t) + block;
+               index = UDF_SB_TYPEVIRT(sb,partition).s_start_offset / sizeof(uint32_t) + block;
        }
 
        loc = udf_block_map(UDF_SB_VAT(sb), newblock);
@@ -83,7 +75,7 @@ uint32_t udf_get_pblock_virt15(struct super_block * sb, uint32_t block,
                return 0xFFFFFFFF;
        }
 
-       loc = le32_to_cpu(((__le32 *) bh->b_data)[index]);
+       loc = le32_to_cpu(((__le32 *)bh->b_data)[index]);
 
        brelse(bh);
 
@@ -93,8 +85,8 @@ uint32_t udf_get_pblock_virt15(struct super_block * sb, uint32_t block,
        }
 
        return udf_get_pblock(sb, loc,
-                             UDF_I_LOCATION(UDF_SB_VAT(sb)).
-                             partitionReferenceNum, offset);
+                             UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum,
+                             offset);
 }
 
 inline uint32_t udf_get_pblock_virt20(struct super_block * sb, uint32_t block,
@@ -108,40 +100,29 @@ uint32_t udf_get_pblock_spar15(struct super_block * sb, uint32_t block,
 {
        int i;
        struct sparingTable *st = NULL;
-       uint32_t packet =
-           (block + offset) & ~(UDF_SB_TYPESPAR(sb, partition).s_packet_len -
-                                1);
+       uint32_t packet = (block + offset) & ~(UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1);
 
        for (i = 0; i < 4; i++) {
-               if (UDF_SB_TYPESPAR(sb, partition).s_spar_map[i] != NULL) {
-                       st = (struct sparingTable *)UDF_SB_TYPESPAR(sb,
-                                                                   partition).
-                           s_spar_map[i]->b_data;
+               if (UDF_SB_TYPESPAR(sb,partition).s_spar_map[i] != NULL) {
+                       st = (struct sparingTable *)UDF_SB_TYPESPAR(sb,partition).s_spar_map[i]->b_data;
                        break;
                }
        }
 
        if (st) {
                for (i = 0; i < le16_to_cpu(st->reallocationTableLen); i++) {
-                       if (le32_to_cpu(st->mapEntry[i].origLocation) >=
-                           0xFFFFFFF0)
+                       if (le32_to_cpu(st->mapEntry[i].origLocation) >= 0xFFFFFFF0) {
                                break;
-                       else if (le32_to_cpu(st->mapEntry[i].origLocation) ==
-                                packet) {
-                               return le32_to_cpu(st->mapEntry[i].
-                                                  mappedLocation) + ((block +
-                                                                      offset) &
-                                                                     (UDF_SB_TYPESPAR
-                                                                      (sb,
-                                                                       partition).
-                                                                      s_packet_len
-                                                                      - 1));
-                       } else if (le32_to_cpu(st->mapEntry[i].origLocation) >
-                                  packet)
+                       } else if (le32_to_cpu(st->mapEntry[i].origLocation) == packet) {
+                               return le32_to_cpu(st->mapEntry[i].mappedLocation) +
+                                       ((block + offset) & (UDF_SB_TYPESPAR(sb,partition).s_packet_len - 1));
+                       } else if (le32_to_cpu(st->mapEntry[i].origLocation) > packet) {
                                break;
+                       }
                }
        }
-       return UDF_SB_PARTROOT(sb, partition) + block + offset;
+
+       return UDF_SB_PARTROOT(sb,partition) + block + offset;
 }
 
 int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
@@ -153,20 +134,14 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
        int i, j, k, l;
 
        for (i = 0; i < UDF_SB_NUMPARTS(sb); i++) {
-               if (old_block > UDF_SB_PARTROOT(sb, i) &&
-                   old_block < UDF_SB_PARTROOT(sb, i) + UDF_SB_PARTLEN(sb, i))
-               {
-                       sdata = &UDF_SB_TYPESPAR(sb, i);
-                       packet =
-                           (old_block -
-                            UDF_SB_PARTROOT(sb,
-                                            i)) & ~(sdata->s_packet_len - 1);
+               if (old_block > UDF_SB_PARTROOT(sb,i) &&
+                   old_block < UDF_SB_PARTROOT(sb,i) + UDF_SB_PARTLEN(sb,i)) {
+                       sdata = &UDF_SB_TYPESPAR(sb,i);
+                       packet = (old_block - UDF_SB_PARTROOT(sb,i)) & ~(sdata->s_packet_len - 1);
 
                        for (j = 0; j < 4; j++) {
-                               if (UDF_SB_TYPESPAR(sb, i).s_spar_map[j] !=
-                                   NULL) {
-                                       st = (struct sparingTable *)sdata->
-                                           s_spar_map[j]->b_data;
+                               if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL) {
+                                       st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
                                        break;
                                }
                        }
@@ -174,122 +149,51 @@ int udf_relocate_blocks(struct super_block *sb, long old_block, long *new_block)
                        if (!st)
                                return 1;
 
-                       for (k = 0; k < le16_to_cpu(st->reallocationTableLen);
-                            k++) {
-                               if (le32_to_cpu(st->mapEntry[k].origLocation) ==
-                                   0xFFFFFFFF) {
+                       for (k = 0; k < le16_to_cpu(st->reallocationTableLen); k++) {
+                               if (le32_to_cpu(st->mapEntry[k].origLocation) == 0xFFFFFFFF) {
                                        for (; j < 4; j++) {
                                                if (sdata->s_spar_map[j]) {
-                                                       st = (struct
-                                                             sparingTable *)
-                                                           sdata->
-                                                           s_spar_map[j]->
-                                                           b_data;
-                                                       st->mapEntry[k].
-                                                           origLocation =
-                                                           cpu_to_le32(packet);
-                                                       udf_update_tag((char *)
-                                                                      st,
-                                                                      sizeof
-                                                                      (struct
-                                                                       sparingTable)
-                                                                      +
-                                                                      le16_to_cpu
-                                                                      (st->
-                                                                       reallocationTableLen)
-                                                                      *
-                                                                      sizeof
-                                                                      (struct
-                                                                       sparingEntry));
-                                                       mark_buffer_dirty
-                                                           (sdata->
-                                                            s_spar_map[j]);
+                                                       st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
+                                                       st->mapEntry[k].origLocation = cpu_to_le32(packet);
+                                                       udf_update_tag((char *)st, sizeof(struct sparingTable) + le16_to_cpu(st->reallocationTableLen) * sizeof(struct sparingEntry));
+                                                       mark_buffer_dirty(sdata->s_spar_map[j]);
                                                }
                                        }
-                                       *new_block =
-                                           le32_to_cpu(st->mapEntry[k].
-                                                       mappedLocation) +
-                                           ((old_block -
-                                             UDF_SB_PARTROOT(sb,
-                                                             i)) & (sdata->
-                                                                    s_packet_len
-                                                                    - 1));
+                                       *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
+                                               ((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
                                        return 0;
-                               } else
-                                   if (le32_to_cpu
-                                       (st->mapEntry[k].origLocation) ==
-                                       packet) {
-                                       *new_block =
-                                           le32_to_cpu(st->mapEntry[k].
-                                                       mappedLocation) +
-                                           ((old_block -
-                                             UDF_SB_PARTROOT(sb,
-                                                             i)) & (sdata->
-                                                                    s_packet_len
-                                                                    - 1));
+                               } else if (le32_to_cpu(st->mapEntry[k].origLocation) == packet) {
+                                       *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
+                                               ((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
                                        return 0;
-                               } else
-                                   if (le32_to_cpu
-                                       (st->mapEntry[k].origLocation) > packet)
+                               } else if (le32_to_cpu(st->mapEntry[k].origLocation) > packet) {
                                        break;
+                               }
                        }
-                       for (l = k; l < le16_to_cpu(st->reallocationTableLen);
-                            l++) {
-                               if (le32_to_cpu(st->mapEntry[l].origLocation) ==
-                                   0xFFFFFFFF) {
+
+                       for (l = k; l < le16_to_cpu(st->reallocationTableLen); l++) {
+                               if (le32_to_cpu(st->mapEntry[l].origLocation) == 0xFFFFFFFF) {
                                        for (; j < 4; j++) {
                                                if (sdata->s_spar_map[j]) {
-                                                       st = (struct
-                                                             sparingTable *)
-                                                           sdata->
-                                                           s_spar_map[j]->
-                                                           b_data;
-                                                       mapEntry =
-                                                           st->mapEntry[l];
-                                                       mapEntry.origLocation =
-                                                           cpu_to_le32(packet);
-                                                       memmove(&st->
-                                                               mapEntry[k + 1],
-                                                               &st->
-                                                               mapEntry[k],
-                                                               (l -
-                                                                k) *
-                                                               sizeof(struct
-                                                                      sparingEntry));
-                                                       st->mapEntry[k] =
-                                                           mapEntry;
-                                                       udf_update_tag((char *)
-                                                                      st,
-                                                                      sizeof
-                                                                      (struct
-                                                                       sparingTable)
-                                                                      +
-                                                                      le16_to_cpu
-                                                                      (st->
-                                                                       reallocationTableLen)
-                                                                      *
-                                                                      sizeof
-                                                                      (struct
-                                                                       sparingEntry));
-                                                       mark_buffer_dirty
-                                                           (sdata->
-                                                            s_spar_map[j]);
+                                                       st = (struct sparingTable *)sdata->s_spar_map[j]->b_data;
+                                                       mapEntry = st->mapEntry[l];
+                                                       mapEntry.origLocation = cpu_to_le32(packet);
+                                                       memmove(&st->mapEntry[k + 1], &st->mapEntry[k], (l - k) * sizeof(struct sparingEntry));
+                                                       st->mapEntry[k] = mapEntry;
+                                                       udf_update_tag((char *)st, sizeof(struct sparingTable) + le16_to_cpu(st->reallocationTableLen) * sizeof(struct sparingEntry));
+                                                       mark_buffer_dirty(sdata->s_spar_map[j]);
                                                }
                                        }
-                                       *new_block =
-                                           le32_to_cpu(st->mapEntry[k].
-                                                       mappedLocation) +
-                                           ((old_block -
-                                             UDF_SB_PARTROOT(sb,
-                                                             i)) & (sdata->
-                                                                    s_packet_len
-                                                                    - 1));
+                                       *new_block = le32_to_cpu(st->mapEntry[k].mappedLocation) +
+                                               ((old_block - UDF_SB_PARTROOT(sb,i)) & (sdata->s_packet_len - 1));
                                        return 0;
                                }
                        }
+
                        return 1;
-               }
+               } /* if old_block */
        }
+
        if (i == UDF_SB_NUMPARTS(sb)) {
                /* outside of partitions */
                /* for now, fail =) */
index 72097ee6b75284c6d3b06a3cf90084a918052ee3..7b30964665dbebd7f39002ff26d6cfd9ecd3921f 100644 (file)
@@ -104,11 +104,11 @@ static int udf_get_sb(struct file_system_type *fs_type,
 }
 
 static struct file_system_type udf_fstype = {
-       .owner = THIS_MODULE,
-       .name = "udf",
-       .get_sb = udf_get_sb,
-       .kill_sb = kill_block_super,
-       .fs_flags = FS_REQUIRES_DEV,
+       .owner          = THIS_MODULE,
+       .name           = "udf",
+       .get_sb         = udf_get_sb,
+       .kill_sb        = kill_block_super,
+       .fs_flags       = FS_REQUIRES_DEV,
 };
 
 static struct kmem_cache *udf_inode_cachep;
@@ -116,8 +116,7 @@ static struct kmem_cache *udf_inode_cachep;
 static struct inode *udf_alloc_inode(struct super_block *sb)
 {
        struct udf_inode_info *ei;
-       ei = (struct udf_inode_info *)kmem_cache_alloc(udf_inode_cachep,
-                                                      GFP_KERNEL);
+       ei = (struct udf_inode_info *)kmem_cache_alloc(udf_inode_cachep, GFP_KERNEL);
        if (!ei)
                return NULL;
 
@@ -150,7 +149,7 @@ static int init_inodecache(void)
                                             0, (SLAB_RECLAIM_ACCOUNT |
                                                 SLAB_MEM_SPREAD),
                                             init_once);
-       if (udf_inode_cachep == NULL)
+       if (!udf_inode_cachep)
                return -ENOMEM;
        return 0;
 }
@@ -162,15 +161,15 @@ static void destroy_inodecache(void)
 
 /* Superblock operations */
 static const struct super_operations udf_sb_ops = {
-       .alloc_inode = udf_alloc_inode,
-       .destroy_inode = udf_destroy_inode,
-       .write_inode = udf_write_inode,
-       .delete_inode = udf_delete_inode,
-       .clear_inode = udf_clear_inode,
-       .put_super = udf_put_super,
-       .write_super = udf_write_super,
-       .statfs = udf_statfs,
-       .remount_fs = udf_remount_fs,
+       .alloc_inode    = udf_alloc_inode,
+       .destroy_inode  = udf_destroy_inode,
+       .write_inode    = udf_write_inode,
+       .delete_inode   = udf_delete_inode,
+       .clear_inode    = udf_clear_inode,
+       .put_super      = udf_put_super,
+       .write_super    = udf_write_super,
+       .statfs         = udf_statfs,
+       .remount_fs     = udf_remount_fs,
 };
 
 struct udf_options {
@@ -193,16 +192,20 @@ struct udf_options {
 static int __init init_udf_fs(void)
 {
        int err;
+
        err = init_inodecache();
        if (err)
                goto out1;
        err = register_filesystem(&udf_fstype);
        if (err)
                goto out;
+
        return 0;
-      out:
+
+out:
        destroy_inodecache();
-      out1:
+
+out1:
        return err;
 }
 
@@ -213,7 +216,7 @@ static void __exit exit_udf_fs(void)
 }
 
 module_init(init_udf_fs)
-    module_exit(exit_udf_fs)
+module_exit(exit_udf_fs)
 
 /*
  * udf_parse_options
@@ -239,7 +242,7 @@ module_init(init_udf_fs)
  *
  *     The remaining are for debugging and disaster recovery:
  *
- *     novrs           Skip volume sequence recognition 
+ *     novrs           Skip volume sequence recognition
  *
  *     The following expect a offset from 0.
  *
@@ -268,6 +271,7 @@ module_init(init_udf_fs)
  *     July 1, 1997 - Andrew E. Mileski
  *     Written, tested, and released.
  */
+
 enum {
        Opt_novrs, Opt_nostrict, Opt_bs, Opt_unhide, Opt_undelete,
        Opt_noadinicb, Opt_adinicb, Opt_shortad, Opt_longad,
@@ -278,32 +282,32 @@ enum {
 };
 
 static match_table_t tokens = {
-       {Opt_novrs, "novrs"},
-       {Opt_nostrict, "nostrict"},
-       {Opt_bs, "bs=%u"},
-       {Opt_unhide, "unhide"},
-       {Opt_undelete, "undelete"},
-       {Opt_noadinicb, "noadinicb"},
-       {Opt_adinicb, "adinicb"},
-       {Opt_shortad, "shortad"},
-       {Opt_longad, "longad"},
-       {Opt_uforget, "uid=forget"},
-       {Opt_uignore, "uid=ignore"},
-       {Opt_gforget, "gid=forget"},
-       {Opt_gignore, "gid=ignore"},
-       {Opt_gid, "gid=%u"},
-       {Opt_uid, "uid=%u"},
-       {Opt_umask, "umask=%o"},
-       {Opt_session, "session=%u"},
-       {Opt_lastblock, "lastblock=%u"},
-       {Opt_anchor, "anchor=%u"},
-       {Opt_volume, "volume=%u"},
-       {Opt_partition, "partition=%u"},
-       {Opt_fileset, "fileset=%u"},
-       {Opt_rootdir, "rootdir=%u"},
-       {Opt_utf8, "utf8"},
-       {Opt_iocharset, "iocharset=%s"},
-       {Opt_err, NULL}
+       {Opt_novrs,     "novrs"},
+       {Opt_nostrict,  "nostrict"},
+       {Opt_bs,        "bs=%u"},
+       {Opt_unhide,    "unhide"},
+       {Opt_undelete,  "undelete"},
+       {Opt_noadinicb, "noadinicb"},
+       {Opt_adinicb,   "adinicb"},
+       {Opt_shortad,   "shortad"},
+       {Opt_longad,    "longad"},
+       {Opt_uforget,   "uid=forget"},
+       {Opt_uignore,   "uid=ignore"},
+       {Opt_gforget,   "gid=forget"},
+       {Opt_gignore,   "gid=ignore"},
+       {Opt_gid,       "gid=%u"},
+       {Opt_uid,       "uid=%u"},
+       {Opt_umask,     "umask=%o"},
+       {Opt_session,   "session=%u"},
+       {Opt_lastblock, "lastblock=%u"},
+       {Opt_anchor,    "anchor=%u"},
+       {Opt_volume,    "volume=%u"},
+       {Opt_partition, "partition=%u"},
+       {Opt_fileset,   "fileset=%u"},
+       {Opt_rootdir,   "rootdir=%u"},
+       {Opt_utf8,      "utf8"},
+       {Opt_iocharset, "iocharset=%s"},
+       {Opt_err,       NULL}
 };
 
 static int udf_parse_options(char *options, struct udf_options *uopt)
@@ -444,9 +448,11 @@ static int udf_parse_options(char *options, struct udf_options *uopt)
 void udf_write_super(struct super_block *sb)
 {
        lock_kernel();
+
        if (!(sb->s_flags & MS_RDONLY))
                udf_open_lvid(sb);
        sb->s_dirt = 0;
+
        unlock_kernel();
 }
 
@@ -455,16 +461,16 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
        struct udf_options uopt;
 
        uopt.flags = UDF_SB(sb)->s_flags;
-       uopt.uid = UDF_SB(sb)->s_uid;
-       uopt.gid = UDF_SB(sb)->s_gid;
+       uopt.uid   = UDF_SB(sb)->s_uid;
+       uopt.gid   = UDF_SB(sb)->s_gid;
        uopt.umask = UDF_SB(sb)->s_umask;
 
        if (!udf_parse_options(options, &uopt))
                return -EINVAL;
 
        UDF_SB(sb)->s_flags = uopt.flags;
-       UDF_SB(sb)->s_uid = uopt.uid;
-       UDF_SB(sb)->s_gid = uopt.gid;
+       UDF_SB(sb)->s_uid   = uopt.uid;
+       UDF_SB(sb)->s_gid   = uopt.gid;
        UDF_SB(sb)->s_umask = uopt.umask;
 
        if (UDF_SB_LVIDBH(sb)) {
@@ -517,6 +523,7 @@ static int udf_set_blocksize(struct super_block *sb, int bsize)
                printk(KERN_ERR "udf: bad block size (%d)\n", bsize);
                return 0;
        }
+
        return sb->s_blocksize;
 }
 
@@ -552,15 +559,12 @@ static int udf_vrs(struct super_block *sb, int silent)
 
                /* Look for ISO  descriptors */
                vsd = (struct volStructDesc *)(bh->b_data +
-                                              (sector &
-                                               (sb->s_blocksize - 1)));
+                                              (sector & (sb->s_blocksize - 1)));
 
                if (vsd->stdIdent[0] == 0) {
                        brelse(bh);
                        break;
-               } else
-                   if (!strncmp
-                       (vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN)) {
+               } else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN)) {
                        iso9660 = sector;
                        switch (vsd->structType) {
                        case 0:
@@ -587,21 +591,13 @@ static int udf_vrs(struct super_block *sb, int silent)
                                          vsd->structType);
                                break;
                        }
-               } else
-                   if (!strncmp
-                       (vsd->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN)) {
-               } else
-                   if (!strncmp
-                       (vsd->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN)) {
+               } else if (!strncmp(vsd->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN)) {
+               } else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01, VSD_STD_ID_LEN)) {
                        brelse(bh);
                        break;
-               } else
-                   if (!strncmp
-                       (vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN)) {
+               } else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN)) {
                        nsr02 = sector;
-               } else
-                   if (!strncmp
-                       (vsd->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN)) {
+               } else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN)) {
                        nsr03 = sector;
                }
                brelse(bh);
@@ -644,11 +640,10 @@ static void udf_find_anchor(struct super_block *sb)
 
        if (lastblock) {
                int varlastblock = udf_variable_to_fixed(lastblock);
-               int last[] = { lastblock, lastblock - 2,
-                       lastblock - 150, lastblock - 152,
-                       varlastblock, varlastblock - 2,
-                       varlastblock - 150, varlastblock - 152
-               };
+               int last[] =  { lastblock, lastblock - 2,
+                               lastblock - 150, lastblock - 152,
+                               varlastblock, varlastblock - 2,
+                               varlastblock - 150, varlastblock - 152 };
 
                lastblock = 0;
 
@@ -664,88 +659,54 @@ static void udf_find_anchor(struct super_block *sb)
                        if (last[i] < 0 || !(bh = sb_bread(sb, last[i]))) {
                                ident = location = 0;
                        } else {
-                               ident =
-                                   le16_to_cpu(((tag *) bh->b_data)->tagIdent);
-                               location =
-                                   le32_to_cpu(((tag *) bh->b_data)->
-                                               tagLocation);
+                               ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
+                               location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
                                brelse(bh);
                        }
 
                        if (ident == TAG_IDENT_AVDP) {
                                if (location == last[i] - UDF_SB_SESSION(sb)) {
-                                       lastblock = UDF_SB_ANCHOR(sb)[0] =
-                                           last[i] - UDF_SB_SESSION(sb);
-                                       UDF_SB_ANCHOR(sb)[1] =
-                                           last[i] - 256 - UDF_SB_SESSION(sb);
-                               } else if (location ==
-                                          udf_variable_to_fixed(last[i]) -
-                                          UDF_SB_SESSION(sb)) {
+                                       lastblock = UDF_SB_ANCHOR(sb)[0] = last[i] - UDF_SB_SESSION(sb);
+                                       UDF_SB_ANCHOR(sb)[1] = last[i] - 256 - UDF_SB_SESSION(sb);
+                               } else if (location == udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb)) {
                                        UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
-                                       lastblock = UDF_SB_ANCHOR(sb)[0] =
-                                           udf_variable_to_fixed(last[i]) -
-                                           UDF_SB_SESSION(sb);
-                                       UDF_SB_ANCHOR(sb)[1] =
-                                           lastblock - 256 -
-                                           UDF_SB_SESSION(sb);
-                               } else
-                                       udf_debug
-                                           ("Anchor found at block %d, location mismatch %d.\n",
-                                            last[i], location);
-                       } else if (ident == TAG_IDENT_FE
-                                  || ident == TAG_IDENT_EFE) {
+                                       lastblock = UDF_SB_ANCHOR(sb)[0] = udf_variable_to_fixed(last[i]) - UDF_SB_SESSION(sb);
+                                       UDF_SB_ANCHOR(sb)[1] = lastblock - 256 - UDF_SB_SESSION(sb);
+                               } else {
+                                       udf_debug("Anchor found at block %d, location mismatch %d.\n",
+                                                 last[i], location);
+                               }
+                       } else if (ident == TAG_IDENT_FE || ident == TAG_IDENT_EFE) {
                                lastblock = last[i];
                                UDF_SB_ANCHOR(sb)[3] = 512;
                        } else {
-                               if (last[i] < 256
-                                   || !(bh = sb_bread(sb, last[i] - 256))) {
+                               if (last[i] < 256 || !(bh = sb_bread(sb, last[i] - 256))) {
                                        ident = location = 0;
                                } else {
-                                       ident =
-                                           le16_to_cpu(((tag *) bh->b_data)->
-                                                       tagIdent);
-                                       location =
-                                           le32_to_cpu(((tag *) bh->b_data)->
-                                                       tagLocation);
+                                       ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
+                                       location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
                                        brelse(bh);
                                }
 
                                if (ident == TAG_IDENT_AVDP &&
-                                   location ==
-                                   last[i] - 256 - UDF_SB_SESSION(sb)) {
+                                   location == last[i] - 256 - UDF_SB_SESSION(sb)) {
                                        lastblock = last[i];
                                        UDF_SB_ANCHOR(sb)[1] = last[i] - 256;
                                } else {
-                                       if (last[i] < 312 + UDF_SB_SESSION(sb)
-                                           || !(bh =
-                                                sb_bread(sb,
-                                                         last[i] - 312 -
-                                                         UDF_SB_SESSION(sb))))
-                                       {
+                                       if (last[i] < 312 + UDF_SB_SESSION(sb) ||
+                                           !(bh = sb_bread(sb, last[i] - 312 - UDF_SB_SESSION(sb)))) {
                                                ident = location = 0;
                                        } else {
-                                               ident =
-                                                   le16_to_cpu(((tag *) bh->
-                                                                b_data)->
-                                                               tagIdent);
-                                               location =
-                                                   le32_to_cpu(((tag *) bh->
-                                                                b_data)->
-                                                               tagLocation);
+                                               ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
+                                               location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
                                                brelse(bh);
                                        }
 
                                        if (ident == TAG_IDENT_AVDP &&
-                                           location ==
-                                           udf_variable_to_fixed(last[i]) -
-                                           256) {
-                                               UDF_SET_FLAG(sb,
-                                                            UDF_FLAG_VARCONV);
-                                               lastblock =
-                                                   udf_variable_to_fixed(last
-                                                                         [i]);
-                                               UDF_SB_ANCHOR(sb)[1] =
-                                                   lastblock - 256;
+                                           location == udf_variable_to_fixed(last[i]) - 256) {
+                                               UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+                                               lastblock = udf_variable_to_fixed(last[i]);
+                                               UDF_SB_ANCHOR(sb)[1] = lastblock - 256;
                                        }
                                }
                        }
@@ -755,9 +716,8 @@ static void udf_find_anchor(struct super_block *sb)
        if (!lastblock) {
                /* We havn't found the lastblock. check 312 */
                if ((bh = sb_bread(sb, 312 + UDF_SB_SESSION(sb)))) {
-                       ident = le16_to_cpu(((tag *) bh->b_data)->tagIdent);
-                       location =
-                           le32_to_cpu(((tag *) bh->b_data)->tagLocation);
+                       ident = le16_to_cpu(((tag *)bh->b_data)->tagIdent);
+                       location = le32_to_cpu(((tag *)bh->b_data)->tagLocation);
                        brelse(bh);
 
                        if (ident == TAG_IDENT_AVDP && location == 256)
@@ -767,19 +727,13 @@ static void udf_find_anchor(struct super_block *sb)
 
        for (i = 0; i < ARRAY_SIZE(UDF_SB_ANCHOR(sb)); i++) {
                if (UDF_SB_ANCHOR(sb)[i]) {
-                       if (!(bh = udf_read_tagged(sb,
-                                                  UDF_SB_ANCHOR(sb)[i],
-                                                  UDF_SB_ANCHOR(sb)[i],
-                                                  &ident))) {
+                       if (!(bh = udf_read_tagged(sb, UDF_SB_ANCHOR(sb)[i],
+                                                  UDF_SB_ANCHOR(sb)[i], &ident))) {
                                UDF_SB_ANCHOR(sb)[i] = 0;
                        } else {
                                brelse(bh);
-                               if ((ident != TAG_IDENT_AVDP) && (i ||
-                                                                 (ident !=
-                                                                  TAG_IDENT_FE
-                                                                  && ident !=
-                                                                  TAG_IDENT_EFE)))
-                               {
+                               if ((ident != TAG_IDENT_AVDP) &&
+                                   (i || (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE))) {
                                        UDF_SB_ANCHOR(sb)[i] = 0;
                                }
                        }
@@ -789,9 +743,7 @@ static void udf_find_anchor(struct super_block *sb)
        UDF_SB_LASTBLOCK(sb) = lastblock;
 }
 
-static int
-udf_find_fileset(struct super_block *sb, kernel_lb_addr * fileset,
-                kernel_lb_addr * root)
+static int udf_find_fileset(struct super_block *sb, kernel_lb_addr *fileset, kernel_lb_addr *root)
 {
        struct buffer_head *bh = NULL;
        long lastblock;
@@ -801,18 +753,19 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr * fileset,
            fileset->partitionReferenceNum != 0xFFFF) {
                bh = udf_read_ptagged(sb, *fileset, 0, &ident);
 
-               if (!bh)
+               if (!bh) {
                        return 1;
-               else if (ident != TAG_IDENT_FSD) {
+               else if (ident != TAG_IDENT_FSD) {
                        brelse(bh);
                        return 1;
                }
 
        }
 
-       if (!bh) {              /* Search backwards through the partitions */
+       if (!bh) { /* Search backwards through the partitions */
                kernel_lb_addr newfileset;
 
+/* --> cvg: FIXME - is it reasonable? */
                return 1;
 
                for (newfileset.partitionReferenceNum = UDF_SB_NUMPARTS(sb) - 1;
@@ -820,14 +773,11 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr * fileset,
                      fileset->logicalBlockNum == 0xFFFFFFFF &&
                      fileset->partitionReferenceNum == 0xFFFF);
                     newfileset.partitionReferenceNum--) {
-                       lastblock =
-                           UDF_SB_PARTLEN(sb,
-                                          newfileset.partitionReferenceNum);
+                       lastblock = UDF_SB_PARTLEN(sb, newfileset.partitionReferenceNum);
                        newfileset.logicalBlockNum = 0;
 
                        do {
-                               bh = udf_read_ptagged(sb, newfileset, 0,
-                                                     &ident);
+                               bh = udf_read_ptagged(sb, newfileset, 0, &ident);
                                if (!bh) {
                                        newfileset.logicalBlockNum++;
                                        continue;
@@ -835,38 +785,28 @@ udf_find_fileset(struct super_block *sb, kernel_lb_addr * fileset,
 
                                switch (ident) {
                                case TAG_IDENT_SBD:
-                                       {
-                                               struct spaceBitmapDesc *sp;
-                                               sp = (struct spaceBitmapDesc *)
-                                                   bh->b_data;
-                                               newfileset.logicalBlockNum +=
-                                                   1 +
-                                                   ((le32_to_cpu
-                                                     (sp->numOfBytes) +
-                                                     sizeof(struct
-                                                            spaceBitmapDesc) -
-                                                     1)
-                                                    >> sb->s_blocksize_bits);
-                                               brelse(bh);
-                                               break;
-                                       }
+                               {
+                                       struct spaceBitmapDesc *sp;
+                                       sp = (struct spaceBitmapDesc *)bh->b_data;
+                                       newfileset.logicalBlockNum += 1 +
+                                               ((le32_to_cpu(sp->numOfBytes) +
+                                                 sizeof(struct spaceBitmapDesc) - 1)
+                                                >> sb->s_blocksize_bits);
+                                       brelse(bh);
+                                       break;
+                               }
                                case TAG_IDENT_FSD:
-                                       {
-                                               *fileset = newfileset;
-                                               break;
-                                       }
+                                       *fileset = newfileset;
+                                       break;
                                default:
-                                       {
-                                               newfileset.logicalBlockNum++;
-                                               brelse(bh);
-                                               bh = NULL;
-                                               break;
-                                       }
+                                       newfileset.logicalBlockNum++;
+                                       brelse(bh);
+                                       bh = NULL;
+                                       break;
                                }
-                       }
-                       while (newfileset.logicalBlockNum < lastblock &&
-                              fileset->logicalBlockNum == 0xFFFFFFFF &&
-                              fileset->partitionReferenceNum == 0xFFFF);
+                       } while (newfileset.logicalBlockNum < lastblock &&
+                                fileset->logicalBlockNum == 0xFFFFFFFF &&
+                                fileset->partitionReferenceNum == 0xFFFF);
                }
        }
 
@@ -898,10 +838,10 @@ static void udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh)
                              lets_to_cpu(pvoldesc->recordingDateAndTime))) {
                kernel_timestamp ts;
                ts = lets_to_cpu(pvoldesc->recordingDateAndTime);
-               udf_debug
-                   ("recording time %ld/%ld, %04u/%02u/%02u %02u:%02u (%x)\n",
-                    recording, recording_usec, ts.year, ts.month, ts.day,
-                    ts.hour, ts.minute, ts.typeAndTimezone);
+               udf_debug("recording time %ld/%ld, %04u/%02u/%02u %02u:%02u (%x)\n",
+                         recording, recording_usec,
+                         ts.year, ts.month, ts.day, ts.hour,
+                         ts.minute, ts.typeAndTimezone);
                UDF_SB_RECORDTIME(sb).tv_sec = recording;
                UDF_SB_RECORDTIME(sb).tv_nsec = recording_usec * 1000;
        }
@@ -920,9 +860,8 @@ static void udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh)
        }
 }
 
-static void
-udf_load_fileset(struct super_block *sb, struct buffer_head *bh,
-                kernel_lb_addr * root)
+static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh,
+                            kernel_lb_addr *root)
 {
        struct fileSetDesc *fset;
 
@@ -945,121 +884,72 @@ static void udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
 
        for (i = 0; i < UDF_SB_NUMPARTS(sb); i++) {
                udf_debug("Searching map: (%d == %d)\n",
-                         UDF_SB_PARTMAPS(sb)[i].s_partition_num,
-                         le16_to_cpu(p->partitionNumber));
-               if (UDF_SB_PARTMAPS(sb)[i].s_partition_num ==
-                   le16_to_cpu(p->partitionNumber)) {
-                       UDF_SB_PARTLEN(sb, i) = le32_to_cpu(p->partitionLength);        /* blocks */
-                       UDF_SB_PARTROOT(sb, i) =
-                           le32_to_cpu(p->partitionStartingLocation);
-                       if (le32_to_cpu(p->accessType) ==
-                           PD_ACCESS_TYPE_READ_ONLY)
-                               UDF_SB_PARTFLAGS(sb, i) |=
-                                   UDF_PART_FLAG_READ_ONLY;
-                       if (le32_to_cpu(p->accessType) ==
-                           PD_ACCESS_TYPE_WRITE_ONCE)
-                               UDF_SB_PARTFLAGS(sb, i) |=
-                                   UDF_PART_FLAG_WRITE_ONCE;
-                       if (le32_to_cpu(p->accessType) ==
-                           PD_ACCESS_TYPE_REWRITABLE)
-                               UDF_SB_PARTFLAGS(sb, i) |=
-                                   UDF_PART_FLAG_REWRITABLE;
-                       if (le32_to_cpu(p->accessType) ==
-                           PD_ACCESS_TYPE_OVERWRITABLE)
-                               UDF_SB_PARTFLAGS(sb, i) |=
-                                   UDF_PART_FLAG_OVERWRITABLE;
-
-                       if (!strcmp
-                           (p->partitionContents.ident,
-                            PD_PARTITION_CONTENTS_NSR02)
-                           || !strcmp(p->partitionContents.ident,
-                                      PD_PARTITION_CONTENTS_NSR03)) {
+                         UDF_SB_PARTMAPS(sb)[i].s_partition_num, le16_to_cpu(p->partitionNumber));
+               if (UDF_SB_PARTMAPS(sb)[i].s_partition_num == le16_to_cpu(p->partitionNumber)) {
+                       UDF_SB_PARTLEN(sb,i) = le32_to_cpu(p->partitionLength); /* blocks */
+                       UDF_SB_PARTROOT(sb,i) = le32_to_cpu(p->partitionStartingLocation);
+                       if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_READ_ONLY)
+                               UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_READ_ONLY;
+                       if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_WRITE_ONCE)
+                               UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_WRITE_ONCE;
+                       if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_REWRITABLE)
+                               UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_REWRITABLE;
+                       if (le32_to_cpu(p->accessType) == PD_ACCESS_TYPE_OVERWRITABLE)
+                               UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_OVERWRITABLE;
+
+                       if (!strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) ||
+                           !strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03)) {
                                struct partitionHeaderDesc *phd;
 
-                               phd =
-                                   (struct partitionHeaderDesc *)(p->
-                                                                  partitionContentsUse);
+                               phd = (struct partitionHeaderDesc *)(p->partitionContentsUse);
                                if (phd->unallocSpaceTable.extLength) {
-                                       kernel_lb_addr loc =
-                                           { le32_to_cpu(phd->
-                                                         unallocSpaceTable.
-                                                         extPosition), i };
-
-                                       UDF_SB_PARTMAPS(sb)[i].s_uspace.
-                                           s_table = udf_iget(sb, loc);
-                                       UDF_SB_PARTFLAGS(sb, i) |=
-                                           UDF_PART_FLAG_UNALLOC_TABLE;
-                                       udf_debug
-                                           ("unallocSpaceTable (part %d) @ %ld\n",
-                                            i,
-                                            UDF_SB_PARTMAPS(sb)[i].s_uspace.
-                                            s_table->i_ino);
+                                       kernel_lb_addr loc = {
+                                               .logicalBlockNum = le32_to_cpu(phd->unallocSpaceTable.extPosition),
+                                               .partitionReferenceNum = i,
+                                       };
+
+                                       UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table =
+                                               udf_iget(sb, loc);
+                                       UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_TABLE;
+                                       udf_debug("unallocSpaceTable (part %d) @ %ld\n",
+                                                 i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table->i_ino);
                                }
                                if (phd->unallocSpaceBitmap.extLength) {
                                        UDF_SB_ALLOC_BITMAP(sb, i, s_uspace);
-                                       if (UDF_SB_PARTMAPS(sb)[i].s_uspace.
-                                           s_bitmap != NULL) {
-                                               UDF_SB_PARTMAPS(sb)[i].s_uspace.
-                                                   s_bitmap->s_extLength =
-                                                   le32_to_cpu(phd->
-                                                               unallocSpaceBitmap.
-                                                               extLength);
-                                               UDF_SB_PARTMAPS(sb)[i].s_uspace.
-                                                   s_bitmap->s_extPosition =
-                                                   le32_to_cpu(phd->
-                                                               unallocSpaceBitmap.
-                                                               extPosition);
-                                               UDF_SB_PARTFLAGS(sb, i) |=
-                                                   UDF_PART_FLAG_UNALLOC_BITMAP;
-                                               udf_debug
-                                                   ("unallocSpaceBitmap (part %d) @ %d\n",
-                                                    i,
-                                                    UDF_SB_PARTMAPS(sb)[i].
-                                                    s_uspace.s_bitmap->
-                                                    s_extPosition);
+                                       if (UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap != NULL) {
+                                               UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extLength =
+                                                       le32_to_cpu(phd->unallocSpaceBitmap.extLength);
+                                               UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition =
+                                                       le32_to_cpu(phd->unallocSpaceBitmap.extPosition);
+                                               UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_BITMAP;
+                                               udf_debug("unallocSpaceBitmap (part %d) @ %d\n",
+                                                         i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_bitmap->s_extPosition);
                                        }
                                }
                                if (phd->partitionIntegrityTable.extLength)
-                                       udf_debug
-                                           ("partitionIntegrityTable (part %d)\n",
-                                            i);
+                                       udf_debug("partitionIntegrityTable (part %d)\n", i);
                                if (phd->freedSpaceTable.extLength) {
-                                       kernel_lb_addr loc =
-                                           { le32_to_cpu(phd->freedSpaceTable.
-                                                         extPosition), i };
-
-                                       UDF_SB_PARTMAPS(sb)[i].s_fspace.
-                                           s_table = udf_iget(sb, loc);
-                                       UDF_SB_PARTFLAGS(sb, i) |=
-                                           UDF_PART_FLAG_FREED_TABLE;
-                                       udf_debug
-                                           ("freedSpaceTable (part %d) @ %ld\n",
-                                            i,
-                                            UDF_SB_PARTMAPS(sb)[i].s_fspace.
-                                            s_table->i_ino);
+                                       kernel_lb_addr loc = {
+                                               .logicalBlockNum = le32_to_cpu(phd->freedSpaceTable.extPosition),
+                                               .partitionReferenceNum = i,
+                                       };
+
+                                       UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table =
+                                               udf_iget(sb, loc);
+                                       UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_TABLE;
+                                       udf_debug("freedSpaceTable (part %d) @ %ld\n",
+                                                 i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table->i_ino);
                                }
                                if (phd->freedSpaceBitmap.extLength) {
                                        UDF_SB_ALLOC_BITMAP(sb, i, s_fspace);
-                                       if (UDF_SB_PARTMAPS(sb)[i].s_fspace.
-                                           s_bitmap != NULL) {
-                                               UDF_SB_PARTMAPS(sb)[i].s_fspace.
-                                                   s_bitmap->s_extLength =
-                                                   le32_to_cpu(phd->
-                                                               freedSpaceBitmap.
-                                                               extLength);
-                                               UDF_SB_PARTMAPS(sb)[i].s_fspace.
-                                                   s_bitmap->s_extPosition =
-                                                   le32_to_cpu(phd->
-                                                               freedSpaceBitmap.
-                                                               extPosition);
-                                               UDF_SB_PARTFLAGS(sb, i) |=
-                                                   UDF_PART_FLAG_FREED_BITMAP;
-                                               udf_debug
-                                                   ("freedSpaceBitmap (part %d) @ %d\n",
-                                                    i,
-                                                    UDF_SB_PARTMAPS(sb)[i].
-                                                    s_fspace.s_bitmap->
-                                                    s_extPosition);
+                                       if (UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap != NULL) {
+                                               UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extLength =
+                                                       le32_to_cpu(phd->freedSpaceBitmap.extLength);
+                                               UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extPosition =
+                                                       le32_to_cpu(phd->freedSpaceBitmap.extPosition);
+                                               UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_BITMAP;
+                                               udf_debug("freedSpaceBitmap (part %d) @ %d\n",
+                                                         i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_bitmap->s_extPosition);
                                        }
                                }
                        }
@@ -1070,16 +960,14 @@ static void udf_load_partdesc(struct super_block *sb, struct buffer_head *bh)
                udf_debug("Partition (%d) not found in partition map\n",
                          le16_to_cpu(p->partitionNumber));
        } else {
-               udf_debug
-                   ("Partition (%d:%d type %x) starts at physical %d, block length %d\n",
-                    le16_to_cpu(p->partitionNumber), i, UDF_SB_PARTTYPE(sb, i),
-                    UDF_SB_PARTROOT(sb, i), UDF_SB_PARTLEN(sb, i));
+               udf_debug("Partition (%d:%d type %x) starts at physical %d, block length %d\n",
+                         le16_to_cpu(p->partitionNumber), i, UDF_SB_PARTTYPE(sb,i),
+                         UDF_SB_PARTROOT(sb,i), UDF_SB_PARTLEN(sb,i));
        }
 }
 
-static int
-udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh,
-                   kernel_lb_addr * fileset)
+static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh,
+                              kernel_lb_addr *fileset)
 {
        struct logicalVolDesc *lvd;
        int i, j, offset;
@@ -1090,116 +978,69 @@ udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh,
        UDF_SB_ALLOC_PARTMAPS(sb, le32_to_cpu(lvd->numPartitionMaps));
 
        for (i = 0, offset = 0;
-            i < UDF_SB_NUMPARTS(sb)
-            && offset < le32_to_cpu(lvd->mapTableLength);
-            i++, offset +=
-            ((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->
-            partitionMapLength) {
-               type =
-                   ((struct genericPartitionMap *)
-                    &(lvd->partitionMaps[offset]))->partitionMapType;
+            i < UDF_SB_NUMPARTS(sb) && offset < le32_to_cpu(lvd->mapTableLength);
+            i++, offset += ((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapLength) {
+               type = ((struct genericPartitionMap *)&(lvd->partitionMaps[offset]))->partitionMapType;
                if (type == 1) {
-                       struct genericPartitionMap1 *gpm1 =
-                           (struct genericPartitionMap1 *)&(lvd->
-                                                            partitionMaps
-                                                            [offset]);
-                       UDF_SB_PARTTYPE(sb, i) = UDF_TYPE1_MAP15;
-                       UDF_SB_PARTVSN(sb, i) = le16_to_cpu(gpm1->volSeqNum);
-                       UDF_SB_PARTNUM(sb, i) = le16_to_cpu(gpm1->partitionNum);
-                       UDF_SB_PARTFUNC(sb, i) = NULL;
+                       struct genericPartitionMap1 *gpm1 = (struct genericPartitionMap1 *)&(lvd->partitionMaps[offset]);
+                       UDF_SB_PARTTYPE(sb,i) = UDF_TYPE1_MAP15;
+                       UDF_SB_PARTVSN(sb,i) = le16_to_cpu(gpm1->volSeqNum);
+                       UDF_SB_PARTNUM(sb,i) = le16_to_cpu(gpm1->partitionNum);
+                       UDF_SB_PARTFUNC(sb,i) = NULL;
                } else if (type == 2) {
-                       struct udfPartitionMap2 *upm2 =
-                           (struct udfPartitionMap2 *)&(lvd->
-                                                        partitionMaps[offset]);
-                       if (!strncmp
-                           (upm2->partIdent.ident, UDF_ID_VIRTUAL,
-                            strlen(UDF_ID_VIRTUAL))) {
-                               if (le16_to_cpu
-                                   (((__le16 *) upm2->partIdent.
-                                     identSuffix)[0]) == 0x0150) {
-                                       UDF_SB_PARTTYPE(sb, i) =
-                                           UDF_VIRTUAL_MAP15;
-                                       UDF_SB_PARTFUNC(sb, i) =
-                                           udf_get_pblock_virt15;
-                               } else
-                                   if (le16_to_cpu
-                                       (((__le16 *) upm2->partIdent.
-                                         identSuffix)[0]) == 0x0200) {
-                                       UDF_SB_PARTTYPE(sb, i) =
-                                           UDF_VIRTUAL_MAP20;
-                                       UDF_SB_PARTFUNC(sb, i) =
-                                           udf_get_pblock_virt20;
+                       struct udfPartitionMap2 *upm2 = (struct udfPartitionMap2 *)&(lvd->partitionMaps[offset]);
+                       if (!strncmp(upm2->partIdent.ident, UDF_ID_VIRTUAL, strlen(UDF_ID_VIRTUAL))) {
+                               if (le16_to_cpu(((__le16 *)upm2->partIdent.identSuffix)[0]) == 0x0150) {
+                                       UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP15;
+                                       UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt15;
+                               } else if (le16_to_cpu(((__le16 *)upm2->partIdent.identSuffix)[0]) == 0x0200) {
+                                       UDF_SB_PARTTYPE(sb,i) = UDF_VIRTUAL_MAP20;
+                                       UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_virt20;
                                }
-                       } else
-                           if (!strncmp
-                               (upm2->partIdent.ident, UDF_ID_SPARABLE,
-                                strlen(UDF_ID_SPARABLE))) {
+                       } else if (!strncmp(upm2->partIdent.ident, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE))) {
                                uint32_t loc;
                                uint16_t ident;
                                struct sparingTable *st;
-                               struct sparablePartitionMap *spm =
-                                   (struct sparablePartitionMap *)&(lvd->
-                                                                    partitionMaps
-                                                                    [offset]);
-
-                               UDF_SB_PARTTYPE(sb, i) = UDF_SPARABLE_MAP15;
-                               UDF_SB_TYPESPAR(sb, i).s_packet_len =
-                                   le16_to_cpu(spm->packetLength);
+                               struct sparablePartitionMap *spm = (struct sparablePartitionMap *)&(lvd->partitionMaps[offset]);
+
+                               UDF_SB_PARTTYPE(sb,i) = UDF_SPARABLE_MAP15;
+                               UDF_SB_TYPESPAR(sb,i).s_packet_len = le16_to_cpu(spm->packetLength);
                                for (j = 0; j < spm->numSparingTables; j++) {
-                                       loc =
-                                           le32_to_cpu(spm->
-                                                       locSparingTable[j]);
-                                       UDF_SB_TYPESPAR(sb, i).s_spar_map[j] =
-                                           udf_read_tagged(sb, loc, loc,
-                                                           &ident);
-                                       if (UDF_SB_TYPESPAR(sb, i).
-                                           s_spar_map[j] != NULL) {
-                                               st = (struct sparingTable *)
-                                                   UDF_SB_TYPESPAR(sb,
-                                                                   i).
-                                                   s_spar_map[j]->b_data;
-                                               if (ident != 0
-                                                   || strncmp(st->sparingIdent.
-                                                              ident,
-                                                              UDF_ID_SPARING,
-                                                              strlen
-                                                              (UDF_ID_SPARING)))
-                                               {
-                                                       brelse(UDF_SB_TYPESPAR
-                                                              (sb,
-                                                               i).
-                                                              s_spar_map[j]);
-                                                       UDF_SB_TYPESPAR(sb,
-                                                                       i).
-                                                           s_spar_map[j] =
-                                                           NULL;
+                                       loc = le32_to_cpu(spm->locSparingTable[j]);
+                                       UDF_SB_TYPESPAR(sb,i).s_spar_map[j] =
+                                               udf_read_tagged(sb, loc, loc, &ident);
+                                       if (UDF_SB_TYPESPAR(sb,i).s_spar_map[j] != NULL) {
+                                               st = (struct sparingTable *)UDF_SB_TYPESPAR(sb,i).s_spar_map[j]->b_data;
+                                               if (ident != 0 ||
+                                                   strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING))) {
+                                                       brelse(UDF_SB_TYPESPAR(sb,i).s_spar_map[j]);
+                                                       UDF_SB_TYPESPAR(sb,i).s_spar_map[j] = NULL;
                                                }
                                        }
                                }
-                               UDF_SB_PARTFUNC(sb, i) = udf_get_pblock_spar15;
+                               UDF_SB_PARTFUNC(sb,i) = udf_get_pblock_spar15;
                        } else {
-                               udf_debug("Unknown ident: %s\n",
-                                         upm2->partIdent.ident);
+                               udf_debug("Unknown ident: %s\n", upm2->partIdent.ident);
                                continue;
                        }
-                       UDF_SB_PARTVSN(sb, i) = le16_to_cpu(upm2->volSeqNum);
-                       UDF_SB_PARTNUM(sb, i) = le16_to_cpu(upm2->partitionNum);
+                       UDF_SB_PARTVSN(sb,i) = le16_to_cpu(upm2->volSeqNum);
+                       UDF_SB_PARTNUM(sb,i) = le16_to_cpu(upm2->partitionNum);
                }
                udf_debug("Partition (%d:%d) type %d on volume %d\n",
-                         i, UDF_SB_PARTNUM(sb, i), type, UDF_SB_PARTVSN(sb,
-                                                                        i));
+                         i, UDF_SB_PARTNUM(sb,i), type, UDF_SB_PARTVSN(sb,i));
        }
 
        if (fileset) {
-               long_ad *la = (long_ad *) & (lvd->logicalVolContentsUse[0]);
+               long_ad *la = (long_ad *)&(lvd->logicalVolContentsUse[0]);
 
                *fileset = lelb_to_cpu(la->extLocation);
-               udf_debug
-                   ("FileSet found in LogicalVolDesc at block=%d, partition=%d\n",
-                    fileset->logicalBlockNum, fileset->partitionReferenceNum);
+               udf_debug("FileSet found in LogicalVolDesc at block=%d, partition=%d\n",
+                         fileset->logicalBlockNum,
+                         fileset->partitionReferenceNum);
        }
        if (lvd->integritySeqExt.extLength)
                udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt));
+
        return 0;
 }
 
@@ -1219,9 +1060,7 @@ static void udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc)
                UDF_SB_LVIDBH(sb) = bh;
 
                if (UDF_SB_LVID(sb)->nextIntegrityExt.extLength)
-                       udf_load_logicalvolint(sb,
-                                              leea_to_cpu(UDF_SB_LVID(sb)->
-                                                          nextIntegrityExt));
+                       udf_load_logicalvolint(sb, leea_to_cpu(UDF_SB_LVID(sb)->nextIntegrityExt));
 
                if (UDF_SB_LVIDBH(sb) != bh)
                        brelse(bh);
@@ -1247,9 +1086,8 @@ static void udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc)
  *     July 1, 1997 - Andrew E. Mileski
  *     Written, tested, and released.
  */
-static int
-udf_process_sequence(struct super_block *sb, long block, long lastblock,
-                    kernel_lb_addr * fileset)
+static int udf_process_sequence(struct super_block *sb, long block, long lastblock,
+                                kernel_lb_addr *fileset)
 {
        struct buffer_head *bh = NULL;
        struct udf_vds_record vds[VDS_POS_LENGTH];
@@ -1274,82 +1112,71 @@ udf_process_sequence(struct super_block *sb, long block, long lastblock,
                gd = (struct generic_desc *)bh->b_data;
                vdsn = le32_to_cpu(gd->volDescSeqNum);
                switch (ident) {
-               case TAG_IDENT_PVD:     /* ISO 13346 3/10.1 */
+               case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */
                        if (vdsn >= vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum) {
-                               vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum =
-                                   vdsn;
+                               vds[VDS_POS_PRIMARY_VOL_DESC].volDescSeqNum = vdsn;
                                vds[VDS_POS_PRIMARY_VOL_DESC].block = block;
                        }
                        break;
-               case TAG_IDENT_VDP:     /* ISO 13346 3/10.3 */
+               case TAG_IDENT_VDP: /* ISO 13346 3/10.3 */
                        if (vdsn >= vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum) {
                                vds[VDS_POS_VOL_DESC_PTR].volDescSeqNum = vdsn;
                                vds[VDS_POS_VOL_DESC_PTR].block = block;
 
                                vdp = (struct volDescPtr *)bh->b_data;
-                               next_s =
-                                   le32_to_cpu(vdp->nextVolDescSeqExt.
-                                               extLocation);
-                               next_e =
-                                   le32_to_cpu(vdp->nextVolDescSeqExt.
-                                               extLength);
+                               next_s = le32_to_cpu(vdp->nextVolDescSeqExt.extLocation);
+                               next_e = le32_to_cpu(vdp->nextVolDescSeqExt.extLength);
                                next_e = next_e >> sb->s_blocksize_bits;
                                next_e += next_s;
                        }
                        break;
-               case TAG_IDENT_IUVD:    /* ISO 13346 3/10.4 */
+               case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */
                        if (vdsn >= vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum) {
-                               vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum =
-                                   vdsn;
+                               vds[VDS_POS_IMP_USE_VOL_DESC].volDescSeqNum = vdsn;
                                vds[VDS_POS_IMP_USE_VOL_DESC].block = block;
                        }
                        break;
-               case TAG_IDENT_PD:      /* ISO 13346 3/10.5 */
+               case TAG_IDENT_PD: /* ISO 13346 3/10.5 */
                        if (!vds[VDS_POS_PARTITION_DESC].block)
                                vds[VDS_POS_PARTITION_DESC].block = block;
                        break;
-               case TAG_IDENT_LVD:     /* ISO 13346 3/10.6 */
+               case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */
                        if (vdsn >= vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum) {
-                               vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum =
-                                   vdsn;
+                               vds[VDS_POS_LOGICAL_VOL_DESC].volDescSeqNum = vdsn;
                                vds[VDS_POS_LOGICAL_VOL_DESC].block = block;
                        }
                        break;
-               case TAG_IDENT_USD:     /* ISO 13346 3/10.8 */
-                       if (vdsn >=
-                           vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum) {
-                               vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum =
-                                   vdsn;
+               case TAG_IDENT_USD: /* ISO 13346 3/10.8 */
+                       if (vdsn >= vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum) {
+                               vds[VDS_POS_UNALLOC_SPACE_DESC].volDescSeqNum = vdsn;
                                vds[VDS_POS_UNALLOC_SPACE_DESC].block = block;
                        }
                        break;
-               case TAG_IDENT_TD:      /* ISO 13346 3/10.9 */
+               case TAG_IDENT_TD: /* ISO 13346 3/10.9 */
                        vds[VDS_POS_TERMINATING_DESC].block = block;
                        if (next_e) {
                                block = next_s;
                                lastblock = next_e;
                                next_s = next_e = 0;
-                       } else
+                       } else {
                                done = 1;
+                       }
                        break;
                }
                brelse(bh);
        }
        for (i = 0; i < VDS_POS_LENGTH; i++) {
                if (vds[i].block) {
-                       bh = udf_read_tagged(sb, vds[i].block, vds[i].block,
-                                            &ident);
+                       bh = udf_read_tagged(sb, vds[i].block, vds[i].block, &ident);
 
-                       if (i == VDS_POS_PRIMARY_VOL_DESC)
+                       if (i == VDS_POS_PRIMARY_VOL_DESC) {
                                udf_load_pvoldesc(sb, bh);
-                       else if (i == VDS_POS_LOGICAL_VOL_DESC)
+                       } else if (i == VDS_POS_LOGICAL_VOL_DESC) {
                                udf_load_logicalvol(sb, bh, fileset);
-                       else if (i == VDS_POS_PARTITION_DESC) {
+                       else if (i == VDS_POS_PARTITION_DESC) {
                                struct buffer_head *bh2 = NULL;
                                udf_load_partdesc(sb, bh);
-                               for (j = vds[i].block + 1;
-                                    j < vds[VDS_POS_TERMINATING_DESC].block;
-                                    j++) {
+                               for (j = vds[i].block + 1; j <  vds[VDS_POS_TERMINATING_DESC].block; j++) {
                                        bh2 = udf_read_tagged(sb, j, j, &ident);
                                        gd = (struct generic_desc *)bh2->b_data;
                                        if (ident == TAG_IDENT_PD)
@@ -1378,16 +1205,17 @@ static int udf_check_valid(struct super_block *sb, int novrs, int silent)
        /* Check that it is NSR02 compliant */
        /* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */
        else if ((block = udf_vrs(sb, silent)) == -1) {
-               udf_debug
-                   ("Failed to read byte 32768. Assuming open disc. Skipping validity check\n");
+               udf_debug("Failed to read byte 32768. Assuming open disc. "
+                         "Skipping validity check\n");
                if (!UDF_SB_LASTBLOCK(sb))
                        UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
                return 0;
-       } else
+       } else {
                return !block;
+       }
 }
 
-static int udf_load_partition(struct super_block *sb, kernel_lb_addr * fileset)
+static int udf_load_partition(struct super_block *sb, kernel_lb_addr *fileset)
 {
        struct anchorVolDescPtr *anchor;
        uint16_t ident;
@@ -1399,28 +1227,20 @@ static int udf_load_partition(struct super_block *sb, kernel_lb_addr * fileset)
                return 1;
 
        for (i = 0; i < ARRAY_SIZE(UDF_SB_ANCHOR(sb)); i++) {
-               if (UDF_SB_ANCHOR(sb)[i] && (bh = udf_read_tagged(sb,
-                                                                 UDF_SB_ANCHOR
-                                                                 (sb)[i],
-                                                                 UDF_SB_ANCHOR
-                                                                 (sb)[i],
-                                                                 &ident))) {
+               if (UDF_SB_ANCHOR(sb)[i] &&
+                   (bh = udf_read_tagged(sb, UDF_SB_ANCHOR(sb)[i],
+                                         UDF_SB_ANCHOR(sb)[i], &ident))) {
                        anchor = (struct anchorVolDescPtr *)bh->b_data;
 
                        /* Locate the main sequence */
-                       main_s =
-                           le32_to_cpu(anchor->mainVolDescSeqExt.extLocation);
-                       main_e =
-                           le32_to_cpu(anchor->mainVolDescSeqExt.extLength);
+                       main_s = le32_to_cpu(anchor->mainVolDescSeqExt.extLocation);
+                       main_e = le32_to_cpu(anchor->mainVolDescSeqExt.extLength );
                        main_e = main_e >> sb->s_blocksize_bits;
                        main_e += main_s;
 
                        /* Locate the reserve sequence */
-                       reserve_s =
-                           le32_to_cpu(anchor->reserveVolDescSeqExt.
-                                       extLocation);
-                       reserve_e =
-                           le32_to_cpu(anchor->reserveVolDescSeqExt.extLength);
+                       reserve_s = le32_to_cpu(anchor->reserveVolDescSeqExt.extLocation);
+                       reserve_e = le32_to_cpu(anchor->reserveVolDescSeqExt.extLength);
                        reserve_e = reserve_e >> sb->s_blocksize_bits;
                        reserve_e += reserve_s;
 
@@ -1428,10 +1248,8 @@ static int udf_load_partition(struct super_block *sb, kernel_lb_addr * fileset)
 
                        /* Process the main & reserve sequences */
                        /* responsible for finding the PartitionDesc(s) */
-                       if (!
-                           (udf_process_sequence(sb, main_s, main_e, fileset)
-                            && udf_process_sequence(sb, reserve_s, reserve_e,
-                                                    fileset))) {
+                       if (!(udf_process_sequence(sb, main_s, main_e, fileset) &&
+                             udf_process_sequence(sb, reserve_s, reserve_e, fileset))) {
                                break;
                        }
                }
@@ -1444,81 +1262,67 @@ static int udf_load_partition(struct super_block *sb, kernel_lb_addr * fileset)
                udf_debug("Using anchor in block %d\n", UDF_SB_ANCHOR(sb)[i]);
 
        for (i = 0; i < UDF_SB_NUMPARTS(sb); i++) {
+               kernel_lb_addr uninitialized_var(ino);
                switch (UDF_SB_PARTTYPE(sb, i)) {
                case UDF_VIRTUAL_MAP15:
                case UDF_VIRTUAL_MAP20:
-                       {
-                               kernel_lb_addr uninitialized_var(ino);
+                       if (!UDF_SB_LASTBLOCK(sb)) {
+                               UDF_SB_LASTBLOCK(sb) = udf_get_last_block(sb);
+                               udf_find_anchor(sb);
+                       }
 
-                               if (!UDF_SB_LASTBLOCK(sb)) {
-                                       UDF_SB_LASTBLOCK(sb) =
-                                           udf_get_last_block(sb);
-                                       udf_find_anchor(sb);
-                               }
+                       if (!UDF_SB_LASTBLOCK(sb)) {
+                               udf_debug("Unable to determine Lastblock (For "
+                                               "Virtual Partition)\n");
+                               return 1;
+                       }
 
-                               if (!UDF_SB_LASTBLOCK(sb)) {
-                                       udf_debug
-                                           ("Unable to determine Lastblock (For Virtual Partition)\n");
-                                       return 1;
+                       for (j = 0; j < UDF_SB_NUMPARTS(sb); j++) {
+                               if (j != i && UDF_SB_PARTVSN(sb, i) ==
+                                       UDF_SB_PARTVSN(sb, j) &&
+                                       UDF_SB_PARTNUM(sb, i) ==
+                                               UDF_SB_PARTNUM(sb, j)) {
+                                       ino.partitionReferenceNum = j;
+                                       ino.logicalBlockNum =
+                                           UDF_SB_LASTBLOCK(sb) -
+                                           UDF_SB_PARTROOT(sb, j);
+                                       break;
                                }
+                       }
 
-                               for (j = 0; j < UDF_SB_NUMPARTS(sb); j++) {
-                                       if (j != i &&
-                                           UDF_SB_PARTVSN(sb,
-                                                          i) ==
-                                           UDF_SB_PARTVSN(sb, j)
-                                           && UDF_SB_PARTNUM(sb,
-                                                             i) ==
-                                           UDF_SB_PARTNUM(sb, j)) {
-                                               ino.partitionReferenceNum = j;
-                                               ino.logicalBlockNum =
-                                                   UDF_SB_LASTBLOCK(sb) -
-                                                   UDF_SB_PARTROOT(sb, j);
-                                               break;
-                                       }
-                               }
+                       if (j == UDF_SB_NUMPARTS(sb))
+                               return 1;
 
-                               if (j == UDF_SB_NUMPARTS(sb))
-                                       return 1;
+                       if (!(UDF_SB_VAT(sb) = udf_iget(sb, ino)))
+                               return 1;
 
-                               if (!(UDF_SB_VAT(sb) = udf_iget(sb, ino)))
-                                       return 1;
+                       if (UDF_SB_PARTTYPE(sb, i) == UDF_VIRTUAL_MAP15) {
+                               UDF_SB_TYPEVIRT(sb, i).s_start_offset =
+                                   udf_ext0_offset(UDF_SB_VAT(sb));
+                               UDF_SB_TYPEVIRT(sb, i).s_num_entries =
+                                   (UDF_SB_VAT(sb)->i_size - 36) >> 2;
+                       } else if (UDF_SB_PARTTYPE(sb, i) == UDF_VIRTUAL_MAP20) {
+                               struct buffer_head *bh = NULL;
+                               uint32_t pos;
 
-                               if (UDF_SB_PARTTYPE(sb, i) == UDF_VIRTUAL_MAP15) {
-                                       UDF_SB_TYPEVIRT(sb, i).s_start_offset =
-                                           udf_ext0_offset(UDF_SB_VAT(sb));
-                                       UDF_SB_TYPEVIRT(sb, i).s_num_entries =
-                                           (UDF_SB_VAT(sb)->i_size - 36) >> 2;
-                               } else if (UDF_SB_PARTTYPE(sb, i) ==
-                                          UDF_VIRTUAL_MAP20) {
-                                       struct buffer_head *bh = NULL;
-                                       uint32_t pos;
-
-                                       pos = udf_block_map(UDF_SB_VAT(sb), 0);
-                                       bh = sb_bread(sb, pos);
-                                       if (!bh)
-                                               return 1;
-                                       UDF_SB_TYPEVIRT(sb, i).s_start_offset =
-                                           le16_to_cpu(((struct
-                                                         virtualAllocationTable20
-                                                         *)bh->b_data +
-                                                        udf_ext0_offset
-                                                        (UDF_SB_VAT(sb)))->
-                                                       lengthHeader) +
-                                           udf_ext0_offset(UDF_SB_VAT(sb));
-                                       UDF_SB_TYPEVIRT(sb, i).s_num_entries =
-                                           (UDF_SB_VAT(sb)->i_size -
-                                            UDF_SB_TYPEVIRT(sb,
-                                                            i).
-                                            s_start_offset) >> 2;
-                                       brelse(bh);
-                               }
-                               UDF_SB_PARTROOT(sb, i) =
-                                   udf_get_pblock(sb, 0, i, 0);
-                               UDF_SB_PARTLEN(sb, i) =
-                                   UDF_SB_PARTLEN(sb,
-                                                  ino.partitionReferenceNum);
+                               pos = udf_block_map(UDF_SB_VAT(sb), 0);
+                               bh = sb_bread(sb, pos);
+                               if (!bh)
+                                       return 1;
+                               UDF_SB_TYPEVIRT(sb, i).s_start_offset =
+                                   le16_to_cpu(((struct
+                                       virtualAllocationTable20 *)bh->b_data +
+                                         udf_ext0_offset(UDF_SB_VAT(sb)))->
+                                               lengthHeader) +
+                                         udf_ext0_offset(UDF_SB_VAT(sb));
+                               UDF_SB_TYPEVIRT(sb, i).s_num_entries =
+                                   (UDF_SB_VAT(sb)->i_size -
+                                    UDF_SB_TYPEVIRT(sb, i).s_start_offset) >> 2;
+                               brelse(bh);
                        }
+                       UDF_SB_PARTROOT(sb, i) = udf_get_pblock(sb, 0, i, 0);
+                       UDF_SB_PARTLEN(sb, i) = UDF_SB_PARTLEN(sb,
+                                               ino.partitionReferenceNum);
                }
        }
        return 0;
@@ -1555,42 +1359,32 @@ static void udf_open_lvid(struct super_block *sb)
 
 static void udf_close_lvid(struct super_block *sb)
 {
+       kernel_timestamp cpu_time;
+       int i;
+
        if (UDF_SB_LVIDBH(sb) &&
            UDF_SB_LVID(sb)->integrityType == LVID_INTEGRITY_TYPE_OPEN) {
-               int i;
-               kernel_timestamp cpu_time;
-
                UDF_SB_LVIDIU(sb)->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
                UDF_SB_LVIDIU(sb)->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
                if (udf_time_to_stamp(&cpu_time, CURRENT_TIME))
-                       UDF_SB_LVID(sb)->recordingDateAndTime =
-                           cpu_to_lets(cpu_time);
-               if (UDF_MAX_WRITE_VERSION >
-                   le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev))
-                       UDF_SB_LVIDIU(sb)->maxUDFWriteRev =
-                           cpu_to_le16(UDF_MAX_WRITE_VERSION);
-               if (UDF_SB_UDFREV(sb) >
-                   le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev))
-                       UDF_SB_LVIDIU(sb)->minUDFReadRev =
-                           cpu_to_le16(UDF_SB_UDFREV(sb));
-               if (UDF_SB_UDFREV(sb) >
-                   le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev))
-                       UDF_SB_LVIDIU(sb)->minUDFWriteRev =
-                           cpu_to_le16(UDF_SB_UDFREV(sb));
-               UDF_SB_LVID(sb)->integrityType =
-                   cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE);
+                       UDF_SB_LVID(sb)->recordingDateAndTime = cpu_to_lets(cpu_time);
+               if (UDF_MAX_WRITE_VERSION > le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev))
+                       UDF_SB_LVIDIU(sb)->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION);
+               if (UDF_SB_UDFREV(sb) > le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev))
+                       UDF_SB_LVIDIU(sb)->minUDFReadRev = cpu_to_le16(UDF_SB_UDFREV(sb));
+               if (UDF_SB_UDFREV(sb) > le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev))
+                       UDF_SB_LVIDIU(sb)->minUDFWriteRev = cpu_to_le16(UDF_SB_UDFREV(sb));
+               UDF_SB_LVID(sb)->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE);
 
                UDF_SB_LVID(sb)->descTag.descCRC =
-                   cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
-                                       le16_to_cpu(UDF_SB_LVID(sb)->descTag.
-                                                   descCRCLength), 0));
+                       cpu_to_le16(udf_crc((char *)UDF_SB_LVID(sb) + sizeof(tag),
+                                           le16_to_cpu(UDF_SB_LVID(sb)->descTag.descCRCLength), 0));
 
                UDF_SB_LVID(sb)->descTag.tagChecksum = 0;
                for (i = 0; i < 16; i++)
                        if (i != 4)
                                UDF_SB_LVID(sb)->descTag.tagChecksum +=
-                                   ((uint8_t *) &
-                                    (UDF_SB_LVID(sb)->descTag))[i];
+                                       ((uint8_t *)&(UDF_SB_LVID(sb)->descTag))[i];
 
                mark_buffer_dirty(UDF_SB_LVIDBH(sb));
        }
@@ -1628,6 +1422,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
        sbi = kmalloc(sizeof(struct udf_sb_info), GFP_KERNEL);
        if (!sbi)
                return -ENOMEM;
+
        sb->s_fs_info = sbi;
        memset(UDF_SB(sb), 0x00, sizeof(struct udf_sb_info));
 
@@ -1679,7 +1474,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
        UDF_SB_ANCHOR(sb)[2] = uopt.anchor;
        UDF_SB_ANCHOR(sb)[3] = 256;
 
-       if (udf_check_valid(sb, uopt.novrs, silent)) {  /* read volume recognition sequences */
+       if (udf_check_valid(sb, uopt.novrs, silent)) { /* read volume recognition sequences */
                printk("UDF-fs: No VRS found\n");
                goto error_out;
        }
@@ -1701,10 +1496,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
        udf_debug("Lastblock=%d\n", UDF_SB_LASTBLOCK(sb));
 
        if (UDF_SB_LVIDBH(sb)) {
-               uint16_t minUDFReadRev =
-                   le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev);
-               uint16_t minUDFWriteRev =
-                   le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev);
+               uint16_t minUDFReadRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFReadRev);
+               uint16_t minUDFWriteRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->minUDFWriteRev);
                /* uint16_t maxUDFWriteRev = le16_to_cpu(UDF_SB_LVIDIU(sb)->maxUDFWriteRev); */
 
                if (minUDFReadRev > UDF_MAX_READ_VERSION) {
@@ -1729,10 +1522,8 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
                goto error_out;
        }
 
-       if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
-           UDF_PART_FLAG_READ_ONLY) {
-               printk
-                   ("UDF-fs: Partition marked readonly; forcing readonly mount\n");
+       if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_READ_ONLY) {
+               printk("UDF-fs: Partition marked readonly; forcing readonly mount\n");
                sb->s_flags |= MS_RDONLY;
        }
 
@@ -1744,10 +1535,11 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
        if (!silent) {
                kernel_timestamp ts;
                udf_time_to_stamp(&ts, UDF_SB_RECORDTIME(sb));
-               udf_info
-                   ("UDF %s (%s) Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
-                    UDFFS_VERSION, UDFFS_DATE, UDF_SB_VOLIDENT(sb), ts.year,
-                    ts.month, ts.day, ts.hour, ts.minute, ts.typeAndTimezone);
+               udf_info("UDF %s (%s) Mounting volume '%s', "
+                        "timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
+                        UDFFS_VERSION, UDFFS_DATE,
+                        UDF_SB_VOLIDENT(sb), ts.year, ts.month, ts.day, ts.hour, ts.minute,
+                        ts.typeAndTimezone);
        }
        if (!(sb->s_flags & MS_RDONLY))
                udf_open_lvid(sb);
@@ -1772,30 +1564,21 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
        sb->s_maxbytes = MAX_LFS_FILESIZE;
        return 0;
 
-      error_out:
+error_out:
        if (UDF_SB_VAT(sb))
                iput(UDF_SB_VAT(sb));
        if (UDF_SB_NUMPARTS(sb)) {
-               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
-                   UDF_PART_FLAG_UNALLOC_TABLE)
-                       iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.
-                            s_table);
-               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
-                   UDF_PART_FLAG_FREED_TABLE)
-                       iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.
-                            s_table);
-               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
-                   UDF_PART_FLAG_UNALLOC_BITMAP)
-                       UDF_SB_FREE_BITMAP(sb, UDF_SB_PARTITION(sb), s_uspace);
-               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
-                   UDF_PART_FLAG_FREED_BITMAP)
-                       UDF_SB_FREE_BITMAP(sb, UDF_SB_PARTITION(sb), s_fspace);
-               if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) ==
-                   UDF_SPARABLE_MAP15) {
+               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE)
+                       iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
+               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE)
+                       iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
+               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
+                       UDF_SB_FREE_BITMAP(sb,UDF_SB_PARTITION(sb), s_uspace);
+               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
+                       UDF_SB_FREE_BITMAP(sb,UDF_SB_PARTITION(sb), s_fspace);
+               if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15) {
                        for (i = 0; i < 4; i++)
-                               brelse(UDF_SB_TYPESPAR
-                                      (sb,
-                                       UDF_SB_PARTITION(sb)).s_spar_map[i]);
+                               brelse(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
                }
        }
 #ifdef CONFIG_UDF_NLS
@@ -1808,6 +1591,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
        UDF_SB_FREE(sb);
        kfree(sbi);
        sb->s_fs_info = NULL;
+
        return -EINVAL;
 }
 
@@ -1823,8 +1607,8 @@ void udf_error(struct super_block *sb, const char *function,
        va_start(args, fmt);
        vsnprintf(error_buf, sizeof(error_buf), fmt, args);
        va_end(args);
-       printk(KERN_CRIT "UDF-fs error (device %s): %s: %s\n",
-              sb->s_id, function, error_buf);
+       printk (KERN_CRIT "UDF-fs error (device %s): %s: %s\n",
+               sb->s_id, function, error_buf);
 }
 
 void udf_warning(struct super_block *sb, const char *function,
@@ -1859,26 +1643,17 @@ static void udf_put_super(struct super_block *sb)
        if (UDF_SB_VAT(sb))
                iput(UDF_SB_VAT(sb));
        if (UDF_SB_NUMPARTS(sb)) {
-               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
-                   UDF_PART_FLAG_UNALLOC_TABLE)
-                       iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.
-                            s_table);
-               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
-                   UDF_PART_FLAG_FREED_TABLE)
-                       iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.
-                            s_table);
-               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
-                   UDF_PART_FLAG_UNALLOC_BITMAP)
-                       UDF_SB_FREE_BITMAP(sb, UDF_SB_PARTITION(sb), s_uspace);
-               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
-                   UDF_PART_FLAG_FREED_BITMAP)
-                       UDF_SB_FREE_BITMAP(sb, UDF_SB_PARTITION(sb), s_fspace);
-               if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) ==
-                   UDF_SPARABLE_MAP15) {
+               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE)
+                       iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
+               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE)
+                       iput(UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
+               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP)
+                       UDF_SB_FREE_BITMAP(sb,UDF_SB_PARTITION(sb), s_uspace);
+               if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP)
+                       UDF_SB_FREE_BITMAP(sb,UDF_SB_PARTITION(sb), s_fspace);
+               if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15) {
                        for (i = 0; i < 4; i++)
-                               brelse(UDF_SB_TYPESPAR
-                                      (sb,
-                                       UDF_SB_PARTITION(sb)).s_spar_map[i]);
+                               brelse(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
                }
        }
 #ifdef CONFIG_UDF_NLS
@@ -1917,8 +1692,7 @@ static int udf_statfs(struct dentry *dentry, struct kstatfs *buf)
        buf->f_bavail = buf->f_bfree;
        buf->f_files = (UDF_SB_LVIDBH(sb) ?
                        (le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) +
-                        le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs)) : 0) +
-           buf->f_bfree;
+                        le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs)) : 0) + buf->f_bfree;
        buf->f_ffree = buf->f_bfree;
        /* __kernel_fsid_t f_fsid */
        buf->f_namelen = UDF_NAME_LEN - 2;
@@ -1930,8 +1704,7 @@ static unsigned char udf_bitmap_lookup[16] = {
        0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
 };
 
-static unsigned int
-udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
+static unsigned int udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
 {
        struct buffer_head *bh = NULL;
        unsigned int accum = 0;
@@ -1961,8 +1734,8 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
 
        bm = (struct spaceBitmapDesc *)bh->b_data;
        bytes = le32_to_cpu(bm->numOfBytes);
-       index = sizeof(struct spaceBitmapDesc); /* offset in first block only */
-       ptr = (uint8_t *) bh->b_data;
+       index = sizeof(struct spaceBitmapDesc); /* offset in first block only */
+       ptr = (uint8_t *)bh->b_data;
 
        while (bytes > 0) {
                while ((bytes > 0) && (index < sb->s_blocksize)) {
@@ -1981,19 +1754,18 @@ udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap)
                                goto out;
                        }
                        index = 0;
-                       ptr = (uint8_t *) bh->b_data;
+                       ptr = (uint8_t *)bh->b_data;
                }
        }
        brelse(bh);
 
-      out:
+out:
        unlock_kernel();
 
        return accum;
 }
 
-static unsigned int
-udf_count_free_table(struct super_block *sb, struct inode *table)
+static unsigned int udf_count_free_table(struct super_block *sb, struct inode *table)
 {
        unsigned int accum = 0;
        uint32_t elen;
@@ -2007,8 +1779,9 @@ udf_count_free_table(struct super_block *sb, struct inode *table)
        epos.offset = sizeof(struct unallocSpaceEntry);
        epos.bh = NULL;
 
-       while ((etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1)
+       while ((etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) {
                accum += (elen >> table->i_sb->s_blocksize_bits);
+       }
        brelse(epos.bh);
 
        unlock_kernel();
@@ -2021,12 +1794,8 @@ static unsigned int udf_count_free(struct super_block *sb)
        unsigned int accum = 0;
 
        if (UDF_SB_LVIDBH(sb)) {
-               if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) >
-                   UDF_SB_PARTITION(sb)) {
-                       accum =
-                           le32_to_cpu(UDF_SB_LVID(sb)->
-                                       freeSpaceTable[UDF_SB_PARTITION(sb)]);
-
+               if (le32_to_cpu(UDF_SB_LVID(sb)->numOfPartitions) > UDF_SB_PARTITION(sb)) {
+                       accum = le32_to_cpu(UDF_SB_LVID(sb)->freeSpaceTable[UDF_SB_PARTITION(sb)]);
                        if (accum == 0xFFFFFFFF)
                                accum = 0;
                }
@@ -2035,40 +1804,24 @@ static unsigned int udf_count_free(struct super_block *sb)
        if (accum)
                return accum;
 
-       if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
-           UDF_PART_FLAG_UNALLOC_BITMAP) {
-               accum +=
-                   udf_count_free_bitmap(sb,
-                                         UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION
-                                                             (sb)].s_uspace.
-                                         s_bitmap);
+       if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_BITMAP) {
+               accum += udf_count_free_bitmap(sb,
+                                              UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_bitmap);
        }
-       if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
-           UDF_PART_FLAG_FREED_BITMAP) {
-               accum +=
-                   udf_count_free_bitmap(sb,
-                                         UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION
-                                                             (sb)].s_fspace.
-                                         s_bitmap);
+       if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_BITMAP) {
+               accum += udf_count_free_bitmap(sb,
+                                              UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_bitmap);
        }
        if (accum)
                return accum;
 
-       if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
-           UDF_PART_FLAG_UNALLOC_TABLE) {
-               accum +=
-                   udf_count_free_table(sb,
-                                        UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION
-                                                            (sb)].s_uspace.
-                                        s_table);
+       if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_UNALLOC_TABLE) {
+               accum += udf_count_free_table(sb,
+                                             UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_uspace.s_table);
        }
-       if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) &
-           UDF_PART_FLAG_FREED_TABLE) {
-               accum +=
-                   udf_count_free_table(sb,
-                                        UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION
-                                                            (sb)].s_fspace.
-                                        s_table);
+       if (UDF_SB_PARTFLAGS(sb,UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_FREED_TABLE) {
+               accum += udf_count_free_table(sb,
+                                             UDF_SB_PARTMAPS(sb)[UDF_SB_PARTITION(sb)].s_fspace.s_table);
        }
 
        return accum;
index c4b82a920082655964012b897c71bc61828cf9e4..e6f933dd6a7b9929440a781903ea11a4192698f8 100644 (file)
@@ -11,7 +11,7 @@
  *     Each contributing author retains all rights to their own work.
  *
  *  (C) 1998-2001 Ben Fennema
- *  (C) 1999 Stelias Computing Inc 
+ *  (C) 1999 Stelias Computing Inc
  *
  * HISTORY
  *
@@ -33,8 +33,7 @@
 #include <linux/buffer_head.h>
 #include "udf_i.h"
 
-static void udf_pc_to_char(struct super_block *sb, char *from, int fromlen,
-                          char *to)
+static void udf_pc_to_char(struct super_block *sb, char *from, int fromlen, char *to)
 {
        struct pathComponent *pc;
        int elen = 0;
@@ -81,9 +80,9 @@ static int udf_symlink_filler(struct file *file, struct page *page)
        char *p = kmap(page);
 
        lock_kernel();
-       if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
+       if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) {
                symlink = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
-       else {
+       else {
                bh = sb_bread(inode->i_sb, udf_block_map(inode, 0));
 
                if (!bh)
@@ -100,7 +99,8 @@ static int udf_symlink_filler(struct file *file, struct page *page)
        kunmap(page);
        unlock_page(page);
        return 0;
-      out:
+
+out:
        unlock_kernel();
        SetPageError(page);
        kunmap(page);
@@ -112,5 +112,5 @@ static int udf_symlink_filler(struct file *file, struct page *page)
  * symlinks can't do much...
  */
 const struct address_space_operations udf_symlink_aops = {
-       .readpage = udf_symlink_filler,
+       .readpage               = udf_symlink_filler,
 };
index b2002da0a5c0ee4dc521e01d664e8a2efdc41e3d..7fc3912885a565bddbdadd8a9ade8057bd82b3ac 100644 (file)
@@ -32,13 +32,11 @@ static void extent_trunc(struct inode *inode, struct extent_position *epos,
                         kernel_lb_addr eloc, int8_t etype, uint32_t elen,
                         uint32_t nelen)
 {
-       kernel_lb_addr neloc = { 0, 0 };
-       int last_block =
-           (elen + inode->i_sb->s_blocksize -
-            1) >> inode->i_sb->s_blocksize_bits;
-       int first_block =
-           (nelen + inode->i_sb->s_blocksize -
-            1) >> inode->i_sb->s_blocksize_bits;
+       kernel_lb_addr neloc = {};
+       int last_block = (elen + inode->i_sb->s_blocksize - 1) >>
+               inode->i_sb->s_blocksize_bits;
+       int first_block = (nelen + inode->i_sb->s_blocksize - 1) >>
+               inode->i_sb->s_blocksize_bits;
 
        if (nelen) {
                if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
@@ -70,7 +68,7 @@ static void extent_trunc(struct inode *inode, struct extent_position *epos,
  */
 void udf_truncate_tail_extent(struct inode *inode)
 {
-       struct extent_position epos = { NULL, 0, {0, 0} };
+       struct extent_position epos = {};
        kernel_lb_addr eloc;
        uint32_t elen, nelen;
        uint64_t lbcount = 0;
@@ -156,16 +154,16 @@ void udf_discard_prealloc(struct inode *inode)
                extent_trunc(inode, &epos, eloc, etype, elen, 0);
                if (!epos.bh) {
                        UDF_I_LENALLOC(inode) =
-                           epos.offset - udf_file_entry_alloc_offset(inode);
+                               epos.offset - udf_file_entry_alloc_offset(inode);
                        mark_inode_dirty(inode);
                } else {
                        struct allocExtDesc *aed =
-                           (struct allocExtDesc *)(epos.bh->b_data);
+                               (struct allocExtDesc *)(epos.bh->b_data);
                        aed->lengthAllocDescs =
-                           cpu_to_le32(epos.offset -
-                                       sizeof(struct allocExtDesc));
-                       if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)
-                           || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
+                               cpu_to_le32(epos.offset -
+                                           sizeof(struct allocExtDesc));
+                       if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
+                           UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
                                udf_update_tag(epos.bh->b_data, epos.offset);
                        else
                                udf_update_tag(epos.bh->b_data,
@@ -182,7 +180,7 @@ void udf_discard_prealloc(struct inode *inode)
 void udf_truncate_extents(struct inode *inode)
 {
        struct extent_position epos;
-       kernel_lb_addr eloc, neloc = { 0, 0 };
+       kernel_lb_addr eloc, neloc = {};
        uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc;
        int8_t etype;
        struct super_block *sb = inode->i_sb;
@@ -198,9 +196,8 @@ void udf_truncate_extents(struct inode *inode)
                BUG();
 
        etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset);
-       byte_offset =
-           (offset << sb->s_blocksize_bits) +
-           (inode->i_size & (sb->s_blocksize - 1));
+       byte_offset = (offset << sb->s_blocksize_bits) +
+               (inode->i_size & (sb->s_blocksize - 1));
        if (etype != -1) {
                epos.offset -= adsize;
                extent_trunc(inode, &epos, eloc, etype, elen, byte_offset);
@@ -215,9 +212,7 @@ void udf_truncate_extents(struct inode *inode)
                else
                        lenalloc -= sizeof(struct allocExtDesc);
 
-               while ((etype =
-                       udf_current_aext(inode, &epos, &eloc, &elen,
-                                        0)) != -1) {
+               while ((etype = udf_current_aext(inode, &epos, &eloc, &elen, 0)) != -1) {
                        if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) {
                                udf_write_aext(inode, &epos, neloc, nelen, 0);
                                if (indirect_ext_len) {
@@ -229,52 +224,35 @@ void udf_truncate_extents(struct inode *inode)
                                                        0, indirect_ext_len);
                                } else {
                                        if (!epos.bh) {
-                                               UDF_I_LENALLOC(inode) =
-                                                   lenalloc;
+                                               UDF_I_LENALLOC(inode) = lenalloc;
                                                mark_inode_dirty(inode);
                                        } else {
                                                struct allocExtDesc *aed =
-                                                   (struct allocExtDesc
-                                                    *)(epos.bh->b_data);
+                                                       (struct allocExtDesc *)(epos.bh->b_data);
                                                aed->lengthAllocDescs =
                                                    cpu_to_le32(lenalloc);
-                                               if (!UDF_QUERY_FLAG
-                                                   (sb, UDF_FLAG_STRICT)
-                                                   || UDF_SB_UDFREV(sb) >=
-                                                   0x0201)
-                                                       udf_update_tag(epos.bh->
-                                                                      b_data,
-                                                                      lenalloc
-                                                                      +
-                                                                      sizeof
-                                                                      (struct
-                                                                       allocExtDesc));
+                                               if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) ||
+                                                   UDF_SB_UDFREV(sb) >= 0x0201)
+                                                       udf_update_tag(epos.bh->b_data,
+                                                                      lenalloc +
+                                                                      sizeof(struct allocExtDesc));
                                                else
-                                                       udf_update_tag(epos.bh->
-                                                                      b_data,
-                                                                      sizeof
-                                                                      (struct
-                                                                       allocExtDesc));
-                                               mark_buffer_dirty_inode(epos.bh,
-                                                                       inode);
+                                                       udf_update_tag(epos.bh->b_data,
+                                                                      sizeof(struct allocExtDesc));
+                                               mark_buffer_dirty_inode(epos.bh, inode);
                                        }
                                }
                                brelse(epos.bh);
                                epos.offset = sizeof(struct allocExtDesc);
                                epos.block = eloc;
-                               epos.bh =
-                                   udf_tread(sb,
-                                             udf_get_lb_pblock(sb, eloc, 0));
+                               epos.bh = udf_tread(sb, udf_get_lb_pblock(sb, eloc, 0));
                                if (elen)
-                                       indirect_ext_len = (elen +
-                                                           sb->s_blocksize -
-                                                           1) >> sb->
-                                           s_blocksize_bits;
+                                       indirect_ext_len = (elen + sb->s_blocksize -1) >>
+                                               sb->s_blocksize_bits;
                                else
                                        indirect_ext_len = 1;
                        } else {
-                               extent_trunc(inode, &epos, eloc, etype, elen,
-                                            0);
+                               extent_trunc(inode, &epos, eloc, etype, elen, 0);
                                epos.offset += adsize;
                        }
                }
@@ -292,16 +270,13 @@ void udf_truncate_extents(struct inode *inode)
                                struct allocExtDesc *aed =
                                    (struct allocExtDesc *)(epos.bh->b_data);
                                aed->lengthAllocDescs = cpu_to_le32(lenalloc);
-                               if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT)
-                                   || UDF_SB_UDFREV(sb) >= 0x0201)
+                               if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT) ||
+                                   UDF_SB_UDFREV(sb) >= 0x0201)
                                        udf_update_tag(epos.bh->b_data,
-                                                      lenalloc +
-                                                      sizeof(struct
-                                                             allocExtDesc));
+                                                      lenalloc + sizeof(struct allocExtDesc));
                                else
                                        udf_update_tag(epos.bh->b_data,
-                                                      sizeof(struct
-                                                             allocExtDesc));
+                                                      sizeof(struct allocExtDesc));
                                mark_buffer_dirty_inode(epos.bh, inode);
                        }
                }
@@ -314,21 +289,14 @@ void udf_truncate_extents(struct inode *inode)
                         *  no extent above inode->i_size => truncate is
                         *  extending the file by 'offset' blocks.
                         */
-                       if ((!epos.bh
-                            && epos.offset ==
-                            udf_file_entry_alloc_offset(inode)) || (epos.bh
-                                                                    && epos.
-                                                                    offset ==
-                                                                    sizeof
-                                                                    (struct
-                                                                     allocExtDesc)))
-                       {
+                       if ((!epos.bh &&
+                            epos.offset == udf_file_entry_alloc_offset(inode)) ||
+                           (epos.bh && epos.offset == sizeof(struct allocExtDesc))) {
                                /* File has no extents at all or has empty last
                                 * indirect extent! Create a fake extent... */
                                extent.extLocation.logicalBlockNum = 0;
                                extent.extLocation.partitionReferenceNum = 0;
-                               extent.extLength =
-                                   EXT_NOT_RECORDED_NOT_ALLOCATED;
+                               extent.extLength = EXT_NOT_RECORDED_NOT_ALLOCATED;
                        } else {
                                epos.offset -= adsize;
                                etype = udf_next_aext(inode, &epos,
@@ -337,10 +305,7 @@ void udf_truncate_extents(struct inode *inode)
                                extent.extLength |= etype << 30;
                        }
                        udf_extend_file(inode, &epos, &extent,
-                                       offset +
-                                       ((inode->
-                                         i_size & (sb->s_blocksize - 1)) !=
-                                        0));
+                                       offset + ((inode->i_size & (sb->s_blocksize - 1)) != 0));
                }
        }
        UDF_I_LENEXTENTS(inode) = inode->i_size;
index bee4308a8113880a3f3e75196122dd14cac4a593..d7dbe6f3ba0ca8b0b5944c338501ec1b280bcace 100644 (file)
@@ -23,4 +23,4 @@ static inline struct udf_inode_info *UDF_I(struct inode *inode)
 #define UDF_I_LAD(X)           ( UDF_I(X)->i_ext.i_lad )
 #define UDF_I_DATA(X)          ( UDF_I(X)->i_ext.i_data )
 
-#endif                         /* !defined(_LINUX_UDF_I_H) */
+#endif /* !defined(_LINUX_UDF_I_H) */
index 60f31d8cebee2522ed32acd4131eeabe73177d80..3e937d3fb8f99b12b24515943eec3b30f81815ad 100644 (file)
@@ -20,8 +20,8 @@
 #define UDF_FLAG_VARCONV               8
 #define UDF_FLAG_NLS_MAP               9
 #define UDF_FLAG_UTF8                  10
-#define UDF_FLAG_UID_FORGET     11     /* save -1 for uid to disk */
-#define UDF_FLAG_UID_IGNORE     12     /* use sb uid instead of on disk uid */
+#define UDF_FLAG_UID_FORGET     11    /* save -1 for uid to disk */
+#define UDF_FLAG_UID_IGNORE     12    /* use sb uid instead of on disk uid */
 #define UDF_FLAG_GID_FORGET     13
 #define UDF_FLAG_GID_IGNORE     14
 
@@ -41,8 +41,7 @@ static inline struct udf_sb_info *UDF_SB(struct super_block *sb)
 
 #define UDF_SB_FREE(X)\
 {\
-       if (UDF_SB(X))\
-       {\
+       if (UDF_SB(X)) {\
                kfree(UDF_SB_PARTMAPS(X));\
                UDF_SB_PARTMAPS(X) = NULL;\
        }\
@@ -51,13 +50,10 @@ static inline struct udf_sb_info *UDF_SB(struct super_block *sb)
 #define UDF_SB_ALLOC_PARTMAPS(X,Y)\
 {\
        UDF_SB_PARTMAPS(X) = kmalloc(sizeof(struct udf_part_map) * Y, GFP_KERNEL);\
-       if (UDF_SB_PARTMAPS(X) != NULL)\
-       {\
+       if (UDF_SB_PARTMAPS(X) != NULL) {\
                UDF_SB_NUMPARTS(X) = Y;\
                memset(UDF_SB_PARTMAPS(X), 0x00, sizeof(struct udf_part_map) * Y);\
-       }\
-       else\
-       {\
+       } else {\
                UDF_SB_NUMPARTS(X) = 0;\
                udf_error(X, __FUNCTION__, "Unable to allocate space for %d partition maps", Y);\
        }\
@@ -72,15 +68,12 @@ static inline struct udf_sb_info *UDF_SB(struct super_block *sb)
                UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap = kmalloc(size, GFP_KERNEL);\
        else\
                UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap = vmalloc(size);\
-       if (UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap != NULL)\
-       {\
+       if (UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap != NULL) {\
                memset(UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap, 0x00, size);\
                UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap->s_block_bitmap =\
                        (struct buffer_head **)(UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap + 1);\
                UDF_SB_PARTMAPS(X)[(Y)].Z.s_bitmap->s_nr_groups = nr_groups;\
-       }\
-       else\
-       {\
+       } else {\
                udf_error(X, __FUNCTION__, "Unable to allocate space for bitmap and %d buffer_head pointers", nr_groups);\
        }\
 }
@@ -90,8 +83,7 @@ static inline struct udf_sb_info *UDF_SB(struct super_block *sb)
        int i;\
        int nr_groups = UDF_SB_BITMAP_NR_GROUPS(X,Y,Z);\
        int size = sizeof(struct udf_bitmap) + (sizeof(struct buffer_head *) * nr_groups);\
-       for (i=0; i<nr_groups; i++)\
-       {\
+       for (i = 0; i < nr_groups; i++) {\
                if (UDF_SB_BITMAP(X,Y,Z,i))\
                        brelse(UDF_SB_BITMAP(X,Y,Z,i));\
        }\
@@ -139,4 +131,4 @@ static inline struct udf_sb_info *UDF_SB(struct super_block *sb)
 #define UDF_SB_FLAGS(X)                                ( UDF_SB(X)->s_flags )
 #define UDF_SB_VAT(X)                          ( UDF_SB(X)->s_vat )
 
-#endif                         /* __LINUX_UDF_SB_H */
+#endif /* __LINUX_UDF_SB_H */
index 76f2b82a39dcb3a20723b39489c36c7988cd77a4..c8016cc9e7e669cae81d09544f174eea22a32a78 100644 (file)
@@ -63,8 +63,8 @@ struct udf_vds_record {
 };
 
 struct generic_desc {
-       tag descTag;
-       __le32 volDescSeqNum;
+       tag             descTag;
+       __le32          volDescSeqNum;
 };
 
 struct ustr {
index 450daab35a132bbad240443642990728ca06e4e0..c4bd1203f857a5bb72c8df677c23aaebacc5f396 100644 (file)
@@ -7,75 +7,93 @@
 static inline kernel_lb_addr lelb_to_cpu(lb_addr in)
 {
        kernel_lb_addr out;
+
        out.logicalBlockNum = le32_to_cpu(in.logicalBlockNum);
        out.partitionReferenceNum = le16_to_cpu(in.partitionReferenceNum);
+
        return out;
 }
 
 static inline lb_addr cpu_to_lelb(kernel_lb_addr in)
 {
        lb_addr out;
+
        out.logicalBlockNum = cpu_to_le32(in.logicalBlockNum);
        out.partitionReferenceNum = cpu_to_le16(in.partitionReferenceNum);
+
        return out;
 }
 
 static inline kernel_timestamp lets_to_cpu(timestamp in)
 {
        kernel_timestamp out;
+
        memcpy(&out, &in, sizeof(timestamp));
        out.typeAndTimezone = le16_to_cpu(in.typeAndTimezone);
        out.year = le16_to_cpu(in.year);
+
        return out;
 }
 
 static inline short_ad lesa_to_cpu(short_ad in)
 {
        short_ad out;
+
        out.extLength = le32_to_cpu(in.extLength);
        out.extPosition = le32_to_cpu(in.extPosition);
+
        return out;
 }
 
 static inline short_ad cpu_to_lesa(short_ad in)
 {
        short_ad out;
+
        out.extLength = cpu_to_le32(in.extLength);
        out.extPosition = cpu_to_le32(in.extPosition);
+
        return out;
 }
 
 static inline kernel_long_ad lela_to_cpu(long_ad in)
 {
        kernel_long_ad out;
+
        out.extLength = le32_to_cpu(in.extLength);
        out.extLocation = lelb_to_cpu(in.extLocation);
+
        return out;
 }
 
 static inline long_ad cpu_to_lela(kernel_long_ad in)
 {
        long_ad out;
+
        out.extLength = cpu_to_le32(in.extLength);
        out.extLocation = cpu_to_lelb(in.extLocation);
+
        return out;
 }
 
 static inline kernel_extent_ad leea_to_cpu(extent_ad in)
 {
        kernel_extent_ad out;
+
        out.extLength = le32_to_cpu(in.extLength);
        out.extLocation = le32_to_cpu(in.extLocation);
+
        return out;
 }
 
 static inline timestamp cpu_to_lets(kernel_timestamp in)
 {
        timestamp out;
+
        memcpy(&out, &in, sizeof(timestamp));
        out.typeAndTimezone = cpu_to_le16(in.typeAndTimezone);
        out.year = cpu_to_le16(in.year);
+
        return out;
 }
 
-#endif                         /* __UDF_ENDIAN_H */
+#endif /* __UDF_ENDIAN_H */
index b9f3198080e9c27a6f78865f53c8094db6cdac6f..3fd80eb66af337f47942fd8483d9ad1f11ba5669 100644 (file)
    Boston, MA 02111-1307, USA.  */
 
 /*
- * dgb 10/02/98: ripped this from glibc source to help convert timestamps to unix time 
+ * dgb 10/02/98: ripped this from glibc source to help convert timestamps to unix time
  *     10/04/98: added new table-based lookup after seeing how ugly the gnu code is
  * blf 09/27/99: ripped out all the old code and inserted new table from
- *                                     John Brockmeyer (without leap second corrections)
- *                              rewrote udf_stamp_to_time and fixed timezone accounting in
                                      udf_time_to_stamp.
+ *              John Brockmeyer (without leap second corrections)
+ *              rewrote udf_stamp_to_time and fixed timezone accounting in
*              udf_time_to_stamp.
  */
 
 /*
  * We don't take into account leap seconds. This may be correct or incorrect.
  * For more NIST information (especially dealing with leap seconds), see:
- *  http://www.boulder.nist.gov/timefreq/pubs/bulletin/leapsecond.htm
+ * http://www.boulder.nist.gov/timefreq/pubs/bulletin/leapsecond.htm
  */
 
 #include <linux/types.h>
@@ -54,28 +54,28 @@ static const unsigned short int __mon_yday[2][13] = {
 };
 
 #define MAX_YEAR_SECONDS       69
-#define SPD 0x15180            /*3600*24 */
-#define SPY(y,l,s) (SPD * (365*y+l)+s)
-
-static time_t year_seconds[MAX_YEAR_SECONDS] = {
-/*1970*/ SPY(0, 0, 0), SPY(1, 0, 0), SPY(2, 0, 0), SPY(3, 1, 0),
-/*1974*/ SPY(4, 1, 0), SPY(5, 1, 0), SPY(6, 1, 0), SPY(7, 2, 0),
-/*1978*/ SPY(8, 2, 0), SPY(9, 2, 0), SPY(10, 2, 0), SPY(11, 3, 0),
-/*1982*/ SPY(12, 3, 0), SPY(13, 3, 0), SPY(14, 3, 0), SPY(15, 4, 0),
-/*1986*/ SPY(16, 4, 0), SPY(17, 4, 0), SPY(18, 4, 0), SPY(19, 5, 0),
-/*1990*/ SPY(20, 5, 0), SPY(21, 5, 0), SPY(22, 5, 0), SPY(23, 6, 0),
-/*1994*/ SPY(24, 6, 0), SPY(25, 6, 0), SPY(26, 6, 0), SPY(27, 7, 0),
-/*1998*/ SPY(28, 7, 0), SPY(29, 7, 0), SPY(30, 7, 0), SPY(31, 8, 0),
-/*2002*/ SPY(32, 8, 0), SPY(33, 8, 0), SPY(34, 8, 0), SPY(35, 9, 0),
-/*2006*/ SPY(36, 9, 0), SPY(37, 9, 0), SPY(38, 9, 0), SPY(39, 10, 0),
-/*2010*/ SPY(40, 10, 0), SPY(41, 10, 0), SPY(42, 10, 0), SPY(43, 11, 0),
-/*2014*/ SPY(44, 11, 0), SPY(45, 11, 0), SPY(46, 11, 0), SPY(47, 12, 0),
-/*2018*/ SPY(48, 12, 0), SPY(49, 12, 0), SPY(50, 12, 0), SPY(51, 13, 0),
-/*2022*/ SPY(52, 13, 0), SPY(53, 13, 0), SPY(54, 13, 0), SPY(55, 14, 0),
-/*2026*/ SPY(56, 14, 0), SPY(57, 14, 0), SPY(58, 14, 0), SPY(59, 15, 0),
-/*2030*/ SPY(60, 15, 0), SPY(61, 15, 0), SPY(62, 15, 0), SPY(63, 16, 0),
-/*2034*/ SPY(64, 16, 0), SPY(65, 16, 0), SPY(66, 16, 0), SPY(67, 17, 0),
-/*2038*/ SPY(68, 17, 0)
+#define SPD                    0x15180 /*3600*24 */
+#define SPY(y,l,s)             (SPD * (365*y+l)+s)
+
+static time_t year_seconds[MAX_YEAR_SECONDS]= {
+/*1970*/ SPY( 0, 0,0), SPY( 1, 0,0), SPY( 2, 0,0), SPY( 3, 1,0),
+/*1974*/ SPY( 4, 1,0), SPY( 5, 1,0), SPY( 6, 1,0), SPY( 7, 2,0),
+/*1978*/ SPY( 8, 2,0), SPY( 9, 2,0), SPY(10, 2,0), SPY(11, 3,0),
+/*1982*/ SPY(12, 3,0), SPY(13, 3,0), SPY(14, 3,0), SPY(15, 4,0),
+/*1986*/ SPY(16, 4,0), SPY(17, 4,0), SPY(18, 4,0), SPY(19, 5,0),
+/*1990*/ SPY(20, 5,0), SPY(21, 5,0), SPY(22, 5,0), SPY(23, 6,0),
+/*1994*/ SPY(24, 6,0), SPY(25, 6,0), SPY(26, 6,0), SPY(27, 7,0),
+/*1998*/ SPY(28, 7,0), SPY(29, 7,0), SPY(30, 7,0), SPY(31, 8,0),
+/*2002*/ SPY(32, 8,0), SPY(33, 8,0), SPY(34, 8,0), SPY(35, 9,0),
+/*2006*/ SPY(36, 9,0), SPY(37, 9,0), SPY(38, 9,0), SPY(39,10,0),
+/*2010*/ SPY(40,10,0), SPY(41,10,0), SPY(42,10,0), SPY(43,11,0),
+/*2014*/ SPY(44,11,0), SPY(45,11,0), SPY(46,11,0), SPY(47,12,0),
+/*2018*/ SPY(48,12,0), SPY(49,12,0), SPY(50,12,0), SPY(51,13,0),
+/*2022*/ SPY(52,13,0), SPY(53,13,0), SPY(54,13,0), SPY(55,14,0),
+/*2026*/ SPY(56,14,0), SPY(57,14,0), SPY(58,14,0), SPY(59,15,0),
+/*2030*/ SPY(60,15,0), SPY(61,15,0), SPY(62,15,0), SPY(63,16,0),
+/*2034*/ SPY(64,16,0), SPY(65,16,0), SPY(66,16,0), SPY(67,17,0),
+/*2038*/ SPY(68,17,0)
 };
 
 extern struct timezone sys_tz;
@@ -83,7 +83,7 @@ extern struct timezone sys_tz;
 #define SECS_PER_HOUR  (60 * 60)
 #define SECS_PER_DAY   (SECS_PER_HOUR * 24)
 
-time_t *udf_stamp_to_time(time_t * dest, long *dest_usec, kernel_timestamp src)
+time_t *udf_stamp_to_time(time_t *dest, long *dest_usec, kernel_timestamp src)
 {
        int yday;
        uint8_t type = src.typeAndTimezone >> 12;
@@ -93,10 +93,11 @@ time_t *udf_stamp_to_time(time_t * dest, long *dest_usec, kernel_timestamp src)
                offset = src.typeAndTimezone << 4;
                /* sign extent offset */
                offset = (offset >> 4);
-               if (offset == -2047)    /* unspecified offset */
+               if (offset == -2047) /* unspecified offset */
                        offset = 0;
-       } else
+       } else {
                offset = 0;
+       }
 
        if ((src.year < EPOCH_YEAR) ||
            (src.year >= EPOCH_YEAR + MAX_YEAR_SECONDS)) {
@@ -107,12 +108,10 @@ time_t *udf_stamp_to_time(time_t * dest, long *dest_usec, kernel_timestamp src)
        *dest = year_seconds[src.year - EPOCH_YEAR];
        *dest -= offset * 60;
 
-       yday = ((__mon_yday[__isleap(src.year)]
+       yday = ((__mon_yday[__isleap (src.year)]
                 [src.month - 1]) + (src.day - 1));
-       *dest += (((yday * 24) + src.hour) * 60 + src.minute) * 60 + src.second;
-       *dest_usec =
-           src.centiseconds * 10000 + src.hundredsOfMicroseconds * 100 +
-           src.microseconds;
+       *dest += ( ( (yday * 24) + src.hour ) * 60 + src.minute ) * 60 + src.second;
+       *dest_usec = src.centiseconds * 10000 + src.hundredsOfMicroseconds * 100 + src.microseconds;
        return dest;
 }
 
@@ -145,8 +144,9 @@ kernel_timestamp *udf_time_to_stamp(kernel_timestamp * dest, struct timespec ts)
                long int yg = y + days / 365 - (days % 365 < 0);
 
                /* Adjust DAYS and Y to match the guessed year.  */
-               days -= ((yg - y) * 365 + LEAPS_THRU_END_OF(yg - 1)
-                        - LEAPS_THRU_END_OF(y - 1));
+               days -= ((yg - y) * 365
+                        + LEAPS_THRU_END_OF (yg - 1)
+                        - LEAPS_THRU_END_OF (y - 1));
                y = yg;
        }
        dest->year = y;
@@ -158,11 +158,9 @@ kernel_timestamp *udf_time_to_stamp(kernel_timestamp * dest, struct timespec ts)
        dest->day = days + 1;
 
        dest->centiseconds = ts.tv_nsec / 10000000;
-       dest->hundredsOfMicroseconds =
-           (ts.tv_nsec / 1000 - dest->centiseconds * 10000) / 100;
-       dest->microseconds =
-           (ts.tv_nsec / 1000 - dest->centiseconds * 10000 -
-            dest->hundredsOfMicroseconds * 100);
+       dest->hundredsOfMicroseconds = (ts.tv_nsec / 1000 - dest->centiseconds * 10000) / 100;
+       dest->microseconds = (ts.tv_nsec / 1000 - dest->centiseconds * 10000 -
+                             dest->hundredsOfMicroseconds * 100);
        return dest;
 }
 
index 46835240275c9829aeb26773df610edccf282d52..9e6099c26c27a7434de44af03b05f79cc97bd0ca 100644 (file)
 
 static int udf_translate_to_linux(uint8_t *, uint8_t *, int, uint8_t *, int);
 
-static int udf_char_to_ustr(struct ustr *dest, const uint8_t * src, int strlen)
+static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen)
 {
        if ((!dest) || (!src) || (!strlen) || (strlen > UDF_NAME_LEN - 2))
                return 0;
+
        memset(dest, 0, sizeof(struct ustr));
        memcpy(dest->u_name, src, strlen);
        dest->u_cmpID = 0x08;
        dest->u_len = strlen;
+
        return strlen;
 }
 
 /*
  * udf_build_ustr
  */
-int udf_build_ustr(struct ustr *dest, dstring * ptr, int size)
+int udf_build_ustr(struct ustr *dest, dstring *ptr, int size)
 {
        int usesize;
 
@@ -55,13 +57,14 @@ int udf_build_ustr(struct ustr *dest, dstring * ptr, int size)
        dest->u_cmpID = ptr[0];
        dest->u_len = ptr[size - 1];
        memcpy(dest->u_name, ptr + 1, usesize - 1);
+
        return 0;
 }
 
 /*
  * udf_build_ustr_exact
  */
-static int udf_build_ustr_exact(struct ustr *dest, dstring * ptr, int exactsize)
+static int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize)
 {
        if ((!dest) || (!ptr) || (!exactsize))
                return -1;
@@ -70,6 +73,7 @@ static int udf_build_ustr_exact(struct ustr *dest, dstring * ptr, int exactsize)
        dest->u_cmpID = ptr[0];
        dest->u_len = exactsize - 1;
        memcpy(dest->u_name, ptr + 1, exactsize - 1);
+
        return 0;
 }
 
@@ -129,20 +133,15 @@ int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i)
                        c = (c << 8) | ocu[i++];
 
                /* Compress Unicode to UTF-8 */
-               if (c < 0x80U)
-                       utf_o->u_name[utf_o->u_len++] = (uint8_t) c;
-               else if (c < 0x800U) {
-                       utf_o->u_name[utf_o->u_len++] =
-                           (uint8_t) (0xc0 | (c >> 6));
-                       utf_o->u_name[utf_o->u_len++] =
-                           (uint8_t) (0x80 | (c & 0x3f));
+               if (c < 0x80U) {
+                       utf_o->u_name[utf_o->u_len++] = (uint8_t)c;
+               } else if (c < 0x800U) {
+                       utf_o->u_name[utf_o->u_len++] = (uint8_t)(0xc0 | (c >> 6));
+                       utf_o->u_name[utf_o->u_len++] = (uint8_t)(0x80 | (c & 0x3f));
                } else {
-                       utf_o->u_name[utf_o->u_len++] =
-                           (uint8_t) (0xe0 | (c >> 12));
-                       utf_o->u_name[utf_o->u_len++] =
-                           (uint8_t) (0x80 | ((c >> 6) & 0x3f));
-                       utf_o->u_name[utf_o->u_len++] =
-                           (uint8_t) (0x80 | (c & 0x3f));
+                       utf_o->u_name[utf_o->u_len++] = (uint8_t)(0xe0 | (c >> 12));
+                       utf_o->u_name[utf_o->u_len++] = (uint8_t)(0x80 | ((c >> 6) & 0x3f));
+                       utf_o->u_name[utf_o->u_len++] = (uint8_t)(0x80 | (c & 0x3f));
                }
        }
        utf_o->u_cmpID = 8;
@@ -173,7 +172,7 @@ int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i)
  *     November 12, 1997 - Andrew E. Mileski
  *     Written, tested, and released.
  */
-static int udf_UTF8toCS0(dstring * ocu, struct ustr *utf, int length)
+static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length)
 {
        unsigned c, i, max_val, utf_char;
        int utf_cnt, u_len;
@@ -182,12 +181,12 @@ static int udf_UTF8toCS0(dstring * ocu, struct ustr *utf, int length)
        ocu[0] = 8;
        max_val = 0xffU;
 
-      try_again:
+try_again:
        u_len = 0U;
        utf_char = 0U;
        utf_cnt = 0U;
        for (i = 0U; i < utf->u_len; i++) {
-               c = (uint8_t) utf->u_name[i];
+               c = (uint8_t)utf->u_name[i];
 
                /* Complete a multi-byte UTF-8 character */
                if (utf_cnt) {
@@ -213,37 +212,40 @@ static int udf_UTF8toCS0(dstring * ocu, struct ustr *utf, int length)
                                } else if ((c & 0xfeU) == 0xfcU) {
                                        utf_char = c & 0x01U;
                                        utf_cnt = 5;
-                               } else
+                               } else {
                                        goto error_out;
+                               }
                                continue;
-                       } else
+                       } else {
                                /* Single byte UTF-8 character (most common) */
                                utf_char = c;
+                       }
                }
 
                /* Choose no compression if necessary */
                if (utf_char > max_val) {
-                       if (0xffU == max_val) {
+                       if (max_val == 0xffU) {
                                max_val = 0xffffU;
-                               ocu[0] = (uint8_t) 0x10U;
+                               ocu[0] = (uint8_t)0x10U;
                                goto try_again;
                        }
                        goto error_out;
                }
 
                if (max_val == 0xffffU) {
-                       ocu[++u_len] = (uint8_t) (utf_char >> 8);
+                       ocu[++u_len] = (uint8_t)(utf_char >> 8);
                }
-               ocu[++u_len] = (uint8_t) (utf_char & 0xffU);
+               ocu[++u_len] = (uint8_t)(utf_char & 0xffU);
        }
 
        if (utf_cnt) {
-             error_out:
+error_out:
                ocu[++u_len] = '?';
                printk(KERN_DEBUG "udf: bad UTF-8 character\n");
        }
 
-       ocu[length - 1] = (uint8_t) u_len + 1;
+       ocu[length - 1] = (uint8_t)u_len + 1;
+
        return u_len + 1;
 }
 
@@ -288,7 +290,7 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o,
        return utf_o->u_len;
 }
 
-static int udf_NLStoCS0(struct nls_table *nls, dstring * ocu, struct ustr *uni,
+static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni,
                        int length)
 {
        unsigned len, i, max_val;
@@ -299,7 +301,7 @@ static int udf_NLStoCS0(struct nls_table *nls, dstring * ocu, struct ustr *uni,
        ocu[0] = 8;
        max_val = 0xffU;
 
-      try_again:
+try_again:
        u_len = 0U;
        for (i = 0U; i < uni->u_len; i++) {
                len = nls->char2uni(&uni->u_name[i], uni->u_len - i, &uni_char);
@@ -308,21 +310,21 @@ static int udf_NLStoCS0(struct nls_table *nls, dstring * ocu, struct ustr *uni,
 
                if (uni_char > max_val) {
                        max_val = 0xffffU;
-                       ocu[0] = (uint8_t) 0x10U;
+                       ocu[0] = (uint8_t)0x10U;
                        goto try_again;
                }
 
                if (max_val == 0xffffU)
-                       ocu[++u_len] = (uint8_t) (uni_char >> 8);
-               ocu[++u_len] = (uint8_t) (uni_char & 0xffU);
+                       ocu[++u_len] = (uint8_t)(uni_char >> 8);
+               ocu[++u_len] = (uint8_t)(uni_char & 0xffU);
                i += len - 1;
        }
 
-       ocu[length - 1] = (uint8_t) u_len + 1;
+       ocu[length - 1] = (uint8_t)u_len + 1;
        return u_len + 1;
 }
 
-int udf_get_filename(struct super_block *sb, uint8_t * sname, uint8_t * dname,
+int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname,
                     int flen)
 {
        struct ustr filename, unifilename;
@@ -334,30 +336,29 @@ int udf_get_filename(struct super_block *sb, uint8_t * sname, uint8_t * dname,
 
        if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) {
                if (!udf_CS0toUTF8(&filename, &unifilename)) {
-                       udf_debug("Failed in udf_get_filename: sname = %s\n",
-                                 sname);
+                       udf_debug("Failed in udf_get_filename: sname = %s\n", sname);
                        return 0;
                }
        } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) {
-               if (!udf_CS0toNLS
-                   (UDF_SB(sb)->s_nls_map, &filename, &unifilename)) {
-                       udf_debug("Failed in udf_get_filename: sname = %s\n",
-                                 sname);
+               if (!udf_CS0toNLS(UDF_SB(sb)->s_nls_map, &filename, &unifilename)) {
+                       udf_debug("Failed in udf_get_filename: sname = %s\n", sname);
                        return 0;
                }
-       } else
+       } else {
                return 0;
+       }
 
-       if ((len =
-            udf_translate_to_linux(dname, filename.u_name, filename.u_len,
-                                   unifilename.u_name, unifilename.u_len))) {
+       len = udf_translate_to_linux(dname, filename.u_name, filename.u_len,
+                                    unifilename.u_name, unifilename.u_len);
+       if (len) {
                return len;
        }
+
        return 0;
 }
 
-int udf_put_filename(struct super_block *sb, const uint8_t * sname,
-                    uint8_t * dname, int flen)
+int udf_put_filename(struct super_block *sb, const uint8_t *sname,
+                    uint8_t *dname, int flen)
 {
        struct ustr unifilename;
        int namelen;
@@ -367,31 +368,29 @@ int udf_put_filename(struct super_block *sb, const uint8_t * sname,
        }
 
        if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) {
-               if (!
-                   (namelen =
-                    udf_UTF8toCS0(dname, &unifilename, UDF_NAME_LEN))) {
+               namelen = udf_UTF8toCS0(dname, &unifilename, UDF_NAME_LEN);
+               if (!namelen) {
                        return 0;
                }
        } else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) {
-               if (!
-                   (namelen =
-                    udf_NLStoCS0(UDF_SB(sb)->s_nls_map, dname, &unifilename,
-                                 UDF_NAME_LEN))) {
+               namelen = udf_NLStoCS0(UDF_SB(sb)->s_nls_map, dname, &unifilename, UDF_NAME_LEN);
+               if (!namelen) {
                        return 0;
                }
-       } else
+       } else {
                return 0;
+       }
 
        return namelen;
 }
 
 #define ILLEGAL_CHAR_MARK      '_'
-#define EXT_MARK                       '.'
-#define CRC_MARK                       '#'
-#define EXT_SIZE                       5
+#define EXT_MARK               '.'
+#define CRC_MARK               '#'
+#define EXT_SIZE               5
 
-static int udf_translate_to_linux(uint8_t * newName, uint8_t * udfName,
-                                 int udfLen, uint8_t * fidName, int fidNameLen)
+static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, int udfLen,
+                                 uint8_t *fidName, int fidNameLen)
 {
        int index, newIndex = 0, needsCRC = 0;
        int extIndex = 0, newExtIndex = 0, hasExt = 0;
@@ -399,8 +398,8 @@ static int udf_translate_to_linux(uint8_t * newName, uint8_t * udfName,
        uint8_t curr;
        const uint8_t hexChar[] = "0123456789ABCDEF";
 
-       if (udfName[0] == '.' && (udfLen == 1 ||
-                                 (udfLen == 2 && udfName[1] == '.'))) {
+       if (udfName[0] == '.' &&
+           (udfLen == 1 || (udfLen == 2 && udfName[1] == '.'))) {
                needsCRC = 1;
                newIndex = udfLen;
                memcpy(newName, udfName, udfLen);
@@ -410,16 +409,13 @@ static int udf_translate_to_linux(uint8_t * newName, uint8_t * udfName,
                        if (curr == '/' || curr == 0) {
                                needsCRC = 1;
                                curr = ILLEGAL_CHAR_MARK;
-                               while (index + 1 < udfLen
-                                      && (udfName[index + 1] == '/'
-                                          || udfName[index + 1] == 0))
+                               while (index + 1 < udfLen && (udfName[index + 1] == '/' ||
+                                                             udfName[index + 1] == 0))
                                        index++;
-                       }
-                       if (curr == EXT_MARK
-                           && (udfLen - index - 1) <= EXT_SIZE) {
-                               if (udfLen == index + 1)
+                       } if (curr == EXT_MARK && (udfLen - index - 1) <= EXT_SIZE) {
+                               if (udfLen == index + 1) {
                                        hasExt = 0;
-                               else {
+                               else {
                                        hasExt = 1;
                                        extIndex = index;
                                        newExtIndex = newIndex;
@@ -437,23 +433,16 @@ static int udf_translate_to_linux(uint8_t * newName, uint8_t * udfName,
 
                if (hasExt) {
                        int maxFilenameLen;
-                       for (index = 0;
-                            index < EXT_SIZE && extIndex + index + 1 < udfLen;
-                            index++) {
+                       for(index = 0; index < EXT_SIZE && extIndex + index + 1 < udfLen; index++) {
                                curr = udfName[extIndex + index + 1];
 
                                if (curr == '/' || curr == 0) {
                                        needsCRC = 1;
                                        curr = ILLEGAL_CHAR_MARK;
-                                       while (extIndex + index + 2 < udfLen
-                                              && (index + 1 < EXT_SIZE
-                                                  &&
-                                                  (udfName
-                                                   [extIndex + index + 2] ==
-                                                   '/'
-                                                   || udfName[extIndex +
-                                                              index + 2] ==
-                                                   0)))
+                                       while(extIndex + index + 2 < udfLen &&
+                                             (index + 1 < EXT_SIZE
+                                              && (udfName[extIndex + index + 2] == '/' ||
+                                                  udfName[extIndex + index + 2] == 0)))
                                                index++;
                                }
                                ext[localExtIndex++] = curr;
@@ -463,8 +452,9 @@ static int udf_translate_to_linux(uint8_t * newName, uint8_t * udfName,
                                newIndex = maxFilenameLen;
                        else
                                newIndex = newExtIndex;
-               } else if (newIndex > 250)
+               } else if (newIndex > 250) {
                        newIndex = 250;
+               }
                newName[newIndex++] = CRC_MARK;
                valueCRC = udf_crc(fidName, fidNameLen, 0);
                newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12];
@@ -478,5 +468,6 @@ static int udf_translate_to_linux(uint8_t * newName, uint8_t * udfName,
                                newName[newIndex++] = ext[index];
                }
        }
+
        return newIndex;
 }
index 8948a6461834d1d8fa2eb5cd3a3239d48a8a4483..45662f6dbdb66b34b8966670187ffd6655737aa6 100644 (file)
 #define ACPI_FUNCTION_NAME(name)
 #endif
 
+#ifdef DEBUG_FUNC_TRACE
+
 #define ACPI_FUNCTION_TRACE(a)          ACPI_FUNCTION_NAME(a) \
                          acpi_ut_trace(ACPI_DEBUG_PARAMETERS)
 #define ACPI_FUNCTION_TRACE_PTR(a,b)    ACPI_FUNCTION_NAME(a) \
 
 #endif                         /* ACPI_SIMPLE_RETURN_MACROS */
 
+#else /* !DEBUG_FUNC_TRACE */
+
+#define ACPI_FUNCTION_TRACE(a)
+#define ACPI_FUNCTION_TRACE_PTR(a,b)
+#define ACPI_FUNCTION_TRACE_U32(a,b)
+#define ACPI_FUNCTION_TRACE_STR(a,b)
+#define ACPI_FUNCTION_EXIT
+#define ACPI_FUNCTION_STATUS_EXIT(s)
+#define ACPI_FUNCTION_VALUE_EXIT(s)
+#define ACPI_FUNCTION_TRACE(a)
+#define ACPI_FUNCTION_ENTRY()
+
+#define return_VOID                     return
+#define return_ACPI_STATUS(s)           return(s)
+#define return_VALUE(s)                 return(s)
+#define return_UINT8(s)                 return(s)
+#define return_UINT32(s)                return(s)
+#define return_PTR(s)                   return(s)
+
+#endif /* DEBUG_FUNC_TRACE */
+
 /* Conditional execution */
 
 #define ACPI_DEBUG_EXEC(a)              a
 #define ACPI_DEBUG_EXEC(a)
 #define ACPI_NORMAL_EXEC(a)             a;
 
-#define ACPI_DEBUG_DEFINE(a)
-#define ACPI_DEBUG_ONLY_MEMBERS(a)
-#define ACPI_FUNCTION_NAME(a)
-#define ACPI_FUNCTION_TRACE(a)
-#define ACPI_FUNCTION_TRACE_PTR(a,b)
-#define ACPI_FUNCTION_TRACE_U32(a,b)
-#define ACPI_FUNCTION_TRACE_STR(a,b)
-#define ACPI_FUNCTION_EXIT
-#define ACPI_FUNCTION_STATUS_EXIT(s)
-#define ACPI_FUNCTION_VALUE_EXIT(s)
-#define ACPI_FUNCTION_ENTRY()
-#define ACPI_DUMP_STACK_ENTRY(a)
-#define ACPI_DUMP_OPERANDS(a,b,c,d,e)
-#define ACPI_DUMP_ENTRY(a,b)
-#define ACPI_DUMP_TABLES(a,b)
-#define ACPI_DUMP_PATHNAME(a,b,c,d)
-#define ACPI_DUMP_RESOURCE_LIST(a)
-#define ACPI_DUMP_BUFFER(a,b)
-#define ACPI_DEBUG_PRINT(pl)
-#define ACPI_DEBUG_PRINT_RAW(pl)
+#define ACPI_DEBUG_DEFINE(a)           do { } while(0)
+#define ACPI_DEBUG_ONLY_MEMBERS(a)     do { } while(0)
+#define ACPI_FUNCTION_NAME(a)          do { } while(0)
+#define ACPI_FUNCTION_TRACE(a)         do { } while(0)
+#define ACPI_FUNCTION_TRACE_PTR(a,b)   do { } while(0)
+#define ACPI_FUNCTION_TRACE_U32(a,b)   do { } while(0)
+#define ACPI_FUNCTION_TRACE_STR(a,b)   do { } while(0)
+#define ACPI_FUNCTION_EXIT             do { } while(0)
+#define ACPI_FUNCTION_STATUS_EXIT(s)   do { } while(0)
+#define ACPI_FUNCTION_VALUE_EXIT(s)    do { } while(0)
+#define ACPI_FUNCTION_ENTRY()          do { } while(0)
+#define ACPI_DUMP_STACK_ENTRY(a)       do { } while(0)
+#define ACPI_DUMP_OPERANDS(a,b,c,d,e)  do { } while(0)
+#define ACPI_DUMP_ENTRY(a,b)           do { } while(0)
+#define ACPI_DUMP_TABLES(a,b)          do { } while(0)
+#define ACPI_DUMP_PATHNAME(a,b,c,d)    do { } while(0)
+#define ACPI_DUMP_RESOURCE_LIST(a)     do { } while(0)
+#define ACPI_DUMP_BUFFER(a,b)          do { } while(0)
+#define ACPI_DEBUG_PRINT(pl)           do { } while(0)
+#define ACPI_DEBUG_PRINT_RAW(pl)       do { } while(0)
 
 #define return_VOID                     return
 #define return_ACPI_STATUS(s)           return(s)
index 7812267b577f2d857827ed501faf66894829afcf..c090a8b0bc99d68e486ab0170bef9a75dc87aeb6 100644 (file)
 
 /* Defaults for debug_level, debug and normal */
 
-#define ACPI_DEBUG_DEFAULT          (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT)
-#define ACPI_NORMAL_DEFAULT         (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT)
+#define ACPI_DEBUG_DEFAULT          (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR)
+#define ACPI_NORMAL_DEFAULT         (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR)
 #define ACPI_DEBUG_ALL              (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL)
 
 #endif                         /* __ACOUTPUT_H__ */
index c6fa5e023bc78289b92cb4d5b5da5d94f3df0266..5e3dcf3299bf90c68ae537de9c07d9fbbb9d69f6 100644 (file)
@@ -321,7 +321,8 @@ struct acpi_bus_event {
 };
 
 extern struct kset acpi_subsys;
-
+extern int acpi_bus_generate_genetlink_event(struct acpi_device *device,
+                                               u8 type, int data);
 /*
  * External Functions
  */
index e2fcee2b340d8e4134a7320c80eb92aaef4f611b..62c5ee4311da36deec078b467ca381c36919e9ed 100644 (file)
@@ -13,6 +13,7 @@
 
 extern int pxm_to_node(int);
 extern int node_to_pxm(int);
+extern void __acpi_map_pxm_to_node(int, int);
 extern int acpi_map_pxm_to_node(int);
 extern void __cpuinit acpi_unmap_pxm_to_node(int);
 
index dab2ec59a3b0b7a822d49c99cdec3f98b9834214..c785485e62a6cd55d476da76092deca582b761df 100644 (file)
 
 /*! [Begin] no source code translation */
 
-#if defined(__linux__)
+#if defined(_LINUX) || defined(__linux__)
 #include "aclinux.h"
 
 #elif defined(_AED_EFI)
index a568717f98c6dcbbeb1808fc329b167caafacf7b..6ed15a0978ebb7b9fd0b308699b37eef280e124b 100644 (file)
 #define ACPI_USE_NATIVE_DIVIDE
 #endif
 
+#ifndef __cdecl
 #define __cdecl
+#endif
+
 #define ACPI_FLUSH_CPU_CACHE()
 #endif                         /* __KERNEL__ */
 
index b4b0ffdab098f50c5e1bb44f12400150e8ff923c..f9f987f8e661b9afef361919314363500c05b183 100644 (file)
@@ -21,6 +21,8 @@
 #define ACPI_PSD_REV0_REVISION         0       /* Support for _PSD as in ACPI 3.0 */
 #define ACPI_PSD_REV0_ENTRIES          5
 
+#define ACPI_TSD_REV0_REVISION         0       /* Support for _PSD as in ACPI 3.0 */
+#define ACPI_TSD_REV0_ENTRIES          5
 /*
  * Types of coordination defined in ACPI 3.0. Same macros can be used across
  * P, C and T states
@@ -125,17 +127,53 @@ struct acpi_processor_performance {
 
 /* Throttling Control */
 
+struct acpi_tsd_package {
+       acpi_integer num_entries;
+       acpi_integer revision;
+       acpi_integer domain;
+       acpi_integer coord_type;
+       acpi_integer num_processors;
+} __attribute__ ((packed));
+
+struct acpi_ptc_register {
+       u8 descriptor;
+       u16 length;
+       u8 space_id;
+       u8 bit_width;
+       u8 bit_offset;
+       u8 reserved;
+       u64 address;
+} __attribute__ ((packed));
+
+struct acpi_processor_tx_tss {
+       acpi_integer freqpercentage;    /* */
+       acpi_integer power;     /* milliWatts */
+       acpi_integer transition_latency;        /* microseconds */
+       acpi_integer control;   /* control value */
+       acpi_integer status;    /* success indicator */
+};
 struct acpi_processor_tx {
        u16 power;
        u16 performance;
 };
 
+struct acpi_processor;
 struct acpi_processor_throttling {
-       int state;
+       unsigned int state;
+       unsigned int platform_limit;
+       struct acpi_pct_register control_register;
+       struct acpi_pct_register status_register;
+       unsigned int state_count;
+       struct acpi_processor_tx_tss *states_tss;
+       struct acpi_tsd_package domain_info;
+       cpumask_t shared_cpu_map;
+       int (*acpi_processor_get_throttling) (struct acpi_processor * pr);
+       int (*acpi_processor_set_throttling) (struct acpi_processor * pr,
+                                             int state);
+
        u32 address;
        u8 duty_offset;
        u8 duty_width;
-       int state_count;
        struct acpi_processor_tx states[ACPI_PROCESSOR_MAX_THROTTLING];
 };
 
@@ -169,6 +207,9 @@ struct acpi_processor {
        u32 id;
        u32 pblk;
        int performance_platform_limit;
+       int throttling_platform_limit;
+       /* 0 - states 0..n-th state available */
+
        struct acpi_processor_flags flags;
        struct acpi_processor_power power;
        struct acpi_processor_performance *performance;
@@ -270,7 +311,7 @@ static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr)
 
 /* in processor_throttling.c */
 int acpi_processor_get_throttling_info(struct acpi_processor *pr);
-int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
+extern int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
 extern struct file_operations acpi_processor_throttling_fops;
 
 /* in processor_idle.c */
index 917b9fe372cf388e328b6c1e80405e0516a059d5..06377400dc09b4750d54c32a6d433c0224cb3857 100644 (file)
@@ -85,10 +85,6 @@ static __inline__ int irq_canonicalize(int irq)
        return ((irq == 2) ? 9 : irq);
 }
 
-extern void disable_irq(unsigned int);
-extern void disable_irq_nosync(unsigned int);
-extern void enable_irq(unsigned int);
-
 struct pt_regs;
 extern void (*perf_irq)(unsigned long, struct pt_regs *);
 
index 40a9876b661a1162aa11cbd401e7e872c611c390..c2e11cc374ba6a28a1b33bf94f13a523bc73df90 100644 (file)
@@ -26,6 +26,9 @@
 #define AT91_MCI_MR            0x04            /* Mode Register */
 #define                AT91_MCI_CLKDIV         (0xff  <<  0)   /* Clock Divider */
 #define                AT91_MCI_PWSDIV         (7     <<  8)   /* Power Saving Divider */
+#define                AT91_MCI_RDPROOF        (1     << 11)   /* Read Proof Enable [SAM926[03] only] */
+#define                AT91_MCI_WRPROOF        (1     << 12)   /* Write Proof Enable [SAM926[03] only] */
+#define                AT91_MCI_PDCFBYTE       (1     << 13)   /* PDC Force Byte Transfer [SAM926[03] only] */
 #define                AT91_MCI_PDCPADV        (1     << 14)   /* PDC Padding Value */
 #define                AT91_MCI_PDCMODE        (1     << 15)   /* PDC-orientated Mode */
 #define                AT91_MCI_BLKLEN         (0xfff << 18)   /* Data Block Length */
index d4e4f828577cc51c41bb23221fd15960026f9d88..52b7fab7ef60555f58dd916fafb54891580394d3 100644 (file)
@@ -19,6 +19,39 @@ static inline int iop13xx_cpu_id(void)
        return id;
 }
 
+/* WDTCR CP6 R7 Page 9 */
+static inline u32 read_wdtcr(void)
+{
+       u32 val;
+       asm volatile("mrc p6, 0, %0, c7, c9, 0":"=r" (val));
+       return val;
+}
+static inline void write_wdtcr(u32 val)
+{
+       asm volatile("mcr p6, 0, %0, c7, c9, 0"::"r" (val));
+}
+
+/* WDTSR CP6 R8 Page 9 */
+static inline u32 read_wdtsr(void)
+{
+       u32 val;
+       asm volatile("mrc p6, 0, %0, c8, c9, 0":"=r" (val));
+       return val;
+}
+static inline void write_wdtsr(u32 val)
+{
+       asm volatile("mcr p6, 0, %0, c8, c9, 0"::"r" (val));
+}
+
+/* RCSR - Reset Cause Status Register  */
+static inline u32 read_rcsr(void)
+{
+       u32 val;
+       asm volatile("mrc p6, 0, %0, c0, c1, 0":"=r" (val));
+       return val;
+}
+
+extern unsigned long get_iop_tick_rate(void);
 #endif
 
 /*
@@ -480,4 +513,14 @@ static inline int iop13xx_cpu_id(void)
 #define IOP13XX_PBI_LR1                IOP13XX_PBI_OFFSET(0x14)
 
 #define IOP13XX_PROCESSOR_FREQ         IOP13XX_REG_ADDR32(0x2180)
+
+/* Watchdog timer definitions */
+#define IOP_WDTCR_EN_ARM       0x1e1e1e1e
+#define IOP_WDTCR_EN           0xe1e1e1e1
+#define IOP_WDTCR_DIS_ARM      0x1f1f1f1f
+#define IOP_WDTCR_DIS          0xf1f1f1f1
+#define IOP_RCSR_WDT           (1 << 5) /* reset caused by watchdog timer */
+#define IOP13XX_WDTSR_WRITE_EN (1 << 31) /* used to speed up reset requests */
+#define IOP13XX_WDTCR_IB_RESET (1 << 0)
+
 #endif /* _IOP13XX_HW_H_ */
index 127827058e1f4841e1eb00f248b544b94db6d23a..8575af8db78c7cf3b2c71b92a111133bb19663ca 100644 (file)
@@ -13,43 +13,13 @@ static inline void arch_idle(void)
        cpu_do_idle();
 }
 
-/* WDTCR CP6 R7 Page 9 */
-static inline u32 read_wdtcr(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c7, c9, 0":"=r" (val));
-       return val;
-}
-static inline void write_wdtcr(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c7, c9, 0"::"r" (val));
-}
-
-/* WDTSR CP6 R8 Page 9 */
-static inline u32 read_wdtsr(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c8, c9, 0":"=r" (val));
-       return val;
-}
-static inline void write_wdtsr(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c8, c9, 0"::"r" (val));
-}
-
-#define IOP13XX_WDTCR_EN_ARM   0x1e1e1e1e
-#define IOP13XX_WDTCR_EN       0xe1e1e1e1
-#define IOP13XX_WDTCR_DIS_ARM  0x1f1f1f1f
-#define IOP13XX_WDTCR_DIS      0xf1f1f1f1
-#define IOP13XX_WDTSR_WRITE_EN (1 << 31)
-#define IOP13XX_WDTCR_IB_RESET (1 << 0)
 static inline void arch_reset(char mode)
 {
        /*
         * Reset the internal bus (warning both cores are reset)
         */
-       write_wdtcr(IOP13XX_WDTCR_EN_ARM);
-       write_wdtcr(IOP13XX_WDTCR_EN);
+       write_wdtcr(IOP_WDTCR_EN_ARM);
+       write_wdtcr(IOP_WDTCR_EN);
        write_wdtsr(IOP13XX_WDTSR_WRITE_EN | IOP13XX_WDTCR_IB_RESET);
        write_wdtcr(0x1000);
 
index b9525d59b7ad3616f94b8e8f7f214c32a6893aef..dd9c2934190e045a9e6872bfe84fa26d3c574fec 100644 (file)
@@ -1,7 +1,6 @@
 #include <asm/types.h>
 #include <linux/serial_reg.h>
 #include <asm/hardware.h>
-#include <asm/processor.h>
 
 #define UART_BASE ((volatile u32 *)IOP13XX_UART1_PHYS)
 #define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE)
@@ -9,7 +8,7 @@
 static inline void putc(char c)
 {
        while ((UART_BASE[UART_LSR] & TX_DONE) != TX_DONE)
-               cpu_relax();
+               barrier();
        UART_BASE[UART_TX] = c;
 }
 
index e64f52bf2bcefb8a6fed77b39cd0bb1d24479eba..070f15818fe718593c675233b471c5f231fd1d0b 100644 (file)
@@ -26,7 +26,7 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id)
 {
        if (machine_is_iq80321())
                uart_base = (volatile u8 *)IQ80321_UART;
-       else if (machine_is_iq31244())
+       else if (machine_is_iq31244() || machine_is_em7210())
                uart_base = (volatile u8 *)IQ31244_UART;
        else
                uart_base = (volatile u8 *)0xfe800000;
diff --git a/include/asm-arm/arch-mxc/board-mx31ads.h b/include/asm-arm/arch-mxc/board-mx31ads.h
new file mode 100644 (file)
index 0000000..be29b83
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. 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 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX31ADS_H__
+#define __ASM_ARCH_MXC_BOARD_MX31ADS_H__
+
+/*!
+ * @name PBC Controller parameters
+ */
+/*! @{ */
+/*!
+ * Base address of PBC controller
+ */
+#define PBC_BASE_ADDRESS        IO_ADDRESS(CS4_BASE_ADDR)
+/* Offsets for the PBC Controller register */
+/*!
+ * PBC Board status register offset
+ */
+#define PBC_BSTAT               0x000002
+/*!
+ * PBC Board control register 1 set address.
+ */
+#define PBC_BCTRL1_SET          0x000004
+/*!
+ * PBC Board control register 1 clear address.
+ */
+#define PBC_BCTRL1_CLEAR        0x000006
+/*!
+ * PBC Board control register 2 set address.
+ */
+#define PBC_BCTRL2_SET          0x000008
+/*!
+ * PBC Board control register 2 clear address.
+ */
+#define PBC_BCTRL2_CLEAR        0x00000A
+/*!
+ * PBC Board control register 3 set address.
+ */
+#define PBC_BCTRL3_SET          0x00000C
+/*!
+ * PBC Board control register 3 clear address.
+ */
+#define PBC_BCTRL3_CLEAR        0x00000E
+/*!
+ * PBC Board control register 4 set address.
+ */
+#define PBC_BCTRL4_SET          0x000010
+/*!
+ * PBC Board control register 4 clear address.
+ */
+#define PBC_BCTRL4_CLEAR        0x000012
+/*!
+ * PBC Board status register 1.
+ */
+#define PBC_BSTAT1              0x000014
+/*!
+ * PBC Board interrupt status register.
+ */
+#define PBC_INTSTATUS           0x000016
+/*!
+ * PBC Board interrupt current status register.
+ */
+#define PBC_INTCURR_STATUS      0x000018
+/*!
+ * PBC Interrupt mask register set address.
+ */
+#define PBC_INTMASK_SET         0x00001A
+/*!
+ * PBC Interrupt mask register clear address.
+ */
+#define PBC_INTMASK_CLEAR       0x00001C
+
+/*!
+ * External UART A.
+ */
+#define PBC_SC16C652_UARTA      0x010000
+/*!
+ * External UART B.
+ */
+#define PBC_SC16C652_UARTB      0x010010
+/*!
+ * Ethernet Controller IO base address.
+ */
+#define PBC_CS8900A_IOBASE      0x020000
+/*!
+ * Ethernet Controller Memory base address.
+ */
+#define PBC_CS8900A_MEMBASE     0x021000
+/*!
+ * Ethernet Controller DMA base address.
+ */
+#define PBC_CS8900A_DMABASE     0x022000
+/*!
+ * External chip select 0.
+ */
+#define PBC_XCS0                0x040000
+/*!
+ * LCD Display enable.
+ */
+#define PBC_LCD_EN_B            0x060000
+/*!
+ * Code test debug enable.
+ */
+#define PBC_CODE_B              0x070000
+/*!
+ * PSRAM memory select.
+ */
+#define PBC_PSRAM_B             0x5000000
+
+#define PBC_INTSTATUS_REG      (PBC_INTSTATUS + PBC_BASE_ADDRESS)
+#define PBC_INTCURR_STATUS_REG (PBC_INTCURR_STATUS + PBC_BASE_ADDRESS)
+#define PBC_INTMASK_SET_REG    (PBC_INTMASK_SET + PBC_BASE_ADDRESS)
+#define PBC_INTMASK_CLEAR_REG  (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS)
+#define EXPIO_PARENT_INT       IOMUX_TO_IRQ(MX31_PIN_GPIO1_4)
+
+#define EXPIO_INT_LOW_BAT      (MXC_EXP_IO_BASE + 0)
+#define EXPIO_INT_PB_IRQ       (MXC_EXP_IO_BASE + 1)
+#define EXPIO_INT_OTG_FS_OVR   (MXC_EXP_IO_BASE + 2)
+#define EXPIO_INT_FSH_OVR      (MXC_EXP_IO_BASE + 3)
+#define EXPIO_INT_RES4         (MXC_EXP_IO_BASE + 4)
+#define EXPIO_INT_RES5         (MXC_EXP_IO_BASE + 5)
+#define EXPIO_INT_RES6         (MXC_EXP_IO_BASE + 6)
+#define EXPIO_INT_RES7         (MXC_EXP_IO_BASE + 7)
+#define EXPIO_INT_ENET_INT     (MXC_EXP_IO_BASE + 8)
+#define EXPIO_INT_OTG_FS_INT   (MXC_EXP_IO_BASE + 9)
+#define EXPIO_INT_XUART_INTA   (MXC_EXP_IO_BASE + 10)
+#define EXPIO_INT_XUART_INTB   (MXC_EXP_IO_BASE + 11)
+#define EXPIO_INT_SYNTH_IRQ    (MXC_EXP_IO_BASE + 12)
+#define EXPIO_INT_CE_INT1      (MXC_EXP_IO_BASE + 13)
+#define EXPIO_INT_CE_INT2      (MXC_EXP_IO_BASE + 14)
+#define EXPIO_INT_RES15                (MXC_EXP_IO_BASE + 15)
+
+#define MXC_MAX_EXP_IO_LINES   16
+
+#endif                         /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */
diff --git a/include/asm-arm/arch-mxc/common.h b/include/asm-arm/arch-mxc/common.h
new file mode 100644 (file)
index 0000000..23b4350
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. 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 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_COMMON_H__
+#define __ASM_ARCH_MXC_COMMON_H__
+
+struct sys_timer;
+
+extern void mxc_map_io(void);
+extern void mxc_init_irq(void);
+extern struct sys_timer mxc_timer;
+
+#endif
diff --git a/include/asm-arm/arch-mxc/dma.h b/include/asm-arm/arch-mxc/dma.h
new file mode 100644 (file)
index 0000000..65e639d
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. 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 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_DMA_H__
+#define __ASM_ARCH_MXC_DMA_H__
+
+/*!
+ * @file dma.h
+ * @brief This file contains Unified DMA API for all MXC platforms.
+ * The API is platform independent.
+ *
+ * @ingroup SDMA
+ */
+#endif
diff --git a/include/asm-arm/arch-mxc/entry-macro.S b/include/asm-arm/arch-mxc/entry-macro.S
new file mode 100644 (file)
index 0000000..b542433
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
+ *  Copyright 2004-2007 Freescale Semiconductor, Inc. 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 as
+ * published by the Free Software Foundation.
+ */
+
+       @ this macro disables fast irq (not implemented)
+       .macro  disable_fiq
+       .endm
+
+       .macro  get_irqnr_preamble, base, tmp
+       .endm
+
+       .macro  arch_ret_to_user, tmp1, tmp2
+       .endm
+
+       @ this macro checks which interrupt occured
+       @ and returns its number in irqnr
+       @ and returns if an interrupt occured in irqstat
+       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+       ldr     \base, =AVIC_IO_ADDRESS(AVIC_BASE_ADDR)
+       @ Load offset & priority of the highest priority
+       @ interrupt pending from AVIC_NIVECSR
+       ldr     \irqstat, [\base, #0x40]
+       @ Shift to get the decoded IRQ number, using ASR so
+       @ 'no interrupt pending' becomes 0xffffffff
+       mov     \irqnr, \irqstat, asr #16
+       @ set zero flag if IRQ + 1 == 0
+       adds    \tmp, \irqnr, #1
+       .endm
+
+       @ irq priority table (not used)
+       .macro  irq_prio_table
+       .endm
diff --git a/include/asm-arm/arch-mxc/hardware.h b/include/asm-arm/arch-mxc/hardware.h
new file mode 100644 (file)
index 0000000..3c09b92
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *  Copyright 2004-2007 Freescale Semiconductor, Inc. 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 as
+ * published by the Free Software Foundation.
+ */
+
+/*!
+ * @file hardware.h
+ * @brief This file contains the hardware definitions of the board.
+ *
+ * @ingroup System
+ */
+#ifndef __ASM_ARCH_MXC_HARDWARE_H__
+#define __ASM_ARCH_MXC_HARDWARE_H__
+
+#include <asm/sizes.h>
+
+#include <asm/arch/mx31.h>
+
+#include <asm/arch/mxc.h>
+
+#define MXC_MAX_GPIO_LINES      (GPIO_NUM_PIN * GPIO_PORT_NUM)
+
+/*
+ * ---------------------------------------------------------------------------
+ * Board specific defines
+ * ---------------------------------------------------------------------------
+ */
+#define MXC_EXP_IO_BASE         (MXC_GPIO_INT_BASE + MXC_MAX_GPIO_LINES)
+
+#include <asm/arch/board-mx31ads.h>
+
+#ifndef MXC_MAX_EXP_IO_LINES
+#define MXC_MAX_EXP_IO_LINES 0
+#endif
+
+#define MXC_MAX_VIRTUAL_INTS   16
+#define MXC_VIRTUAL_INTS_BASE  (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES)
+#define MXC_SDIO1_CARD_IRQ     MXC_VIRTUAL_INTS_BASE
+#define MXC_SDIO2_CARD_IRQ     (MXC_VIRTUAL_INTS_BASE + 1)
+#define MXC_SDIO3_CARD_IRQ     (MXC_VIRTUAL_INTS_BASE + 2)
+
+#define MXC_MAX_INTS            (MXC_MAX_INT_LINES + \
+                                MXC_MAX_GPIO_LINES + \
+                                MXC_MAX_EXP_IO_LINES + \
+                                MXC_MAX_VIRTUAL_INTS)
+
+#endif                         /* __ASM_ARCH_MXC_HARDWARE_H__ */
diff --git a/include/asm-arm/arch-mxc/io.h b/include/asm-arm/arch-mxc/io.h
new file mode 100644 (file)
index 0000000..cf6c83a
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  Copyright 2004-2007 Freescale Semiconductor, Inc. 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 as
+ * published by the Free Software Foundation.
+ */
+
+/*!
+ * @file io.h
+ * @brief This file contains some memory mapping macros.
+ * @note There is no real ISA or PCI buses. But have to define these macros
+ * for some drivers to compile.
+ *
+ * @ingroup System
+ */
+
+#ifndef __ASM_ARCH_MXC_IO_H__
+#define __ASM_ARCH_MXC_IO_H__
+
+/*! Allow IO space to be anywhere in the memory */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*!
+ * io address mapping macro
+ */
+#define __io(a)                        ((void __iomem *)(a))
+
+#define __mem_pci(a)           (a)
+
+#endif
diff --git a/include/asm-arm/arch-mxc/irqs.h b/include/asm-arm/arch-mxc/irqs.h
new file mode 100644 (file)
index 0000000..e4686c6
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  Copyright 2004-2007 Freescale Semiconductor, Inc. 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 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_IRQS_H__
+#define __ASM_ARCH_MXC_IRQS_H__
+
+#include <asm/hardware.h>
+
+/*!
+ * @file irqs.h
+ * @brief This file defines the number of normal interrupts and fast interrupts
+ *
+ * @ingroup Interrupt
+ */
+
+#define MXC_IRQ_TO_EXPIO(irq)  ((irq) - MXC_EXP_IO_BASE)
+
+#define MXC_IRQ_TO_GPIO(irq)   ((irq) - MXC_GPIO_INT_BASE)
+#define MXC_GPIO_TO_IRQ(x)     (MXC_GPIO_INT_BASE + x)
+
+/*!
+ * Number of normal interrupts
+ */
+#define NR_IRQS                MXC_MAX_INTS
+
+/*!
+ * Number of fast interrupts
+ */
+#define NR_FIQS                MXC_MAX_INTS
+
+#endif                         /* __ASM_ARCH_MXC_IRQS_H__ */
diff --git a/include/asm-arm/arch-mxc/memory.h b/include/asm-arm/arch-mxc/memory.h
new file mode 100644 (file)
index 0000000..c89aac8
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. 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 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_MEMORY_H__
+#define __ASM_ARCH_MXC_MEMORY_H__
+
+#include <asm/hardware.h>
+
+/*!
+ * @file memory.h
+ * @brief This file contains macros needed by the Linux kernel and drivers.
+ *
+ * @ingroup Memory
+ */
+
+/*!
+ * Virtual view <-> DMA view memory address translations
+ * This macro is used to translate the virtual address to an address
+ * suitable to be passed to set_dma_addr()
+ */
+#define __virt_to_bus(a)       __virt_to_phys(a)
+
+/*!
+ * Used to convert an address for DMA operations to an address that the
+ * kernel can use.
+ */
+#define __bus_to_virt(a)       __phys_to_virt(a)
+
+#endif                         /* __ASM_ARCH_MXC_MEMORY_H__ */
diff --git a/include/asm-arm/arch-mxc/mx31.h b/include/asm-arm/arch-mxc/mx31.h
new file mode 100644 (file)
index 0000000..85c49c9
--- /dev/null
@@ -0,0 +1,335 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. 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 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_MX31_H__
+#define __ASM_ARCH_MXC_MX31_H__
+
+#ifndef __ASM_ARCH_MXC_HARDWARE_H__
+#error "Do not include directly."
+#endif
+
+/*!
+ * defines the hardware clock tick rate
+ */
+#define CLOCK_TICK_RATE                16625000
+
+/*
+ * MX31 memory map:
+ *
+ * Virt                Phys            Size    What
+ * ---------------------------------------------------------------------------
+ * F8000000    1FFC0000        16K     IRAM
+ * F9000000    30000000        256M    L2CC
+ * FC000000    43F00000        1M      AIPS 1
+ * FC100000    50000000        1M      SPBA
+ * FC200000    53F00000        1M      AIPS 2
+ * FC500000    60000000        128M    ROMPATCH
+ * FC400000    68000000        128M    AVIC
+ *             70000000        256M    IPU (MAX M2)
+ *             80000000        256M    CSD0 SDRAM/DDR
+ *             90000000        256M    CSD1 SDRAM/DDR
+ *             A0000000        128M    CS0 Flash
+ *             A8000000        128M    CS1 Flash
+ *             B0000000        32M     CS2
+ *             B2000000        32M     CS3
+ * F4000000    B4000000        32M     CS4
+ *             B6000000        32M     CS5
+ * FC320000    B8000000        64K     NAND, SDRAM, WEIM, M3IF, EMI controllers
+ *             C0000000        64M     PCMCIA/CF
+ */
+
+#define CS0_BASE_ADDR          0xA0000000
+#define CS1_BASE_ADDR          0xA8000000
+#define CS2_BASE_ADDR          0xB0000000
+#define CS3_BASE_ADDR          0xB2000000
+
+#define CS4_BASE_ADDR          0xB4000000
+#define CS4_BASE_ADDR_VIRT     0xF4000000
+#define CS4_SIZE               SZ_32M
+
+#define CS5_BASE_ADDR          0xB6000000
+#define PCMCIA_MEM_BASE_ADDR   0xBC000000
+
+/*
+ * IRAM
+ */
+#define IRAM_BASE_ADDR         0x1FFC0000      /* internal ram */
+#define IRAM_BASE_ADDR_VIRT    0xF8000000
+#define IRAM_SIZE              SZ_16K
+
+/*
+ * L2CC
+ */
+#define L2CC_BASE_ADDR         0x30000000
+#define L2CC_BASE_ADDR_VIRT    0xF9000000
+#define L2CC_SIZE              SZ_1M
+
+/*
+ * AIPS 1
+ */
+#define AIPS1_BASE_ADDR                0x43F00000
+#define AIPS1_BASE_ADDR_VIRT   0xFC000000
+#define AIPS1_SIZE             SZ_1M
+
+#define MAX_BASE_ADDR          (AIPS1_BASE_ADDR + 0x00004000)
+#define EVTMON_BASE_ADDR       (AIPS1_BASE_ADDR + 0x00008000)
+#define CLKCTL_BASE_ADDR       (AIPS1_BASE_ADDR + 0x0000C000)
+#define ETB_SLOT4_BASE_ADDR    (AIPS1_BASE_ADDR + 0x00010000)
+#define ETB_SLOT5_BASE_ADDR    (AIPS1_BASE_ADDR + 0x00014000)
+#define ECT_CTIO_BASE_ADDR     (AIPS1_BASE_ADDR + 0x00018000)
+#define I2C_BASE_ADDR          (AIPS1_BASE_ADDR + 0x00080000)
+#define I2C3_BASE_ADDR         (AIPS1_BASE_ADDR + 0x00084000)
+#define OTG_BASE_ADDR          (AIPS1_BASE_ADDR + 0x00088000)
+#define ATA_BASE_ADDR          (AIPS1_BASE_ADDR + 0x0008C000)
+#define UART1_BASE_ADDR        (AIPS1_BASE_ADDR + 0x00090000)
+#define UART2_BASE_ADDR        (AIPS1_BASE_ADDR + 0x00094000)
+#define I2C2_BASE_ADDR         (AIPS1_BASE_ADDR + 0x00098000)
+#define OWIRE_BASE_ADDR        (AIPS1_BASE_ADDR + 0x0009C000)
+#define SSI1_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000A0000)
+#define CSPI1_BASE_ADDR        (AIPS1_BASE_ADDR + 0x000A4000)
+#define KPP_BASE_ADDR          (AIPS1_BASE_ADDR + 0x000A8000)
+#define IOMUXC_BASE_ADDR       (AIPS1_BASE_ADDR + 0x000AC000)
+#define UART4_BASE_ADDR        (AIPS1_BASE_ADDR + 0x000B0000)
+#define UART5_BASE_ADDR        (AIPS1_BASE_ADDR + 0x000B4000)
+#define ECT_IP1_BASE_ADDR      (AIPS1_BASE_ADDR + 0x000B8000)
+#define ECT_IP2_BASE_ADDR      (AIPS1_BASE_ADDR + 0x000BC000)
+
+/*
+ * SPBA global module enabled #0
+ */
+#define SPBA0_BASE_ADDR        0x50000000
+#define SPBA0_BASE_ADDR_VIRT   0xFC100000
+#define SPBA0_SIZE             SZ_1M
+
+#define MMC_SDHC1_BASE_ADDR    (SPBA0_BASE_ADDR + 0x00004000)
+#define MMC_SDHC2_BASE_ADDR    (SPBA0_BASE_ADDR + 0x00008000)
+#define UART3_BASE_ADDR        (SPBA0_BASE_ADDR + 0x0000C000)
+#define CSPI2_BASE_ADDR        (SPBA0_BASE_ADDR + 0x00010000)
+#define SSI2_BASE_ADDR         (SPBA0_BASE_ADDR + 0x00014000)
+#define SIM1_BASE_ADDR         (SPBA0_BASE_ADDR + 0x00018000)
+#define IIM_BASE_ADDR          (SPBA0_BASE_ADDR + 0x0001C000)
+#define ATA_DMA_BASE_ADDR      (SPBA0_BASE_ADDR + 0x00020000)
+#define MSHC1_BASE_ADDR                (SPBA0_BASE_ADDR + 0x00024000)
+#define MSHC2_BASE_ADDR                (SPBA0_BASE_ADDR + 0x00024000)
+#define SPBA_CTRL_BASE_ADDR    (SPBA0_BASE_ADDR + 0x0003C000)
+
+/*
+ * AIPS 2
+ */
+#define AIPS2_BASE_ADDR                0x53F00000
+#define AIPS2_BASE_ADDR_VIRT   0xFC200000
+#define AIPS2_SIZE             SZ_1M
+#define CCM_BASE_ADDR          (AIPS2_BASE_ADDR + 0x00080000)
+#define CSPI3_BASE_ADDR                (AIPS2_BASE_ADDR + 0x00084000)
+#define FIRI_BASE_ADDR         (AIPS2_BASE_ADDR + 0x0008C000)
+#define GPT1_BASE_ADDR         (AIPS2_BASE_ADDR + 0x00090000)
+#define EPIT1_BASE_ADDR                (AIPS2_BASE_ADDR + 0x00094000)
+#define EPIT2_BASE_ADDR                (AIPS2_BASE_ADDR + 0x00098000)
+#define GPIO3_BASE_ADDR                (AIPS2_BASE_ADDR + 0x000A4000)
+#define SCC_BASE_ADDR          (AIPS2_BASE_ADDR + 0x000AC000)
+#define SCM_BASE_ADDR          (AIPS2_BASE_ADDR + 0x000AE000)
+#define SMN_BASE_ADDR          (AIPS2_BASE_ADDR + 0x000AF000)
+#define RNGA_BASE_ADDR         (AIPS2_BASE_ADDR + 0x000B0000)
+#define IPU_CTRL_BASE_ADDR     (AIPS2_BASE_ADDR + 0x000C0000)
+#define AUDMUX_BASE_ADDR       (AIPS2_BASE_ADDR + 0x000C4000)
+#define MPEG4_ENC_BASE_ADDR    (AIPS2_BASE_ADDR + 0x000C8000)
+#define GPIO1_BASE_ADDR                (AIPS2_BASE_ADDR + 0x000CC000)
+#define GPIO2_BASE_ADDR                (AIPS2_BASE_ADDR + 0x000D0000)
+#define SDMA_BASE_ADDR         (AIPS2_BASE_ADDR + 0x000D4000)
+#define RTC_BASE_ADDR          (AIPS2_BASE_ADDR + 0x000D8000)
+#define WDOG_BASE_ADDR         (AIPS2_BASE_ADDR + 0x000DC000)
+#define PWM_BASE_ADDR          (AIPS2_BASE_ADDR + 0x000E0000)
+#define RTIC_BASE_ADDR         (AIPS2_BASE_ADDR + 0x000EC000)
+
+/*
+ * ROMP and AVIC
+ */
+#define ROMP_BASE_ADDR         0x60000000
+#define ROMP_BASE_ADDR_VIRT    0xFC500000
+#define ROMP_SIZE              SZ_1M
+
+#define AVIC_BASE_ADDR         0x68000000
+#define AVIC_BASE_ADDR_VIRT    0xFC400000
+#define AVIC_SIZE              SZ_1M
+
+/*
+ * NAND, SDRAM, WEIM, M3IF, EMI controllers
+ */
+#define X_MEMC_BASE_ADDR       0xB8000000
+#define X_MEMC_BASE_ADDR_VIRT  0xFC320000
+#define X_MEMC_SIZE            SZ_64K
+
+#define NFC_BASE_ADDR          (X_MEMC_BASE_ADDR + 0x0000)
+#define ESDCTL_BASE_ADDR       (X_MEMC_BASE_ADDR + 0x1000)
+#define WEIM_BASE_ADDR         (X_MEMC_BASE_ADDR + 0x2000)
+#define M3IF_BASE_ADDR         (X_MEMC_BASE_ADDR + 0x3000)
+#define EMI_CTL_BASE_ADDR      (X_MEMC_BASE_ADDR + 0x4000)
+#define PCMCIA_CTL_BASE_ADDR   EMI_CTL_BASE_ADDR
+
+/*
+ * Memory regions and CS
+ */
+#define IPU_MEM_BASE_ADDR      0x70000000
+#define CSD0_BASE_ADDR         0x80000000
+#define CSD1_BASE_ADDR         0x90000000
+#define CS0_BASE_ADDR          0xA0000000
+#define CS1_BASE_ADDR          0xA8000000
+#define CS2_BASE_ADDR          0xB0000000
+#define CS3_BASE_ADDR          0xB2000000
+
+#define CS4_BASE_ADDR          0xB4000000
+#define CS4_BASE_ADDR_VIRT     0xF4000000
+#define CS4_SIZE               SZ_32M
+
+#define CS5_BASE_ADDR          0xB6000000
+#define PCMCIA_MEM_BASE_ADDR   0xBC000000
+
+/*!
+ * This macro defines the physical to virtual address mapping for all the
+ * peripheral modules. It is used by passing in the physical address as x
+ * and returning the virtual address. If the physical address is not mapped,
+ * it returns 0xDEADBEEF
+ */
+#define IO_ADDRESS(x)   \
+       (((x >= IRAM_BASE_ADDR) && (x < (IRAM_BASE_ADDR + IRAM_SIZE))) ? IRAM_IO_ADDRESS(x):\
+       ((x >= L2CC_BASE_ADDR) && (x < (L2CC_BASE_ADDR + L2CC_SIZE))) ? L2CC_IO_ADDRESS(x):\
+       ((x >= AIPS1_BASE_ADDR) && (x < (AIPS1_BASE_ADDR + AIPS1_SIZE))) ? AIPS1_IO_ADDRESS(x):\
+       ((x >= SPBA0_BASE_ADDR) && (x < (SPBA0_BASE_ADDR + SPBA0_SIZE))) ? SPBA0_IO_ADDRESS(x):\
+       ((x >= AIPS2_BASE_ADDR) && (x < (AIPS2_BASE_ADDR + AIPS2_SIZE))) ? AIPS2_IO_ADDRESS(x):\
+       ((x >= ROMP_BASE_ADDR) && (x < (ROMP_BASE_ADDR + ROMP_SIZE))) ? ROMP_IO_ADDRESS(x):\
+       ((x >= AVIC_BASE_ADDR) && (x < (AVIC_BASE_ADDR + AVIC_SIZE))) ? AVIC_IO_ADDRESS(x):\
+       ((x >= CS4_BASE_ADDR) && (x < (CS4_BASE_ADDR + CS4_SIZE))) ? CS4_IO_ADDRESS(x):\
+       ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? X_MEMC_IO_ADDRESS(x):\
+       0xDEADBEEF)
+
+/*
+ * define the address mapping macros: in physical address order
+ */
+
+#define IRAM_IO_ADDRESS(x)  \
+       (((x) - IRAM_BASE_ADDR) + IRAM_BASE_ADDR_VIRT)
+
+#define L2CC_IO_ADDRESS(x)  \
+       (((x) - L2CC_BASE_ADDR) + L2CC_BASE_ADDR_VIRT)
+
+#define AIPS1_IO_ADDRESS(x)  \
+       (((x) - AIPS1_BASE_ADDR) + AIPS1_BASE_ADDR_VIRT)
+
+#define SPBA0_IO_ADDRESS(x)  \
+       (((x) - SPBA0_BASE_ADDR) + SPBA0_BASE_ADDR_VIRT)
+
+#define AIPS2_IO_ADDRESS(x)  \
+       (((x) - AIPS2_BASE_ADDR) + AIPS2_BASE_ADDR_VIRT)
+
+#define ROMP_IO_ADDRESS(x)  \
+       (((x) - ROMP_BASE_ADDR) + ROMP_BASE_ADDR_VIRT)
+
+#define AVIC_IO_ADDRESS(x)  \
+       (((x) - AVIC_BASE_ADDR) + AVIC_BASE_ADDR_VIRT)
+
+#define CS4_IO_ADDRESS(x)  \
+       (((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT)
+
+#define X_MEMC_IO_ADDRESS(x)  \
+       (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+
+#define PCMCIA_IO_ADDRESS(x) \
+       (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+
+/* Start of physical RAM - On many MX31 platforms, this is the first SDRAM bank (CSD0) */
+#define PHYS_OFFSET             CSD0_BASE_ADDR
+
+/*
+ * Interrupt numbers
+ */
+#define MXC_INT_PEN_ADS7843    0
+#define MXC_INT_RESV1          1
+#define MXC_INT_CS8900A                2
+#define MXC_INT_I2C3           3
+#define MXC_INT_I2C2           4
+#define MXC_INT_MPEG4_ENCODER  5
+#define MXC_INT_RTIC           6
+#define MXC_INT_FIRI           7
+#define MXC_INT_MMC_SDHC2      8
+#define MXC_INT_MMC_SDHC1      9
+#define MXC_INT_I2C            10
+#define MXC_INT_SSI2           11
+#define MXC_INT_SSI1           12
+#define MXC_INT_CSPI2          13
+#define MXC_INT_CSPI1          14
+#define MXC_INT_ATA            15
+#define MXC_INT_MBX            16
+#define MXC_INT_CSPI3          17
+#define MXC_INT_UART3          18
+#define MXC_INT_IIM            19
+#define MXC_INT_SIM2           20
+#define MXC_INT_SIM1           21
+#define MXC_INT_RNGA           22
+#define MXC_INT_EVTMON         23
+#define MXC_INT_KPP            24
+#define MXC_INT_RTC            25
+#define MXC_INT_PWM            26
+#define MXC_INT_EPIT2          27
+#define MXC_INT_EPIT1          28
+#define MXC_INT_GPT            29
+#define MXC_INT_RESV30         30
+#define MXC_INT_RESV31         31
+#define MXC_INT_UART2          32
+#define MXC_INT_NANDFC         33
+#define MXC_INT_SDMA           34
+#define MXC_INT_USB1           35
+#define MXC_INT_USB2           36
+#define MXC_INT_USB3           37
+#define MXC_INT_USB4           38
+#define MXC_INT_MSHC1          39
+#define MXC_INT_MSHC2          40
+#define MXC_INT_IPU_ERR                41
+#define MXC_INT_IPU_SYN                42
+#define MXC_INT_RESV43         43
+#define MXC_INT_RESV44         44
+#define MXC_INT_UART1          45
+#define MXC_INT_UART4          46
+#define MXC_INT_UART5          47
+#define MXC_INT_ECT            48
+#define MXC_INT_SCC_SCM                49
+#define MXC_INT_SCC_SMN                50
+#define MXC_INT_GPIO2          51
+#define MXC_INT_GPIO1          52
+#define MXC_INT_CCM            53
+#define MXC_INT_PCMCIA         54
+#define MXC_INT_WDOG           55
+#define MXC_INT_GPIO3          56
+#define MXC_INT_RESV57         57
+#define MXC_INT_EXT_POWER      58
+#define MXC_INT_EXT_TEMPER     59
+#define MXC_INT_EXT_SENSOR60   60
+#define MXC_INT_EXT_SENSOR61   61
+#define MXC_INT_EXT_WDOG       62
+#define MXC_INT_EXT_TV         63
+
+#define MXC_MAX_INT_LINES      64
+
+#define MXC_GPIO_INT_BASE      MXC_MAX_INT_LINES
+
+/*!
+ * Number of GPIO port as defined in the IC Spec
+ */
+#define GPIO_PORT_NUM          3
+/*!
+ * Number of GPIO pins per port
+ */
+#define GPIO_NUM_PIN           32
+
+#define PROD_SIGNATURE         0x1     /* For MX31 */
+
+#define SYSTEM_REV_MIN         CHIP_REV_1_0
+#define SYSTEM_REV_NUM         3
+
+#endif                 /*  __ASM_ARCH_MXC_MX31_H__ */
diff --git a/include/asm-arm/arch-mxc/mxc.h b/include/asm-arm/arch-mxc/mxc.h
new file mode 100644 (file)
index 0000000..0837f1f
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. 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 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_H__
+#define __ASM_ARCH_MXC_H__
+
+#ifndef __ASM_ARCH_MXC_HARDWARE_H__
+#error "Do not include directly."
+#endif
+
+/*
+ *****************************************
+ * GPT  Register definitions             *
+ *****************************************
+ */
+#define MXC_GPT_GPTCR          IO_ADDRESS(GPT1_BASE_ADDR + 0x00)
+#define MXC_GPT_GPTPR          IO_ADDRESS(GPT1_BASE_ADDR + 0x04)
+#define MXC_GPT_GPTSR          IO_ADDRESS(GPT1_BASE_ADDR + 0x08)
+#define MXC_GPT_GPTIR          IO_ADDRESS(GPT1_BASE_ADDR + 0x0C)
+#define MXC_GPT_GPTOCR1                IO_ADDRESS(GPT1_BASE_ADDR + 0x10)
+#define MXC_GPT_GPTOCR2                IO_ADDRESS(GPT1_BASE_ADDR + 0x14)
+#define MXC_GPT_GPTOCR3                IO_ADDRESS(GPT1_BASE_ADDR + 0x18)
+#define MXC_GPT_GPTICR1                IO_ADDRESS(GPT1_BASE_ADDR + 0x1C)
+#define MXC_GPT_GPTICR2                IO_ADDRESS(GPT1_BASE_ADDR + 0x20)
+#define MXC_GPT_GPTCNT         IO_ADDRESS(GPT1_BASE_ADDR + 0x24)
+
+/*!
+ * GPT Control register bit definitions
+ */
+#define GPTCR_FO3                      (1 << 31)
+#define GPTCR_FO2                      (1 << 30)
+#define GPTCR_FO1                      (1 << 29)
+
+#define GPTCR_OM3_SHIFT                        26
+#define GPTCR_OM3_MASK                 (7 << GPTCR_OM3_SHIFT)
+#define GPTCR_OM3_DISCONNECTED         (0 << GPTCR_OM3_SHIFT)
+#define GPTCR_OM3_TOGGLE               (1 << GPTCR_OM3_SHIFT)
+#define GPTCR_OM3_CLEAR                        (2 << GPTCR_OM3_SHIFT)
+#define GPTCR_OM3_SET                  (3 << GPTCR_OM3_SHIFT)
+#define GPTCR_OM3_GENERATE_LOW         (7 << GPTCR_OM3_SHIFT)
+
+#define GPTCR_OM2_SHIFT                        23
+#define GPTCR_OM2_MASK                 (7 << GPTCR_OM2_SHIFT)
+#define GPTCR_OM2_DISCONNECTED         (0 << GPTCR_OM2_SHIFT)
+#define GPTCR_OM2_TOGGLE               (1 << GPTCR_OM2_SHIFT)
+#define GPTCR_OM2_CLEAR                        (2 << GPTCR_OM2_SHIFT)
+#define GPTCR_OM2_SET                  (3 << GPTCR_OM2_SHIFT)
+#define GPTCR_OM2_GENERATE_LOW         (7 << GPTCR_OM2_SHIFT)
+
+#define GPTCR_OM1_SHIFT                        20
+#define GPTCR_OM1_MASK                 (7 << GPTCR_OM1_SHIFT)
+#define GPTCR_OM1_DISCONNECTED         (0 << GPTCR_OM1_SHIFT)
+#define GPTCR_OM1_TOGGLE               (1 << GPTCR_OM1_SHIFT)
+#define GPTCR_OM1_CLEAR                        (2 << GPTCR_OM1_SHIFT)
+#define GPTCR_OM1_SET                  (3 << GPTCR_OM1_SHIFT)
+#define GPTCR_OM1_GENERATE_LOW         (7 << GPTCR_OM1_SHIFT)
+
+#define GPTCR_IM2_SHIFT                        18
+#define GPTCR_IM2_MASK                 (3 << GPTCR_IM2_SHIFT)
+#define GPTCR_IM2_CAPTURE_DISABLE      (0 << GPTCR_IM2_SHIFT)
+#define GPTCR_IM2_CAPTURE_RISING       (1 << GPTCR_IM2_SHIFT)
+#define GPTCR_IM2_CAPTURE_FALLING      (2 << GPTCR_IM2_SHIFT)
+#define GPTCR_IM2_CAPTURE_BOTH         (3 << GPTCR_IM2_SHIFT)
+
+#define GPTCR_IM1_SHIFT                        16
+#define GPTCR_IM1_MASK                 (3 << GPTCR_IM1_SHIFT)
+#define GPTCR_IM1_CAPTURE_DISABLE      (0 << GPTCR_IM1_SHIFT)
+#define GPTCR_IM1_CAPTURE_RISING       (1 << GPTCR_IM1_SHIFT)
+#define GPTCR_IM1_CAPTURE_FALLING      (2 << GPTCR_IM1_SHIFT)
+#define GPTCR_IM1_CAPTURE_BOTH         (3 << GPTCR_IM1_SHIFT)
+
+#define GPTCR_SWR                      (1 << 15)
+#define GPTCR_FRR                      (1 << 9)
+
+#define GPTCR_CLKSRC_SHIFT             6
+#define GPTCR_CLKSRC_MASK              (7 << GPTCR_CLKSRC_SHIFT)
+#define GPTCR_CLKSRC_NOCLOCK           (0 << GPTCR_CLKSRC_SHIFT)
+#define GPTCR_CLKSRC_HIGHFREQ          (2 << GPTCR_CLKSRC_SHIFT)
+#define GPTCR_CLKSRC_CLKIN             (3 << GPTCR_CLKSRC_SHIFT)
+#define GPTCR_CLKSRC_CLK32K            (7 << GPTCR_CLKSRC_SHIFT)
+
+#define GPTCR_STOPEN                   (1 << 5)
+#define GPTCR_DOZEN                    (1 << 4)
+#define GPTCR_WAITEN                   (1 << 3)
+#define GPTCR_DBGEN                    (1 << 2)
+
+#define GPTCR_ENMOD                    (1 << 1)
+#define GPTCR_ENABLE                   (1 << 0)
+
+#define GPTSR_OF1                      (1 << 0)
+#define GPTSR_OF2                      (1 << 1)
+#define GPTSR_OF3                      (1 << 2)
+#define GPTSR_IF1                      (1 << 3)
+#define GPTSR_IF2                      (1 << 4)
+#define GPTSR_ROV                      (1 << 5)
+
+#define GPTIR_OF1IE                    GPTSR_OF1
+#define GPTIR_OF2IE                    GPTSR_OF2
+#define GPTIR_OF3IE                    GPTSR_OF3
+#define GPTIR_IF1IE                    GPTSR_IF1
+#define GPTIR_IF2IE                    GPTSR_IF2
+#define GPTIR_ROVIE                    GPTSR_ROV
+
+/*
+ *****************************************
+ * AVIC Registers                        *
+ *****************************************
+ */
+#define AVIC_BASE              IO_ADDRESS(AVIC_BASE_ADDR)
+#define AVIC_INTCNTL           (AVIC_BASE + 0x00)      /* int control reg */
+#define AVIC_NIMASK            (AVIC_BASE + 0x04)      /* int mask reg */
+#define AVIC_INTENNUM          (AVIC_BASE + 0x08)      /* int enable number reg */
+#define AVIC_INTDISNUM         (AVIC_BASE + 0x0C)      /* int disable number reg */
+#define AVIC_INTENABLEH                (AVIC_BASE + 0x10)      /* int enable reg high */
+#define AVIC_INTENABLEL                (AVIC_BASE + 0x14)      /* int enable reg low */
+#define AVIC_INTTYPEH          (AVIC_BASE + 0x18)      /* int type reg high */
+#define AVIC_INTTYPEL          (AVIC_BASE + 0x1C)      /* int type reg low */
+#define AVIC_NIPRIORITY7       (AVIC_BASE + 0x20)      /* norm int priority lvl7 */
+#define AVIC_NIPRIORITY6       (AVIC_BASE + 0x24)      /* norm int priority lvl6 */
+#define AVIC_NIPRIORITY5       (AVIC_BASE + 0x28)      /* norm int priority lvl5 */
+#define AVIC_NIPRIORITY4       (AVIC_BASE + 0x2C)      /* norm int priority lvl4 */
+#define AVIC_NIPRIORITY3       (AVIC_BASE + 0x30)      /* norm int priority lvl3 */
+#define AVIC_NIPRIORITY2       (AVIC_BASE + 0x34)      /* norm int priority lvl2 */
+#define AVIC_NIPRIORITY1       (AVIC_BASE + 0x38)      /* norm int priority lvl1 */
+#define AVIC_NIPRIORITY0       (AVIC_BASE + 0x3C)      /* norm int priority lvl0 */
+#define AVIC_NIVECSR           (AVIC_BASE + 0x40)      /* norm int vector/status */
+#define AVIC_FIVECSR           (AVIC_BASE + 0x44)      /* fast int vector/status */
+#define AVIC_INTSRCH           (AVIC_BASE + 0x48)      /* int source reg high */
+#define AVIC_INTSRCL           (AVIC_BASE + 0x4C)      /* int source reg low */
+#define AVIC_INTFRCH           (AVIC_BASE + 0x50)      /* int force reg high */
+#define AVIC_INTFRCL           (AVIC_BASE + 0x54)      /* int force reg low */
+#define AVIC_NIPNDH            (AVIC_BASE + 0x58)      /* norm int pending high */
+#define AVIC_NIPNDL            (AVIC_BASE + 0x5C)      /* norm int pending low */
+#define AVIC_FIPNDH            (AVIC_BASE + 0x60)      /* fast int pending high */
+#define AVIC_FIPNDL            (AVIC_BASE + 0x64)      /* fast int pending low */
+
+#define SYSTEM_PREV_REG                IO_ADDRESS(IIM_BASE_ADDR + 0x20)
+#define SYSTEM_SREV_REG                IO_ADDRESS(IIM_BASE_ADDR + 0x24)
+#define IIM_PROD_REV_SH                3
+#define IIM_PROD_REV_LEN       5
+
+#endif                         /*  __ASM_ARCH_MXC_H__ */
diff --git a/include/asm-arm/arch-mxc/system.h b/include/asm-arm/arch-mxc/system.h
new file mode 100644 (file)
index 0000000..109956b
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright 2004-2007 Freescale Semiconductor, Inc. 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; 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_MXC_SYSTEM_H__
+#define __ASM_ARCH_MXC_SYSTEM_H__
+
+/*!
+ * @file system.h
+ * @brief This file contains idle and reset functions.
+ *
+ * @ingroup System
+ */
+
+/*!
+ * This function puts the CPU into idle mode. It is called by default_idle()
+ * in process.c file.
+ */
+static inline void arch_idle(void)
+{
+       cpu_do_idle();
+}
+
+/*
+ * This function resets the system. It is called by machine_restart().
+ *
+ * @param  mode         indicates different kinds of resets
+ */
+static inline void arch_reset(char mode)
+{
+       cpu_reset(0);
+}
+
+#endif                         /* __ASM_ARCH_MXC_SYSTEM_H__ */
diff --git a/include/asm-arm/arch-mxc/timex.h b/include/asm-arm/arch-mxc/timex.h
new file mode 100644 (file)
index 0000000..59019fa
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ *  Copyright (C) 1999 ARM Limited
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. 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; 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_MXC_TIMEX_H__
+#define __ASM_ARCH_MXC_TIMEX_H__
+
+#include <asm/hardware.h>      /* for CLOCK_TICK_RATE */
+
+#endif                         /* __ASM_ARCH_MXC_TIMEX_H__ */
diff --git a/include/asm-arm/arch-mxc/uncompress.h b/include/asm-arm/arch-mxc/uncompress.h
new file mode 100644 (file)
index 0000000..ec5787d
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *  include/asm-arm/arch-mxc/uncompress.h
+ *
+ *
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) Shane Nay (shane@minirl.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARCH_MXC_UNCOMPRESS_H__
+#define __ASM_ARCH_MXC_UNCOMPRESS_H__
+
+#define __MXC_BOOT_UNCOMPRESS
+
+#include <asm/hardware.h>
+#include <asm/processor.h>
+
+#define UART(x) (*(volatile unsigned long *)(serial_port + (x)))
+
+#define USR2 0x98
+#define USR2_TXFE (1<<14)
+#define TXR  0x40
+#define UCR1 0x80
+#define UCR1_UARTEN 1
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader.  We search for the first enabled
+ * port in the most probable order.  If you didn't setup a port in
+ * your bootloader then nothing will appear (which might be desired).
+ *
+ * This does not append a newline
+ */
+
+static void putc(int ch)
+{
+       static unsigned long serial_port = 0;
+
+       if (unlikely(serial_port == 0)) {
+               do {
+                       serial_port = UART1_BASE_ADDR;
+                       if (UART(UCR1) & UCR1_UARTEN)
+                               break;
+                       serial_port = UART2_BASE_ADDR;
+                       if (UART(UCR1) & UCR1_UARTEN)
+                               break;
+                       return;
+               } while (0);
+       }
+
+       while (!(UART(USR2) & USR2_TXFE))
+               cpu_relax();
+
+       UART(TXR) = ch;
+}
+
+#define flush() do { } while (0)
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+
+#define arch_decomp_wdog()
+
+#endif                         /* __ASM_ARCH_MXC_UNCOMPRESS_H__ */
diff --git a/include/asm-arm/arch-mxc/vmalloc.h b/include/asm-arm/arch-mxc/vmalloc.h
new file mode 100644 (file)
index 0000000..83a73da
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (C) 2000 Russell King.
+ *  Copyright 2004-2007 Freescale Semiconductor, Inc. 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; 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_MXC_VMALLOC_H__
+#define __ASM_ARCH_MXC_VMALLOC_H__
+
+/*!
+ * @file vmalloc.h
+ *
+ * @brief This file contains platform specific macros for vmalloc.
+ *
+ * @ingroup System
+ */
+
+/*!
+ * vmalloc ending address
+ */
+#define VMALLOC_END       0xF4000000
+
+#endif                         /* __ASM_ARCH_MXC_VMALLOC_H__ */
index e26269546240320706d98e9c46d0a27cbb5c7add..7ee194dc6354708784a750b44a71ec6da92a9659 100644 (file)
 
 /* BBus Utility */
 
-/* GPIO Configuration Register */
-#define BBU_GC(x)      __REG2(0x9060000c, (x))
+/* GPIO Configuration Registers block 1 */
+/* NOTE: the HRM starts counting at 1 for the GPIO registers, here the start is
+ * at 0 for each block.  That is, BBU_GCONFb1(0) is GPIO Configuration Register
+ * #1, BBU_GCONFb2(0) is GPIO Configuration Register #8. */
+#define BBU_GCONFb1(x) __REG2(0x90600010, (x))
+#define BBU_GCONFb2(x) __REG2(0x90600100, (x))
+
+#define BBU_GCONFx_DIR(m)      __REGBIT(3 + (((m) & 7) << 2))
+#define BBU_GCONFx_DIR_INPUT(m)        __REGVAL(BBU_GCONFx_DIR(m), 0)
+#define BBU_GCONFx_DIR_OUTPUT(m)       __REGVAL(BBU_GCONFx_DIR(m), 1)
+#define BBU_GCONFx_INV(m)      __REGBIT(2 + (((m) & 7) << 2))
+#define BBU_GCONFx_INV_NO(m)           __REGVAL(BBU_GCONFx_INV(m), 0)
+#define BBU_GCONFx_INV_YES(m)          __REGVAL(BBU_GCONFx_INV(m), 1)
+#define BBU_GCONFx_FUNC(m)     __REGBITS(1 + (((m) & 7) << 2), ((m) & 7) << 2)
+#define BBU_GCONFx_FUNC_0(m)           __REGVAL(BBU_GCONFx_FUNC(m), 0)
+#define BBU_GCONFx_FUNC_1(m)           __REGVAL(BBU_GCONFx_FUNC(m), 1)
+#define BBU_GCONFx_FUNC_2(m)           __REGVAL(BBU_GCONFx_FUNC(m), 2)
+#define BBU_GCONFx_FUNC_3(m)           __REGVAL(BBU_GCONFx_FUNC(m), 3)
+
+#define BBU_GCTRL1     __REG(0x90600030)
+#define BBU_GCTRL2     __REG(0x90600034)
+#define BBU_GCTRL3     __REG(0x90600120)
+
+#define BBU_GSTAT1     __REG(0x90600040)
+#define BBU_GSTAT2     __REG(0x90600044)
+#define BBU_GSTAT3     __REG(0x90600130)
 
 #endif /* ifndef __ASM_ARCH_REGSBBU_H */
index 8ed8448767b93392438b042be864624bb416710c..fb455a0ed8455a77bd81fd41af28c7c342037a15 100644 (file)
@@ -79,9 +79,9 @@
 #define MEM_SMC(x)     __REG2(0xa0700200, (x) << 3)
 
 /* Static Memory Configuration Register x: Write protect */
-#define MEM_SMC_WSMC           __REGBIT(20)
-#define MEM_SMC_WSMC_OFF               __REGVAL(MEM_SMC_WSMC, 0)
-#define MEM_SMC_WSMC_ON                        __REGVAL(MEM_SMC_WSMC, 1)
+#define MEM_SMC_PSMC           __REGBIT(20)
+#define MEM_SMC_PSMC_OFF               __REGVAL(MEM_SMC_PSMC, 0)
+#define MEM_SMC_PSMC_ON                        __REGVAL(MEM_SMC_PSMC, 1)
 
 /* Static Memory Configuration Register x: Buffer enable */
 #define MEM_SMC_BSMC           __REGBIT(19)
index a42546aeb92a0eaa67426292e7b128595c1d7b55..749262f86204ea4ad365ee267f0ee243f1f0a327 100644 (file)
@@ -64,7 +64,7 @@
 
 /* Timer x Control register: Timer enable */
 #define SYS_TCx_TEN            __REGBIT(15)
-#define SYS_TCx_TEN_DIS                        __REGVAL(SYS_TCx_TEN, 1)
+#define SYS_TCx_TEN_DIS                        __REGVAL(SYS_TCx_TEN, 0)
 #define SYS_TCx_TEN_EN                 __REGVAL(SYS_TCx_TEN, 1)
 
 /* Timer x Control register: CPU debug mode */
index 52243a62c4e76de36fbe21f8aa10d4846684e283..6903db7fae154b15b5490e4ba2d8154a7690d869 100644 (file)
@@ -7,5 +7,19 @@
  *
  */
 
-extern int pxa_pm_prepare(suspend_state_t state);
+struct pxa_cpu_pm_fns {
+       int     save_size;
+       void    (*save)(unsigned long *);
+       void    (*restore)(unsigned long *);
+       int     (*valid)(suspend_state_t state);
+       void    (*enter)(suspend_state_t state);
+};
+
+extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
+
+/* sleep.S */
+extern void pxa25x_cpu_suspend(unsigned int);
+extern void pxa27x_cpu_suspend(unsigned int);
+extern void pxa_cpu_resume(void);
+
 extern int pxa_pm_enter(suspend_state_t state);
diff --git a/include/asm-arm/arch-s3c2400/map.h b/include/asm-arm/arch-s3c2400/map.h
new file mode 100644 (file)
index 0000000..1184d90
--- /dev/null
@@ -0,0 +1,66 @@
+/* linux/include/asm-arm/arch-s3c2400/map.h
+ *
+ * Copyright 2003,2007  Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Copyright 2003, Lucas Correia Villa Real
+ *
+ * S3C2400 - Memory map definitions
+ *
+ * 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.
+*/
+
+#define S3C2400_PA_MEMCTRL     (0x14000000)
+#define S3C2400_PA_USBHOST     (0x14200000)
+#define S3C2400_PA_IRQ         (0x14400000)
+#define S3C2400_PA_DMA         (0x14600000)
+#define S3C2400_PA_CLKPWR      (0x14800000)
+#define S3C2400_PA_LCD         (0x14A00000)
+#define S3C2400_PA_UART                (0x15000000)
+#define S3C2400_PA_TIMER       (0x15100000)
+#define S3C2400_PA_USBDEV      (0x15200140)
+#define S3C2400_PA_WATCHDOG    (0x15300000)
+#define S3C2400_PA_IIC         (0x15400000)
+#define S3C2400_PA_IIS         (0x15508000)
+#define S3C2400_PA_GPIO                (0x15600000)
+#define S3C2400_PA_RTC         (0x15700040)
+#define S3C2400_PA_ADC         (0x15800000)
+#define S3C2400_PA_SPI         (0x15900000)
+
+#define S3C2400_PA_MMC         (0x15A00000)
+#define S3C2400_SZ_MMC         SZ_1M
+
+/* physical addresses of all the chip-select areas */
+
+#define S3C2400_CS0    (0x00000000)
+#define S3C2400_CS1    (0x02000000)
+#define S3C2400_CS2    (0x04000000)
+#define S3C2400_CS3    (0x06000000)
+#define S3C2400_CS4    (0x08000000)
+#define S3C2400_CS5    (0x0A000000)
+#define S3C2400_CS6    (0x0C000000)
+#define S3C2400_CS7    (0x0E000000)
+
+#define S3C2400_SDRAM_PA    (S3C2400_CS6)
+
+/* Use a single interface for common resources between S3C24XX cpus */
+
+#define S3C24XX_PA_IRQ         S3C2400_PA_IRQ
+#define S3C24XX_PA_MEMCTRL     S3C2400_PA_MEMCTRL
+#define S3C24XX_PA_USBHOST     S3C2400_PA_USBHOST
+#define S3C24XX_PA_DMA         S3C2400_PA_DMA
+#define S3C24XX_PA_CLKPWR      S3C2400_PA_CLKPWR
+#define S3C24XX_PA_LCD         S3C2400_PA_LCD
+#define S3C24XX_PA_UART                S3C2400_PA_UART
+#define S3C24XX_PA_TIMER       S3C2400_PA_TIMER
+#define S3C24XX_PA_USBDEV      S3C2400_PA_USBDEV
+#define S3C24XX_PA_WATCHDOG    S3C2400_PA_WATCHDOG
+#define S3C24XX_PA_IIC         S3C2400_PA_IIC
+#define S3C24XX_PA_IIS         S3C2400_PA_IIS
+#define S3C24XX_PA_GPIO                S3C2400_PA_GPIO
+#define S3C24XX_PA_RTC         S3C2400_PA_RTC
+#define S3C24XX_PA_ADC         S3C2400_PA_ADC
+#define S3C24XX_PA_SPI         S3C2400_PA_SPI
diff --git a/include/asm-arm/arch-s3c2400/memory.h b/include/asm-arm/arch-s3c2400/memory.h
new file mode 100644 (file)
index 0000000..fb0381d
--- /dev/null
@@ -0,0 +1,23 @@
+/* linux/include/asm-arm/arch-s3c2400/memory.h
+ *  from linux/include/asm-arm/arch-rpc/memory.h
+ *
+ *  Copyright 2007 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ *  Copyright (C) 1996,1997,1998 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET    UL(0x0C000000)
+
+#define __virt_to_bus(x) __virt_to_phys(x)
+#define __bus_to_virt(x) __phys_to_virt(x)
+
+#endif
index 93064860e0e57bc106d5db72af34fd446fcf668c..9c8cd9abb82ba6bac45b3609be47f949d4f3148f 100644 (file)
 */
 
 #include <asm/arch/map.h>
-#include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
+#include <asm/plat-s3c/regs-serial.h>
 
 #define S3C2410_UART1_OFF (0x4000)
 #define SHIFT_2440TXF (14-9)
 
-               .macro addruart, rx
+       .macro addruart, rx
                mrc     p15, 0, \rx, c1, c0
                tst     \rx, #1
                ldreq   \rx, = S3C24XX_PA_UART
                ldrne   \rx, = S3C24XX_VA_UART
-#if CONFIG_DEBUG_S3C2410_UART != 0
-               add     \rx, \rx, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C2410_UART)
+#if CONFIG_DEBUG_S3C_UART != 0
+               add     \rx, \rx, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART)
 #endif
-               .endm
+       .endm
 
-               .macro  senduart,rd,rx
-               strb    \rd, [\rx, # S3C2410_UTXH ]
-               .endm
-
-               .macro  busyuart, rd, rx
-               ldr     \rd, [ \rx, # S3C2410_UFCON ]
-               tst     \rd, #S3C2410_UFCON_FIFOMODE    @ fifo enabled?
-               beq     1001f                           @
-               @ FIFO enabled...
-1003:
+       .macro fifo_full_s3c24xx rd, rx
                @ check for arm920 vs arm926. currently assume all arm926
                @ devices have an 64 byte FIFO identical to the s3c2440
                mrc     p15, 0, \rd, c0, c0
                ldr     \rd, [ \rx, # S3C2410_UFSTAT ]
                moveq   \rd, \rd, lsr #SHIFT_2440TXF
                tst     \rd, #S3C2410_UFSTAT_TXFULL
-               bne     1003b
-               b       1002f
-
-1001:
-               @ busy waiting for non fifo
-               ldr     \rd, [ \rx, # S3C2410_UTRSTAT ]
-               tst     \rd, #S3C2410_UTRSTAT_TXFE
-               beq     1001b
+       .endm
 
-1002:          @ exit busyuart
-               .endm
+       .macro  fifo_full_s3c2410 rd, rx
+               ldr     \rd, [ \rx, # S3C2410_UFSTAT ]
+               tst     \rd, #S3C2410_UFSTAT_TXFULL
+       .endm
 
-               .macro  waituart,rd,rx
+/* fifo level reading */
 
-               ldr     \rd, [ \rx, # S3C2410_UFCON ]
-               tst     \rd, #S3C2410_UFCON_FIFOMODE    @ fifo enabled?
-               beq     1001f                           @
-               @ FIFO enabled...
-1003:
+       .macro fifo_level_s3c24xx rd, rx
+               @ check for arm920 vs arm926. currently assume all arm926
+               @ devices have an 64 byte FIFO identical to the s3c2440
+               mrc     p15, 0, \rd, c0, c0
+               and     \rd, \rd, #0xff0
+               teq     \rd, #0x260
+               beq     10000f
                mrc     p15, 0, \rd, c1, c0
                tst     \rd, #1
                addeq   \rd, \rx, #(S3C24XX_PA_GPIO - S3C24XX_PA_UART)
                and     \rd, \rd, #0x00ff0000
                teq     \rd, #0x00440000                @ is it 2440?
 
+10000:
                ldr     \rd, [ \rx, # S3C2410_UFSTAT ]
                andne   \rd, \rd, #S3C2410_UFSTAT_TXMASK
                andeq   \rd, \rd, #S3C2440_UFSTAT_TXMASK
-               teq     \rd, #0
-               bne     1003b
-               b       1002f
+       .endm
+
+       .macro fifo_level_s3c2410 rd, rx
+               ldr     \rd, [ \rx, # S3C2410_UFSTAT ]
+               and     \rd, \rd, #S3C2410_UFSTAT_TXMASK
+       .endm
+
+/* Select the correct implementation depending on the configuration. The
+ * S3C2440 will get selected by default, as these are the most widely
+ * used variants of these
+*/
+
+#if defined(CONFIG_CPU_LLSERIAL_S3C2410_ONLY)
+#define fifo_full  fifo_full_s3c2410
+#define fifo_level fifo_level_s3c2410
+#warning 2410only
+#elif !defined(CONFIG_CPU_LLSERIAL_S3C2440_ONLY)
+#define fifo_full  fifo_full_s3c24xx
+#define fifo_level fifo_level_s3c24xx
+#warning generic
+#endif
 
-1001:
-               @ idle waiting for non fifo
-               ldr     \rd, [ \rx, # S3C2410_UTRSTAT ]
-               tst     \rd, #S3C2410_UTRSTAT_TXFE
-               beq     1001b
+/* include the reset of the code which will do the work */
 
-1002:          @ exit busyuart
-               .endm
+#include <asm/plat-s3c/debug-macro.S>
index 19e77f038042ec0b64644e25136c326d57ff5b1d..b33ed3b05ef584823e3c1175924fb1f2310f48ee 100644 (file)
 #ifndef __ASM_ARCH_MAP_H
 #define __ASM_ARCH_MAP_H
 
-/* we have a bit of a tight squeeze to fit all our registers from
- * 0xF00000000 upwards, since we use all of the nGCS space in some
- * capacity, and also need to fit the S3C2410 registers in as well...
- *
- * we try to ensure stuff like the IRQ registers are available for
- * an single MOVS instruction (ie, only 8 bits of set data)
- *
- * Note, we are trying to remove some of these from the implementation
- * as they are only useful to certain drivers...
- */
-
-#ifndef __ASSEMBLY__
-#define S3C2410_ADDR(x)          ((void __iomem __force *)0xF0000000 + (x))
-#else
-#define S3C2410_ADDR(x)          (0xF0000000 + (x))
-#endif
+#include <asm/plat-s3c/map.h>
 
-#define S3C2400_ADDR(x)          S3C2410_ADDR(x)
+#define S3C2410_ADDR(x)                S3C_ADDR(x)
 
 /* interrupt controller is the first thing we put in, to make
  * the assembly code for the irq detection easier
  */
-#define S3C24XX_VA_IRQ    S3C2410_ADDR(0x00000000)
-#define S3C2400_PA_IRQ    (0x14400000)
+#define S3C24XX_VA_IRQ    S3C_VA_IRQ
 #define S3C2410_PA_IRQ    (0x4A000000)
 #define S3C24XX_SZ_IRQ    SZ_1M
 
 /* memory controller registers */
-#define S3C24XX_VA_MEMCTRL S3C2410_ADDR(0x00100000)
-#define S3C2400_PA_MEMCTRL (0x14000000)
+#define S3C24XX_VA_MEMCTRL S3C_VA_MEM
 #define S3C2410_PA_MEMCTRL (0x48000000)
 #define S3C24XX_SZ_MEMCTRL SZ_1M
 
 /* USB host controller */
-#define S3C2400_PA_USBHOST (0x14200000)
 #define S3C2410_PA_USBHOST (0x49000000)
 #define S3C24XX_SZ_USBHOST SZ_1M
 
 /* DMA controller */
-#define S3C2400_PA_DMA    (0x14600000)
 #define S3C2410_PA_DMA    (0x4B000000)
 #define S3C24XX_SZ_DMA    SZ_1M
 
 /* Clock and Power management */
-#define S3C24XX_VA_CLKPWR  S3C2410_ADDR(0x00200000)
-#define S3C2400_PA_CLKPWR  (0x14800000)
+#define S3C24XX_VA_CLKPWR  S3C_VA_SYS
 #define S3C2410_PA_CLKPWR  (0x4C000000)
 #define S3C24XX_SZ_CLKPWR  SZ_1M
 
 /* LCD controller */
-#define S3C24XX_VA_LCD    S3C2410_ADDR(0x00300000)
-#define S3C2400_PA_LCD    (0x14A00000)
 #define S3C2410_PA_LCD    (0x4D000000)
 #define S3C24XX_SZ_LCD    SZ_1M
 
 #define S3C2410_PA_NAND           (0x4E000000)
 #define S3C24XX_SZ_NAND           SZ_1M
 
-/* MMC controller - available on the S3C2400 */
-#define S3C2400_PA_MMC            (0x15A00000)
-#define S3C2400_SZ_MMC            SZ_1M
-
 /* UARTs */
-#define S3C24XX_VA_UART           S3C2410_ADDR(0x00400000)
-#define S3C2400_PA_UART           (0x15000000)
+#define S3C24XX_VA_UART           S3C_VA_UART
 #define S3C2410_PA_UART           (0x50000000)
 #define S3C24XX_SZ_UART           SZ_1M
 
 /* Timers */
-#define S3C24XX_VA_TIMER   S3C2410_ADDR(0x00500000)
-#define S3C2400_PA_TIMER   (0x15100000)
+#define S3C24XX_VA_TIMER   S3C_VA_TIMER
 #define S3C2410_PA_TIMER   (0x51000000)
 #define S3C24XX_SZ_TIMER   SZ_1M
 
 /* USB Device port */
-#define S3C24XX_VA_USBDEV  S3C2410_ADDR(0x00600000)
-#define S3C2400_PA_USBDEV  (0x15200140)
 #define S3C2410_PA_USBDEV  (0x52000000)
 #define S3C24XX_SZ_USBDEV  SZ_1M
 
 /* Watchdog */
-#define S3C24XX_VA_WATCHDOG S3C2410_ADDR(0x00700000)
-#define S3C2400_PA_WATCHDOG (0x15300000)
+#define S3C24XX_VA_WATCHDOG S3C_VA_WATCHDOG
 #define S3C2410_PA_WATCHDOG (0x53000000)
 #define S3C24XX_SZ_WATCHDOG SZ_1M
 
 /* IIC hardware controller */
-#define S3C2400_PA_IIC    (0x15400000)
 #define S3C2410_PA_IIC    (0x54000000)
 #define S3C24XX_SZ_IIC    SZ_1M
 
 /* IIS controller */
-#define S3C2400_PA_IIS    (0x15508000)
 #define S3C2410_PA_IIS    (0x55000000)
 #define S3C24XX_SZ_IIS    SZ_1M
 
  * it is the same distance apart from the UART in the
  * phsyical address space, as the initial mapping for the IO
  * is done as a 1:1 maping. This puts it (currently) at
- * 0xF6800000, which is not in the way of any current mapping
+ * 0xFA800000, which is not in the way of any current mapping
  * by the base system.
 */
 
-#define S3C2400_PA_GPIO           (0x15600000)
 #define S3C2410_PA_GPIO           (0x56000000)
 #define S3C24XX_VA_GPIO           ((S3C2410_PA_GPIO - S3C24XX_PA_UART) + S3C24XX_VA_UART)
 #define S3C24XX_SZ_GPIO           SZ_1M
 
 /* RTC */
-#define S3C2400_PA_RTC    (0x15700040)
 #define S3C2410_PA_RTC    (0x57000000)
 #define S3C24XX_SZ_RTC    SZ_1M
 
 /* ADC */
-#define S3C2400_PA_ADC    (0x15800000)
 #define S3C2410_PA_ADC    (0x58000000)
 #define S3C24XX_SZ_ADC    SZ_1M
 
 /* SPI */
-#define S3C2400_PA_SPI    (0x15900000)
 #define S3C2410_PA_SPI    (0x59000000)
 #define S3C24XX_SZ_SPI    SZ_1M
 
 
 #define S3C2410_SDRAM_PA    (S3C2410_CS6)
 
-#define S3C2400_CS0 (0x00000000)
-#define S3C2400_CS1 (0x02000000)
-#define S3C2400_CS2 (0x04000000)
-#define S3C2400_CS3 (0x06000000)
-#define S3C2400_CS4 (0x08000000)
-#define S3C2400_CS5 (0x0A000000)
-#define S3C2400_CS6 (0x0C000000)
-#define S3C2400_CS7 (0x0E000000)
-
-#define S3C2400_SDRAM_PA    (S3C2400_CS6)
-
 /* Use a single interface for common resources between S3C24XX cpus */
 
-#ifdef CONFIG_CPU_S3C2400
-#define S3C24XX_PA_IRQ      S3C2400_PA_IRQ
-#define S3C24XX_PA_MEMCTRL  S3C2400_PA_MEMCTRL
-#define S3C24XX_PA_USBHOST  S3C2400_PA_USBHOST
-#define S3C24XX_PA_DMA      S3C2400_PA_DMA
-#define S3C24XX_PA_CLKPWR   S3C2400_PA_CLKPWR
-#define S3C24XX_PA_LCD      S3C2400_PA_LCD
-#define S3C24XX_PA_UART     S3C2400_PA_UART
-#define S3C24XX_PA_TIMER    S3C2400_PA_TIMER
-#define S3C24XX_PA_USBDEV   S3C2400_PA_USBDEV
-#define S3C24XX_PA_WATCHDOG S3C2400_PA_WATCHDOG
-#define S3C24XX_PA_IIC      S3C2400_PA_IIC
-#define S3C24XX_PA_IIS      S3C2400_PA_IIS
-#define S3C24XX_PA_GPIO     S3C2400_PA_GPIO
-#define S3C24XX_PA_RTC      S3C2400_PA_RTC
-#define S3C24XX_PA_ADC      S3C2400_PA_ADC
-#define S3C24XX_PA_SPI      S3C2400_PA_SPI
-#else
 #define S3C24XX_PA_IRQ      S3C2410_PA_IRQ
 #define S3C24XX_PA_MEMCTRL  S3C2410_PA_MEMCTRL
 #define S3C24XX_PA_USBHOST  S3C2410_PA_USBHOST
 #define S3C24XX_PA_RTC      S3C2410_PA_RTC
 #define S3C24XX_PA_ADC      S3C2410_PA_ADC
 #define S3C24XX_PA_SPI      S3C2410_PA_SPI
-#endif
 
 /* deal with the registers that move under the 2412/2413 */
 
index 4be6a74c430342c66e2410b57857794ceb138b2c..533e2436e70734f58c4bd111ffafc8c46971a947 100644 (file)
 #ifndef __ASM_ARCH_MEMORY_H
 #define __ASM_ARCH_MEMORY_H
 
-/*
- * DRAM starts at 0x30000000 for S3C2410/S3C2440
- * and at 0x0C000000 for S3C2400
- */
-#ifdef CONFIG_CPU_S3C2400
-#define PHYS_OFFSET    UL(0x0C000000)
-#else
 #define PHYS_OFFSET    UL(0x30000000)
-#endif
-
-/*
- * These are exactly the same on the S3C2410 as the
- * physical memory view.
-*/
 
 #define __virt_to_bus(x) __virt_to_phys(x)
 #define __bus_to_virt(x) __phys_to_virt(x)
index b7faeb04c0ffb1afcabc0225aaa68c8a6784bf7d..76fe5f6934267f702341b80ebba58ac7c3857c34 100644 (file)
@@ -12,7 +12,7 @@
 #ifndef ___ASM_ARCH_REGS_LCD_H
 #define ___ASM_ARCH_REGS_LCD_H "$Id: lcd.h,v 1.3 2003/06/26 13:25:06 ben Exp $"
 
-#define S3C2410_LCDREG(x) ((x) + S3C24XX_VA_LCD)
+#define S3C2410_LCDREG(x)      (x)
 
 /* LCD control registers */
 #define S3C2410_LCDCON1            S3C2410_LCDREG(0x00)
index 1c74ef17da3363eda55e8dcf8fee51c84d502148..63891786dfa03aa867ca804e13e2b86ea9490b29 100644 (file)
@@ -17,7 +17,7 @@
 #include <asm/arch/idle.h>
 #include <asm/arch/reset.h>
 
-#include <asm/arch/regs-watchdog.h>
+#include <asm/plat-s3c/regs-watchdog.h>
 #include <asm/arch/regs-clock.h>
 
 void (*s3c24xx_idle)(void);
index dcb2cef38f509b1eee3f88d54037b76aeab207d3..48a5731ee98868400793a809b515729857018160 100644 (file)
@@ -1,6 +1,7 @@
 /* linux/include/asm-arm/arch-s3c2410/uncompress.h
  *
- * Copyright (c) 2003 Simtec Electronics
+ * Copyright (c) 2003, 2007 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
  *     Ben Dooks <ben@simtec.co.uk>
  *
  * S3C2410 - uncompress code
 #ifndef __ASM_ARCH_UNCOMPRESS_H
 #define __ASM_ARCH_UNCOMPRESS_H
 
-typedef unsigned int upf_t;    /* cannot include linux/serial_core.h */
-
-/* defines for UART registers */
-#include "asm/arch/regs-serial.h"
-#include "asm/arch/regs-gpio.h"
-#include "asm/arch/regs-watchdog.h"
-
+#include <asm/arch/regs-gpio.h>
 #include <asm/arch/map.h>
 
 /* working in physical space... */
 #undef S3C2410_GPIOREG
-#undef S3C2410_WDOGREG
-
 #define S3C2410_GPIOREG(x) ((S3C24XX_PA_GPIO + (x)))
-#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x)))
 
-/* how many bytes we allow into the FIFO at a time in FIFO mode */
-#define FIFO_MAX        (14)
+#include <asm/plat-s3c/uncompress.h>
 
-#define uart_base S3C24XX_PA_UART + (0x4000*CONFIG_S3C2410_LOWLEVEL_UART_PORT)
-
-static __inline__ void
-uart_wr(unsigned int reg, unsigned int val)
+static inline int is_arm926(void)
 {
-       volatile unsigned int *ptr;
-
-       ptr = (volatile unsigned int *)(reg + uart_base);
-       *ptr = val;
-}
+       unsigned int cpuid;
 
-static __inline__ unsigned int
-uart_rd(unsigned int reg)
-{
-       volatile unsigned int *ptr;
+       asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r" (cpuid));
 
-       ptr = (volatile unsigned int *)(reg + uart_base);
-       return *ptr;
+       return ((cpuid & 0xff0) == 0x260);
 }
 
-
-/* we can deal with the case the UARTs are being run
- * in FIFO mode, so that we don't hold up our execution
- * waiting for tx to happen...
-*/
-
-static void putc(int ch)
+static void arch_detect_cpu(void)
 {
-       int cpuid = S3C2410_GSTATUS1_2410;
+       unsigned int cpuid;
 
-#ifndef CONFIG_CPU_S3C2400
        cpuid = *((volatile unsigned int *)S3C2410_GSTATUS1);
        cpuid &= S3C2410_GSTATUS1_IDMASK;
-#endif
-
-       if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
-               int level;
-
-               while (1) {
-                       level = uart_rd(S3C2410_UFSTAT);
-
-                       if (cpuid == S3C2410_GSTATUS1_2440 ||
-                           cpuid == S3C2410_GSTATUS1_2442) {
-                               level &= S3C2440_UFSTAT_TXMASK;
-                               level >>= S3C2440_UFSTAT_TXSHIFT;
-                       } else {
-                               level &= S3C2410_UFSTAT_TXMASK;
-                               level >>= S3C2410_UFSTAT_TXSHIFT;
-                       }
-
-                       if (level < FIFO_MAX)
-                               break;
-               }
 
+       if (is_arm926() || cpuid == S3C2410_GSTATUS1_2440 ||
+           cpuid == S3C2410_GSTATUS1_2442) {
+               fifo_mask = S3C2440_UFSTAT_TXMASK;
+               fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
        } else {
-               /* not using fifos */
-
-               while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE)
-                       barrier();
+               fifo_mask = S3C2410_UFSTAT_TXMASK;
+               fifo_max = 15 << S3C2410_UFSTAT_TXSHIFT;
        }
-
-       /* write byte to transmission register */
-       uart_wr(S3C2410_UTXH, ch);
 }
 
-static inline void flush(void)
-{
-}
-
-#define __raw_writel(d,ad) do { *((volatile unsigned int *)(ad)) = (d); } while(0)
-
-/* CONFIG_S3C2410_BOOT_WATCHDOG
- *
- * Simple boot-time watchdog setup, to reboot the system if there is
- * any problem with the boot process
-*/
-
-#ifdef CONFIG_S3C2410_BOOT_WATCHDOG
-
-#define WDOG_COUNT (0xff00)
-
-static inline void arch_decomp_wdog(void)
-{
-       __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
-}
-
-static void arch_decomp_wdog_start(void)
-{
-       __raw_writel(WDOG_COUNT, S3C2410_WTDAT);
-       __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
-       __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x80), S3C2410_WTCON);
-}
-
-#else
-#define arch_decomp_wdog_start()
-#define arch_decomp_wdog()
-#endif
-
-#ifdef CONFIG_S3C2410_BOOT_ERROR_RESET
-
-static void arch_decomp_error(const char *x)
-{
-       putstr("\n\n");
-       putstr(x);
-       putstr("\n\n -- System resetting\n");
-
-       __raw_writel(0x4000, S3C2410_WTDAT);
-       __raw_writel(0x4000, S3C2410_WTCNT);
-       __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
-
-       while(1);
-}
-
-#define arch_error arch_decomp_error
-#endif
-
-static void error(char *err);
-
-static void
-arch_decomp_setup(void)
-{
-       /* we may need to setup the uart(s) here if we are not running
-        * on an BAST... the BAST will have left the uarts configured
-        * after calling linux.
-        */
-
-       arch_decomp_wdog_start();
-}
-
-
 #endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/include/asm-arm/arch-sa1100/jornada720.h b/include/asm-arm/arch-sa1100/jornada720.h
new file mode 100644 (file)
index 0000000..45d2bb5
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * include/asm-arm/arch-sa1100/jornada720.h
+ *
+ * This file contains SSP/MCU communication definitions for HP Jornada 710/720/728
+ *
+ * Copyright (C) 2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
+ *  Copyright (C) 2000 John Ankcorn <jca@lcs.mit.edu>
+ *
+ * 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.
+ *
+ */
+
+ /* HP Jornada 7xx microprocessor commands */
+#define GETBATTERYDATA         0xc0
+#define GETSCANKEYCODE         0x90
+#define GETTOUCHSAMPLES                0xa0
+#define GETCONTRAST            0xD0
+#define SETCONTRAST            0xD1
+#define GETBRIGHTNESS          0xD2
+#define SETBRIGHTNESS          0xD3
+#define CONTRASTOFF            0xD8
+#define BRIGHTNESSOFF          0xD9
+#define PWMOFF                 0xDF
+#define TXDUMMY                        0x11
+#define ERRORCODE              0x00
index d7a777f05088d6332a3a723a7308f3c82070a7cd..ec1c685562ce2ec19366c4e93cc1c6988a1cf5f3 100644 (file)
@@ -1,13 +1,14 @@
 #ifndef __ASMARM_ELF_H
 #define __ASMARM_ELF_H
 
+#include <asm/hwcap.h>
+
 #ifndef __ASSEMBLY__
 /*
  * ELF register definitions..
  */
 #include <asm/ptrace.h>
 #include <asm/user.h>
-#include <asm/hwcap.h>
 
 typedef unsigned long elf_greg_t;
 typedef unsigned long elf_freg_t[3];
index 54b5ae44ed94498151572c7fa1e0a193e1ec20e9..d595c15166a42754944109c8ea47b8b454039142 100644 (file)
 #define fd_disable_irq()       disable_irq(IRQ_FLOPPYDISK)
 #define fd_enable_irq()                enable_irq(IRQ_FLOPPYDISK)
 
+static inline int fd_dma_setup(void *data, unsigned int length,
+                              unsigned int mode, unsigned long addr)
+{
+       set_dma_mode(DMA_FLOPPY, mode);
+       __set_dma_addr(DMA_FLOPPY, data);
+       set_dma_count(DMA_FLOPPY, length);
+       virtual_dma_port = addr;
+       enable_dma(DMA_FLOPPY);
+       return 0;
+}
+#define fd_dma_setup           fd_dma_setup
+
 #define fd_request_dma()       request_dma(DMA_FLOPPY,"floppy")
 #define fd_free_dma()          free_dma(DMA_FLOPPY)
 #define fd_disable_dma()       disable_dma(DMA_FLOPPY)
-#define fd_enable_dma()                enable_dma(DMA_FLOPPY)
-#define fd_clear_dma_ff()      clear_dma_ff(DMA_FLOPPY)
-#define fd_set_dma_mode(mode)  set_dma_mode(DMA_FLOPPY, (mode))
-#define fd_set_dma_addr(addr)  set_dma_addr(DMA_FLOPPY, virt_to_bus((addr)))
-#define fd_set_dma_count(len)  set_dma_count(DMA_FLOPPY, (len))
-#define fd_cacheflush(addr,sz)
 
 /* need to clean up dma.h */
 #define DMA_FLOPPYDISK         DMA_FLOPPY
index 81ca5d3e2bff4581759c6fdd604c8d4897f432eb..fb90b421f31c94d5c771255bdc429abd5aca0409 100644 (file)
@@ -194,6 +194,13 @@ extern int init_atu;
 #define IOP_TMR_PRIVILEGED 0x08
 #define IOP_TMR_RATIO_1_1  0x00
 
+/* Watchdog timer definitions */
+#define IOP_WDTCR_EN_ARM        0x1e1e1e1e
+#define IOP_WDTCR_EN            0xe1e1e1e1
+/* iop3xx does not support stopping the watchdog, so we just re-arm */
+#define IOP_WDTCR_DIS_ARM      (IOP_WDTCR_EN_ARM)
+#define IOP_WDTCR_DIS          (IOP_WDTCR_EN)
+
 /* Application accelerator unit  */
 #define IOP3XX_AAU_PHYS_BASE (IOP3XX_PERIPHERAL_PHYS_BASE + 0x800)
 #define IOP3XX_AAU_UPPER_PA (IOP3XX_AAU_PHYS_BASE + 0xa7)
@@ -274,6 +281,32 @@ static inline void write_tisr(u32 val)
        asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (val));
 }
 
+static inline u32 read_wdtcr(void)
+{
+       u32 val;
+       asm volatile("mrc p6, 0, %0, c7, c1, 0":"=r" (val));
+       return val;
+}
+static inline void write_wdtcr(u32 val)
+{
+       asm volatile("mcr p6, 0, %0, c7, c1, 0"::"r" (val));
+}
+
+extern unsigned long get_iop_tick_rate(void);
+
+/* only iop13xx has these registers, we define these to present a
+ * common register interface for the iop_wdt driver.
+ */
+#define IOP_RCSR_WDT   (0)
+static inline u32 read_rcsr(void)
+{
+       return 0;
+}
+static inline void write_wdtsr(u32 val)
+{
+       do { } while (0);
+}
+
 extern struct platform_device iop3xx_dma_0_channel;
 extern struct platform_device iop3xx_dma_1_channel;
 extern struct platform_device iop3xx_aau_channel;
index 0c8be19fd66bff98f1ec13ef7484bfde6722c4a0..b186bc820e30f04c94d1f9ebb36912f045601308 100644 (file)
@@ -102,7 +102,8 @@ extern int is_in_rom(unsigned long);
 #define v4_tlb_fns     (0)
 #define v4wb_tlb_fns   (0)
 #define v4wbi_tlb_fns  (0)
-#define v6_tlb_fns     (0)
+#define v6wbi_tlb_fns  (0)
+#define v7wbi_tlb_fns  (0)
 
 #define v3_user_fns    (0)
 #define v4_user_fns    (0)
diff --git a/include/asm-arm/plat-s3c/debug-macro.S b/include/asm-arm/plat-s3c/debug-macro.S
new file mode 100644 (file)
index 0000000..84c40b8
--- /dev/null
@@ -0,0 +1,75 @@
+/* linux/include/asm-arm/plat-s3c/debug-macro.S
+ *
+ * Copyright 2005, 2007 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * 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 <asm/plat-s3c/regs-serial.h>
+
+/* The S3C2440 implementations are used by default as they are the
+ * most widely re-used */
+
+       .macro fifo_level_s3c2440 rd, rx
+               ldr     \rd, [ \rx, # S3C2410_UFSTAT ]
+               and     \rd, \rd, #S3C2440_UFSTAT_TXMASK
+       .endm
+
+#ifndef fifo_level
+#define fifo_level fifo_level_s3c2410
+#endif
+
+       .macro  fifo_full_s3c2440 rd, rx
+               ldr     \rd, [ \rx, # S3C2410_UFSTAT ]
+               tst     \rd, #S3C2440_UFSTAT_TXFULL
+       .endm
+
+#ifndef fifo_full
+#define fifo_full fifo_full_s3c2440
+#endif
+
+       .macro  senduart,rd,rx
+               strb    \rd, [\rx, # S3C2410_UTXH ]
+       .endm
+
+       .macro  busyuart, rd, rx
+               ldr     \rd, [ \rx, # S3C2410_UFCON ]
+               tst     \rd, #S3C2410_UFCON_FIFOMODE    @ fifo enabled?
+               beq     1001f                           @
+               @ FIFO enabled...
+1003:
+               fifo_full \rd, \rx
+               bne     1003b
+               b       1002f
+
+1001:
+               @ busy waiting for non fifo
+               ldr     \rd, [ \rx, # S3C2410_UTRSTAT ]
+               tst     \rd, #S3C2410_UTRSTAT_TXFE
+               beq     1001b
+
+1002:          @ exit busyuart
+       .endm
+
+       .macro  waituart,rd,rx
+               ldr     \rd, [ \rx, # S3C2410_UFCON ]
+               tst     \rd, #S3C2410_UFCON_FIFOMODE    @ fifo enabled?
+               beq     1001f                           @
+               @ FIFO enabled...
+1003:
+               fifo_level \rd, \rx
+               teq     \rd, #0
+               bne     1003b
+               b       1002f
+1001:
+               @ idle waiting for non fifo
+               ldr     \rd, [ \rx, # S3C2410_UTRSTAT ]
+               tst     \rd, #S3C2410_UTRSTAT_TXFE
+               beq     1001b
+
+1002:          @ exit busyuart
+       .endm
diff --git a/include/asm-arm/plat-s3c/map.h b/include/asm-arm/plat-s3c/map.h
new file mode 100644 (file)
index 0000000..95a82b0
--- /dev/null
@@ -0,0 +1,40 @@
+/* linux/include/asm-arm/plat-s3c/map.h
+ *
+ * Copyright 2003, 2007 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - Memory map definitions (virtual addresses)
+ *
+ * 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_PLAT_MAP_H
+#define __ASM_PLAT_MAP_H __FILE__
+
+/* Fit all our registers in at 0xF4000000 upwards, trying to use as
+ * little of the VA space as possible so vmalloc and friends have a
+ * better chance of getting memory.
+ *
+ * we try to ensure stuff like the IRQ registers are available for
+ * an single MOVS instruction (ie, only 8 bits of set data)
+ */
+
+#define S3C_ADDR_BASE  (0xF4000000)
+
+#ifndef __ASSEMBLY__
+#define S3C_ADDR(x)    ((void __iomem __force *)S3C_ADDR_BASE + (x))
+#else
+#define S3C_ADDR(x)    (S3C_ADDR_BASE + (x))
+#endif
+
+#define S3C_VA_IRQ     S3C_ADDR(0x000000000)   /* irq controller(s) */
+#define S3C_VA_SYS     S3C_ADDR(0x001000000)   /* system control */
+#define S3C_VA_MEM     S3C_ADDR(0x002000000)   /* system control */
+#define S3C_VA_TIMER   S3C_ADDR(0x003000000)   /* timer block */
+#define S3C_VA_WATCHDOG        S3C_ADDR(0x004000000)   /* watchdog */
+#define S3C_VA_UART    S3C_ADDR(0x010000000)   /* UART */
+
+#endif /* __ASM_PLAT_MAP_H */
similarity index 96%
rename from include/asm-arm/arch-s3c2410/regs-serial.h
rename to include/asm-arm/plat-s3c/regs-serial.h
index 8946702a87f506f7f3c7066fa18b049a69e991c9..923e114db663a6f3dac75240712e4a09e737d8e3 100644 (file)
 #ifndef __ASM_ARM_REGS_SERIAL_H
 #define __ASM_ARM_REGS_SERIAL_H
 
-#define S3C24XX_VA_UART0      (S3C24XX_VA_UART)
-#define S3C24XX_VA_UART1      (S3C24XX_VA_UART + 0x4000 )
-#define S3C24XX_VA_UART2      (S3C24XX_VA_UART + 0x8000 )
-#define S3C24XX_VA_UART3      (S3C24XX_VA_UART + 0xC000 )
+#define S3C24XX_VA_UART0      (S3C_VA_UART)
+#define S3C24XX_VA_UART1      (S3C_VA_UART + 0x4000 )
+#define S3C24XX_VA_UART2      (S3C_VA_UART + 0x8000 )
+#define S3C24XX_VA_UART3      (S3C_VA_UART + 0xC000 )
 
 #define S3C2410_PA_UART0      (S3C24XX_PA_UART)
 #define S3C2410_PA_UART1      (S3C24XX_PA_UART + 0x4000 )
similarity index 86%
rename from include/asm-arm/arch-s3c2410/regs-timer.h
rename to include/asm-arm/plat-s3c/regs-timer.h
index 6f8fe432fe3a982e38ea005a2cae94204d0db446..8b0d594397b17500e42d03f7579f52cf75b0a38f 100644 (file)
 #ifndef __ASM_ARCH_REGS_TIMER_H
 #define __ASM_ARCH_REGS_TIMER_H "$Id: timer.h,v 1.4 2003/05/06 19:30:50 ben Exp $"
 
-#define S3C2410_TIMERREG(x) (S3C24XX_VA_TIMER + (x))
-#define S3C2410_TIMERREG2(tmr,reg) S3C2410_TIMERREG((reg)+0x0c+((tmr)*0x0c))
+#define S3C_TIMERREG(x) (S3C_VA_TIMER + (x))
+#define S3C_TIMERREG2(tmr,reg) S3C_TIMERREG((reg)+0x0c+((tmr)*0x0c))
 
-#define S3C2410_TCFG0        S3C2410_TIMERREG(0x00)
-#define S3C2410_TCFG1        S3C2410_TIMERREG(0x04)
-#define S3C2410_TCON         S3C2410_TIMERREG(0x08)
+#define S3C2410_TCFG0        S3C_TIMERREG(0x00)
+#define S3C2410_TCFG1        S3C_TIMERREG(0x04)
+#define S3C2410_TCON         S3C_TIMERREG(0x08)
 
 #define S3C2410_TCFG_PRESCALER0_MASK (255<<0)
 #define S3C2410_TCFG_PRESCALER1_MASK (255<<8)
@@ -71,9 +71,9 @@
 
 /* WARNING - timer 4 has no buffer reg, and it's observation is at +4 */
 
-#define S3C2410_TCNTB(tmr)    S3C2410_TIMERREG2(tmr, 0x00)
-#define S3C2410_TCMPB(tmr)    S3C2410_TIMERREG2(tmr, 0x04)
-#define S3C2410_TCNTO(tmr)    S3C2410_TIMERREG2(tmr, (((tmr) == 4) ? 0x04 : 0x08))
+#define S3C2410_TCNTB(tmr)    S3C_TIMERREG2(tmr, 0x00)
+#define S3C2410_TCMPB(tmr)    S3C_TIMERREG2(tmr, 0x04)
+#define S3C2410_TCNTO(tmr)    S3C_TIMERREG2(tmr, (((tmr) == 4) ? 0x04 : 0x08))
 
 #define S3C2410_TCON_T4RELOAD    (1<<22)
 #define S3C2410_TCON_T4MANUALUPD  (1<<21)
similarity index 83%
rename from include/asm-arm/arch-s3c2410/regs-watchdog.h
rename to include/asm-arm/plat-s3c/regs-watchdog.h
index a9c5d491bdb6b691c40261c724aec6a72149d51a..56c4193b7a46c9402a8b13530cef81658abaab6d 100644 (file)
 #ifndef __ASM_ARCH_REGS_WATCHDOG_H
 #define __ASM_ARCH_REGS_WATCHDOG_H "$Id: watchdog.h,v 1.2 2003/04/29 13:31:09 ben Exp $"
 
-#define S3C2410_WDOGREG(x) ((x) + S3C24XX_VA_WATCHDOG)
+#define S3C_WDOGREG(x) ((x) + S3C_VA_WATCHDOG)
 
-#define S3C2410_WTCON     S3C2410_WDOGREG(0x00)
-#define S3C2410_WTDAT     S3C2410_WDOGREG(0x04)
-#define S3C2410_WTCNT     S3C2410_WDOGREG(0x08)
+#define S3C2410_WTCON     S3C_WDOGREG(0x00)
+#define S3C2410_WTDAT     S3C_WDOGREG(0x04)
+#define S3C2410_WTCNT     S3C_WDOGREG(0x08)
 
 /* the watchdog can either generate a reset pulse, or an
  * interrupt.
diff --git a/include/asm-arm/plat-s3c/uncompress.h b/include/asm-arm/plat-s3c/uncompress.h
new file mode 100644 (file)
index 0000000..b5e6208
--- /dev/null
@@ -0,0 +1,155 @@
+/* linux/include/asm-arm/plat-s3c/uncompress.h
+ *
+ * Copyright 2003, 2007 Simtec Electronics
+ *     http://armlinux.simtec.co.uk/
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - uncompress code
+ *
+ * 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_PLAT_UNCOMPRESS_H
+#define __ASM_PLAT_UNCOMPRESS_H
+
+typedef unsigned int upf_t;    /* cannot include linux/serial_core.h */
+
+/* uart setup */
+
+static unsigned int fifo_mask;
+static unsigned int fifo_max;
+
+/* forward declerations */
+
+static void arch_detect_cpu(void);
+
+/* defines for UART registers */
+
+#include "asm/plat-s3c/regs-serial.h"
+#include "asm/plat-s3c/regs-watchdog.h"
+
+/* working in physical space... */
+#undef S3C2410_WDOGREG
+#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x)))
+
+/* how many bytes we allow into the FIFO at a time in FIFO mode */
+#define FIFO_MAX        (14)
+
+#define uart_base S3C24XX_PA_UART + (0x4000*CONFIG_S3C_LOWLEVEL_UART_PORT)
+
+static __inline__ void
+uart_wr(unsigned int reg, unsigned int val)
+{
+       volatile unsigned int *ptr;
+
+       ptr = (volatile unsigned int *)(reg + uart_base);
+       *ptr = val;
+}
+
+static __inline__ unsigned int
+uart_rd(unsigned int reg)
+{
+       volatile unsigned int *ptr;
+
+       ptr = (volatile unsigned int *)(reg + uart_base);
+       return *ptr;
+}
+
+/* we can deal with the case the UARTs are being run
+ * in FIFO mode, so that we don't hold up our execution
+ * waiting for tx to happen...
+*/
+
+static void putc(int ch)
+{
+       if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
+               int level;
+
+               while (1) {
+                       level = uart_rd(S3C2410_UFSTAT);
+                       level &= fifo_mask;
+
+                       if (level < fifo_max)
+                               break;
+               }
+
+       } else {
+               /* not using fifos */
+
+               while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE)
+                       barrier();
+       }
+
+       /* write byte to transmission register */
+       uart_wr(S3C2410_UTXH, ch);
+}
+
+static inline void flush(void)
+{
+}
+
+#define __raw_writel(d,ad) do { *((volatile unsigned int *)(ad)) = (d); } while(0)
+
+/* CONFIG_S3C_BOOT_WATCHDOG
+ *
+ * Simple boot-time watchdog setup, to reboot the system if there is
+ * any problem with the boot process
+*/
+
+#ifdef CONFIG_S3C_BOOT_WATCHDOG
+
+#define WDOG_COUNT (0xff00)
+
+static inline void arch_decomp_wdog(void)
+{
+       __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
+}
+
+static void arch_decomp_wdog_start(void)
+{
+       __raw_writel(WDOG_COUNT, S3C2410_WTDAT);
+       __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
+       __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x80), S3C2410_WTCON);
+}
+
+#else
+#define arch_decomp_wdog_start()
+#define arch_decomp_wdog()
+#endif
+
+#ifdef CONFIG_S3C_BOOT_ERROR_RESET
+
+static void arch_decomp_error(const char *x)
+{
+       putstr("\n\n");
+       putstr(x);
+       putstr("\n\n -- System resetting\n");
+
+       __raw_writel(0x4000, S3C2410_WTDAT);
+       __raw_writel(0x4000, S3C2410_WTCNT);
+       __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
+
+       while(1);
+}
+
+#define arch_error arch_decomp_error
+#endif
+
+static void error(char *err);
+
+static void
+arch_decomp_setup(void)
+{
+       /* we may need to setup the uart(s) here if we are not running
+        * on an BAST... the BAST will have left the uarts configured
+        * after calling linux.
+        */
+
+       arch_detect_cpu();
+       arch_decomp_wdog_start();
+}
+
+
+#endif /* __ASM_PLAT_UNCOMPRESS_H */
index eae85b09db2eb85f5c2136fb649fdc35fbabc033..69c65d56a6ac6e1d8d520b55f72c92caf2969705 100644 (file)
@@ -24,7 +24,6 @@
 struct task_struct;
 struct exec_domain;
 
-#include <asm/ptrace.h>
 #include <asm/types.h>
 #include <asm/domain.h>
 
index bfdbebebdc1b77b334fade15af3ed6af9073f3c9..d327b25c986cb754aabc0e762d259f0398879f33 100644 (file)
 /*
  * Unimplemented (or alternatively implemented) syscalls
  */
-#define __IGNORE_sync_file_range       1
 #define __IGNORE_fadvise64_64          1
 
 #endif /* __KERNEL__ */
index 14c5e0946c471eb635788c034d1047f69d7cd201..bd6be9d7f7729a467a509c956505b9d6c6f1bc08 100644 (file)
@@ -26,8 +26,8 @@
 #define FPSID_REV_MASK         (0xF  << FPSID_REV_BIT)
 
 /* FPEXC bits */
-#define FPEXC_EXCEPTION                (1<<31)
-#define FPEXC_ENABLE           (1<<30)
+#define FPEXC_EX               (1 << 31)
+#define FPEXC_EN               (1 << 30)
 
 /* FPSCR bits */
 #define FPSCR_DEFAULT_NAN      (1<<25)
index 9aaac87efba9dc969bb18858454dbaaa0940aefa..52971b49ed3be9a59ad1188601c52b670d87facb 100644 (file)
 
 struct irqaction;
 
-#define disable_irq_nosync(i) disable_irq(i)
-
-extern void disable_irq(unsigned int);
-extern void enable_irq(unsigned int);
-
 #define __IRQT_FALEDGE (1 << 0)
 #define __IRQT_RISEDGE (1 << 1)
 #define __IRQT_LOWLVL  (1 << 2)
index 41be646c351403615810d80a2d185033d63c9e7a..56eec28cc2c493ce44e673f5ea606c8ff1246adf 100644 (file)
@@ -59,7 +59,4 @@ static __inline__ int irq_canonicalize(int irq)
        return irq;
 }
 
-extern void enable_irq(unsigned int);
-extern void disable_irq(unsigned int);
-
 #endif /* _H8300_IRQ_H_ */
index eb7da5402bfaa17623bb523bed36c171adc0c776..bda6c810c0f4e3ac48973f3af52fdd478862f05b 100644 (file)
@@ -149,4 +149,6 @@ apply_paravirt(struct paravirt_patch_site *start,
 #define __parainstructions_end NULL
 #endif
 
+extern void text_poke(void *addr, unsigned char *opcode, int len);
+
 #endif /* _I386_ALTERNATIVE_H */
index 64dcdf46117bf2c1dbaeba8e88fa36912fab67c2..f86ede28f6dc84750ab60250cc7d122534d9c74a 100644 (file)
@@ -34,7 +34,7 @@ static inline void __set_64bit (unsigned long long * ptr,
                "\n1:\t"
                "movl (%0), %%eax\n\t"
                "movl 4(%0), %%edx\n\t"
-               "lock cmpxchg8b (%0)\n\t"
+               LOCK_PREFIX "cmpxchg8b (%0)\n\t"
                "jnz 1b"
                : /* no outputs */
                :       "D"(ptr),
index c03290ccecb274889663681107cce207501d2cb6..43114c824608b21f96c89a814b5499c1d71008d3 100644 (file)
@@ -47,6 +47,14 @@ extern void e820_register_memory(void);
 extern void limit_regions(unsigned long long size);
 extern void print_memory_map(char *who);
 
+#if defined(CONFIG_PM) && defined(CONFIG_SOFTWARE_SUSPEND)
+extern void e820_mark_nosave_regions(void);
+#else
+static inline void e820_mark_nosave_regions(void)
+{
+}
+#endif
+
 #endif/*!__ASSEMBLY__*/
 
 #endif/*__E820_HEADER*/
diff --git a/include/asm-i386/geode.h b/include/asm-i386/geode.h
new file mode 100644 (file)
index 0000000..6da4bbb
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * AMD Geode definitions
+ * Copyright (C) 2006, Advanced Micro Devices, 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 published by the Free Software Foundation.
+ */
+
+#ifndef _ASM_GEODE_H_
+#define _ASM_GEODE_H_
+
+#include <asm/processor.h>
+#include <linux/io.h>
+
+/* Generic southbridge functions */
+
+#define GEODE_DEV_PMS 0
+#define GEODE_DEV_ACPI 1
+#define GEODE_DEV_GPIO 2
+#define GEODE_DEV_MFGPT 3
+
+extern int geode_get_dev_base(unsigned int dev);
+
+/* Useful macros */
+#define geode_pms_base()       geode_get_dev_base(GEODE_DEV_PMS)
+#define geode_acpi_base()      geode_get_dev_base(GEODE_DEV_ACPI)
+#define geode_gpio_base()      geode_get_dev_base(GEODE_DEV_GPIO)
+#define geode_mfgpt_base()     geode_get_dev_base(GEODE_DEV_MFGPT)
+
+/* MSRS */
+
+#define GX_GLCP_SYS_RSTPLL     0x4C000014
+
+#define MSR_LBAR_SMB           0x5140000B
+#define MSR_LBAR_GPIO          0x5140000C
+#define MSR_LBAR_MFGPT         0x5140000D
+#define MSR_LBAR_ACPI          0x5140000E
+#define MSR_LBAR_PMS           0x5140000F
+
+#define MSR_PIC_YSEL_LOW       0x51400020
+#define MSR_PIC_YSEL_HIGH      0x51400021
+#define MSR_PIC_ZSEL_LOW       0x51400022
+#define MSR_PIC_ZSEL_HIGH      0x51400023
+
+#define MFGPT_IRQ_MSR          0x51400028
+#define MFGPT_NR_MSR           0x51400029
+
+/* Resource Sizes */
+
+#define LBAR_GPIO_SIZE         0xFF
+#define LBAR_MFGPT_SIZE                0x40
+#define LBAR_ACPI_SIZE         0x40
+#define LBAR_PMS_SIZE          0x80
+
+/* ACPI registers (PMS block) */
+
+/*
+ * PM1_EN is only valid when VSA is enabled for 16 bit reads.
+ * When VSA is not enabled, *always* read both PM1_STS and PM1_EN
+ * with a 32 bit read at offset 0x0
+ */
+
+#define PM1_STS                        0x00
+#define PM1_EN                 0x02
+#define PM1_CNT                        0x08
+#define PM2_CNT                        0x0C
+#define PM_TMR                 0x10
+#define PM_GPE0_STS            0x18
+#define PM_GPE0_EN             0x1C
+
+/* PMC registers (PMS block) */
+
+#define PM_SSD                 0x00
+#define PM_SCXA                        0x04
+#define PM_SCYA                        0x08
+#define PM_OUT_SLPCTL          0x0C
+#define PM_SCLK                        0x10
+#define PM_SED                 0x1
+#define PM_SCXD                        0x18
+#define PM_SCYD                        0x1C
+#define PM_IN_SLPCTL           0x20
+#define PM_WKD                 0x30
+#define PM_WKXD                        0x34
+#define PM_RD                  0x38
+#define PM_WKXA                        0x3C
+#define PM_FSD                 0x40
+#define PM_TSD                 0x44
+#define PM_PSD                 0x48
+#define PM_NWKD                        0x4C
+#define PM_AWKD                        0x50
+#define PM_SSC                 0x54
+
+/* GPIO */
+
+#define GPIO_OUTPUT_VAL                0x00
+#define GPIO_OUTPUT_ENABLE     0x04
+#define GPIO_OUTPUT_OPEN_DRAIN 0x08
+#define GPIO_OUTPUT_INVERT     0x0C
+#define GPIO_OUTPUT_AUX1       0x10
+#define GPIO_OUTPUT_AUX2       0x14
+#define GPIO_PULL_UP           0x18
+#define GPIO_PULL_DOWN         0x1C
+#define GPIO_INPUT_ENABLE      0x20
+#define GPIO_INPUT_INVERT      0x24
+#define GPIO_INPUT_FILTER      0x28
+#define GPIO_INPUT_EVENT_COUNT 0x2C
+#define GPIO_READ_BACK         0x30
+#define GPIO_INPUT_AUX1                0x34
+#define GPIO_EVENTS_ENABLE     0x38
+#define GPIO_LOCK_ENABLE       0x3C
+#define GPIO_POSITIVE_EDGE_EN  0x40
+#define GPIO_NEGATIVE_EDGE_EN  0x44
+#define GPIO_POSITIVE_EDGE_STS 0x48
+#define GPIO_NEGATIVE_EDGE_STS 0x4C
+
+#define GPIO_MAP_X             0xE0
+#define GPIO_MAP_Y             0xE4
+#define GPIO_MAP_Z             0xE8
+#define GPIO_MAP_W             0xEC
+
+extern void geode_gpio_set(unsigned int, unsigned int);
+extern void geode_gpio_clear(unsigned int, unsigned int);
+extern int geode_gpio_isset(unsigned int, unsigned int);
+extern void geode_gpio_setup_event(unsigned int, int, int);
+extern void geode_gpio_set_irq(unsigned int, unsigned int);
+
+static inline void geode_gpio_event_irq(unsigned int gpio, int pair)
+{
+       geode_gpio_setup_event(gpio, pair, 0);
+}
+
+static inline void geode_gpio_event_pme(unsigned int gpio, int pair)
+{
+       geode_gpio_setup_event(gpio, pair, 1);
+}
+
+/* Specific geode tests */
+
+static inline int is_geode_gx(void)
+{
+       return ((boot_cpu_data.x86_vendor == X86_VENDOR_NSC) &&
+               (boot_cpu_data.x86 == 5) &&
+               (boot_cpu_data.x86_model == 5));
+}
+
+static inline int is_geode_lx(void)
+{
+       return ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
+               (boot_cpu_data.x86 == 5) &&
+               (boot_cpu_data.x86_model == 10));
+}
+
+static inline int is_geode(void)
+{
+       return (is_geode_gx() || is_geode_lx());
+}
+
+#endif
index dddeedf504b70e048dbf7470875c7cea0e2fa482..c82dc7ed96b34a2ebd8493f7ec2293faae354dea 100644 (file)
 
 #ifdef CONFIG_HPET_TIMER
 
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/time.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/irq.h>
-#include <asm/msr.h>
-#include <asm/delay.h>
-#include <asm/mpspec.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
-
-#include <linux/timex.h>
-
 /*
  * Documentation on HPET can be found at:
  *      http://www.intel.com/ial/home/sp/pcmmspec.htm
  *      ftp://download.intel.com/ial/home/sp/mmts098.pdf
  */
 
-#define HPET_MMAP_SIZE 1024
-
-#define HPET_ID                0x000
-#define HPET_PERIOD    0x004
-#define HPET_CFG       0x010
-#define HPET_STATUS    0x020
-#define HPET_COUNTER   0x0f0
-#define HPET_T0_CFG    0x100
-#define HPET_T0_CMP    0x108
-#define HPET_T0_ROUTE  0x110
-#define HPET_T1_CFG    0x120
-#define HPET_T1_CMP    0x128
-#define HPET_T1_ROUTE  0x130
-#define HPET_T2_CFG    0x140
-#define HPET_T2_CMP    0x148
-#define HPET_T2_ROUTE  0x150
-
-#define HPET_ID_LEGSUP 0x00008000
-#define HPET_ID_NUMBER 0x00001f00
-#define HPET_ID_REV    0x000000ff
+#define HPET_MMAP_SIZE         1024
+
+#define HPET_ID                        0x000
+#define HPET_PERIOD            0x004
+#define HPET_CFG               0x010
+#define HPET_STATUS            0x020
+#define HPET_COUNTER           0x0f0
+#define HPET_T0_CFG            0x100
+#define HPET_T0_CMP            0x108
+#define HPET_T0_ROUTE          0x110
+#define HPET_T1_CFG            0x120
+#define HPET_T1_CMP            0x128
+#define HPET_T1_ROUTE          0x130
+#define HPET_T2_CFG            0x140
+#define HPET_T2_CMP            0x148
+#define HPET_T2_ROUTE          0x150
+
+#define HPET_ID_REV            0x000000ff
+#define HPET_ID_NUMBER         0x00001f00
+#define HPET_ID_64BIT          0x00002000
+#define HPET_ID_LEGSUP         0x00008000
+#define HPET_ID_VENDOR         0xffff0000
 #define        HPET_ID_NUMBER_SHIFT    8
+#define HPET_ID_VENDOR_SHIFT   16
 
-#define HPET_CFG_ENABLE        0x001
-#define HPET_CFG_LEGACY        0x002
+#define HPET_ID_VENDOR_8086    0x8086
+
+#define HPET_CFG_ENABLE                0x001
+#define HPET_CFG_LEGACY                0x002
 #define        HPET_LEGACY_8254        2
 #define        HPET_LEGACY_RTC         8
 
-#define HPET_TN_ENABLE         0x004
-#define HPET_TN_PERIODIC       0x008
-#define HPET_TN_PERIODIC_CAP   0x010
-#define HPET_TN_SETVAL         0x040
-#define HPET_TN_32BIT          0x100
-
-/* Use our own asm for 64 bit multiply/divide */
-#define ASM_MUL64_REG(eax_out,edx_out,reg_in,eax_in)                   \
-               __asm__ __volatile__("mull %2"                          \
-                               :"=a" (eax_out), "=d" (edx_out)         \
-                               :"r" (reg_in), "0" (eax_in))
+#define HPET_TN_LEVEL          0x0002
+#define HPET_TN_ENABLE         0x0004
+#define HPET_TN_PERIODIC       0x0008
+#define HPET_TN_PERIODIC_CAP   0x0010
+#define HPET_TN_64BIT_CAP      0x0020
+#define HPET_TN_SETVAL         0x0040
+#define HPET_TN_32BIT          0x0100
+#define HPET_TN_ROUTE          0x3e00
+#define HPET_TN_FSB            0x4000
+#define HPET_TN_FSB_CAP                0x8000
+#define HPET_TN_ROUTE_SHIFT    9
 
-#define ASM_DIV64_REG(eax_out,edx_out,reg_in,eax_in,edx_in)            \
-               __asm__ __volatile__("divl %2"                          \
-                               :"=a" (eax_out), "=d" (edx_out)         \
-                               :"r" (reg_in), "0" (eax_in), "1" (edx_in))
-
-#define KERNEL_TICK_USEC       (1000000UL/HZ)  /* tick value in microsec */
 /* Max HPET Period is 10^8 femto sec as in HPET spec */
-#define HPET_MAX_PERIOD (100000000UL)
+#define HPET_MAX_PERIOD                100000000UL
 /*
  * Min HPET period is 10^5 femto sec just for safety. If it is less than this,
  * then 32 bit HPET counter wrapsaround in less than 0.5 sec.
  */
-#define HPET_MIN_PERIOD (100000UL)
-#define HPET_TICK_RATE  (HZ * 100000UL)
+#define HPET_MIN_PERIOD                100000UL
 
-extern unsigned long hpet_address;     /* hpet memory map physical address */
+/* hpet memory map physical address */
+extern unsigned long hpet_address;
 extern int is_hpet_enabled(void);
-
-#ifdef CONFIG_X86_64
-extern unsigned long hpet_tick;        /* hpet clks count per tick */
-extern int hpet_use_timer;
-extern int hpet_rtc_timer_init(void);
 extern int hpet_enable(void);
-extern int is_hpet_capable(void);
-extern int hpet_readl(unsigned long a);
-#else
-extern int hpet_enable(void);
-#endif
 
 #ifdef CONFIG_HPET_EMULATE_RTC
+
+#include <linux/interrupt.h>
+
 extern int hpet_mask_rtc_irq_bit(unsigned long bit_mask);
 extern int hpet_set_rtc_irq_bit(unsigned long bit_mask);
-extern int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec);
+extern int hpet_set_alarm_time(unsigned char hrs, unsigned char min,
+                              unsigned char sec);
 extern int hpet_set_periodic_freq(unsigned long freq);
 extern int hpet_rtc_dropped_irq(void);
 extern int hpet_rtc_timer_init(void);
 extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id);
+
 #endif /* CONFIG_HPET_EMULATE_RTC */
 
 #else
index 6cb0dd4dcddef8c1e89791fe78c64aa8185befad..7577d058d86e7ef292bf63f78eb3e139527cbc0b 100644 (file)
@@ -3,19 +3,15 @@
 
 #include <linux/clockchips.h>
 
+/* i8253A PIT registers */
+#define PIT_MODE               0x43
+#define PIT_CH0                        0x40
+#define PIT_CH2                        0x42
+
 extern spinlock_t i8253_lock;
 
 extern struct clock_event_device *global_clock_event;
 
-/**
- * pit_interrupt_hook - hook into timer tick
- * @regs:      standard registers from interrupt
- *
- * Call the global clock event handler.
- **/
-static inline void pit_interrupt_hook(void)
-{
-       global_clock_event->event_handler(global_clock_event);
-}
+extern void setup_pit_timer(void);
 
 #endif /* __ASM_I8253_H__ */
index 56e5689863aece4257d00395b66d6fa8ae8a489e..23ecda0b28a07cd1d55b27375e7e231024c8f2e6 100644 (file)
@@ -12,5 +12,5 @@
 
 static inline void do_timer_interrupt_hook(void)
 {
-       pit_interrupt_hook();
+       global_clock_event->event_handler(global_clock_event);
 }
index a96d9f6604eec83839c89c34d0262e3c6938ed8e..48540ba971667225977fed53cbc6d898d2e9d628 100644 (file)
@@ -7,11 +7,6 @@
 #ifndef _MACH_IO_PORTS_H
 #define _MACH_IO_PORTS_H
 
-/* i8253A PIT registers */
-#define PIT_MODE               0x43
-#define PIT_CH0                        0x40
-#define PIT_CH2                        0x42
-
 /* i8259A PIC registers */
 #define PIC_MASTER_CMD         0x20
 #define PIC_MASTER_IMR         0x21
index a955e57ad016a9ce203d90cce3b1f56ad7dbd2c0..e23fd9fbebb3a5b024a9c8c2e155ea02ae51c8a9 100644 (file)
@@ -19,14 +19,37 @@ static inline void kb_wait(void)
 static inline void mach_reboot(void)
 {
        int i;
+
+       /* old method, works on most machines */
        for (i = 0; i < 10; i++) {
+               kb_wait();
+               udelay(50);
+               outb(0xfe, 0x64);       /* pulse reset low */
+               udelay(50);
+       }
+
+       /* New method: sets the "System flag" which, when set, indicates
+        * successful completion of the keyboard controller self-test (Basic
+        * Assurance Test, BAT).  This is needed for some machines with no
+        * keyboard plugged in.  This read-modify-write sequence sets only the
+        * system flag
+        */
+       for (i = 0; i < 10; i++) {
+               int cmd;
+
+               outb(0x20, 0x64);       /* read Controller Command Byte */
+               udelay(50);
+               kb_wait();
+               udelay(50);
+               cmd = inb(0x60);
+               udelay(50);
                kb_wait();
                udelay(50);
                outb(0x60, 0x64);       /* write Controller Command Byte */
                udelay(50);
                kb_wait();
                udelay(50);
-               outb(0x14, 0x60);       /* set "System flag" */
+               outb(cmd | 0x04, 0x60); /* set "System flag" */
                udelay(50);
                kb_wait();
                udelay(50);
index 60f9dcc15d5427c64ca4a0edd7d4a3adab6ddee8..bc2b5892630859f8c42441204d2beec90a2151dd 100644 (file)
@@ -12,7 +12,7 @@
  **/
 static inline void do_timer_interrupt_hook(void)
 {
-       pit_interrupt_hook();
+       global_clock_event->event_handler(global_clock_event);
        voyager_timer_interrupt();
 }
 
index 99a890047023c71ff33671a5d7ef47e9e9541d7a..1613b42eaf5837a2db14c86cc0c45e0c0816f398 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <asm/io.h>
 #include <asm/system.h>
+#include <asm/processor.h>
 #include <linux/mc146818rtc.h>
 
 #ifndef RTC_PORT
@@ -43,8 +44,10 @@ static inline void lock_cmos(unsigned char reg)
        unsigned long new;
        new = ((smp_processor_id()+1) << 8) | reg;
        for (;;) {
-               if (cmos_lock)
+               if (cmos_lock) {
+                       cpu_relax();
                        continue;
+               }
                if (__cmpxchg(&cmos_lock, 0, new, sizeof(cmos_lock)) == 0)
                        return;
        }
index b0a02ee34ffd74720747c295077720e86604933c..d56d89742e8fdcd0bfd96ccd1ff83292eea0bc99 100644 (file)
@@ -5,3 +5,7 @@ extern void mcheck_init(struct cpuinfo_x86 *c);
 #endif
 
 extern int mce_disabled;
+
+extern void stop_mce(void);
+extern void restart_mce(void);
+
index fb1e133efd9fecdc182d827ddd8c75841b8c6660..ff30c98f87b023290c8d1355f3873540e7d6c2ae 100644 (file)
@@ -57,5 +57,7 @@ unsigned lapic_adjust_nmi_hz(unsigned hz);
 int lapic_watchdog_ok(void);
 void disable_lapic_nmi_watchdog(void);
 void enable_lapic_nmi_watchdog(void);
+void stop_nmi(void);
+void restart_nmi(void);
 
 #endif /* ASM_NMI_H */
index 99cf5d3692a920699c5e50a99d32609363b81218..80ecc66b6d8647c901c5d7038bae1267b9219c26 100644 (file)
@@ -44,7 +44,6 @@
 extern int nx_enabled;
 
 #ifdef CONFIG_X86_PAE
-extern unsigned long long __supported_pte_mask;
 typedef struct { unsigned long pte_low, pte_high; } pte_t;
 typedef struct { unsigned long long pmd; } pmd_t;
 typedef struct { unsigned long long pgd; } pgd_t;
index 392d3fe5d45ecf280897f39d0af6542cbe021ec2..d790343e9982f3ad2f9919b1f354a5bb01a5e968 100644 (file)
@@ -3,6 +3,11 @@
 
 
 #ifdef __KERNEL__
+
+struct pci_sysdata {
+       int             node;           /* NUMA node */
+};
+
 #include <linux/mm.h>          /* for struct page */
 
 /* Can be used to override the logic in pci_scan_bus for skipping
diff --git a/include/asm-i386/processor-cyrix.h b/include/asm-i386/processor-cyrix.h
new file mode 100644 (file)
index 0000000..97568ad
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * NSC/Cyrix CPU indexed register access. Must be inlined instead of
+ * macros to ensure correct access ordering
+ * Access order is always 0x22 (=offset), 0x23 (=value)
+ *
+ * When using the old macros a line like
+ *   setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x88);
+ * gets expanded to:
+ *  do {
+ *    outb((CX86_CCR2), 0x22);
+ *    outb((({
+ *        outb((CX86_CCR2), 0x22);
+ *        inb(0x23);
+ *    }) | 0x88), 0x23);
+ *  } while (0);
+ *
+ * which in fact violates the access order (= 0x22, 0x22, 0x23, 0x23).
+ */
+
+static inline u8 getCx86(u8 reg)
+{
+       outb(reg, 0x22);
+       return inb(0x23);
+}
+
+static inline void setCx86(u8 reg, u8 data)
+{
+       outb(reg, 0x22);
+       outb(data, 0x23);
+}
index 422cffef00c901b0c301d308b77c7e70e557719c..3845fe72383e518d89075695c2eec4dd0a9f277c 100644 (file)
@@ -88,7 +88,6 @@ struct cpuinfo_x86 {
 #define X86_VENDOR_UMC 3
 #define X86_VENDOR_NEXGEN 4
 #define X86_VENDOR_CENTAUR 5
-#define X86_VENDOR_RISE 6
 #define X86_VENDOR_TRANSMETA 7
 #define X86_VENDOR_NSC 8
 #define X86_VENDOR_NUM 9
@@ -169,17 +168,6 @@ static inline void clear_in_cr4 (unsigned long mask)
        write_cr4(cr4);
 }
 
-/*
- *      NSC/Cyrix CPU indexed register access macros
- */
-
-#define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); })
-
-#define setCx86(reg, data) do { \
-       outb((reg), 0x22); \
-       outb((data), 0x23); \
-} while (0)
-
 /* Stop speculative execution */
 static inline void sync_core(void)
 {
diff --git a/include/asm-i386/resume-trace.h b/include/asm-i386/resume-trace.h
new file mode 100644 (file)
index 0000000..ec9cfd6
--- /dev/null
@@ -0,0 +1,13 @@
+#define TRACE_RESUME(user) do {                                        \
+       if (pm_trace_enabled) {                                 \
+               void *tracedata;                                \
+               asm volatile("movl $1f,%0\n"                    \
+                       ".section .tracedata,\"a\"\n"           \
+                       "1:\t.word %c1\n"                       \
+                       "\t.long %c2\n"                         \
+                       ".previous"                             \
+                       :"=r" (tracedata)                       \
+                       : "i" (__LINE__), "i" (__FILE__));      \
+               generate_resume_trace(tracedata, user);         \
+       }                                                       \
+} while (0)
index b9277361954b795ed539fe013385240cd8c26eca..a9b64453bdf54ecd03d239fe4d68c3b82ad92959 100644 (file)
 #define _I386_STRING_H_
 
 #ifdef __KERNEL__
-/*
- * On a 486 or Pentium, we are better off not using the
- * byte string operations. But on a 386 or a PPro the
- * byte string ops are faster than doing it by hand
- * (MUCH faster on a Pentium).
- */
-
-/*
- * This string-include defines all string functions as inline
- * functions. Use gcc. It also assumes ds=es=data space, this should be
- * normal. Most of the string-functions are rather heavily hand-optimized,
- * see especially strsep,strstr,str[c]spn. They should work, but are not
- * very easy to understand. Everything is done entirely within the register
- * set, making the functions fast and clean. String instructions have been
- * used through-out, making for "slightly" unclear code :-)
- *
- *             NO Copyright (C) 1991, 1992 Linus Torvalds,
- *             consider these trivial functions to be PD.
- */
 
-/* AK: in fact I bet it would be better to move this stuff all out of line.
- */
+/* Let gcc decide wether to inline or use the out of line functions */
 
 #define __HAVE_ARCH_STRCPY
-static inline char * strcpy(char * dest,const char *src)
-{
-int d0, d1, d2;
-__asm__ __volatile__(
-       "1:\tlodsb\n\t"
-       "stosb\n\t"
-       "testb %%al,%%al\n\t"
-       "jne 1b"
-       : "=&S" (d0), "=&D" (d1), "=&a" (d2)
-       :"0" (src),"1" (dest) : "memory");
-return dest;
-}
+extern char *strcpy(char *dest, const char *src);
 
 #define __HAVE_ARCH_STRNCPY
-static inline char * strncpy(char * dest,const char *src,size_t count)
-{
-int d0, d1, d2, d3;
-__asm__ __volatile__(
-       "1:\tdecl %2\n\t"
-       "js 2f\n\t"
-       "lodsb\n\t"
-       "stosb\n\t"
-       "testb %%al,%%al\n\t"
-       "jne 1b\n\t"
-       "rep\n\t"
-       "stosb\n"
-       "2:"
-       : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
-       :"0" (src),"1" (dest),"2" (count) : "memory");
-return dest;
-}
+extern char *strncpy(char *dest, const char *src, size_t count);
 
 #define __HAVE_ARCH_STRCAT
-static inline char * strcat(char * dest,const char * src)
-{
-int d0, d1, d2, d3;
-__asm__ __volatile__(
-       "repne\n\t"
-       "scasb\n\t"
-       "decl %1\n"
-       "1:\tlodsb\n\t"
-       "stosb\n\t"
-       "testb %%al,%%al\n\t"
-       "jne 1b"
-       : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
-       : "0" (src), "1" (dest), "2" (0), "3" (0xffffffffu):"memory");
-return dest;
-}
+extern char *strcat(char *dest, const char *src);
 
 #define __HAVE_ARCH_STRNCAT
-static inline char * strncat(char * dest,const char * src,size_t count)
-{
-int d0, d1, d2, d3;
-__asm__ __volatile__(
-       "repne\n\t"
-       "scasb\n\t"
-       "decl %1\n\t"
-       "movl %8,%3\n"
-       "1:\tdecl %3\n\t"
-       "js 2f\n\t"
-       "lodsb\n\t"
-       "stosb\n\t"
-       "testb %%al,%%al\n\t"
-       "jne 1b\n"
-       "2:\txorl %2,%2\n\t"
-       "stosb"
-       : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
-       : "0" (src),"1" (dest),"2" (0),"3" (0xffffffffu), "g" (count)
-       : "memory");
-return dest;
-}
+extern char *strncat(char *dest, const char *src, size_t count);
 
 #define __HAVE_ARCH_STRCMP
-static inline int strcmp(const char * cs,const char * ct)
-{
-int d0, d1;
-register int __res;
-__asm__ __volatile__(
-       "1:\tlodsb\n\t"
-       "scasb\n\t"
-       "jne 2f\n\t"
-       "testb %%al,%%al\n\t"
-       "jne 1b\n\t"
-       "xorl %%eax,%%eax\n\t"
-       "jmp 3f\n"
-       "2:\tsbbl %%eax,%%eax\n\t"
-       "orb $1,%%al\n"
-       "3:"
-       :"=a" (__res), "=&S" (d0), "=&D" (d1)
-       :"1" (cs),"2" (ct)
-       :"memory");
-return __res;
-}
+extern int strcmp(const char *cs, const char *ct);
 
 #define __HAVE_ARCH_STRNCMP
-static inline int strncmp(const char * cs,const char * ct,size_t count)
-{
-register int __res;
-int d0, d1, d2;
-__asm__ __volatile__(
-       "1:\tdecl %3\n\t"
-       "js 2f\n\t"
-       "lodsb\n\t"
-       "scasb\n\t"
-       "jne 3f\n\t"
-       "testb %%al,%%al\n\t"
-       "jne 1b\n"
-       "2:\txorl %%eax,%%eax\n\t"
-       "jmp 4f\n"
-       "3:\tsbbl %%eax,%%eax\n\t"
-       "orb $1,%%al\n"
-       "4:"
-       :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
-       :"1" (cs),"2" (ct),"3" (count)
-       :"memory");
-return __res;
-}
+extern int strncmp(const char *cs, const char *ct, size_t count);
 
 #define __HAVE_ARCH_STRCHR
-static inline char * strchr(const char * s, int c)
-{
-int d0;
-register char * __res;
-__asm__ __volatile__(
-       "movb %%al,%%ah\n"
-       "1:\tlodsb\n\t"
-       "cmpb %%ah,%%al\n\t"
-       "je 2f\n\t"
-       "testb %%al,%%al\n\t"
-       "jne 1b\n\t"
-       "movl $1,%1\n"
-       "2:\tmovl %1,%0\n\t"
-       "decl %0"
-       :"=a" (__res), "=&S" (d0)
-       :"1" (s),"0" (c)
-       :"memory");
-return __res;
-}
+extern char *strchr(const char *s, int c);
 
 #define __HAVE_ARCH_STRRCHR
-static inline char * strrchr(const char * s, int c)
-{
-int d0, d1;
-register char * __res;
-__asm__ __volatile__(
-       "movb %%al,%%ah\n"
-       "1:\tlodsb\n\t"
-       "cmpb %%ah,%%al\n\t"
-       "jne 2f\n\t"
-       "leal -1(%%esi),%0\n"
-       "2:\ttestb %%al,%%al\n\t"
-       "jne 1b"
-       :"=g" (__res), "=&S" (d0), "=&a" (d1)
-       :"0" (0),"1" (s),"2" (c)
-       :"memory");
-return __res;
-}
+extern char *strrchr(const char *s, int c);
 
 #define __HAVE_ARCH_STRLEN
-static inline size_t strlen(const char * s)
-{
-int d0;
-register int __res;
-__asm__ __volatile__(
-       "repne\n\t"
-       "scasb\n\t"
-       "notl %0\n\t"
-       "decl %0"
-       :"=c" (__res), "=&D" (d0)
-       :"1" (s),"a" (0), "0" (0xffffffffu)
-       :"memory");
-return __res;
-}
+extern size_t strlen(const char *s);
 
 static __always_inline void * __memcpy(void * to, const void * from, size_t n)
 {
@@ -207,9 +39,7 @@ __asm__ __volatile__(
        "rep ; movsl\n\t"
        "movl %4,%%ecx\n\t"
        "andl $3,%%ecx\n\t"
-#if 1  /* want to pay 2 byte penalty for a chance to skip microcoded rep? */
        "jz 1f\n\t"
-#endif
        "rep ; movsb\n\t"
        "1:"
        : "=&c" (d0), "=&D" (d1), "=&S" (d2)
@@ -328,23 +158,7 @@ void *memmove(void * dest,const void * src, size_t n);
 #define memcmp __builtin_memcmp
 
 #define __HAVE_ARCH_MEMCHR
-static inline void * memchr(const void * cs,int c,size_t count)
-{
-int d0;
-register void * __res;
-if (!count)
-       return NULL;
-__asm__ __volatile__(
-       "repne\n\t"
-       "scasb\n\t"
-       "je 1f\n\t"
-       "movl $1,%0\n"
-       "1:\tdecl %0"
-       :"=D" (__res), "=&c" (d0)
-       :"a" (c),"0" (cs),"1" (count)
-       :"memory");
-return __res;
-}
+extern void *memchr(const void * cs,int c,size_t count);
 
 static inline void * __memset_generic(void * s, char c,size_t count)
 {
@@ -386,29 +200,10 @@ return (s);
 
 /* Added by Gertjan van Wingerde to make minix and sysv module work */
 #define __HAVE_ARCH_STRNLEN
-static inline size_t strnlen(const char * s, size_t count)
-{
-int d0;
-register int __res;
-__asm__ __volatile__(
-       "movl %2,%0\n\t"
-       "jmp 2f\n"
-       "1:\tcmpb $0,(%0)\n\t"
-       "je 3f\n\t"
-       "incl %0\n"
-       "2:\tdecl %1\n\t"
-       "cmpl $-1,%1\n\t"
-       "jne 1b\n"
-       "3:\tsubl %2,%0"
-       :"=a" (__res), "=&d" (d0)
-       :"c" (s),"1" (count)
-       :"memory");
-return __res;
-}
+extern size_t strnlen(const char * s, size_t count);
 /* end of additional stuff */
 
 #define __HAVE_ARCH_STRSTR
-
 extern char *strstr(const char *cs, const char *ct);
 
 /*
@@ -474,19 +269,7 @@ __asm__  __volatile__( \
  * find the first occurrence of byte 'c', or 1 past the area if none
  */
 #define __HAVE_ARCH_MEMSCAN
-static inline void * memscan(void * addr, int c, size_t size)
-{
-       if (!size)
-               return addr;
-       __asm__("repnz; scasb\n\t"
-               "jnz 1f\n\t"
-               "dec %%edi\n"
-               "1:"
-               : "=D" (addr), "=c" (size)
-               : "0" (addr), "1" (size), "a" (c)
-               : "memory");
-       return addr;
-}
+extern void *memscan(void * addr, int c, size_t size);
 
 #endif /* __KERNEL__ */
 
index 51a713e33a9ee8d590e4729657521601588a6a8b..0db7e994fb8b4f40ad9a96ecf2258d7fd6dc57f6 100644 (file)
@@ -5,13 +5,11 @@
 
 #define TICK_SIZE (tick_nsec / 1000)
 
-void setup_pit_timer(void);
 unsigned long long native_sched_clock(void);
 unsigned long native_calculate_cpu_khz(void);
 
 extern int timer_ack;
 extern int no_timer_check;
-extern int no_sync_cmos_clock;
 extern int recalibrate_cpu_khz(void);
 
 #ifndef CONFIG_PARAVIRT
index fc525c5cd5a9ddbfc4620272bf2697fa29497ea4..a50fa6741486ae8cafb7525cd6335c7852d11930 100644 (file)
@@ -160,7 +160,11 @@ DECLARE_PER_CPU(struct tlb_state, cpu_tlbstate);
        native_flush_tlb_others(&mask, mm, va)
 #endif
 
-#define flush_tlb_kernel_range(start, end) flush_tlb_all()
+static inline void flush_tlb_kernel_range(unsigned long start,
+                                       unsigned long end)
+{
+       flush_tlb_all();
+}
 
 static inline void flush_tlb_pgtables(struct mm_struct *mm,
                                      unsigned long start, unsigned long end)
index 7fc512d90ea85762884f419b3ae8285a34e2028f..19b2dafd0c81b1f822e8fa34d8b65c91cd0378c6 100644 (file)
@@ -67,7 +67,7 @@ static inline int node_to_first_cpu(int node)
        return first_cpu(mask);
 }
 
-#define pcibus_to_node(bus) ((long) (bus)->sysdata)
+#define pcibus_to_node(bus) ((struct pci_sysdata *)((bus)->sysdata))->node
 #define pcibus_to_cpumask(bus) node_to_cpumask(pcibus_to_node(bus))
 
 /* sched_domains SD_NODE_INIT for NUMAQ machines */
index e2aa5e0d0cc7fa9c1a4ec84002f98a80bf697f11..d2a4f7be9c2c5ee3a1516b0b5bf636addc2cefac 100644 (file)
@@ -581,7 +581,7 @@ long __must_check __strncpy_from_user(char *dst,
  * If there is a limit on the length of a valid string, you may wish to
  * consider using strnlen_user() instead.
  */
-#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
+#define strlen_user(str) strnlen_user(str, LONG_MAX)
 
 long strnlen_user(const char __user *str, long n);
 unsigned long __must_check clear_user(void __user *mem, unsigned long len);
index 35b360b82e43f9958d0f967347fcb2052a618578..a66d26827cbbe23c2864c053f81d6e5332a99a04 100644 (file)
@@ -33,9 +33,6 @@ irq_canonicalize (int irq)
        return ((irq == 2) ? 9 : irq);
 }
 
-extern void disable_irq (unsigned int);
-extern void disable_irq_nosync (unsigned int);
-extern void enable_irq (unsigned int);
 extern void set_irq_affinity_info (unsigned int irq, int dest, int redir);
 bool is_affinity_mask_valid(cpumask_t cpumask);
 
index 4901cb105e2fe9d7a33c3ae40c1637e651201392..eb29a526059169271d29e573182867957a8508a5 100644 (file)
@@ -59,9 +59,6 @@
 #define IRQ_USER       8
 
 extern unsigned int irq_canonicalize(unsigned int irq);
-extern void enable_irq(unsigned int);
-extern void disable_irq(unsigned int);
-#define disable_irq_nosync     disable_irq
 
 struct pt_regs;
 
index 2ffb06abe881c703d98347ee3bf9c0f0528a35c2..262db6b8da7349c073f0eaf126f4e245133e4c6a 100644 (file)
@@ -296,6 +296,9 @@ struct mpic
        unsigned int            dcr_base;
 #endif
 
+       /* Protected sources */
+       unsigned long           *protected;
+
 #ifdef CONFIG_MPIC_WEIRD
        /* Pointer to HW info array */
        u32                     *hw_set;
index 6e391c9894ce7e513f7e75e1a62c263d5f7a6eb1..672083787a1d8eb1664ba77c5509cf58e708cd96 100644 (file)
@@ -139,7 +139,7 @@ extern unsigned long __init of_get_flat_dt_root(void);
 
 /* For updating the device tree at runtime */
 extern void of_attach_node(struct device_node *);
-extern void of_detach_node(const struct device_node *);
+extern void of_detach_node(struct device_node *);
 
 /* Other Prototypes */
 extern void finish_device_tree(void);
index f1311a8f310fe9e3c75c28a1d47644c2f1db3465..cc45780421cac15412e44ef5fc62a425aa089fe8 100644 (file)
@@ -54,6 +54,7 @@ extern void show_regs(struct pt_regs * regs);
 extern void flush_instruction_cache(void);
 extern void hard_reset_now(void);
 extern void poweroff_now(void);
+extern int set_dabr(unsigned long dabr);
 #ifdef CONFIG_6xx
 extern long _get_L2CR(void);
 extern long _get_L3CR(void);
index 1ca49e29288a04795cb93f1db7e89ee1fe540559..5c9e6a873aebd2cce585c0ec98f2413a27e52666 100644 (file)
 #define        IRL0_PRIORITY   13
 #define TOP_PRIORITY   15
 
-extern void disable_irq(unsigned int);
-extern void disable_irq_nosync(unsigned int);
-extern void enable_irq(unsigned int);
-
 extern int intc_evt_to_irq[(0xE20/0x20)+1];
 int intc_irq_describe(char* p, int irq);
 
index ff520ea97473d7a4ee7e020678c0cd763b867829..61fb99643afd3a5ba3d9773f79057a39ac558f85 100644 (file)
 #ifndef _SPARC_IRQ_H
 #define _SPARC_IRQ_H
 
-#include <linux/linkage.h>
-#include <linux/threads.h>     /* For NR_CPUS */
 #include <linux/interrupt.h>
 
-#include <asm/system.h>     /* For SUN4M_NCPUS */
-#include <asm/btfixup.h>
-
-#define __irq_ino(irq) irq
-#define __irq_pil(irq) irq
-
 #define NR_IRQS    16
 
 #define irq_canonicalize(irq)  (irq)
 
-/* Dave Redman (djhr@tadpole.co.uk)
- * changed these to function pointers.. it saves cycles and will allow
- * the irq dependencies to be split into different files at a later date
- * sun4c_irq.c, sun4m_irq.c etc so we could reduce the kernel size.
- * Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Changed these to btfixup entities... It saves cycles :)
- */
-BTFIXUPDEF_CALL(void, disable_irq, unsigned int)
-BTFIXUPDEF_CALL(void, enable_irq, unsigned int)
-BTFIXUPDEF_CALL(void, disable_pil_irq, unsigned int)
-BTFIXUPDEF_CALL(void, enable_pil_irq, unsigned int)
-BTFIXUPDEF_CALL(void, clear_clock_irq, void)
-BTFIXUPDEF_CALL(void, clear_profile_irq, int)
-BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int)
-
-static inline void disable_irq_nosync(unsigned int irq)
-{
-       BTFIXUP_CALL(disable_irq)(irq);
-}
-
-static inline void disable_irq(unsigned int irq)
-{
-       BTFIXUP_CALL(disable_irq)(irq);
-}
-
-static inline void enable_irq(unsigned int irq)
-{
-       BTFIXUP_CALL(enable_irq)(irq);
-}
-
-static inline void disable_pil_irq(unsigned int irq)
-{
-       BTFIXUP_CALL(disable_pil_irq)(irq);
-}
-
-static inline void enable_pil_irq(unsigned int irq)
-{
-       BTFIXUP_CALL(enable_pil_irq)(irq);
-}
-
-static inline void clear_clock_irq(void)
-{
-       BTFIXUP_CALL(clear_clock_irq)();
-}
-
-static inline void clear_profile_irq(int irq)
-{
-       BTFIXUP_CALL(clear_profile_irq)(irq);
-}
-
-static inline void load_profile_irq(int cpu, int limit)
-{
-       BTFIXUP_CALL(load_profile_irq)(cpu, limit);
-}
-
-extern void (*sparc_init_timers)(irq_handler_t lvl10_irq);
-extern void claim_ticker14(irq_handler_t irq_handler,
-                          int irq,
-                          unsigned int timeout);
-
-#ifdef CONFIG_SMP
-BTFIXUPDEF_CALL(void, set_cpu_int, int, int)
-BTFIXUPDEF_CALL(void, clear_cpu_int, int, int)
-BTFIXUPDEF_CALL(void, set_irq_udt, int)
-
-#define set_cpu_int(cpu,level) BTFIXUP_CALL(set_cpu_int)(cpu,level)
-#define clear_cpu_int(cpu,level) BTFIXUP_CALL(clear_cpu_int)(cpu,level)
-#define set_irq_udt(cpu) BTFIXUP_CALL(set_irq_udt)(cpu)
-#endif
-
 extern int request_fast_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, __const__ char *devname);
 
-/* On the sun4m, just like the timers, we have both per-cpu and master
- * interrupt registers.
- */
-
-/* These registers are used for sending/receiving irqs from/to
- * different cpu's.
- */
-struct sun4m_intreg_percpu {
-       unsigned int tbt;        /* Interrupts still pending for this cpu. */
-
-       /* These next two registers are WRITE-ONLY and are only
-        * "on bit" sensitive, "off bits" written have NO affect.
-        */
-       unsigned int clear;  /* Clear this cpus irqs here. */
-       unsigned int set;    /* Set this cpus irqs here. */
-       unsigned char space[PAGE_SIZE - 12];
-};
-
-/*
- * djhr
- * Actually the clear and set fields in this struct are misleading..
- * according to the SLAVIO manual (and the same applies for the SEC)
- * the clear field clears bits in the mask which will ENABLE that IRQ
- * the set field sets bits in the mask to DISABLE the IRQ.
- *
- * Also the undirected_xx address in the SLAVIO is defined as
- * RESERVED and write only..
- *
- * DAVEM_NOTE: The SLAVIO only specifies behavior on uniprocessor
- *             sun4m machines, for MP the layout makes more sense.
- */
-struct sun4m_intregs {
-       struct sun4m_intreg_percpu cpu_intregs[SUN4M_NCPUS];
-       unsigned int tbt;                /* IRQ's that are still pending. */
-       unsigned int irqs;               /* Master IRQ bits. */
-
-       /* Again, like the above, two these registers are WRITE-ONLY. */
-       unsigned int clear;              /* Clear master IRQ's by setting bits here. */
-       unsigned int set;                /* Set master IRQ's by setting bits here. */
-
-       /* This register is both READ and WRITE. */
-       unsigned int undirected_target;  /* Which cpu gets undirected irqs. */
-};
-
-extern struct sun4m_intregs *sun4m_interrupts;
-
-/* 
- * Bit field defines for the interrupt registers on various
- * Sparc machines.
- */
-
-/* The sun4c interrupt register. */
-#define SUN4C_INT_ENABLE  0x01     /* Allow interrupts. */
-#define SUN4C_INT_E14     0x80     /* Enable level 14 IRQ. */
-#define SUN4C_INT_E10     0x20     /* Enable level 10 IRQ. */
-#define SUN4C_INT_E8      0x10     /* Enable level 8 IRQ. */
-#define SUN4C_INT_E6      0x08     /* Enable level 6 IRQ. */
-#define SUN4C_INT_E4      0x04     /* Enable level 4 IRQ. */
-#define SUN4C_INT_E1      0x02     /* Enable level 1 IRQ. */
-
-/* Dave Redman (djhr@tadpole.co.uk)
- * The sun4m interrupt registers.
- */
-#define SUN4M_INT_ENABLE       0x80000000
-#define SUN4M_INT_E14          0x00000080
-#define SUN4M_INT_E10          0x00080000
-
-#define SUN4M_HARD_INT(x)      (0x000000001 << (x))
-#define SUN4M_SOFT_INT(x)      (0x000010000 << (x))
-
-#define        SUN4M_INT_MASKALL       0x80000000        /* mask all interrupts */
-#define        SUN4M_INT_MODULE_ERR    0x40000000        /* module error */
-#define        SUN4M_INT_M2S_WRITE     0x20000000        /* write buffer error */
-#define        SUN4M_INT_ECC           0x10000000        /* ecc memory error */
-#define        SUN4M_INT_FLOPPY        0x00400000        /* floppy disk */
-#define        SUN4M_INT_MODULE        0x00200000        /* module interrupt */
-#define        SUN4M_INT_VIDEO         0x00100000        /* onboard video */
-#define        SUN4M_INT_REALTIME      0x00080000        /* system timer */
-#define        SUN4M_INT_SCSI          0x00040000        /* onboard scsi */
-#define        SUN4M_INT_AUDIO         0x00020000        /* audio/isdn */
-#define        SUN4M_INT_ETHERNET      0x00010000        /* onboard ethernet */
-#define        SUN4M_INT_SERIAL        0x00008000        /* serial ports */
-#define        SUN4M_INT_KBDMS         0x00004000        /* keyboard/mouse */
-#define        SUN4M_INT_SBUSBITS      0x00003F80        /* sbus int bits */
-
-#define SUN4M_INT_SBUS(x)      (1 << (x+7))
-#define SUN4M_INT_VME(x)       (1 << (x))
-
 #endif
index a55f4c3488b071d19c757742e0b34a1c6ffad78f..2cc235b74d94932de828fae558a48eb17294575d 100644 (file)
@@ -46,7 +46,6 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
 #define pgd_ERROR(e)   __builtin_trap()
 
 BTFIXUPDEF_INT(page_none)
-BTFIXUPDEF_INT(page_shared)
 BTFIXUPDEF_INT(page_copy)
 BTFIXUPDEF_INT(page_readonly)
 BTFIXUPDEF_INT(page_kernel)
@@ -66,7 +65,7 @@ BTFIXUPDEF_INT(page_kernel)
 #define PTE_SIZE               (PTRS_PER_PTE*4)
 
 #define PAGE_NONE      __pgprot(BTFIXUP_INT(page_none))
-#define PAGE_SHARED    __pgprot(BTFIXUP_INT(page_shared))
+extern pgprot_t PAGE_SHARED;
 #define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
 #define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
 
index 88687c181f01234e8463ef0581f93e983c0542fe..7d0d4cd1ce548d611f2ea4a34ec40c222e1a384d 100644 (file)
@@ -50,16 +50,6 @@ init_irq_handlers (int base_irq, int num, int interval,
    interrupt.  */
 extern unsigned int handle_irq (int irq, struct pt_regs *regs);
 
-
-/* Enable interrupt handling on an irq.  */
-extern void enable_irq(unsigned int irq);
-
-/* Disable an irq and wait for completion.  */
-extern void disable_irq (unsigned int irq);
-
-/* Disable an irq without waiting. */
-extern void disable_irq_nosync (unsigned int irq);
-
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __V850_IRQ_H__ */
index a29f05087a310abd56d6c938094a7921c5b7993a..1da8f49c0fe23cc7c87a12db6a891bfaaf27d1c1 100644 (file)
@@ -29,6 +29,7 @@
 #ifdef __KERNEL__
 
 #include <acpi/pdc_intel.h>
+#include <asm/numa.h>
 
 #define COMPILER_DEPENDENT_INT64   long long
 #define COMPILER_DEPENDENT_UINT64  unsigned long long
@@ -141,6 +142,16 @@ extern int acpi_pci_disabled;
 extern int acpi_skip_timer_override;
 extern int acpi_use_timer_override;
 
+#ifdef CONFIG_ACPI_NUMA
+extern void __init acpi_fake_nodes(const struct bootnode *fake_nodes,
+                                  int num_nodes);
+#else
+static inline void acpi_fake_nodes(const struct bootnode *fake_nodes,
+                                  int num_nodes)
+{
+}
+#endif
+
 #endif /*__KERNEL__*/
 
 #endif /*_ASM_ACPI_H*/
index eea7aecfac787cef93d9ae09b66745cb313dda06..ab161e810151aa2fbe9bed5f08fef5194b0f28c2 100644 (file)
@@ -154,4 +154,6 @@ apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end)
 #define __parainstructions_end NULL
 #endif
 
+extern void text_poke(void *addr, unsigned char *opcode, int len);
+
 #endif /* _X86_64_ALTERNATIVE_H */
index 45e9fca1febc5410eea5d0aa1c9d261d62e6bc4c..85125ef3c4143a362b9758114544c17f6ee38686 100644 (file)
@@ -83,8 +83,10 @@ extern void disable_APIC_timer(void);
 extern void enable_APIC_timer(void);
 extern void setup_apic_routing(void);
 
-extern void setup_APIC_extened_lvt(unsigned char lvt_off, unsigned char vector,
-                                  unsigned char msg_type, unsigned char mask);
+extern void setup_APIC_extended_lvt(unsigned char lvt_off, unsigned char vector,
+                                   unsigned char msg_type, unsigned char mask);
+
+extern int apic_is_clustered_box(void);
 
 #define K8_APIC_EXT_LVT_BASE    0x500
 #define K8_APIC_EXT_INT_MSG_FIX 0x0
index 2403c4cfced2310704e79c2d4b5372a4f71ca20a..1d5ab0d03950ddd285213f0ca2566d225ae19f03 100644 (file)
@@ -1,4 +1,6 @@
 #ifndef __ASM_X86_64_AUXVEC_H
 #define __ASM_X86_64_AUXVEC_H
 
+#define AT_SYSINFO_EHDR                33
+
 #endif
index 4d5747a0923c7d973e0c476ad1729eae82bc72ff..67f60406e2d8136ac50b3b25afefef629508ec0d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Derived from include/asm-powerpc/iommu.h
  *
- * Copyright (C) IBM Corporation, 2006
+ * Copyright IBM Corporation, 2006-2007
  *
  * Author: Jon Mason <jdmason@us.ibm.com>
  * Author: Muli Ben-Yehuda <muli@il.ibm.com>
@@ -31,6 +31,7 @@
 #include <asm/types.h>
 
 struct iommu_table {
+       struct cal_chipset_ops *chip_ops; /* chipset specific funcs */
        unsigned long  it_base;      /* mapped address of tce table */
        unsigned long  it_hint;      /* Hint for next alloc */
        unsigned long *it_map;       /* A simple allocation bitmap for now */
@@ -42,6 +43,12 @@ struct iommu_table {
        unsigned char  it_busno;     /* Bus number this table belongs to */
 };
 
+struct cal_chipset_ops {
+       void (*handle_quirks)(struct iommu_table *tbl, struct pci_dev *dev);
+       void (*tce_cache_blast)(struct iommu_table *tbl);
+       void (*dump_error_regs)(struct iommu_table *tbl);
+};
+
 #define TCE_TABLE_SIZE_UNSPECIFIED     ~0
 #define TCE_TABLE_SIZE_64K             0
 #define TCE_TABLE_SIZE_128K            1
index 09a6b6b6b74dac10a753cf605acd87949d8c3eb9..5e182062e6ec98ca49e75729cb93a29e3c1622b4 100644 (file)
@@ -128,7 +128,7 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr,
        ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
                                        (unsigned long)(n),sizeof(*(ptr))))
 #define cmpxchg_local(ptr,o,n)\
-       ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
+       ((__typeof__(*(ptr)))__cmpxchg_local((ptr),(unsigned long)(o),\
                                        (unsigned long)(n),sizeof(*(ptr))))
 
 #endif
index 93b2b15d43256008b9b642989523f837d00c7cb2..d02e32e3c3f0678d2bbf816d7fd8bc3293f38be3 100644 (file)
@@ -3,15 +3,12 @@
 
 #include <asm/io.h>
 
-extern void *dmi_ioremap(unsigned long addr, unsigned long size);
-extern void dmi_iounmap(void *addr, unsigned long size);
-
 #define DMI_MAX_DATA 2048
 
 extern int dmi_alloc_index;
 extern char dmi_alloc_data[DMI_MAX_DATA];
 
-/* This is so early that there is no good way to allocate dynamic memory. 
+/* This is so early that there is no good way to allocate dynamic memory.
    Allocate data in an BSS array. */
 static inline void *dmi_alloc(unsigned len)
 {
index 6d24ea7c4d9d2ef90747d0f48405fec4b68f29b0..b4fbe47f6ccde390da948e4bed3171dbfe12b47a 100644 (file)
@@ -162,6 +162,19 @@ extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
 /* 1GB for 64bit, 8MB for 32bit */
 #define STACK_RND_MASK (test_thread_flag(TIF_IA32) ? 0x7ff : 0x3fffff)
 
+
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+struct linux_binprm;
+extern int arch_setup_additional_pages(struct linux_binprm *bprm,
+                                       int executable_stack);
+
+extern int vdso_enabled;
+
+#define ARCH_DLINFO                                            \
+do if (vdso_enabled) {                                         \
+       NEW_AUX_ENT(AT_SYSINFO_EHDR,(unsigned long)current->mm->context.vdso);\
+} while (0)
+
 #endif
 
 #endif
index 2acb9b7f6418ba25b03c9c576b46843a9b8a9bf7..cdfbe4a6ae6f1573f460e255d6309861f4aba6f3 100644 (file)
@@ -22,9 +22,9 @@
  * compile time, but to set the physical address only
  * in the boot process.
  *
- * these 'compile-time allocated' memory buffers are
- * fixed-size 4k pages. (or larger if used with an increment
- * highger than 1) use fixmap_set(idx,phys) to associate
+ * These 'compile-time allocated' memory buffers are
+ * fixed-size 4k pages (or larger if used with an increment
+ * higher than 1). Use set_fixmap(idx,phys) to associate
  * physical memory with fixmap indices.
  *
  * TLB entries of such buffers will not be flushed across
index 59a66f084611c676be7306d1b458b6e678b492da..79bb950f82c5d12205391aeef810ebf1ef583b01 100644 (file)
@@ -1,78 +1,18 @@
 #ifndef _ASM_X8664_HPET_H
 #define _ASM_X8664_HPET_H 1
 
-/*
- * Documentation on HPET can be found at:
- *      http://www.intel.com/ial/home/sp/pcmmspec.htm
- *      ftp://download.intel.com/ial/home/sp/mmts098.pdf
- */
-
-#define HPET_MMAP_SIZE 1024
-
-#define HPET_ID                0x000
-#define HPET_PERIOD    0x004
-#define HPET_CFG       0x010
-#define HPET_STATUS    0x020
-#define HPET_COUNTER   0x0f0
-#define HPET_Tn_OFFSET 0x20
-#define HPET_Tn_CFG(n)  (0x100 + (n) * HPET_Tn_OFFSET)
-#define HPET_Tn_ROUTE(n) (0x104 + (n) * HPET_Tn_OFFSET)
-#define HPET_Tn_CMP(n)  (0x108 + (n) * HPET_Tn_OFFSET)
-#define HPET_T0_CFG    HPET_Tn_CFG(0)
-#define HPET_T0_CMP    HPET_Tn_CMP(0)
-#define HPET_T1_CFG    HPET_Tn_CFG(1)
-#define HPET_T1_CMP    HPET_Tn_CMP(1)
-
-#define HPET_ID_VENDOR 0xffff0000
-#define HPET_ID_LEGSUP 0x00008000
-#define HPET_ID_64BIT  0x00002000
-#define HPET_ID_NUMBER 0x00001f00
-#define HPET_ID_REV    0x000000ff
-#define        HPET_ID_NUMBER_SHIFT    8
-
-#define HPET_ID_VENDOR_SHIFT   16
-#define HPET_ID_VENDOR_8086    0x8086
-
-#define HPET_CFG_ENABLE        0x001
-#define HPET_CFG_LEGACY        0x002
-#define        HPET_LEGACY_8254        2
-#define        HPET_LEGACY_RTC         8
-
-#define HPET_TN_LEVEL          0x0002
-#define HPET_TN_ENABLE         0x0004
-#define HPET_TN_PERIODIC       0x0008
-#define HPET_TN_PERIODIC_CAP   0x0010
-#define HPET_TN_64BIT_CAP      0x0020
-#define HPET_TN_SETVAL         0x0040
-#define HPET_TN_32BIT          0x0100
-#define HPET_TN_ROUTE          0x3e00
-#define HPET_TN_FSB            0x4000
-#define HPET_TN_FSB_CAP                0x8000
-
-#define HPET_TN_ROUTE_SHIFT    9
+#include <asm-i386/hpet.h>
 
 #define HPET_TICK_RATE (HZ * 100000UL)
 
-extern int is_hpet_enabled(void);
 extern int hpet_rtc_timer_init(void);
-extern int apic_is_clustered_box(void);
 extern int hpet_arch_init(void);
 extern int hpet_timer_stop_set_go(unsigned long tick);
 extern int hpet_reenable(void);
 extern unsigned int hpet_calibrate_tsc(void);
 
 extern int hpet_use_timer;
-extern unsigned long hpet_address;
 extern unsigned long hpet_period;
 extern unsigned long hpet_tick;
 
-#ifdef CONFIG_HPET_EMULATE_RTC
-extern int hpet_mask_rtc_irq_bit(unsigned long bit_mask);
-extern int hpet_set_rtc_irq_bit(unsigned long bit_mask);
-extern int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec);
-extern int hpet_set_periodic_freq(unsigned long freq);
-extern int hpet_rtc_dropped_irq(void);
-extern int hpet_rtc_timer_init(void);
-#endif /* CONFIG_HPET_EMULATE_RTC */
-
 #endif
index 6153ae5df2e8ffdd87d8e4bf3261d3648f50f4f9..09dfc18a6dd05cb95e80e2459abbf967271fa736 100644 (file)
 
 
 #ifndef __ASSEMBLY__
+
+/* Interrupt handlers registered during init_IRQ */
+void apic_timer_interrupt(void);
+void spurious_interrupt(void);
+void error_interrupt(void);
+void reschedule_interrupt(void);
+void call_function_interrupt(void);
+void irq_move_cleanup_interrupt(void);
+void invalidate_interrupt0(void);
+void invalidate_interrupt1(void);
+void invalidate_interrupt2(void);
+void invalidate_interrupt3(void);
+void invalidate_interrupt4(void);
+void invalidate_interrupt5(void);
+void invalidate_interrupt6(void);
+void invalidate_interrupt7(void);
+void thermal_interrupt(void);
+void threshold_interrupt(void);
+void i8254_timer_resume(void);
+
 typedef int vector_irq_t[NR_VECTORS];
 DECLARE_PER_CPU(vector_irq_t, vector_irq);
 extern void __setup_vector_irq(int cpu);
index c16c6ff4bdd739f79a96d4c1e1ee46fcc7441509..5cbf9fa5e0b5e26c675f5bce99003dc470f1a704 100644 (file)
@@ -1,42 +1 @@
-#ifndef ASM_HYPERTRANSPORT_H
-#define ASM_HYPERTRANSPORT_H
-
-/*
- * Constants for x86 Hypertransport Interrupts.
- */
-
-#define HT_IRQ_LOW_BASE                        0xf8000000
-
-#define HT_IRQ_LOW_VECTOR_SHIFT                16
-#define  HT_IRQ_LOW_VECTOR_MASK                0x00ff0000
-#define  HT_IRQ_LOW_VECTOR(v)          (((v) << HT_IRQ_LOW_VECTOR_SHIFT) & HT_IRQ_LOW_VECTOR_MASK)
-
-#define HT_IRQ_LOW_DEST_ID_SHIFT       8
-#define  HT_IRQ_LOW_DEST_ID_MASK       0x0000ff00
-#define  HT_IRQ_LOW_DEST_ID(v)         (((v) << HT_IRQ_LOW_DEST_ID_SHIFT) & HT_IRQ_LOW_DEST_ID_MASK)
-
-#define HT_IRQ_LOW_DM_PHYSICAL         0x0000000
-#define HT_IRQ_LOW_DM_LOGICAL          0x0000040
-
-#define HT_IRQ_LOW_RQEOI_EDGE          0x0000000
-#define HT_IRQ_LOW_RQEOI_LEVEL         0x0000020
-
-
-#define HT_IRQ_LOW_MT_FIXED            0x0000000
-#define HT_IRQ_LOW_MT_ARBITRATED       0x0000004
-#define HT_IRQ_LOW_MT_SMI              0x0000008
-#define HT_IRQ_LOW_MT_NMI              0x000000c
-#define HT_IRQ_LOW_MT_INIT             0x0000010
-#define HT_IRQ_LOW_MT_STARTUP          0x0000014
-#define HT_IRQ_LOW_MT_EXTINT           0x0000018
-#define HT_IRQ_LOW_MT_LINT1            0x000008c
-#define HT_IRQ_LOW_MT_LINT0            0x0000098
-
-#define HT_IRQ_LOW_IRQ_MASKED          0x0000001
-
-
-#define HT_IRQ_HIGH_DEST_ID_SHIFT      0
-#define  HT_IRQ_HIGH_DEST_ID_MASK      0x00ffffff
-#define  HT_IRQ_HIGH_DEST_ID(v)                ((((v) >> 8) << HT_IRQ_HIGH_DEST_ID_SHIFT) & HT_IRQ_HIGH_DEST_ID_MASK)
-
-#endif /* ASM_HYPERTRANSPORT_H */
+#include <asm-i386/hypertransport.h>
diff --git a/include/asm-x86_64/i8253.h b/include/asm-x86_64/i8253.h
new file mode 100644 (file)
index 0000000..015d8df
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __ASM_I8253_H__
+#define __ASM_I8253_H__
+
+extern spinlock_t i8253_lock;
+
+#endif /* __ASM_I8253_H__ */
diff --git a/include/asm-x86_64/iommu.h b/include/asm-x86_64/iommu.h
new file mode 100644 (file)
index 0000000..5af471f
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _ASM_X8664_IOMMU_H
+#define _ASM_X8664_IOMMU_H 1
+
+extern void pci_iommu_shutdown(void);
+extern void no_iommu_init(void);
+extern int force_iommu, no_iommu;
+extern int iommu_detected;
+#ifdef CONFIG_IOMMU
+extern void gart_iommu_init(void);
+extern void gart_iommu_shutdown(void);
+extern void __init gart_parse_options(char *);
+extern void iommu_hole_init(void);
+extern int fallback_aper_order;
+extern int fallback_aper_force;
+extern int iommu_aperture;
+extern int iommu_aperture_allowed;
+extern int iommu_aperture_disabled;
+extern int fix_aperture;
+#else
+#define iommu_aperture 0
+#define iommu_aperture_allowed 0
+
+static inline void gart_iommu_shutdown(void)
+{
+}
+
+#endif
+
+#endif
index 177e92b4019beba32d3eef9b645cba0c66c8cd41..7bc030a1996de9c2ad53763eac202643e459a54b 100644 (file)
@@ -105,6 +105,11 @@ extern atomic_t mce_entry;
 
 extern void do_machine_check(struct pt_regs *, long);
 
+extern int mce_notify_user(void);
+
+extern void stop_mce(void);
+extern void restart_mce(void);
+
 #endif
 
 #endif
index 5dc6ed79859a5ca8397e9f6130c4f5d2b205eb87..d2cd4a9d984d1011c66d94c26a66b6063daaeab9 100644 (file)
@@ -15,6 +15,7 @@ typedef struct {
        rwlock_t ldtlock; 
        int size;
        struct semaphore sem; 
+       void *vdso;
 } mm_context_t;
 
 #endif
index 5b8acddb70fba262cac24bd6d27c88c9c8266717..083ad5827e482f170480f6821b2090eaba117289 100644 (file)
@@ -1,47 +1 @@
-#ifndef ASM_MSIDEF_H
-#define ASM_MSIDEF_H
-
-/*
- * Constants for Intel APIC based MSI messages.
- */
-
-/*
- * Shifts for MSI data
- */
-
-#define MSI_DATA_VECTOR_SHIFT          0
-#define  MSI_DATA_VECTOR_MASK          0x000000ff
-#define         MSI_DATA_VECTOR(v)             (((v) << MSI_DATA_VECTOR_SHIFT) & MSI_DATA_VECTOR_MASK)
-
-#define MSI_DATA_DELIVERY_MODE_SHIFT   8
-#define  MSI_DATA_DELIVERY_FIXED       (0 << MSI_DATA_DELIVERY_MODE_SHIFT)
-#define  MSI_DATA_DELIVERY_LOWPRI      (1 << MSI_DATA_DELIVERY_MODE_SHIFT)
-
-#define MSI_DATA_LEVEL_SHIFT           14
-#define         MSI_DATA_LEVEL_DEASSERT        (0 << MSI_DATA_LEVEL_SHIFT)
-#define         MSI_DATA_LEVEL_ASSERT          (1 << MSI_DATA_LEVEL_SHIFT)
-
-#define MSI_DATA_TRIGGER_SHIFT         15
-#define  MSI_DATA_TRIGGER_EDGE         (0 << MSI_DATA_TRIGGER_SHIFT)
-#define  MSI_DATA_TRIGGER_LEVEL                (1 << MSI_DATA_TRIGGER_SHIFT)
-
-/*
- * Shift/mask fields for msi address
- */
-
-#define MSI_ADDR_BASE_HI               0
-#define MSI_ADDR_BASE_LO               0xfee00000
-
-#define MSI_ADDR_DEST_MODE_SHIFT       2
-#define  MSI_ADDR_DEST_MODE_PHYSICAL   (0 << MSI_ADDR_DEST_MODE_SHIFT)
-#define         MSI_ADDR_DEST_MODE_LOGICAL     (1 << MSI_ADDR_DEST_MODE_SHIFT)
-
-#define MSI_ADDR_REDIRECTION_SHIFT     3
-#define  MSI_ADDR_REDIRECTION_CPU      (0 << MSI_ADDR_REDIRECTION_SHIFT) /* dedicated cpu */
-#define  MSI_ADDR_REDIRECTION_LOWPRI   (1 << MSI_ADDR_REDIRECTION_SHIFT) /* lowest priority */
-
-#define MSI_ADDR_DEST_ID_SHIFT         12
-#define         MSI_ADDR_DEST_ID_MASK          0x00ffff0
-#define  MSI_ADDR_DEST_ID(dest)                (((dest) << MSI_ADDR_DEST_ID_SHIFT) & MSI_ADDR_DEST_ID_MASK)
-
-#endif /* ASM_MSIDEF_H */
+#include <asm-i386/msidef.h>
index d0a7f53b1497cf65442c2162716608378589c467..5fb3c0de5cccba5a421a3820bb551619d489fad9 100644 (file)
@@ -88,5 +88,7 @@ unsigned lapic_adjust_nmi_hz(unsigned hz);
 int lapic_watchdog_ok(void);
 void disable_lapic_nmi_watchdog(void);
 void enable_lapic_nmi_watchdog(void);
+void stop_nmi(void);
+void restart_nmi(void);
 
 #endif /* ASM_NMI_H */
index bda94fd5176f43a70c431f0079aeb6715d30a78e..88926eb44f5cb764b3a5db8e2ff6046709469b9a 100644 (file)
@@ -5,6 +5,25 @@
 
 #ifdef __KERNEL__
 
+struct pci_sysdata {
+       int             node;           /* NUMA node */
+       void*           iommu;          /* IOMMU private data */
+};
+
+#ifdef CONFIG_CALGARY_IOMMU
+static inline void* pci_iommu(struct pci_bus *bus)
+{
+       struct pci_sysdata *sd = bus->sysdata;
+       return sd->iommu;
+}
+
+static inline void set_pci_iommu(struct pci_bus *bus, void *val)
+{
+       struct pci_sysdata *sd = bus->sysdata;
+       sd->iommu = val;
+}
+#endif /* CONFIG_CALGARY_IOMMU */
+
 #include <linux/mm.h> /* for struct page */
 
 /* Can be used to override the logic in pci_scan_bus for skipping
index 8bb5646878602f3731e345b46a80486f593e1640..b467be6d367f8b3725c1b7449e9d052ea1c3e768 100644 (file)
@@ -4,6 +4,10 @@
 #include <asm/pda.h>
 #include <linux/threads.h>
 #include <linux/mm.h>
+#include <linux/quicklist.h>
+
+#define QUICK_PGD 0    /* We preserve special mappings over free */
+#define QUICK_PT 1     /* Other page table pages that are zero on free */
 
 #define pmd_populate_kernel(mm, pmd, pte) \
                set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
@@ -20,23 +24,23 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *p
 static inline void pmd_free(pmd_t *pmd)
 {
        BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
-       free_page((unsigned long)pmd);
+       quicklist_free(QUICK_PT, NULL, pmd);
 }
 
 static inline pmd_t *pmd_alloc_one (struct mm_struct *mm, unsigned long addr)
 {
-       return (pmd_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
+       return (pmd_t *)quicklist_alloc(QUICK_PT, GFP_KERNEL|__GFP_REPEAT, NULL);
 }
 
 static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
-       return (pud_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
+       return (pud_t *)quicklist_alloc(QUICK_PT, GFP_KERNEL|__GFP_REPEAT, NULL);
 }
 
 static inline void pud_free (pud_t *pud)
 {
        BUG_ON((unsigned long)pud & (PAGE_SIZE-1));
-       free_page((unsigned long)pud);
+       quicklist_free(QUICK_PT, NULL, pud);
 }
 
 static inline void pgd_list_add(pgd_t *pgd)
@@ -57,41 +61,57 @@ static inline void pgd_list_del(pgd_t *pgd)
        spin_unlock(&pgd_lock);
 }
 
-static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+static inline void pgd_ctor(void *x)
 {
        unsigned boundary;
-       pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
-       if (!pgd)
-               return NULL;
-       pgd_list_add(pgd);
+       pgd_t *pgd = x;
+       struct page *page = virt_to_page(pgd);
+
        /*
         * Copy kernel pointers in from init.
-        * Could keep a freelist or slab cache of those because the kernel
-        * part never changes.
         */
        boundary = pgd_index(__PAGE_OFFSET);
-       memset(pgd, 0, boundary * sizeof(pgd_t));
        memcpy(pgd + boundary,
-              init_level4_pgt + boundary,
-              (PTRS_PER_PGD - boundary) * sizeof(pgd_t));
+               init_level4_pgt + boundary,
+               (PTRS_PER_PGD - boundary) * sizeof(pgd_t));
+
+       spin_lock(&pgd_lock);
+       list_add(&page->lru, &pgd_list);
+       spin_unlock(&pgd_lock);
+}
+
+static inline void pgd_dtor(void *x)
+{
+       pgd_t *pgd = x;
+       struct page *page = virt_to_page(pgd);
+
+        spin_lock(&pgd_lock);
+       list_del(&page->lru);
+       spin_unlock(&pgd_lock);
+}
+
+static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+       pgd_t *pgd = (pgd_t *)quicklist_alloc(QUICK_PGD,
+               GFP_KERNEL|__GFP_REPEAT, pgd_ctor);
        return pgd;
 }
 
 static inline void pgd_free(pgd_t *pgd)
 {
        BUG_ON((unsigned long)pgd & (PAGE_SIZE-1));
-       pgd_list_del(pgd);
-       free_page((unsigned long)pgd);
+       quicklist_free(QUICK_PGD, pgd_dtor, pgd);
 }
 
 static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 {
-       return (pte_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
+       return (pte_t *)quicklist_alloc(QUICK_PT, GFP_KERNEL|__GFP_REPEAT, NULL);
 }
 
 static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
 {
-       void *p = (void *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
+       void *p = (void *)quicklist_alloc(QUICK_PT, GFP_KERNEL|__GFP_REPEAT, NULL);
+
        if (!p)
                return NULL;
        return virt_to_page(p);
@@ -103,17 +123,22 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long add
 static inline void pte_free_kernel(pte_t *pte)
 {
        BUG_ON((unsigned long)pte & (PAGE_SIZE-1));
-       free_page((unsigned long)pte); 
+       quicklist_free(QUICK_PT, NULL, pte);
 }
 
 static inline void pte_free(struct page *pte)
 {
-       __free_page(pte);
-} 
+       quicklist_free_page(QUICK_PT, NULL, pte);
+}
 
-#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
+#define __pte_free_tlb(tlb,pte) quicklist_free_page(QUICK_PT, NULL,(pte))
 
-#define __pmd_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
-#define __pud_free_tlb(tlb,x)   tlb_remove_page((tlb),virt_to_page(x))
+#define __pmd_free_tlb(tlb,x)   quicklist_free(QUICK_PT, NULL, (x))
+#define __pud_free_tlb(tlb,x)   quicklist_free(QUICK_PT, NULL, (x))
 
+static inline void check_pgt_cache(void)
+{
+       quicklist_trim(QUICK_PGD, pgd_dtor, 25, 16);
+       quicklist_trim(QUICK_PT, NULL, 25, 16);
+}
 #endif /* _X86_64_PGALLOC_H */
index 3ba53099297d94c0945fe690198aaeb90b47307d..c9d8764c89d182920dc1b50b4938f63521292c70 100644 (file)
@@ -403,13 +403,14 @@ extern struct list_head pgd_list;
 
 extern int kern_addr_valid(unsigned long addr); 
 
+pte_t *lookup_address(unsigned long addr);
+
 #define io_remap_pfn_range(vma, vaddr, pfn, size, prot)                \
                remap_pfn_range(vma, vaddr, pfn, size, prot)
 
 #define HAVE_ARCH_UNMAPPED_AREA
 
 #define pgtable_cache_init()   do { } while (0)
-#define check_pgt_cache()      do { } while (0)
 
 #define PAGE_AGP    PAGE_KERNEL_NOCACHE
 #define HAVE_PAGE_AGP 1
index efc87a5aff7f0f5febf0ff04f87b8f72c4a72c6f..19525175b91c2a7793bf463c4e78eba925030d3c 100644 (file)
@@ -83,7 +83,6 @@ struct cpuinfo_x86 {
 #define X86_VENDOR_UMC 3
 #define X86_VENDOR_NEXGEN 4
 #define X86_VENDOR_CENTAUR 5
-#define X86_VENDOR_RISE 6
 #define X86_VENDOR_TRANSMETA 7
 #define X86_VENDOR_NUM 8
 #define X86_VENDOR_UNKNOWN 0xff
@@ -390,17 +389,6 @@ static inline void prefetchw(void *x)
 
 #define cpu_relax()   rep_nop()
 
-/*
- *      NSC/Cyrix CPU indexed register access macros
- */
-
-#define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); })
-
-#define setCx86(reg, data) do { \
-       outb((reg), 0x22); \
-       outb((data), 0x23); \
-} while (0)
-
 static inline void serialize_cpu(void)
 {
        __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
index 85255db1e82d63bff6dd84c9f409908651be6b9f..31f20ad65876b25f588e6c2e7e693fff23eb19b0 100644 (file)
@@ -75,8 +75,6 @@ extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long en
 extern void early_quirks(void);
 extern void check_efer(void);
 
-extern int unhandled_signal(struct task_struct *tsk, int sig);
-
 extern void select_idle_routine(const struct cpuinfo_x86 *c);
 
 extern unsigned long table_start, table_end;
@@ -85,24 +83,6 @@ extern int exception_trace;
 extern unsigned cpu_khz;
 extern unsigned tsc_khz;
 
-extern void no_iommu_init(void);
-extern int force_iommu, no_iommu;
-extern int iommu_detected;
-#ifdef CONFIG_IOMMU
-extern void gart_iommu_init(void);
-extern void __init gart_parse_options(char *);
-extern void iommu_hole_init(void);
-extern int fallback_aper_order;
-extern int fallback_aper_force;
-extern int iommu_aperture;
-extern int iommu_aperture_allowed;
-extern int iommu_aperture_disabled;
-extern int fix_aperture;
-#else
-#define iommu_aperture 0
-#define iommu_aperture_allowed 0
-#endif
-
 extern int reboot_force;
 extern int notsc_setup(char *);
 
index 5ea84dbb1e9ce5f07278cb678f00291fbc64e0a5..7f166ccb0606786991e931c9995c6dfe9514809b 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _X86_64_PTRACE_H
 #define _X86_64_PTRACE_H
 
+#include <linux/compiler.h>    /* For __user */
 #include <asm/ptrace-abi.h>
 
 #ifndef __ASSEMBLY__
diff --git a/include/asm-x86_64/resume-trace.h b/include/asm-x86_64/resume-trace.h
new file mode 100644 (file)
index 0000000..34bf998
--- /dev/null
@@ -0,0 +1,13 @@
+#define TRACE_RESUME(user) do {                                        \
+       if (pm_trace_enabled) {                                 \
+               void *tracedata;                                \
+               asm volatile("movq $1f,%0\n"                    \
+                       ".section .tracedata,\"a\"\n"           \
+                       "1:\t.word %c1\n"                       \
+                       "\t.quad %c2\n"                         \
+                       ".previous"                             \
+                       :"=r" (tracedata)                       \
+                       : "i" (__LINE__), "i" (__FILE__));      \
+               generate_resume_trace(tracedata, user);         \
+       }                                                       \
+} while (0)
index 9505d9f4bead96807357ffee406e2d42aaa41a88..e583da7918fb314b34fe8156dd1b7626fbeadf4d 100644 (file)
@@ -29,6 +29,9 @@ return (to);
    function. */
 
 #define __HAVE_ARCH_MEMCPY 1
+#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4
+extern void *memcpy(void *to, const void *from, size_t len);
+#else
 extern void *__memcpy(void *to, const void *from, size_t len); 
 #define memcpy(dst,src,len) \
        ({ size_t __len = (len);                                \
@@ -38,7 +41,7 @@ extern void *__memcpy(void *to, const void *from, size_t len);
           else                                                 \
                 __ret = __builtin_memcpy((dst),(src),__len);   \
           __ret; }) 
-
+#endif
 
 #define __HAVE_ARCH_MEMSET
 void *memset(void *s, int c, size_t n);
index e4f246d62c46bf57c6218df7738ca17dc6356671..02175aa1d16a8aea903a51e6b5e1c71fda57d075 100644 (file)
@@ -75,19 +75,31 @@ static inline unsigned long read_cr0(void)
        unsigned long cr0;
        asm volatile("movq %%cr0,%0" : "=r" (cr0));
        return cr0;
-} 
+}
 
 static inline void write_cr0(unsigned long val) 
 { 
        asm volatile("movq %0,%%cr0" :: "r" (val));
-} 
+}
+
+static inline unsigned long read_cr2(void)
+{
+       unsigned long cr2;
+       asm("movq %%cr2,%0" : "=r" (cr2));
+       return cr2;
+}
+
+static inline void write_cr2(unsigned long val)
+{
+       asm volatile("movq %0,%%cr2" :: "r" (val));
+}
 
 static inline unsigned long read_cr3(void)
 { 
        unsigned long cr3;
        asm("movq %%cr3,%0" : "=r" (cr3));
        return cr3;
-} 
+}
 
 static inline void write_cr3(unsigned long val)
 {
@@ -99,17 +111,29 @@ static inline unsigned long read_cr4(void)
        unsigned long cr4;
        asm("movq %%cr4,%0" : "=r" (cr4));
        return cr4;
-} 
+}
 
 static inline void write_cr4(unsigned long val)
 { 
        asm volatile("movq %0,%%cr4" :: "r" (val) : "memory");
-} 
+}
+
+static inline unsigned long read_cr8(void)
+{
+       unsigned long cr8;
+       asm("movq %%cr8,%0" : "=r" (cr8));
+       return cr8;
+}
+
+static inline void write_cr8(unsigned long val)
+{
+       asm volatile("movq %0,%%cr8" :: "r" (val) : "memory");
+}
 
 #define stts() write_cr0(8 | read_cr0())
 
 #define wbinvd() \
-       __asm__ __volatile__ ("wbinvd": : :"memory");
+       __asm__ __volatile__ ("wbinvd": : :"memory")
 
 #endif /* __KERNEL__ */
 
index 10bb5a8ed688889a68a99161021e9c0704d760d9..33c72ef15a0cddcf1df1a2ae3d7dd4c23df9130a 100644 (file)
@@ -115,6 +115,7 @@ static inline struct thread_info *stack_thread_info(void)
 #define TIF_SYSCALL_AUDIT      7       /* syscall auditing active */
 #define TIF_SECCOMP            8       /* secure computing */
 #define TIF_RESTORE_SIGMASK    9       /* restore signal mask in do_signal */
+#define TIF_MCE_NOTIFY         10      /* notify userspace of an MCE */
 /* 16 free */
 #define TIF_IA32               17      /* 32bit process */ 
 #define TIF_FORK               18      /* ret_from_fork */
@@ -133,6 +134,7 @@ static inline struct thread_info *stack_thread_info(void)
 #define _TIF_SYSCALL_AUDIT     (1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP           (1<<TIF_SECCOMP)
 #define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
+#define _TIF_MCE_NOTIFY                (1<<TIF_MCE_NOTIFY)
 #define _TIF_IA32              (1<<TIF_IA32)
 #define _TIF_FORK              (1<<TIF_FORK)
 #define _TIF_ABI_PENDING       (1<<TIF_ABI_PENDING)
index f6527e1b6c1c68eff886a54bc9ff860b48e85b7e..6ed21f44d3084cc2ee2516b9f2b582ae9b543a5a 100644 (file)
@@ -9,7 +9,6 @@
 #include <asm/8253pit.h>
 #include <asm/msr.h>
 #include <asm/vsyscall.h>
-#include <asm/hpet.h>
 #include <asm/system.h>
 #include <asm/processor.h>
 #include <asm/tsc.h>
index 8516225a838983a65c2962082046dc6e5bb4ced4..888eb4abdd07a2fffa1c3ca3486962a3b56d7be5 100644 (file)
@@ -92,7 +92,11 @@ static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long st
 
 #endif
 
-#define flush_tlb_kernel_range(start, end) flush_tlb_all()
+static inline void flush_tlb_kernel_range(unsigned long start,
+                                       unsigned long end)
+{
+       flush_tlb_all();
+}
 
 static inline void flush_tlb_pgtables(struct mm_struct *mm,
                                      unsigned long start, unsigned long end)
index 4fd6fb23953e997134c701252cbe4af8bf19c3e9..36e52fba796075bfd4c45b845af67fe49e08a7ef 100644 (file)
@@ -22,7 +22,7 @@ extern int __node_distance(int, int);
 #define parent_node(node)              (node)
 #define node_to_first_cpu(node)        (first_cpu(node_to_cpumask[node]))
 #define node_to_cpumask(node)          (node_to_cpumask[node])
-#define pcibus_to_node(bus)            ((long)(bus->sysdata))  
+#define pcibus_to_node(bus)    ((struct pci_sysdata *)((bus)->sysdata))->node
 #define pcibus_to_cpumask(bus)         node_to_cpumask(pcibus_to_node(bus));
 
 #define numa_node_id()                 read_pda(nodenumber)
diff --git a/include/asm-x86_64/vgtod.h b/include/asm-x86_64/vgtod.h
new file mode 100644 (file)
index 0000000..3301f09
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _ASM_VGTOD_H
+#define _ASM_VGTOD_H 1
+
+#include <asm/vsyscall.h>
+#include <linux/clocksource.h>
+
+struct vsyscall_gtod_data {
+       seqlock_t       lock;
+
+       /* open coded 'struct timespec' */
+       time_t          wall_time_sec;
+       u32             wall_time_nsec;
+
+       int             sysctl_enabled;
+       struct timezone sys_tz;
+       struct { /* extract of a clocksource struct */
+               cycle_t (*vread)(void);
+               cycle_t cycle_last;
+               cycle_t mask;
+               u32     mult;
+               u32     shift;
+       } clock;
+       struct timespec wall_to_monotonic;
+};
+extern struct vsyscall_gtod_data __vsyscall_gtod_data
+__section_vsyscall_gtod_data;
+extern struct vsyscall_gtod_data vsyscall_gtod_data;
+
+#endif
index 82b4afe65c914a224a79274edeadfec94addb58d..3b8ceb4af2cf6045290d79570187bd5f2206556b 100644 (file)
@@ -22,6 +22,8 @@ enum vsyscall_num {
 /* Definitions for CONFIG_GENERIC_TIME definitions */
 #define __section_vsyscall_gtod_data __attribute__ \
        ((unused, __section__ (".vsyscall_gtod_data"),aligned(16)))
+#define __section_vsyscall_clock __attribute__ \
+       ((unused, __section__ (".vsyscall_clock"),aligned(16)))
 #define __vsyscall_fn __attribute__ ((unused,__section__(".vsyscall_fn")))
 
 #define VGETCPU_RDTSCP 1
@@ -36,7 +38,6 @@ extern volatile unsigned long __jiffies;
 /* kernel space (writeable) */
 extern int vgetcpu_mode;
 extern struct timezone sys_tz;
-extern struct vsyscall_gtod_data_t vsyscall_gtod_data;
 
 #endif /* __KERNEL__ */
 
index dc234c508a6f8eb9445cba7a378ec8ae3280b02a..d5680cd7746a9b72b4ff0fbc4c07312dc1f97389 100644 (file)
@@ -88,10 +88,8 @@ int acpi_table_parse (char *id, acpi_table_handler handler);
 int __init acpi_table_parse_entries(char *id, unsigned long table_size,
        int entry_id, acpi_table_entry_handler handler, unsigned int max_entries);
 int acpi_table_parse_madt (enum acpi_madt_type id, acpi_table_entry_handler handler, unsigned int max_entries);
-int acpi_table_parse_srat (enum acpi_srat_type id, acpi_table_entry_handler handler, unsigned int max_entries);
 int acpi_parse_mcfg (struct acpi_table_header *header);
 void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
-void acpi_table_print_srat_entry (struct acpi_subtable_header *srat);
 
 /* the following four functions are architecture-dependent */
 #ifdef CONFIG_HAVE_ARCH_PARSE_SRAT
@@ -233,6 +231,9 @@ extern int acpi_paddr_to_node(u64 start_addr, u64 size);
 
 extern int pnpacpi_disabled;
 
+#define PXM_INVAL      (-1)
+#define NID_INVAL      (-1)
+
 #else  /* CONFIG_ACPI */
 
 static inline int acpi_boot_init(void)
index 8ca7ca0b47f0ebecd6be51ad1c2ed4529cd12bc7..4bbd8601b8f04980f2f3adf7bd8aaadf053e02cb 100644 (file)
  * are currently used in an audit field constant understood by the kernel.
  * If you are adding a new #define AUDIT_<whatever>, please ensure that
  * AUDIT_UNUSED_BITS is updated if need be. */
-#define AUDIT_UNUSED_BITS      0x0FFFFC00
+#define AUDIT_UNUSED_BITS      0x07FFFC00
 
 
 /* Rule fields */
 #define AUDIT_NEGATE                   0x80000000
 
 /* These are the supported operators.
- *     4  2  1
- *     =  >  <
- *     -------
- *     0  0  0         0       nonsense
- *     0  0  1         1       <
- *     0  1  0         2       >
- *     0  1  1         3       !=
- *     1  0  0         4       =
- *     1  0  1         5       <=
- *     1  1  0         6       >=
- *     1  1  1         7       all operators
+ *     4  2  1  8
+ *     =  >  <  ?
+ *     ----------
+ *     0  0  0  0      00      nonsense
+ *     0  0  0  1      08      &  bit mask
+ *     0  0  1  0      10      <
+ *     0  1  0  0      20      >
+ *     0  1  1  0      30      !=
+ *     1  0  0  0      40      =
+ *     1  0  0  1      48      &=  bit test
+ *     1  0  1  0      50      <=
+ *     1  1  0  0      60      >=
+ *     1  1  1  1      78      all operators
  */
+#define AUDIT_BIT_MASK                 0x08000000
 #define AUDIT_LESS_THAN                        0x10000000
 #define AUDIT_GREATER_THAN             0x20000000
 #define AUDIT_NOT_EQUAL                        0x30000000
 #define AUDIT_EQUAL                    0x40000000
+#define AUDIT_BIT_TEST                 (AUDIT_BIT_MASK|AUDIT_EQUAL)
 #define AUDIT_LESS_THAN_OR_EQUAL       (AUDIT_LESS_THAN|AUDIT_EQUAL)
 #define AUDIT_GREATER_THAN_OR_EQUAL    (AUDIT_GREATER_THAN|AUDIT_EQUAL)
-#define AUDIT_OPERATORS                        (AUDIT_EQUAL|AUDIT_NOT_EQUAL)
+#define AUDIT_OPERATORS                        (AUDIT_EQUAL|AUDIT_NOT_EQUAL|AUDIT_BIT_MASK)
 
 /* Status symbols */
                                /* Mask values */
@@ -407,7 +411,6 @@ extern int audit_bprm(struct linux_binprm *bprm);
 extern int audit_socketcall(int nargs, unsigned long *args);
 extern int audit_sockaddr(int len, void *addr);
 extern int __audit_fd_pair(int fd1, int fd2);
-extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
 extern int audit_set_macxattr(const char *name);
 extern int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr);
 extern int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout);
@@ -487,7 +490,6 @@ extern int audit_signals;
 #define audit_socketcall(n,a) ({ 0; })
 #define audit_fd_pair(n,a) ({ 0; })
 #define audit_sockaddr(len, addr) ({ 0; })
-#define audit_avc_path(dentry, mnt) ({ 0; })
 #define audit_set_macxattr(n) do { ; } while (0)
 #define audit_mq_open(o,m,a) ({ 0; })
 #define audit_mq_timedsend(d,l,p,t) ({ 0; })
index 1023ba0d6e5541aadfbca392ef42cc68a94a9acd..c897c7b038582157a3374373a4160b8c81e54dc2 100644 (file)
@@ -69,8 +69,8 @@ struct backlight_device {
 
        /* The framebuffer notifier block */
        struct notifier_block fb_notif;
-       /* The class device structure */
-       struct class_device class_dev;
+
+       struct device dev;
 };
 
 static inline void backlight_update_status(struct backlight_device *bd)
@@ -85,6 +85,11 @@ extern struct backlight_device *backlight_device_register(const char *name,
        struct device *dev, void *devdata, struct backlight_ops *ops);
 extern void backlight_device_unregister(struct backlight_device *bd);
 
-#define to_backlight_device(obj) container_of(obj, struct backlight_device, class_dev)
+#define to_backlight_device(obj) container_of(obj, struct backlight_device, dev)
+
+static inline void * bl_get_data(struct backlight_device *bl_dev)
+{
+       return dev_get_drvdata(&bl_dev->dev);
+}
 
 #endif
index f78965fc6426f61e93c91ed729ea246c011f235c..695e34964cb7d265b029c338b1c382ea4f3bf7c2 100644 (file)
@@ -698,11 +698,6 @@ extern int blk_execute_rq(request_queue_t *, struct gendisk *,
                          struct request *, int);
 extern void blk_execute_rq_nowait(request_queue_t *, struct gendisk *,
                                  struct request *, int, rq_end_io_fn *);
-extern int blk_fill_sghdr_rq(request_queue_t *, struct request *,
-                     struct sg_io_hdr *, int);
-extern int blk_unmap_sghdr_rq(struct request *, struct sg_io_hdr *);
-extern int blk_complete_sghdr_rq(struct request *, struct sg_io_hdr *,
-                         struct bio *);
 extern int blk_verify_command(unsigned char *, int);
 
 static inline request_queue_t *bdev_get_queue(struct block_device *bdev)
index 8547b10c388b5fedae1da1982a7f17e947f90708..f415f89e0ac84ae77ba4309bb9eb023007c8f399 100644 (file)
@@ -57,10 +57,10 @@ struct bsg_class_device {
        struct request_queue *queue;
 };
 
-extern int bsg_register_queue(struct request_queue *, const char *);
+extern int bsg_register_queue(struct request_queue *, struct device *, const char *);
 extern void bsg_unregister_queue(struct request_queue *);
 #else
-#define bsg_register_queue(disk, name)         (0)
+#define bsg_register_queue(disk, dev, name)            (0)
 #define bsg_unregister_queue(disk)     do { } while (0)
 #endif
 
index 8486e78f7335ccc07db270c312f1af2192c65448..e0bd46eb24145f0f855d36f3fbd35e3e3359597f 100644 (file)
@@ -23,6 +23,7 @@ enum clock_event_mode {
        CLOCK_EVT_MODE_SHUTDOWN,
        CLOCK_EVT_MODE_PERIODIC,
        CLOCK_EVT_MODE_ONESHOT,
+       CLOCK_EVT_MODE_RESUME,
 };
 
 /* Clock event notification values */
@@ -119,10 +120,6 @@ extern void clockevents_register_device(struct clock_event_device *dev);
 
 extern void clockevents_exchange_device(struct clock_event_device *old,
                                        struct clock_event_device *new);
-extern
-struct clock_event_device *clockevents_request_device(unsigned int features,
-                                                     cpumask_t cpumask);
-extern void clockevents_release_device(struct clock_event_device *dev);
 extern void clockevents_set_mode(struct clock_event_device *dev,
                                 enum clock_event_mode mode);
 extern int clockevents_register_notifier(struct notifier_block *nb);
index c4079b403e9e3e0a2c1d9f7fa9e0a5962caa14f6..1c47a34aa79442f738bebf25f01756ddaceb586d 100644 (file)
@@ -36,7 +36,6 @@ extern const struct file_operations coda_ioctl_operations;
 
 /* operations shared over more than one file */
 int coda_open(struct inode *i, struct file *f);
-int coda_flush(struct file *f, fl_owner_t id);
 int coda_release(struct inode *i, struct file *f);
 int coda_permission(struct inode *inode, int mask, struct nameidata *nd);
 int coda_revalidate_inode(struct dentry *);
index aa8f454b3b77095df06f7ffb383cd6d3a63cfda8..07ae8f846055a5b9004d30fec723ffd18b4d3bc0 100644 (file)
@@ -33,9 +33,6 @@ int venus_setattr(struct super_block *, struct CodaFid *, struct coda_vattr *);
 int venus_lookup(struct super_block *sb, struct CodaFid *fid, 
                 const char *name, int length, int *type, 
                 struct CodaFid *resfid);
-int venus_store(struct super_block *sb, struct CodaFid *fid, int flags,
-               vuid_t uid);
-int venus_release(struct super_block *sb, struct CodaFid *fid, int flags);
 int venus_close(struct super_block *sb, struct CodaFid *fid, int flags,
                vuid_t uid);
 int venus_open(struct super_block *sb, struct CodaFid *fid, int flags,
index a03e9398a6c2ba0d986405f8bec84f7f0141b786..14f7494280f0bda301cc12ebe31b2992fd25e870 100644 (file)
  * code
  */
 #define uninitialized_var(x) x = x
+
+#if !(__GNUC__ == 4 && __GNUC_MINOR__ < 3)
+/* Mark functions as cold. gcc will assume any path leading to a call
+   to them will be unlikely.  This means a lot of manual unlikely()s
+   are unnecessary now for any paths leading to the usual suspects
+   like BUG(), printk(), panic() etc. [but let's keep them for now for
+   older compilers]
+
+   Early snapshots of gcc 4.3 don't support this and we can't detect this
+   in the preprocessor, but we can live with this because they're unreleased.
+   Maketime probing would be overkill here.
+
+   gcc also has a __attribute__((__hot__)) to move hot functions into
+   a special section, but I don't see any sense in this right now in
+   the kernel context */
+#define __cold                 __attribute__((__cold__))
+
+#endif
index 8287a72bb6a913d01f7ca1def252880317dda297..12a1291855e23cb43f77e61cdf6cdc7b59c28ca6 100644 (file)
@@ -174,4 +174,13 @@ extern void __chk_io_ptr(const void __iomem *);
 # define __attribute_const__   /* unimplemented */
 #endif
 
+/*
+ * Tell gcc if a function is cold. The compiler will assume any path
+ * directly leading to the call is unlikely.
+ */
+
+#ifndef __cold
+#define __cold
+#endif
+
 #endif /* __LINUX_COMPILER_H */
index 5b528531633969ded20d830fd60272065c0932ce..f0d0e3295a9b198e767da6225328776b0c670315 100644 (file)
 
 /* These are for everybody (although not all archs will actually
    discard it in modules) */
-#define __init         __attribute__ ((__section__ (".init.text")))
+#define __init         __attribute__ ((__section__ (".init.text"))) __cold
 #define __initdata     __attribute__ ((__section__ (".init.data")))
 #define __exitdata     __attribute__ ((__section__(".exit.data")))
-#define __exit_call    __attribute_used__ __attribute__ ((__section__ (".exitcall.exit")))
+#define __exit_call    __attribute_used__ __attribute__ ((__section__ (".exitcall.exit"))) __cold
 
 /* modpost check for section mismatches during the kernel build.
  * A section mismatch happens when there are references from a
@@ -59,9 +59,9 @@
 #define __initdata_refok          __attribute__ ((__section__ (".data.init.refok")))
 
 #ifdef MODULE
-#define __exit         __attribute__ ((__section__(".exit.text")))
+#define __exit         __attribute__ ((__section__(".exit.text"))) __cold
 #else
-#define __exit         __attribute_used__ __attribute__ ((__section__(".exit.text")))
+#define __exit         __attribute_used__ __attribute__ ((__section__(".exit.text"))) __cold
 #endif
 
 /* For assembly routines */
index 5323f627585474b6c0a0fa9d5d585dec5b65224e..0a3c2ebf200872f0d716ea2faf0c8ab5f69d9b34 100644 (file)
@@ -120,11 +120,11 @@ extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
 # define local_irq_enable_in_hardirq() local_irq_enable()
 #endif
 
-#ifdef CONFIG_GENERIC_HARDIRQS
 extern void disable_irq_nosync(unsigned int irq);
 extern void disable_irq(unsigned int irq);
 extern void enable_irq(unsigned int irq);
 
+#ifdef CONFIG_GENERIC_HARDIRQS
 /*
  * Special lockdep variants of irq disabling/enabling.
  * These should be used for locking constructs that
index 8e3735714c1c42e1c61145b59f95e40fee23821e..28f88ecba344e1eefe5fbca694b3d56fcca2948d 100644 (file)
@@ -77,6 +77,7 @@ typedef enum {
        IRDA_ACT200L_DONGLE      = 10,
        IRDA_MA600_DONGLE        = 11,
        IRDA_TOIM3232_DONGLE     = 12,
+       IRDA_EP7211_DONGLE       = 13,
 } IRDA_DONGLE;
 
 /* Protocol types to be used for SOCK_DGRAM */
index 1eb9cde550c41a7e97598be47a1b24d216190cfa..4300bb462d29b8bac102ff2f6c898d22ed8b0386 100644 (file)
@@ -106,7 +106,7 @@ extern int cond_resched(void);
 extern struct atomic_notifier_head panic_notifier_list;
 extern long (*panic_blink)(long time);
 NORET_TYPE void panic(const char * fmt, ...)
-       __attribute__ ((NORET_AND format (printf, 1, 2)));
+       __attribute__ ((NORET_AND format (printf, 1, 2))) __cold;
 extern void oops_enter(void);
 extern void oops_exit(void);
 extern int oops_may_print(void);
@@ -155,14 +155,14 @@ extern void dump_thread(struct pt_regs *regs, struct user *dump);
 asmlinkage int vprintk(const char *fmt, va_list args)
        __attribute__ ((format (printf, 1, 0)));
 asmlinkage int printk(const char * fmt, ...)
-       __attribute__ ((format (printf, 1, 2)));
+       __attribute__ ((format (printf, 1, 2))) __cold;
 #else
 static inline int vprintk(const char *s, va_list args)
        __attribute__ ((format (printf, 1, 0)));
 static inline int vprintk(const char *s, va_list args) { return 0; }
 static inline int printk(const char *s, ...)
        __attribute__ ((format (printf, 1, 2)));
-static inline int printk(const char *s, ...) { return 0; }
+static inline int __cold printk(const char *s, ...) { return 0; }
 #endif
 
 unsigned long int_sqrt(unsigned long);
@@ -212,7 +212,7 @@ extern enum system_states {
 #define TAINT_USER                     (1<<6)
 #define TAINT_DIE                      (1<<7)
 
-extern void dump_stack(void);
+extern void dump_stack(void) __cold;
 
 enum {
        DUMP_PREFIX_NONE,
index 598793c0745b3c97ec593f1329b351b5743c3b1d..1d379787f2e78e4a1b56cb35c448e8e84ff39f38 100644 (file)
@@ -62,8 +62,8 @@ struct lcd_device {
        struct mutex update_lock;
        /* The framebuffer notifier block */
        struct notifier_block fb_notif;
-       /* The class device structure */
-       struct class_device class_dev;
+
+       struct device dev;
 };
 
 static inline void lcd_set_power(struct lcd_device *ld, int power)
@@ -75,9 +75,15 @@ static inline void lcd_set_power(struct lcd_device *ld, int power)
 }
 
 extern struct lcd_device *lcd_device_register(const char *name,
-       void *devdata, struct lcd_ops *ops);
+       struct device *parent, void *devdata, struct lcd_ops *ops);
 extern void lcd_device_unregister(struct lcd_device *ld);
 
-#define to_lcd_device(obj) container_of(obj, struct lcd_device, class_dev)
+#define to_lcd_device(obj) container_of(obj, struct lcd_device, dev)
+
+static inline void * lcd_get_data(struct lcd_device *ld_dev)
+{
+       return dev_get_drvdata(&ld_dev->dev);
+}
+
 
 #endif
index 494bed7c2fc12f5133504daa7b4a2cc0e3b4b326..421175092ee2495eca787af009dc20f834b6a9f6 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/list.h>
 
 struct device;
-struct class_device;
 /*
  * LED Core
  */
@@ -37,7 +36,7 @@ struct led_classdev {
        void            (*brightness_set)(struct led_classdev *led_cdev,
                                          enum led_brightness brightness);
 
-       struct class_device     *class_dev;
+       struct device           *dev;
        struct list_head         node;                  /* LED Device list */
        char                    *default_trigger;       /* Trigger to use */
 
@@ -109,4 +108,18 @@ extern void ledtrig_ide_activity(void);
 #define ledtrig_ide_activity() do {} while(0)
 #endif
 
+/* For the leds-gpio driver */
+struct gpio_led {
+       const char *name;
+       char *default_trigger;
+       unsigned        gpio;
+       u8              active_low;
+};
+
+struct gpio_led_platform_data {
+       int             num_leds;
+       struct gpio_led *leds;
+};
+
+
 #endif         /* __LINUX_LEDS_H_INCLUDED */
index be5a43928c848fc885625c2e1313b080084cb4d4..9aa6c10f7bb162a699c2b7329099a30430be8e20 100644 (file)
@@ -412,6 +412,7 @@ struct ata_queued_cmd {
        ata_qc_cb_t             complete_fn;
 
        void                    *private_data;
+       void                    *lldd_task;
 };
 
 struct ata_port_stats {
index 9820ca1e45e251fde417743e4ee1ac98c65937d4..4a616d73cc259230ca43d542cd81ae60871599cd 100644 (file)
@@ -575,7 +575,7 @@ struct net_device
 
        /* The TX queue control structures */
        unsigned int                    egress_subqueue_count;
-       struct net_device_subqueue      egress_subqueue[0];
+       struct net_device_subqueue      egress_subqueue[1];
 };
 #define to_net_dev(d) container_of(d, struct net_device, dev)
 
index 5fd44e63fb2671d34df4f9e889569d8b1dde0ff5..448f70b30a0c81fd2148b0b04bbe150bec69e60c 100644 (file)
@@ -31,8 +31,8 @@ extern struct bus_type of_platform_bus_type;
  */
 struct of_platform_driver
 {
-       char                    *name;
-       struct of_device_id     *match_table;
+       const char              *name;
+       const struct of_device_id       *match_table;
        struct module           *owner;
 
        int     (*probe)(struct of_device* dev,
index b15c6498fe67b0ecf8e650724237444242acff93..cbabb9c675c9489eaf86cf5b705aa2db91639c69 100644 (file)
 
 #define PCI_VENDOR_ID_ARIMA            0x161f
 
+#define PCI_VENDOR_ID_BROCADE          0x1657
+
 #define PCI_VENDOR_ID_SIBYTE           0x166d
 #define PCI_DEVICE_ID_BCM1250_PCI      0x0001
 #define PCI_DEVICE_ID_BCM1250_HT       0x0002
 #define PCI_DEVICE_ID_ALTIMA_AC9100    0x03ea
 #define PCI_DEVICE_ID_ALTIMA_AC1003    0x03eb
 
+#define PCI_VENDOR_ID_LENOVO           0x17aa
+
 #define PCI_VENDOR_ID_ARECA            0x17d3
 #define PCI_DEVICE_ID_ARECA_1110       0x1110
 #define PCI_DEVICE_ID_ARECA_1120       0x1120
index 81e9299ca148dd34d576fe5ddad660b2510c3de6..f3f4f28c6960cfabce8efd60f974f8d6dfd7eb62 100644 (file)
@@ -2,6 +2,7 @@
 #define RESUME_TRACE_H
 
 #ifdef CONFIG_PM_TRACE
+#include <asm/resume-trace.h>
 
 extern int pm_trace_enabled;
 
@@ -9,20 +10,10 @@ struct device;
 extern void set_trace_device(struct device *);
 extern void generate_resume_trace(void *tracedata, unsigned int user);
 
-#define TRACE_DEVICE(dev) set_trace_device(dev)
-#define TRACE_RESUME(user) do {                                        \
-       if (pm_trace_enabled) {                                 \
-               void *tracedata;                                \
-               asm volatile("movl $1f,%0\n"                    \
-                       ".section .tracedata,\"a\"\n"           \
-                       "1:\t.word %c1\n"                       \
-                       "\t.long %c2\n"                         \
-                       ".previous"                             \
-                       :"=r" (tracedata)                       \
-                       : "i" (__LINE__), "i" (__FILE__));      \
-               generate_resume_trace(tracedata, user);         \
-       }                                                       \
-} while (0)
+#define TRACE_DEVICE(dev) do { \
+       if (pm_trace_enabled) \
+               set_trace_device(dev); \
+       } while(0)
 
 #else
 
index ea91abe740da0b76810b19a522b9d814f0e8aa6e..0ae338866240dee807f7f35a5f8280ebe1aa15b2 100644 (file)
@@ -237,12 +237,15 @@ extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct
 extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
 extern long do_sigpending(void __user *, unsigned long);
 extern int sigprocmask(int, sigset_t *, sigset_t *);
+extern int show_unhandled_signals;
 
 struct pt_regs;
 extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie);
 
 extern struct kmem_cache *sighand_cachep;
 
+int unhandled_signal(struct task_struct *tsk, int sig);
+
 /*
  * In POSIX a signal is sent either to a specific thread (Linux task)
  * or to the process as a whole (Linux thread group).  How the signal
index ec3b0ced0afec4f75108f7d284a29156625302dd..e6aea5146e5d9a15acb5dc9f6e0216cfe26cb8d8 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/types.h>
 
 #ifdef __KERNEL__
+# include <linux/cache.h>
 # include <linux/seqlock.h>
 #endif
 
@@ -94,6 +95,8 @@ extern struct timespec wall_to_monotonic;
 extern seqlock_t xtime_lock __attribute__((weak));
 
 extern unsigned long read_persistent_clock(void);
+extern int update_persistent_clock(struct timespec now);
+extern int no_sync_cmos_clock __read_mostly;
 void timekeeping_init(void);
 
 static inline unsigned long get_seconds(void)
index c2b10cae5da52d06bf9c62a36aae5d36e24df6d4..89338b468d0de9c90d857e7e6154ecebcd3bc598 100644 (file)
@@ -58,6 +58,13 @@ void vmalloc_sync_all(void);
 /*
  *     Lowlevel-APIs (not for driver use!)
  */
+
+static inline size_t get_vm_area_size(const struct vm_struct *area)
+{
+       /* return actual size without guard page */
+       return area->size - PAGE_SIZE;
+}
+
 extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags);
 extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
                                        unsigned long start, unsigned long end);
index 2e6bdc4e7a0ae1deb116b7d9e96e8e29bbf05b99..df36461fe88141829ab60dee48a2ad2f8d973a89 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/timer.h>
 #include <linux/pci.h>
 #include <scsi/sas.h>
+#include <linux/libata.h>
 #include <linux/list.h>
 #include <asm/semaphore.h>
 #include <scsi/scsi_device.h>
@@ -165,6 +166,13 @@ struct sata_device {
 
         u8     port_no;        /* port number, if this is a PM (Port) */
         struct list_head children; /* PM Ports if this is a PM */
+
+       struct ata_port *ap;
+       struct ata_host ata_host;
+       struct ata_taskfile tf;
+       u32 sstatus;
+       u32 serror;
+       u32 scontrol;
 };
 
 /* ---------- Domain device ---------- */
@@ -624,6 +632,7 @@ int sas_set_phy_speed(struct sas_phy *phy,
                      struct sas_phy_linkrates *rates);
 int sas_phy_enable(struct sas_phy *phy, int enabled);
 int sas_phy_reset(struct sas_phy *phy, int hard_reset);
+int sas_queue_up(struct sas_task *task);
 extern int sas_queuecommand(struct scsi_cmnd *,
                     void (*scsi_done)(struct scsi_cmnd *));
 extern int sas_target_alloc(struct scsi_target *);
@@ -661,4 +670,10 @@ int __sas_task_abort(struct sas_task *);
 int sas_eh_device_reset_handler(struct scsi_cmnd *cmd);
 int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd);
 
+extern void sas_target_destroy(struct scsi_target *);
+extern int sas_slave_alloc(struct scsi_device *);
+extern int sas_ioctl(struct scsi_device *sdev, int cmd, void __user *arg);
+
+extern int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
+                          struct request *req);
 #endif /* _SASLIB_H_ */
diff --git a/include/scsi/sas_ata.h b/include/scsi/sas_ata.h
new file mode 100644 (file)
index 0000000..dd5edc9
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Support for SATA devices on Serial Attached SCSI (SAS) controllers
+ *
+ * Copyright (C) 2006 IBM Corporation
+ *
+ * Written by: Darrick J. Wong <djwong@us.ibm.com>, IBM Corporation
+ *
+ * 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 _SAS_ATA_H_
+#define _SAS_ATA_H_
+
+#include <linux/libata.h>
+#include <scsi/libsas.h>
+
+#ifdef CONFIG_SCSI_SAS_ATA
+
+static inline int dev_is_sata(struct domain_device *dev)
+{
+       return (dev->rphy->identify.target_port_protocols & SAS_PROTOCOL_SATA);
+}
+
+int sas_ata_init_host_and_port(struct domain_device *found_dev,
+                              struct scsi_target *starget);
+
+void sas_ata_task_abort(struct sas_task *task);
+
+#else
+
+
+static inline int dev_is_sata(struct domain_device *dev)
+{
+       return 0;
+}
+int sas_ata_init_host_and_port(struct domain_device *found_dev,
+                              struct scsi_target *starget)
+{
+       return 0;
+}
+void sas_ata_task_abort(struct sas_task *task)
+{
+}
+#endif
+
+#endif /* _SAS_ATA_H_ */
index ba07cf7c04baa69ca12dd8858e450f18595115b7..3b8a6a85c2f818e64435968136472fa7d2317bc1 100644 (file)
@@ -341,7 +341,7 @@ struct scsi_host_template {
        /*
         * Name of proc directory
         */
-       char *proc_name;
+       const char *proc_name;
 
        /*
         * Used to store the procfs directory if a driver implements the
index 9aedc19820b0df1d007b0d8e7150de5e3c07e5fd..abdfd2e27dd7dee85993d9199acb099b13a229c2 100644 (file)
@@ -7,7 +7,7 @@
 
 struct scsi_transport_template;
 struct sas_rphy;
-
+struct request;
 
 enum sas_device_type {
        SAS_PHY_UNUSED,
@@ -23,6 +23,12 @@ enum sas_protocol {
        SAS_PROTOCOL_SSP                = 0x08,
 };
 
+static inline int sas_protocol_ata(enum sas_protocol proto)
+{
+       return ((proto & SAS_PROTOCOL_SATA) ||
+               (proto & SAS_PROTOCOL_STP))? 1 : 0;
+}
+
 enum sas_linkrate {
        /* These Values are defined in the SAS standard */
        SAS_LINK_RATE_UNKNOWN = 0,
@@ -85,10 +91,12 @@ struct sas_phy {
 #define phy_to_shost(phy) \
        dev_to_shost((phy)->dev.parent)
 
+struct request_queue;
 struct sas_rphy {
        struct device           dev;
        struct sas_identify     identify;
        struct list_head        list;
+       struct request_queue    *q;
        u32                     scsi_target_id;
 };
 
@@ -166,6 +174,7 @@ struct sas_function_template {
        int (*phy_reset)(struct sas_phy *, int);
        int (*phy_enable)(struct sas_phy *, int);
        int (*set_phy_speed)(struct sas_phy *, struct sas_phy_linkrates *);
+       int (*smp_handler)(struct Scsi_Host *, struct sas_rphy *, struct request *);
 };
 
 
index 1bf093dcffe03e9f97dc4a8e91b4a99bd6f11b32..359645cff5b2cd662ea209458203eef6b1e96976 100644 (file)
@@ -304,7 +304,7 @@ int __init audit_register_class(int class, unsigned *list)
 
 int audit_match_class(int class, unsigned syscall)
 {
-       if (unlikely(syscall >= AUDIT_BITMASK_SIZE * sizeof(__u32)))
+       if (unlikely(syscall >= AUDIT_BITMASK_SIZE * 32))
                return 0;
        if (unlikely(class >= AUDIT_SYSCALL_CLASSES || !classes[class]))
                return 0;
@@ -456,6 +456,13 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
                case AUDIT_DEVMINOR:
                case AUDIT_EXIT:
                case AUDIT_SUCCESS:
+                       /* bit ops are only useful on syscall args */
+                       if (f->op == AUDIT_BIT_MASK ||
+                                               f->op == AUDIT_BIT_TEST) {
+                               err = -EINVAL;
+                               goto exit_free;
+                       }
+                       break;
                case AUDIT_ARG0:
                case AUDIT_ARG1:
                case AUDIT_ARG2:
@@ -1566,6 +1573,10 @@ int audit_comparator(const u32 left, const u32 op, const u32 right)
                return (left > right);
        case AUDIT_GREATER_THAN_OR_EQUAL:
                return (left >= right);
+       case AUDIT_BIT_MASK:
+               return (left & right);
+       case AUDIT_BIT_TEST:
+               return ((left & right) == right);
        }
        BUG();
        return 0;
index 145cbb79c4b93bbd1dff40bdd0d2a0a63aa06fd6..bde1124d590891d42f4fced9ecf0f15a80fe8297 100644 (file)
@@ -173,12 +173,6 @@ struct audit_aux_data_fd_pair {
        int     fd[2];
 };
 
-struct audit_aux_data_path {
-       struct audit_aux_data   d;
-       struct dentry           *dentry;
-       struct vfsmount         *mnt;
-};
-
 struct audit_aux_data_pids {
        struct audit_aux_data   d;
        pid_t                   target_pid[AUDIT_AUX_PIDS];
@@ -654,12 +648,6 @@ static inline void audit_free_aux(struct audit_context *context)
        struct audit_aux_data *aux;
 
        while ((aux = context->aux)) {
-               if (aux->type == AUDIT_AVC_PATH) {
-                       struct audit_aux_data_path *axi = (void *)aux;
-                       dput(axi->dentry);
-                       mntput(axi->mnt);
-               }
-
                context->aux = aux->next;
                kfree(aux);
        }
@@ -995,7 +983,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
                case AUDIT_IPC: {
                        struct audit_aux_data_ipcctl *axi = (void *)aux;
                        audit_log_format(ab, 
-                                "ouid=%u ogid=%u mode=%x",
+                                "ouid=%u ogid=%u mode=%#o",
                                 axi->uid, axi->gid, axi->mode);
                        if (axi->osid != 0) {
                                char *ctx = NULL;
@@ -1014,7 +1002,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
                case AUDIT_IPC_SET_PERM: {
                        struct audit_aux_data_ipcctl *axi = (void *)aux;
                        audit_log_format(ab,
-                               "qbytes=%lx ouid=%u ogid=%u mode=%x",
+                               "qbytes=%lx ouid=%u ogid=%u mode=%#o",
                                axi->qbytes, axi->uid, axi->gid, axi->mode);
                        break; }
 
@@ -1038,11 +1026,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
                        audit_log_hex(ab, axs->a, axs->len);
                        break; }
 
-               case AUDIT_AVC_PATH: {
-                       struct audit_aux_data_path *axi = (void *)aux;
-                       audit_log_d_path(ab, "path=", axi->dentry, axi->mnt);
-                       break; }
-
                case AUDIT_FD_PAIR: {
                        struct audit_aux_data_fd_pair *axs = (void *)aux;
                        audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]);
@@ -1990,36 +1973,6 @@ void __audit_ptrace(struct task_struct *t)
        selinux_get_task_sid(t, &context->target_sid);
 }
 
-/**
- * audit_avc_path - record the granting or denial of permissions
- * @dentry: dentry to record
- * @mnt: mnt to record
- *
- * Returns 0 for success or NULL context or < 0 on error.
- *
- * Called from security/selinux/avc.c::avc_audit()
- */
-int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt)
-{
-       struct audit_aux_data_path *ax;
-       struct audit_context *context = current->audit_context;
-
-       if (likely(!context))
-               return 0;
-
-       ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
-       if (!ax)
-               return -ENOMEM;
-
-       ax->dentry = dget(dentry);
-       ax->mnt = mntget(mnt);
-
-       ax->d.type = AUDIT_AVC_PATH;
-       ax->d.next = context->aux;
-       context->aux = (void *)ax;
-       return 0;
-}
-
 /**
  * audit_signal_info - record signal info for shutting down audit subsystem
  * @sig: signal value
index 72d034258ba109b25b7a6f4723d47fd8f5cc5808..eb1ddebd2c0413bbcc3c857aa568ac31150c35c0 100644 (file)
@@ -558,7 +558,8 @@ static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer,
  */
 static int hrtimer_switch_to_hres(void)
 {
-       struct hrtimer_cpu_base *base = &__get_cpu_var(hrtimer_bases);
+       int cpu = smp_processor_id();
+       struct hrtimer_cpu_base *base = &per_cpu(hrtimer_bases, cpu);
        unsigned long flags;
 
        if (base->hres_active)
@@ -568,6 +569,8 @@ static int hrtimer_switch_to_hres(void)
 
        if (tick_init_highres()) {
                local_irq_restore(flags);
+               printk(KERN_WARNING "Could not switch to high resolution "
+                                   "mode on CPU %d\n", cpu);
                return 0;
        }
        base->hres_active = 1;
@@ -683,6 +686,7 @@ static void enqueue_hrtimer(struct hrtimer *timer,
        struct rb_node **link = &base->active.rb_node;
        struct rb_node *parent = NULL;
        struct hrtimer *entry;
+       int leftmost = 1;
 
        /*
         * Find the right place in the rbtree:
@@ -694,18 +698,19 @@ static void enqueue_hrtimer(struct hrtimer *timer,
                 * We dont care about collisions. Nodes with
                 * the same expiry time stay together.
                 */
-               if (timer->expires.tv64 < entry->expires.tv64)
+               if (timer->expires.tv64 < entry->expires.tv64) {
                        link = &(*link)->rb_left;
-               else
+               } else {
                        link = &(*link)->rb_right;
+                       leftmost = 0;
+               }
        }
 
        /*
         * Insert the timer to the rbtree and check whether it
         * replaces the first pending timer
         */
-       if (!base->first || timer->expires.tv64 <
-           rb_entry(base->first, struct hrtimer, node)->expires.tv64) {
+       if (leftmost) {
                /*
                 * Reprogram the clock event device. When the timer is already
                 * expired hrtimer_enqueue_reprogram has either called the
index b4f1674fca7987d8f99fa707eb2655cd20f0bc37..50b81b98046a9af5a6016376c72549ef7faf49f1 100644 (file)
@@ -19,7 +19,15 @@ static struct proc_dir_entry *root_irq_dir;
 static int irq_affinity_read_proc(char *page, char **start, off_t off,
                                  int count, int *eof, void *data)
 {
-       int len = cpumask_scnprintf(page, count, irq_desc[(long)data].affinity);
+       struct irq_desc *desc = irq_desc + (long)data;
+       cpumask_t *mask = &desc->affinity;
+       int len;
+
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+       if (desc->status & IRQ_MOVE_PENDING)
+               mask = &desc->pending_mask;
+#endif
+       len = cpumask_scnprintf(page, count, *mask);
 
        if (count - len < 2)
                return -EINVAL;
index 7358609e47357551f75b72c2839c3f910c63b9da..c1a106d87d90385407d49ee2c7f3e86cc010935e 100644 (file)
@@ -57,7 +57,7 @@ config DISABLE_CONSOLE_SUSPEND
 
 config PM_TRACE
        bool "Suspend/resume event tracing"
-       depends on PM_DEBUG && X86_32 && EXPERIMENTAL
+       depends on PM_DEBUG && X86 && EXPERIMENTAL
        default n
        ---help---
        This enables some cheesy code to save the last PM event point in the
index 39d122753bac93eb7cfa62d0f2e2e451a4908dd5..ef8156a6aad519014c030f62e856302dacf045e7 100644 (file)
@@ -255,6 +255,16 @@ flush_signal_handlers(struct task_struct *t, int force_default)
        }
 }
 
+int unhandled_signal(struct task_struct *tsk, int sig)
+{
+       if (is_init(tsk))
+               return 1;
+       if (tsk->ptrace & PT_PTRACED)
+               return 0;
+       return (tsk->sighand->action[sig-1].sa.sa_handler == SIG_IGN) ||
+               (tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL);
+}
+
 
 /* Notify the system that a driver wants to block all signals for this
  * process, and wants to be notified if any signals at all were to be
index 222299844ad1b5a495b5796f1898f95174157632..ddebf3f2affe937d8a9ccb694de85dc9d567f1fb 100644 (file)
@@ -1203,6 +1203,16 @@ static ctl_table fs_table[] = {
 };
 
 static ctl_table debug_table[] = {
+#ifdef CONFIG_X86
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "exception-trace",
+               .data           = &show_unhandled_signals,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec
+       },
+#endif
        { .ctl_name = 0 }
 };
 
index b5e352597cbb628091718d2ac486b59564a95cfc..cd91237dbfe3c160867e60a12f4251b2bf4679fa 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/mm.h>
 #include <linux/time.h>
+#include <linux/timer.h>
 #include <linux/timex.h>
 #include <linux/jiffies.h>
 #include <linux/hrtimer.h>
@@ -175,12 +176,64 @@ u64 current_tick_length(void)
        return tick_length;
 }
 
+#ifdef CONFIG_GENERIC_CMOS_UPDATE
 
-void __attribute__ ((weak)) notify_arch_cmos_timer(void)
+/* Disable the cmos update - used by virtualization and embedded */
+int no_sync_cmos_clock  __read_mostly;
+
+static void sync_cmos_clock(unsigned long dummy);
+
+static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0);
+
+static void sync_cmos_clock(unsigned long dummy)
+{
+       struct timespec now, next;
+       int fail = 1;
+
+       /*
+        * If we have an externally synchronized Linux clock, then update
+        * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+        * called as close as possible to 500 ms before the new second starts.
+        * This code is run on a timer.  If the clock is set, that timer
+        * may not expire at the correct time.  Thus, we adjust...
+        */
+       if (!ntp_synced())
+               /*
+                * Not synced, exit, do not restart a timer (if one is
+                * running, let it run out).
+                */
+               return;
+
+       getnstimeofday(&now);
+       if (abs(xtime.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2)
+               fail = update_persistent_clock(now);
+
+       next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec;
+       if (next.tv_nsec <= 0)
+               next.tv_nsec += NSEC_PER_SEC;
+
+       if (!fail)
+               next.tv_sec = 659;
+       else
+               next.tv_sec = 0;
+
+       if (next.tv_nsec >= NSEC_PER_SEC) {
+               next.tv_sec++;
+               next.tv_nsec -= NSEC_PER_SEC;
+       }
+       mod_timer(&sync_cmos_timer, jiffies + timespec_to_jiffies(&next));
+}
+
+static void notify_cmos_timer(void)
 {
-       return;
+       if (no_sync_cmos_clock)
+               mod_timer(&sync_cmos_timer, jiffies + 1);
 }
 
+#else
+static inline void notify_cmos_timer(void) { }
+#endif
+
 /* adjtimex mainly allows reading (and writing, if superuser) of
  * kernel time-keeping variables. used by xntpd.
  */
@@ -345,6 +398,6 @@ leave:      if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0)
        txc->stbcnt        = 0;
        write_sequnlock_irq(&xtime_lock);
        do_gettimeofday(&txc->time);
-       notify_arch_cmos_timer();
+       notify_cmos_timer();
        return(result);
 }
index 8001d37071f59127dfac4ce83a651ad459395e66..db8e0f3d409b7da605c1ef83e69990e9d098aec4 100644 (file)
@@ -31,6 +31,12 @@ struct tick_device tick_broadcast_device;
 static cpumask_t tick_broadcast_mask;
 static DEFINE_SPINLOCK(tick_broadcast_lock);
 
+#ifdef CONFIG_TICK_ONESHOT
+static void tick_broadcast_clear_oneshot(int cpu);
+#else
+static inline void tick_broadcast_clear_oneshot(int cpu) { }
+#endif
+
 /*
  * Debugging: see timer_list.c
  */
@@ -49,7 +55,7 @@ cpumask_t *tick_get_broadcast_mask(void)
  */
 static void tick_broadcast_start_periodic(struct clock_event_device *bc)
 {
-       if (bc && bc->mode == CLOCK_EVT_MODE_SHUTDOWN)
+       if (bc)
                tick_setup_periodic(bc, 1);
 }
 
@@ -99,8 +105,19 @@ int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu)
                cpu_set(cpu, tick_broadcast_mask);
                tick_broadcast_start_periodic(tick_broadcast_device.evtdev);
                ret = 1;
-       }
+       } else {
+               /*
+                * When the new device is not affected by the stop
+                * feature and the cpu is marked in the broadcast mask
+                * then clear the broadcast bit.
+                */
+               if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) {
+                       int cpu = smp_processor_id();
 
+                       cpu_clear(cpu, tick_broadcast_mask);
+                       tick_broadcast_clear_oneshot(cpu);
+               }
+       }
        spin_unlock_irqrestore(&tick_broadcast_lock, flags);
        return ret;
 }
@@ -299,7 +316,7 @@ void tick_suspend_broadcast(void)
        spin_lock_irqsave(&tick_broadcast_lock, flags);
 
        bc = tick_broadcast_device.evtdev;
-       if (bc && tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
+       if (bc)
                clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
 
        spin_unlock_irqrestore(&tick_broadcast_lock, flags);
@@ -316,6 +333,8 @@ int tick_resume_broadcast(void)
        bc = tick_broadcast_device.evtdev;
 
        if (bc) {
+               clockevents_set_mode(bc, CLOCK_EVT_MODE_RESUME);
+
                switch (tick_broadcast_device.mode) {
                case TICKDEV_MODE_PERIODIC:
                        if(!cpus_empty(tick_broadcast_mask))
@@ -485,6 +504,16 @@ out:
        spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 }
 
+/*
+ * Reset the one shot broadcast for a cpu
+ *
+ * Called with tick_broadcast_lock held
+ */
+static void tick_broadcast_clear_oneshot(int cpu)
+{
+       cpu_clear(cpu, tick_broadcast_oneshot_mask);
+}
+
 /**
  * tick_broadcast_setup_highres - setup the broadcast device for highres
  */
index a96ec9ab3454e57acf53f4fa70b48ed84e634b8d..77a21abc87167482ff63efea9480c4ed11cbb21b 100644 (file)
@@ -318,12 +318,17 @@ static void tick_resume(void)
 {
        struct tick_device *td = &__get_cpu_var(tick_cpu_device);
        unsigned long flags;
+       int broadcast = tick_resume_broadcast();
 
        spin_lock_irqsave(&tick_device_lock, flags);
-       if (td->mode == TICKDEV_MODE_PERIODIC)
-               tick_setup_periodic(td->evtdev, 0);
-       else
-               tick_resume_oneshot();
+       clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_RESUME);
+
+       if (!broadcast) {
+               if (td->mode == TICKDEV_MODE_PERIODIC)
+                       tick_setup_periodic(td->evtdev, 0);
+               else
+                       tick_resume_oneshot();
+       }
        spin_unlock_irqrestore(&tick_device_lock, flags);
 }
 
@@ -360,8 +365,7 @@ static int tick_notify(struct notifier_block *nb, unsigned long reason,
                break;
 
        case CLOCK_EVT_NOTIFY_RESUME:
-               if (!tick_resume_broadcast())
-                       tick_resume();
+               tick_resume();
                break;
 
        default:
index f6997ab0c3c9c1101c9df8c9bd433e4126cc4a40..0258d3115d546a4c16c0f38e292120d077a8bd2c 100644 (file)
@@ -73,8 +73,21 @@ int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *))
        struct clock_event_device *dev = td->evtdev;
 
        if (!dev || !(dev->features & CLOCK_EVT_FEAT_ONESHOT) ||
-           !tick_device_is_functional(dev))
+                   !tick_device_is_functional(dev)) {
+
+               printk(KERN_INFO "Clockevents: "
+                      "could not switch to one-shot mode:");
+               if (!dev) {
+                       printk(" no tick device\n");
+               } else {
+                       if (!tick_device_is_functional(dev))
+                               printk(" %s is not functional.\n", dev->name);
+                       else
+                               printk(" %s does not support one-shot mode.\n",
+                                      dev->name);
+               }
                return -EINVAL;
+       }
 
        td->mode = TICKDEV_MODE_ONESHOT;
        dev->event_handler = handler;
index 52db9e3c526e5bba4dc733a6d5ddd77908458401..b416995b975727ca8b6dbf8b331de5351a1ef7f5 100644 (file)
@@ -546,6 +546,7 @@ void tick_setup_sched_timer(void)
 {
        struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
        ktime_t now = ktime_get();
+       u64 offset;
 
        /*
         * Emulate tick processing via per-CPU hrtimers:
@@ -554,8 +555,12 @@ void tick_setup_sched_timer(void)
        ts->sched_timer.function = tick_sched_timer;
        ts->sched_timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;
 
-       /* Get the next period */
+       /* Get the next period (per cpu) */
        ts->sched_timer.expires = tick_init_jiffy_update();
+       offset = ktime_to_ns(tick_period) >> 1;
+       do_div(offset, NR_CPUS);
+       offset *= smp_processor_id();
+       ts->sched_timer.expires = ktime_add_ns(ts->sched_timer.expires, offset);
 
        for (;;) {
                hrtimer_forward(&ts->sched_timer, now, tick_period);
index 10c13ad0d82d89dadebcee23951830d18599f0e0..a7381d55663a9f219f8313a4801614309ba9d207 100644 (file)
@@ -357,7 +357,8 @@ map_single(struct device *hwdev, char *buffer, size_t size, int dir)
         * This is needed when we sync the memory.  Then we sync the buffer if
         * needed.
         */
-       io_tlb_orig_addr[index] = buffer;
+       for (i = 0; i < nslots; i++)
+               io_tlb_orig_addr[index+i] = buffer + (i << IO_TLB_SHIFT);
        if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)
                memcpy(dma_addr, buffer, size);
 
@@ -418,6 +419,8 @@ sync_single(struct device *hwdev, char *dma_addr, size_t size,
        int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT;
        char *buffer = io_tlb_orig_addr[index];
 
+       buffer += ((unsigned long)dma_addr & ((1 << IO_TLB_SHIFT) - 1));
+
        switch (target) {
        case SYNC_FOR_CPU:
                if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL))
index 8aace3db3a54b9d9ca38291095fee3b0af9d2d15..ca8cac11bd2cf4930533f306a0209bbbea0e9c31 100644 (file)
@@ -2659,8 +2659,6 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
        return handle_pte_fault(mm, vma, address, pte, pmd, write_access);
 }
 
-EXPORT_SYMBOL_GPL(handle_mm_fault);
-
 #ifndef __PAGETABLE_PUD_FOLDED
 /*
  * Allocate page upper directory.
index 1b105d28949f5bf407d30b32007ecdbb95b9452e..9eef6a3985554fa9b69c54a0334865e54247e478 100644 (file)
@@ -54,12 +54,6 @@ DECLARE_RWSEM(nommu_vma_sem);
 struct vm_operations_struct generic_file_vm_ops = {
 };
 
-EXPORT_SYMBOL(vfree);
-EXPORT_SYMBOL(vmalloc_to_page);
-EXPORT_SYMBOL(vmalloc_32);
-EXPORT_SYMBOL(vmap);
-EXPORT_SYMBOL(vunmap);
-
 /*
  * Handle all mappings that got truncated by a "truncate()"
  * system call.
@@ -168,7 +162,6 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
 finish_or_fault:
        return i ? : -EFAULT;
 }
-
 EXPORT_SYMBOL(get_user_pages);
 
 DEFINE_RWLOCK(vmlist_lock);
@@ -178,6 +171,7 @@ void vfree(void *addr)
 {
        kfree(addr);
 }
+EXPORT_SYMBOL(vfree);
 
 void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
 {
@@ -186,17 +180,19 @@ void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
         */
        return kmalloc(size, (gfp_mask | __GFP_COMP) & ~__GFP_HIGHMEM);
 }
+EXPORT_SYMBOL(__vmalloc);
 
 struct page * vmalloc_to_page(void *addr)
 {
        return virt_to_page(addr);
 }
+EXPORT_SYMBOL(vmalloc_to_page);
 
 unsigned long vmalloc_to_pfn(void *addr)
 {
        return page_to_pfn(virt_to_page(addr));
 }
-
+EXPORT_SYMBOL(vmalloc_to_pfn);
 
 long vread(char *buf, char *addr, unsigned long count)
 {
@@ -237,9 +233,8 @@ void *vmalloc_node(unsigned long size, int node)
 }
 EXPORT_SYMBOL(vmalloc_node);
 
-/*
- *     vmalloc_32  -  allocate virtually continguos memory (32bit addressable)
- *
+/**
+ * vmalloc_32  -  allocate virtually contiguous memory (32bit addressable)
  *     @size:          allocation size
  *
  *     Allocate enough 32bit PA addressable pages to cover @size from the
@@ -249,17 +244,33 @@ void *vmalloc_32(unsigned long size)
 {
        return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL);
 }
+EXPORT_SYMBOL(vmalloc_32);
+
+/**
+ * vmalloc_32_user - allocate zeroed virtually contiguous 32bit memory
+ *     @size:          allocation size
+ *
+ * The resulting memory area is 32bit addressable and zeroed so it can be
+ * mapped to userspace without leaking data.
+ */
+void *vmalloc_32_user(unsigned long size)
+{
+       return __vmalloc(size, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL);
+}
+EXPORT_SYMBOL(vmalloc_32_user);
 
 void *vmap(struct page **pages, unsigned int count, unsigned long flags, pgprot_t prot)
 {
        BUG();
        return NULL;
 }
+EXPORT_SYMBOL(vmap);
 
 void vunmap(void *addr)
 {
        BUG();
 }
+EXPORT_SYMBOL(vunmap);
 
 /*
  * Implement a stub for vmalloc_sync_all() if the architecture chose not to
@@ -269,6 +280,13 @@ void  __attribute__((weak)) vmalloc_sync_all(void)
 {
 }
 
+int vm_insert_page(struct vm_area_struct *vma, unsigned long addr,
+                  struct page *page)
+{
+       return -EINVAL;
+}
+EXPORT_SYMBOL(vm_insert_page);
+
 /*
  *  sys_brk() for the most part doesn't need the global kernel
  *  lock, except when an application is doing something nasty
@@ -994,6 +1012,7 @@ unsigned long do_mmap_pgoff(struct file *file,
        show_free_areas();
        return -ENOMEM;
 }
+EXPORT_SYMBOL(do_mmap_pgoff);
 
 /*
  * handle mapping disposal for uClinux
@@ -1074,6 +1093,7 @@ int do_munmap(struct mm_struct *mm, unsigned long addr, size_t len)
 
        return 0;
 }
+EXPORT_SYMBOL(do_munmap);
 
 asmlinkage long sys_munmap(unsigned long addr, size_t len)
 {
@@ -1164,6 +1184,7 @@ unsigned long do_mremap(unsigned long addr,
 
        return vma->vm_start;
 }
+EXPORT_SYMBOL(do_mremap);
 
 asmlinkage unsigned long sys_mremap(unsigned long addr,
        unsigned long old_len, unsigned long new_len,
@@ -1231,7 +1252,6 @@ unsigned long get_unmapped_area(struct file *file, unsigned long addr,
 
        return get_area(file, addr, len, pgoff, flags);
 }
-
 EXPORT_SYMBOL(get_unmapped_area);
 
 /*
@@ -1346,6 +1366,7 @@ int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
        BUG();
        return 0;
 }
+EXPORT_SYMBOL(filemap_fault);
 
 /*
  * Access another process' address space.
index d50920ecc02bed44acc1dd3cdc2deed467b6b262..ec33fcdc852e2c72ecc95194ada98bf702d3a14a 100644 (file)
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -293,6 +293,7 @@ static void *slob_page_alloc(struct slob_page *sp, size_t size, int align)
 static void *slob_alloc(size_t size, gfp_t gfp, int align, int node)
 {
        struct slob_page *sp;
+       struct list_head *prev;
        slob_t *b = NULL;
        unsigned long flags;
 
@@ -307,12 +308,22 @@ static void *slob_alloc(size_t size, gfp_t gfp, int align, int node)
                if (node != -1 && page_to_nid(&sp->page) != node)
                        continue;
 #endif
+               /* Enough room on this page? */
+               if (sp->units < SLOB_UNITS(size))
+                       continue;
 
-               if (sp->units >= SLOB_UNITS(size)) {
-                       b = slob_page_alloc(sp, size, align);
-                       if (b)
-                               break;
-               }
+               /* Attempt to alloc */
+               prev = sp->list.prev;
+               b = slob_page_alloc(sp, size, align);
+               if (!b)
+                       continue;
+
+               /* Improve fragment distribution and reduce our average
+                * search time by starting our next search here. (see
+                * Knuth vol 1, sec 2.5, pg 449) */
+               if (free_slob_pages.next != prev->next)
+                       list_move_tail(&free_slob_pages, prev->next);
+               break;
        }
        spin_unlock_irqrestore(&slob_lock, flags);
 
index e03b39f3540f79adf384c476f185e7a9da91e4ac..3047bf06c1f3256bd59965fc064a32b439135369 100644 (file)
@@ -209,7 +209,7 @@ static int __meminit sparse_init_one_section(struct mem_section *ms,
        return 1;
 }
 
-__attribute__((weak))
+__attribute__((weak)) __init
 void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size)
 {
        return NULL;
index 38212c3f99715b173bb2c7b5f5fa49e9f49b6121..ee4035571c21b55e119bbf4c6c2f6f1a4ee085ab 100644 (file)
@@ -3624,7 +3624,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
 
        /* ensure 32-byte alignment of both the device and private area */
        alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST +
-                    (sizeof(struct net_device_subqueue) * queue_count)) &
+                    (sizeof(struct net_device_subqueue) * (queue_count - 1))) &
                     ~NETDEV_ALIGN_CONST;
        alloc_size += sizeof_priv + NETDEV_ALIGN_CONST;
 
@@ -3642,7 +3642,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
                dev->priv = ((char *)dev +
                             ((sizeof(struct net_device) +
                               (sizeof(struct net_device_subqueue) *
-                               queue_count) + NETDEV_ALIGN_CONST)
+                               (queue_count - 1)) + NETDEV_ALIGN_CONST)
                              & ~NETDEV_ALIGN_CONST));
        }
 
index bd209c4477a9d2a150dd578206a3ad18e8653a38..cfed7d42c4850525fffb56f88a65ba9f011ba9f7 100644 (file)
@@ -182,7 +182,8 @@ static const char *af_family_clock_key_strings[AF_MAX+1] = {
   "clock-21"       , "clock-AF_SNA"      , "clock-AF_IRDA"     ,
   "clock-AF_PPPOX" , "clock-AF_WANPIPE"  , "clock-AF_LLC"      ,
   "clock-27"       , "clock-28"          , "clock-29"          ,
-  "clock-AF_TIPC"  , "clock-AF_BLUETOOTH", "clock-AF_MAX"
+  "clock-AF_TIPC"  , "clock-AF_BLUETOOTH", "clock-AF_IUCV"     ,
+  "clock-AF_RXRPC" , "clock-AF_MAX"
 };
 #endif
 
index 6cbce96a54cef2cc5722f9290181ce1b090f78a0..771031dfbd0f875c807a0f82fd96a870d770c2e7 100644 (file)
@@ -158,7 +158,7 @@ static void unlink_from_unused(struct inet_peer *p)
 #define lookup(_daddr,_stack)                                  \
 ({                                                             \
        struct inet_peer *u, **v;                               \
-       if (_stack) {                                           \
+       if (_stack != NULL) {                                   \
                stackptr = _stack;                              \
                *stackptr++ = &peer_root;                       \
        }                                                       \
@@ -169,7 +169,7 @@ static void unlink_from_unused(struct inet_peer *p)
                        v = &u->avl_left;                       \
                else                                            \
                        v = &u->avl_right;                      \
-               if (_stack)                                     \
+               if (_stack != NULL)                             \
                        *stackptr++ = v;                        \
                u = *v;                                         \
        }                                                       \
index 281aee42d3f0d9c35e26c1dac4863f59628c8b62..df30976f6dfd196c7f40511356131c1f9a11c09a 100644 (file)
@@ -962,8 +962,8 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
        dsfield = ipv4_get_dsfield(iph);
 
        if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS))
-               fl.fl6_flowlabel |= ntohl(((__u32)iph->tos << IPV6_TCLASS_SHIFT)
-                                         & IPV6_TCLASS_MASK);
+               fl.fl6_flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT)
+                                         & IPV6_TCLASS_MASK;
 
        err = ip6_tnl_xmit2(skb, dev, dsfield, &fl, encap_limit, &mtu);
        if (err != 0) {
index db716580e1aef6c642b3e55e6b2abdd861fc9ccd..694ea4d92fa8bd37924938e180a494dab9701bf6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * IrDA netlink layer, for stack configuration.
  *
- * Copyright (c) 2007 Samuel Ortiz <samuel@sortiz>
+ * Copyright (c) 2007 Samuel Ortiz <samuel@sortiz.org>
  *
  * Partly based on the 802.11 nelink implementation
  * (see net/wireless/nl80211.c) which is:
index ecd06738453190dc4d2a596a7d25493ed98d170b..0e69adf63bdbffa522039f1df111ccb0dcbaca99 100644 (file)
@@ -570,10 +570,12 @@ void avc_audit(u32 ssid, u32 tsid,
                case AVC_AUDIT_DATA_FS:
                        if (a->u.fs.dentry) {
                                struct dentry *dentry = a->u.fs.dentry;
-                               if (a->u.fs.mnt)
-                                       audit_avc_path(dentry, a->u.fs.mnt);
-                               audit_log_format(ab, " name=");
-                               audit_log_untrustedstring(ab, dentry->d_name.name);
+                               if (a->u.fs.mnt) {
+                                       audit_log_d_path(ab, "path=", dentry, a->u.fs.mnt);
+                               } else {
+                                       audit_log_format(ab, " name=");
+                                       audit_log_untrustedstring(ab, dentry->d_name.name);
+                               }
                                inode = dentry->d_inode;
                        } else if (a->u.fs.inode) {
                                struct dentry *dentry;
@@ -624,9 +626,8 @@ void avc_audit(u32 ssid, u32 tsid,
                                case AF_UNIX:
                                        u = unix_sk(sk);
                                        if (u->dentry) {
-                                               audit_avc_path(u->dentry, u->mnt);
-                                               audit_log_format(ab, " name=");
-                                               audit_log_untrustedstring(ab, u->dentry->d_name.name);
+                                               audit_log_d_path(ab, "path=",
+                                                                u->dentry, u->mnt);
                                                break;
                                        }
                                        if (!u->addr)